Respond to CR.

pull/1/head
Matthew Chen 7 years ago committed by Matthew Chen
parent 70d14c84c4
commit 76b4deffe4

@ -3516,7 +3516,7 @@
"\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"", "\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"",
); );
INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist"; INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -4231,7 +4231,7 @@
"\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"", "\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"",
); );
INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist"; INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -4289,7 +4289,7 @@
"\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"", "\"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources\"",
); );
INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist"; INFOPLIST_FILE = "Signal/test/Supporting Files/SignalTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

@ -454,7 +454,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
progressiveSearchTimer = nil progressiveSearchTimer = nil
guard let text = searchBar.text else { guard let text = searchBar.text else {
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("GIF_PICKER_VIEW_MISSING_QUERY", OWSAlerts.showErrorAlert(message: NSLocalizedString("GIF_PICKER_VIEW_MISSING_QUERY",
comment: "Alert message shown when user tries to search for GIFs without entering any search terms.")) comment: "Alert message shown when user tries to search for GIFs without entering any search terms."))
return return
} }

@ -196,7 +196,7 @@ NS_ASSUME_NONNULL_BEGIN
return NO; return NO;
} }
if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive) { if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive) {
// Only start backups when app is in the background. // Don't start backups when app is in the background.
return NO; return NO;
} }
if (![TSAccountManager isRegistered]) { if (![TSAccountManager isRegistered]) {
@ -255,8 +255,9 @@ NS_ASSUME_NONNULL_BEGIN
if (!lastExportSuccessDate && !lastExportFailureDate) { if (!lastExportSuccessDate && !lastExportFailureDate) {
backupExportState = OWSBackupState_Idle; backupExportState = OWSBackupState_Idle;
} else if (lastExportSuccessDate && lastExportFailureDate) { } else if (lastExportSuccessDate && lastExportFailureDate) {
backupExportState = ([lastExportSuccessDate compare:lastExportFailureDate] ? OWSBackupState_Succeeded backupExportState = (([lastExportSuccessDate compare:lastExportFailureDate] == NSOrderedDescending)
: OWSBackupState_Failed); ? OWSBackupState_Succeeded
: OWSBackupState_Failed);
} else if (lastExportSuccessDate) { } else if (lastExportSuccessDate) {
backupExportState = OWSBackupState_Succeeded; backupExportState = OWSBackupState_Succeeded;
} else if (lastExportFailureDate) { } else if (lastExportFailureDate) {
@ -387,6 +388,7 @@ NS_ASSUME_NONNULL_BEGIN
[self ensureBackupExportState]; [self ensureBackupExportState];
} else { } else {
DDLogInfo(@"%@ stale backup job failed.", self.logTag);
return; return;
} }

@ -427,15 +427,15 @@ import CloudKit
switch accountStatus { switch accountStatus {
case .couldNotDetermine: case .couldNotDetermine:
Logger.error("\(self.logTag) could not determine CloudKit account status:\(String(describing: error)).") Logger.error("\(self.logTag) could not determine CloudKit account status:\(String(describing: error)).")
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_COULD_NOT_DETERMINE", comment: "Error indicating that the app could not determine that user's CloudKit account status")) OWSAlerts.showErrorAlert(message: NSLocalizedString("CLOUDKIT_STATUS_COULD_NOT_DETERMINE", comment: "Error indicating that the app could not determine that user's CloudKit account status"))
completion(false) completion(false)
case .noAccount: case .noAccount:
Logger.error("\(self.logTag) no CloudKit account.") Logger.error("\(self.logTag) no CloudKit account.")
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_NO_ACCOUNT", comment: "Error indicating that user does not have an iCloud account.")) OWSAlerts.showErrorAlert(message: NSLocalizedString("CLOUDKIT_STATUS_NO_ACCOUNT", comment: "Error indicating that user does not have an iCloud account."))
completion(false) completion(false)
case .restricted: case .restricted:
Logger.error("\(self.logTag) restricted CloudKit account.") Logger.error("\(self.logTag) restricted CloudKit account.")
OWSAlerts.showErrorAlert(withMessage: NSLocalizedString("CLOUDKIT_STATUS_RESTRICTED", comment: "Error indicating that the app was prevented from accessing the user's CloudKit account.")) OWSAlerts.showErrorAlert(message: NSLocalizedString("CLOUDKIT_STATUS_RESTRICTED", comment: "Error indicating that the app was prevented from accessing the user's CloudKit account."))
completion(false) completion(false)
case .available: case .available:
completion(true) completion(true)

@ -20,7 +20,9 @@ enum PushNotificationRequestResult: String {
class FailingTSAccountManager: TSAccountManager { class FailingTSAccountManager: TSAccountManager {
let phoneNumberAwaitingVerification = "+13235555555" let phoneNumberAwaitingVerification = "+13235555555"
override func verifyAccount(withCode: String, success: @escaping () -> Void, failure: @escaping (Error) -> Void) { override func verifyAccount(withCode: String,
pin: String?,
success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
failure(VerificationFailedError()) failure(VerificationFailedError())
} }
@ -34,7 +36,9 @@ class FailingTSAccountManager: TSAccountManager {
} }
class VerifyingTSAccountManager: FailingTSAccountManager { class VerifyingTSAccountManager: FailingTSAccountManager {
override func verifyAccount(withCode: String, success: @escaping () -> Void, failure: @escaping (Error) -> Void) { override func verifyAccount(withCode: String,
pin: String?,
success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
success() success()
} }
@ -57,7 +61,7 @@ class AccountManagerTest: XCTestCase {
let expectation = self.expectation(description: "should fail") let expectation = self.expectation(description: "should fail")
firstly { firstly {
accountManager.register(verificationCode: "") accountManager.register(verificationCode: "", pin: "")
}.then { }.then {
XCTFail("Should fail") XCTFail("Should fail")
}.catch { error in }.catch { error in
@ -78,7 +82,7 @@ class AccountManagerTest: XCTestCase {
let expectation = self.expectation(description: "should fail") let expectation = self.expectation(description: "should fail")
firstly { firstly {
accountManager.register(verificationCode: "123456") accountManager.register(verificationCode: "123456", pin: "")
}.then { }.then {
XCTFail("Should fail") XCTFail("Should fail")
}.catch { error in }.catch { error in
@ -103,7 +107,7 @@ class AccountManagerTest: XCTestCase {
let expectation = self.expectation(description: "should succeed") let expectation = self.expectation(description: "should succeed")
firstly { firstly {
accountManager.register(verificationCode: "123456") accountManager.register(verificationCode: "123456", pin: "")
}.then { }.then {
expectation.fulfill() expectation.fulfill()
}.catch { error in }.catch { error in

@ -6,6 +6,7 @@
#import "NumberUtil.h" #import "NumberUtil.h"
#import "TestUtil.h" #import "TestUtil.h"
#import <SignalMessaging/NSString+OWS.h> #import <SignalMessaging/NSString+OWS.h>
#import <SignalServiceKit/NSDate+OWS.h>
@interface NSString (OWS_Test) @interface NSString (OWS_Test)
@ -83,4 +84,20 @@
XCTAssertEqualObjects(@"alice\u202Dbobalice\u202Ebob".filterUnsafeCharacters, @"alice\uFFFDbobalice\uFFFDbob"); XCTAssertEqualObjects(@"alice\u202Dbobalice\u202Ebob".filterUnsafeCharacters, @"alice\uFFFDbobalice\uFFFDbob");
} }
- (void)testDateComparison
{
NSDate *firstDate = [NSDate new];
[firstDate timeIntervalSince1970];
NSDate *sameDate = [NSDate dateWithTimeIntervalSince1970:firstDate.timeIntervalSince1970];
NSDate *laterDate = [NSDate dateWithTimeIntervalSince1970:firstDate.timeIntervalSince1970 + 1.f];
XCTAssertEqualObjects(firstDate, sameDate);
XCTAssertNotEqualObjects(firstDate, laterDate);
XCTAssertTrue(firstDate.timeIntervalSinceReferenceDate < laterDate.timeIntervalSinceReferenceDate);
XCTAssertFalse([firstDate isBeforeDate:sameDate]);
XCTAssertTrue([firstDate isBeforeDate:laterDate]);
XCTAssertFalse([laterDate isBeforeDate:firstDate]);
}
@end @end

@ -31,7 +31,7 @@
/* The label for the 'don't save' button in action sheets. */ /* The label for the 'don't save' button in action sheets. */
"ALERT_DONT_SAVE" = "Don't Save"; "ALERT_DONT_SAVE" = "Don't Save";
/* Title for a generic error alert. */ /* No comment provided by engineer. */
"ALERT_ERROR_TITLE" = "Error"; "ALERT_ERROR_TITLE" = "Error";
/* The label for the 'save' button in action sheets. */ /* The label for the 'save' button in action sheets. */
@ -115,12 +115,12 @@
/* Attachment error message for video attachments which could not be converted to MP4 */ /* Attachment error message for video attachments which could not be converted to MP4 */
"ATTACHMENT_ERROR_COULD_NOT_CONVERT_TO_MP4" = "Unable to process video."; "ATTACHMENT_ERROR_COULD_NOT_CONVERT_TO_MP4" = "Unable to process video.";
/* Attachment error message for image attachments in which metadata could not be removed */
"ATTACHMENT_ERROR_COULD_NOT_REMOVE_METADATA" = "Unable to remove metadata from image.";
/* Attachment error message for image attachments which cannot be parsed */ /* Attachment error message for image attachments which cannot be parsed */
"ATTACHMENT_ERROR_COULD_NOT_PARSE_IMAGE" = "Image attachment could not be parsed."; "ATTACHMENT_ERROR_COULD_NOT_PARSE_IMAGE" = "Image attachment could not be parsed.";
/* Attachment error message for image attachments in which metadata could not be removed */
"ATTACHMENT_ERROR_COULD_NOT_REMOVE_METADATA" = "Unable to remove metadata from image.";
/* Attachment error message for attachments whose data exceed file size limits */ /* Attachment error message for attachments whose data exceed file size limits */
"ATTACHMENT_ERROR_FILE_SIZE_TOO_LARGE" = "Attachment is too large."; "ATTACHMENT_ERROR_FILE_SIZE_TOO_LARGE" = "Attachment is too large.";
@ -157,42 +157,35 @@
/* button text for back button */ /* button text for back button */
"BACK_BUTTON" = "Back"; "BACK_BUTTON" = "Back";
/* Message indicating that backup export is complete. */ /* Error indicating the a backup export could not export the user's data. */
"BACKUP_EXPORT_COMPLETE_MESSAGE" = "Backup complete."; "BACKUP_EXPORT_ERROR_COULD_NOT_EXPORT" = "Backup data could be exported.";
/* Label for button that copies backup password to the
// pasteboard. */
"BACKUP_EXPORT_COPY_PASSWORD_BUTTON" = "Copy Password";
/* Message indicating that backup export failed. */ /* Error indicating the a backup export failed to save a file to the cloud. */
"BACKUP_EXPORT_FAILED_MESSAGE" = "BACKUP_EXPORT_FAILED_MESSAGE"; "BACKUP_EXPORT_ERROR_SAVE_FILE_TO_CLOUD_FAILED" = "Backup could not upload data.";
/* Message indicating that backup export is in progress. */ /* Indicates that the cloud is being cleaned up. */
"BACKUP_EXPORT_IN_PROGRESS_MESSAGE" = "Exporting Backup..."; "BACKUP_EXPORT_PHASE_CLEAN_UP" = "Cleaning up backup data.";
/* Format for message indicating that backup export is complete. Embeds: {{the backup password}}. */ /* Indicates that the backup export is being configured. */
"BACKUP_EXPORT_PASSWORD_MESSAGE_FORMAT" = "Your backup password is: %@. Make sure to keep a copy of this password or you won't be able to restore from this backup."; "BACKUP_EXPORT_PHASE_CONFIGURATION" = "Initializing backup.";
/* Label for button that 'send backup' in the current /* Indicates that the backup export data is being exported. */
// conversation. */ "BACKUP_EXPORT_PHASE_EXPORT" = "Exporting backup data.";
"BACKUP_EXPORT_SEND_BACKUP_BUTTON" = "Send Backup as Message";
/* Message indicating that sending /* Indicates that the backup export data is being uploaded. */
// the backup failed. */ "BACKUP_EXPORT_PHASE_UPLOAD" = "Uploading backup data.";
"BACKUP_EXPORT_SEND_BACKUP_FAILED" = "Sending Backup Failed.";
/* Message indicating that sending the backup succeeded. */ /* Error indicating the a backup import could not import the user's data. */
"BACKUP_EXPORT_SEND_BACKUP_SUCCESS" = "Backup Sent."; "BACKUP_IMPORT_ERROR_COULD_NOT_IMPORT" = "Backup could not be imported.";
/* Label for button that opens share UI for backup. */ /* Error indicating the a backup import failed to download a file from the cloud. */
"BACKUP_EXPORT_SHARE_BACKUP_BUTTON" = "Share Backup"; "BACKUP_IMPORT_ERROR_DOWNLOAD_FILE_FROM_CLOUD_FAILED" = "Could not download backup data.";
/* Title for the 'backup export' /* Indicates that the backup import is being configured. */
// view. */ "BACKUP_IMPORT_PHASE_CONFIGURATION" = "Configuring backup restore.";
"BACKUP_EXPORT_VIEW_TITLE" = "Backup";
/* Format for backup filenames. Embeds: {{the date and time of the backup}}. Should not include characters like slash (/ or \\) or colon (:). */ /* Indicates that the backup import data is being imported. */
"BACKUP_FILENAME_FORMAT" = "Signal Backup %@"; "BACKUP_IMPORT_PHASE_IMPORT" = "Importing backup.";
/* An explanation of the consequences of blocking another user. */ /* An explanation of the consequences of blocking another user. */
"BLOCK_BEHAVIOR_EXPLANATION" = "Blocked users will not be able to call you or send you messages."; "BLOCK_BEHAVIOR_EXPLANATION" = "Blocked users will not be able to call you or send you messages.";
@ -323,6 +316,15 @@
/* Title for the 'censorship circumvention country' view. */ /* Title for the 'censorship circumvention country' view. */
"CENSORSHIP_CIRCUMVENTION_COUNTRY_VIEW_TITLE" = "Select Country"; "CENSORSHIP_CIRCUMVENTION_COUNTRY_VIEW_TITLE" = "Select Country";
/* Error indicating that the app could not determine that user's CloudKit account status */
"CLOUDKIT_STATUS_COULD_NOT_DETERMINE" = "CLOUDKIT_STATUS_COULD_NOT_DETERMINE";
/* Error indicating that user does not have an iCloud account. */
"CLOUDKIT_STATUS_NO_ACCOUNT" = "CLOUDKIT_STATUS_NO_ACCOUNT";
/* Error indicating that the app was prevented from accessing the user's CloudKit account. */
"CLOUDKIT_STATUS_RESTRICTED" = "CLOUDKIT_STATUS_RESTRICTED";
/* Activity Sheet label */ /* Activity Sheet label */
"COMPARE_SAFETY_NUMBER_ACTION" = "Compare with Clipboard"; "COMPARE_SAFETY_NUMBER_ACTION" = "Compare with Clipboard";
@ -1673,20 +1675,20 @@
/* An explanation of the 'read receipts' setting. */ /* An explanation of the 'read receipts' setting. */
"SETTINGS_READ_RECEIPTS_SECTION_FOOTER" = "See and share when messages have been read. This setting is optional and applies to all conversations."; "SETTINGS_READ_RECEIPTS_SECTION_FOOTER" = "See and share when messages have been read. This setting is optional and applies to all conversations.";
/* No comment provided by engineer. */ /* Remove metadata table cell label */
"SETTINGS_SCREEN_SECURITY" = "Enable Screen Security"; "SETTINGS_REMOVE_METADATA" = "Remove Media Metadata";
/* No comment provided by engineer. */ /* Remove metadata section footer */
"SETTINGS_SCREEN_SECURITY_DETAIL" = "Prevent Signal previews from appearing in the app switcher."; "SETTINGS_REMOVE_METADATA_DETAIL" = "Removes user-identifying metadata and GPS information when sending image and video messages.";
/* Remove metadata table view header label. */ /* Remove metadata section header */
"SETTINGS_REMOVE_METADATA_TITLE" = "Metadata"; "SETTINGS_REMOVE_METADATA_TITLE" = "Metadata";
/* Label for the remove metadata setting. */ /* No comment provided by engineer. */
"SETTINGS_REMOVE_METADATA" = "Remove Media Metadata"; "SETTINGS_SCREEN_SECURITY" = "Enable Screen Security";
/* Footer label explanation of the remove metadata setting. */ /* No comment provided by engineer. */
"SETTINGS_REMOVE_METADATA_DETAIL" = "Removes user-identifying metadata and GPS information when sending image and video messages."; "SETTINGS_SCREEN_SECURITY_DETAIL" = "Prevent Signal previews from appearing in the app switcher.";
/* Settings table section footer. */ /* Settings table section footer. */
"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Call Integration shows Signal calls on your lock screen and in the system's call history. You may optionally show your contact's name and number. If iCloud is enabled, this call history will be shared with Apple."; "SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Call Integration shows Signal calls on your lock screen and in the system's call history. You may optionally show your contact's name and number. If iCloud is enabled, this call history will be shared with Apple.";

@ -55,7 +55,7 @@ import Foundation
} }
@objc @objc
public class func showErrorAlert(withMessage message: String) { public class func showErrorAlert(message message: String) {
self.showAlert(title: CommonStrings.errorAlertTitle, message: message, buttonTitle: nil) self.showAlert(title: CommonStrings.errorAlertTitle, message: message, buttonTitle: nil)
} }

@ -24,6 +24,8 @@ extern const NSTimeInterval kMonthInterval;
+ (NSDate *)ows_dateWithMillisecondsSince1970:(uint64_t)milliseconds; + (NSDate *)ows_dateWithMillisecondsSince1970:(uint64_t)milliseconds;
+ (uint64_t)ows_millisecondsSince1970ForDate:(NSDate *)date; + (uint64_t)ows_millisecondsSince1970ForDate:(NSDate *)date;
- (BOOL)isBeforeDate:(NSDate *)otherDate;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -32,6 +32,11 @@ const NSTimeInterval kMonthInterval = 30 * kDayInterval;
return (uint64_t)(date.timeIntervalSince1970 * 1000); return (uint64_t)(date.timeIntervalSince1970 * 1000);
} }
- (BOOL)isBeforeDate:(NSDate *)otherDate
{
return [self compare:otherDate] == NSOrderedAscending;
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save