diff --git a/Pods b/Pods index 34b98cdc3..4a40f1590 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 34b98cdc33f8cec77b845f5e513500fb85d423a2 +Subproject commit 4a40f1590bbff2c9725a6925c077ad6e67bdda6e diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index a5f0b7ad7..bf40528d2 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -964,7 +964,6 @@ 34D920E620E179C200D51158 /* OWSMessageFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageFooterView.m; sourceTree = ""; }; 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = ""; }; 34D99CE3217509C1000AFB39 /* AppEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppEnvironment.swift; sourceTree = ""; }; - 34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDatabaseConverterTest.h; sourceTree = ""; }; 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDatabaseConverterTest.m; sourceTree = ""; }; 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageTextView.m; sourceTree = ""; }; 34DBF000206BD5A400025978 /* OWSMessageTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTextView.h; sourceTree = ""; }; @@ -2386,7 +2385,6 @@ 45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */, B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */, 455AC69D1F4F8B0300134004 /* ImageCacheTest.swift */, - 34DB0BEB2011548A007B313F /* OWSDatabaseConverterTest.h */, 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */, 34843B25214327C9004DED45 /* OWSOrphanDataCleanerTest.m */, 45666F571D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m */, diff --git a/Signal/test/util/CDSSigningCertificateTest.m b/Signal/test/util/CDSSigningCertificateTest.m index db03dd751..7f0e6c014 100644 --- a/Signal/test/util/CDSSigningCertificateTest.m +++ b/Signal/test/util/CDSSigningCertificateTest.m @@ -17,15 +17,20 @@ - (void)testParsing_good { NSString *pem = [self certificatesPem_good]; - CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem]; + NSError *error; + CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem error:&error]; XCTAssertNotNil(certificate); + XCTAssertNil(error); } - (void)testParsing_bad { NSString *pem = [self certificatesPem_bad]; - - XCTAssertThrows([CDSSigningCertificate parseCertificateFromPem:pem]); + NSError *error; + CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem error:&error]; + XCTAssertNil(certificate); + XCTAssertNotNil(error); + XCTAssertEqual(error.code, CDSSigningCertificateError_InvalidDistinguishedName); } - (void)testVerification_good @@ -33,9 +38,11 @@ NSString *pem = [self certificatesPem_good]; NSData *signature = [self signature_good]; NSString *bodyString = [self bodyString_good]; - - CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem]; + + NSError *error; + CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem error:&error]; XCTAssertNotNil(certificate); + XCTAssertNil(error); BOOL result = [certificate verifySignatureOfBody:bodyString signature:signature]; XCTAssertTrue(result); @@ -46,11 +53,13 @@ NSString *pem = [self certificatesPem_good]; NSData *signature = [self signature_good]; NSString *bodyString = [self bodyString_bad]; - - CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem]; - XCTAssertNotNil(certificate); - XCTAssertThrows([certificate verifySignatureOfBody:bodyString signature:signature]); + NSError *error; + CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem error:&error]; + XCTAssertNotNil(certificate); + XCTAssertNil(error); + + XCTAssertFalse([certificate verifySignatureOfBody:bodyString signature:signature]); } - (void)testVerification_badSignature @@ -58,13 +67,17 @@ NSString *pem = [self certificatesPem_good]; NSData *signature = [self signature_bad]; NSString *bodyString = [self bodyString_good]; - - CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem]; - XCTAssertNotNil(certificate); - XCTAssertThrows([certificate verifySignatureOfBody:bodyString signature:signature]); + NSError *error; + CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:pem error:&error]; + XCTAssertNotNil(certificate); + XCTAssertNil(error); + + XCTAssertFalse([certificate verifySignatureOfBody:bodyString signature:signature]); } +#pragma mark - test values + - (NSString *)certificatesPem_good { return @"-----BEGIN CERTIFICATE----- \ MIIEoTCCAwmgAwIBAgIJANEHdl0yo7CWMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV \ diff --git a/Signal/test/util/FunctionalUtilTest.m b/Signal/test/util/FunctionalUtilTest.m index 9da0540fb..df286cbc5 100644 --- a/Signal/test/util/FunctionalUtilTest.m +++ b/Signal/test/util/FunctionalUtilTest.m @@ -38,15 +38,6 @@ test([[(@[@1,@2]) filter:^(NSNumber* x) { return x.intValue == 2; }] isEqualToArray:(@[@2])]); } --(void) testKeyedBy { - test([[@[] keyedBy:^id(id value) { return @true; }] isEqual:@{}]); - test([[@[@1] keyedBy:^id(id value) { return @true; }] isEqual:@{@true : @1}]); - testThrows(([(@[@1, @2]) keyedBy:^id(id value) { return @true; }])); - test([[(@[@1, @2]) keyedBy:^id(id value) { return value; }] isEqual:(@{@1 : @1, @2 : @2})]); - testThrows([(@[@1, @1, @2, @3, @5]) keyedBy:^id(NSNumber* value) { return @(value.intValue/2); }]); - test([[(@[@3, @5, @7, @11, @13]) keyedBy:^id(NSNumber* value) { return @(value.intValue/2); }] isEqual:(@{@1 : @3, @2 : @5, @3 : @7, @5 : @11, @6 : @13})]); -} - -(void) testGroupBy { test([[@[] groupBy:^id(id value) { return @true; }] isEqual:@{}]); test([[@[@1] groupBy:^id(id value) { return @true; }] isEqual:@{@true : @[@1]}]); diff --git a/Signal/test/util/OWSDatabaseConverterTest.h b/Signal/test/util/OWSDatabaseConverterTest.h deleted file mode 100644 index de2c82a74..000000000 --- a/Signal/test/util/OWSDatabaseConverterTest.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import "SignalBaseTest.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface OWSDatabaseConverterTest : SignalBaseTest - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/test/util/OWSDatabaseConverterTest.m b/Signal/test/util/OWSDatabaseConverterTest.m index c54518628..f44603e46 100644 --- a/Signal/test/util/OWSDatabaseConverterTest.m +++ b/Signal/test/util/OWSDatabaseConverterTest.m @@ -2,7 +2,7 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // -#import "OWSDatabaseConverterTest.h" +#import "SignalBaseTest.h" #import #import #import @@ -39,6 +39,12 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - +@interface OWSDatabaseConverterTest : SignalBaseTest + +@end + +#pragma mark - + @implementation OWSDatabaseConverterTest - (NSData *)randomDatabasePassword diff --git a/Signal/test/util/UtilTest.m b/Signal/test/util/UtilTest.m index 548879d52..0c4522a32 100644 --- a/Signal/test/util/UtilTest.m +++ b/Signal/test/util/UtilTest.m @@ -35,7 +35,6 @@ @implementation UtilTest -(void) testRemoveAllCharactersIn { - testThrows([@"" removeAllCharactersIn:nil]); test([[@"" removeAllCharactersIn:NSCharacterSet.letterCharacterSet] isEqual:@""]); test([[@"1" removeAllCharactersIn:NSCharacterSet.letterCharacterSet] isEqual:@"1"]); diff --git a/SignalServiceKit/src/Contacts/CDSSigningCertificate.h b/SignalServiceKit/src/Contacts/CDSSigningCertificate.h index 37067cb33..ef9721a4b 100644 --- a/SignalServiceKit/src/Contacts/CDSSigningCertificate.h +++ b/SignalServiceKit/src/Contacts/CDSSigningCertificate.h @@ -4,9 +4,24 @@ NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSUInteger, CDSSigningCertificateErrorCode) { + // AssertionError's indicate either developer or some serious system error that should never happen. + // + // Do not use this for an "expected" error, e.g. something that could be induced by user input which + // we specifically need to handle gracefull. + CDSSigningCertificateError_AssertionError = 1, + + CDSSigningCertificateError_InvalidPEMSupplied, + CDSSigningCertificateError_CouldNotExtractLeafCertificate, + CDSSigningCertificateError_InvalidDistinguishedName, + CDSSigningCertificateError_UntrustedCertificate +}; + +NSError *CDSSigningCertificateErrorMake(CDSSigningCertificateErrorCode code, NSString *localizedDescription); + @interface CDSSigningCertificate : NSObject -+ (nullable CDSSigningCertificate *)parseCertificateFromPem:(NSString *)certificatePem; ++ (nullable CDSSigningCertificate *)parseCertificateFromPem:(NSString *)certificatePem error:(NSError **)error; - (BOOL)verifySignatureOfBody:(NSString *)body signature:(NSData *)theirSignature; diff --git a/SignalServiceKit/src/Contacts/CDSSigningCertificate.m b/SignalServiceKit/src/Contacts/CDSSigningCertificate.m index 448b4d92c..a7e5f1f0c 100644 --- a/SignalServiceKit/src/Contacts/CDSSigningCertificate.m +++ b/SignalServiceKit/src/Contacts/CDSSigningCertificate.m @@ -10,6 +10,13 @@ NS_ASSUME_NONNULL_BEGIN +NSError *CDSSigningCertificateErrorMake(CDSSigningCertificateErrorCode code, NSString *localizedDescription) +{ + return [NSError errorWithDomain:@"CDSSigningCertificate" + code:code + userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }]; +} + @interface CDSSigningCertificate () @property (nonatomic) SecPolicyRef policy; @@ -49,15 +56,18 @@ NS_ASSUME_NONNULL_BEGIN } } -+ (nullable CDSSigningCertificate *)parseCertificateFromPem:(NSString *)certificatePem ++ (nullable CDSSigningCertificate *)parseCertificateFromPem:(NSString *)certificatePem error:(NSError **)error { OWSAssertDebug(certificatePem); + *error = nil; CDSSigningCertificate *signingCertificate = [CDSSigningCertificate new]; NSArray *_Nullable anchorCertificates = [self anchorCertificates]; if (anchorCertificates.count < 1) { OWSFailDebug(@"Could not load anchor certificates."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Could not load anchor certificates."); return nil; } @@ -65,6 +75,7 @@ NS_ASSUME_NONNULL_BEGIN if (certificateDerDatas.count < 1) { OWSFailDebug(@"Could not parse PEM."); + *error = CDSSigningCertificateErrorMake(CDSSigningCertificateError_InvalidPEMSupplied, @"Could not parse PEM."); return nil; } @@ -72,10 +83,14 @@ NS_ASSUME_NONNULL_BEGIN NSData *_Nullable leafCertificateData = [certificateDerDatas firstObject]; if (!leafCertificateData) { OWSFailDebug(@"Could not extract leaf certificate data."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_CouldNotExtractLeafCertificate, @"Could not extract leaf certificate data."); return nil; } if (![self verifyDistinguishedNameOfCertificate:leafCertificateData]) { OWSFailDebug(@"Leaf certificate has invalid name."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_InvalidDistinguishedName, @"Could not extract leaf certificate data."); return nil; } @@ -83,7 +98,9 @@ NS_ASSUME_NONNULL_BEGIN for (NSData *certificateDerData in certificateDerDatas) { SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certificateDerData)); if (!certificate) { - OWSFailDebug(@"Could not load DER."); + OWSFailDebug(@"Could not create SecCertificate."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Could not create SecCertificate."); return nil; } [certificates addObject:(__bridge_transfer id)certificate]; @@ -93,6 +110,7 @@ NS_ASSUME_NONNULL_BEGIN signingCertificate.policy = policy; if (!policy) { OWSFailDebug(@"Could not create policy."); + *error = CDSSigningCertificateErrorMake(CDSSigningCertificateError_AssertionError, @"Could not create policy."); return nil; } @@ -100,23 +118,30 @@ NS_ASSUME_NONNULL_BEGIN OSStatus status = SecTrustCreateWithCertificates((__bridge CFTypeRef)certificates, policy, &trust); signingCertificate.trust = trust; if (status != errSecSuccess) { - OWSFailDebug(@"trust could not be created."); + OWSFailDebug(@"Creating trust did not succeed."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Creating trust did not succeed."); return nil; } if (!trust) { OWSFailDebug(@"Could not create trust."); + *error = CDSSigningCertificateErrorMake(CDSSigningCertificateError_AssertionError, @"Could not create trust."); return nil; } status = SecTrustSetNetworkFetchAllowed(trust, NO); if (status != errSecSuccess) { OWSFailDebug(@"trust fetch could not be configured."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"trust fetch could not be configured."); return nil; } status = SecTrustSetAnchorCertificatesOnly(trust, YES); if (status != errSecSuccess) { OWSFailDebug(@"trust anchor certs could not be configured."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"trust anchor certs could not be configured."); return nil; } @@ -124,7 +149,9 @@ NS_ASSUME_NONNULL_BEGIN for (NSData *certificateData in anchorCertificates) { SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certificateData)); if (!certificate) { - OWSFailDebug(@"Could not load DER."); + OWSFailDebug(@"Could not create pinned SecCertificate."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Could not create pinned SecCertificate."); return nil; } @@ -133,6 +160,8 @@ NS_ASSUME_NONNULL_BEGIN status = SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)pinnedCertificates); if (status != errSecSuccess) { OWSFailDebug(@"The anchor certificates couldn't be set."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"The anchor certificates couldn't be set."); return nil; } @@ -140,6 +169,8 @@ NS_ASSUME_NONNULL_BEGIN status = SecTrustEvaluate(trust, &result); if (status != errSecSuccess) { OWSFailDebug(@"Could not evaluate certificates."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Could not evaluate certificates."); return nil; } @@ -147,7 +178,9 @@ NS_ASSUME_NONNULL_BEGIN // See the comments in the header where it is defined. BOOL isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); if (!isValid) { - OWSFailDebug(@"Certificate evaluation failed."); + OWSFailDebug(@"Certificate was not trusted."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_UntrustedCertificate, @"Certificate was not trusted."); return nil; } @@ -155,6 +188,8 @@ NS_ASSUME_NONNULL_BEGIN signingCertificate.publicKey = publicKey; if (!publicKey) { OWSFailDebug(@"Could not extract public key."); + *error = CDSSigningCertificateErrorMake( + CDSSigningCertificateError_AssertionError, @"Could not extract public key."); return nil; } diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m index 757fb1dd1..a14920e26 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m @@ -509,7 +509,14 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont OWSAssertDebug(signature.length > 0); OWSAssertDebug(quoteData); - CDSSigningCertificate *_Nullable certificate = [CDSSigningCertificate parseCertificateFromPem:certificates]; + NSError *error; + CDSSigningCertificate *_Nullable certificate = + [CDSSigningCertificate parseCertificateFromPem:certificates error:&error]; + if (error) { + OWSFailDebug(@"error when parsing signing certificate. %@", error.localizedDescription); + return NO; + } + if (!certificate) { OWSFailDebug(@"could not parse signing certificate."); return NO; diff --git a/SignalServiceKit/src/Util/FunctionalUtil.h b/SignalServiceKit/src/Util/FunctionalUtil.h index 021997a8f..4b4fd0c48 100644 --- a/SignalServiceKit/src/Util/FunctionalUtil.h +++ b/SignalServiceKit/src/Util/FunctionalUtil.h @@ -10,16 +10,12 @@ /// Returns true when all of the items in this array match the given predicate. - (bool)all:(int (^)(id item))predicate; -/// Returns the first item in this array that matches the given predicate, or else returns nil if none match it. -- (id)firstMatchingElseNil:(int (^)(id item))predicate; - /// Returns an array of all the results of passing items from this array through the given projection function. - (NSArray *)map:(id (^)(id item))projection; /// Returns an array of all the results of passing items from this array through the given projection function. - (NSArray *)filter:(int (^)(id item))predicate; -- (NSDictionary *)keyedBy:(id (^)(id))keySelector; - (NSDictionary *)groupBy:(id (^)(id value))keySelector; @end diff --git a/SignalServiceKit/src/Util/FunctionalUtil.m b/SignalServiceKit/src/Util/FunctionalUtil.m index a33279b79..8065d6cc5 100644 --- a/SignalServiceKit/src/Util/FunctionalUtil.m +++ b/SignalServiceKit/src/Util/FunctionalUtil.m @@ -46,15 +46,6 @@ } return true; } -- (id)firstMatchingElseNil:(int (^)(id item))predicate { - tskit_require(predicate != nil); - for (id e in self) { - if (predicate(e)) { - return e; - } - } - return nil; -} - (NSArray *)map:(id (^)(id item))projection { tskit_require(projection != nil); @@ -76,18 +67,6 @@ return r; } -- (NSDictionary *)keyedBy:(id (^)(id value))keySelector { - tskit_require(keySelector != nil); - - NSMutableDictionary *result = [NSMutableDictionary dictionary]; - - for (id value in self) { - result[keySelector(value)] = value; - } - tskit_require(result.count == self.count); - - return result; -} - (NSDictionary *)groupBy:(id (^)(id value))keySelector { tskit_require(keySelector != nil); diff --git a/SignalServiceKit/tests/Account/SignedPreKeyDeletionTests.m b/SignalServiceKit/tests/Account/SignedPreKeyDeletionTests.m index 8b6dafb50..8788fe965 100644 --- a/SignalServiceKit/tests/Account/SignedPreKeyDeletionTests.m +++ b/SignalServiceKit/tests/Account/SignedPreKeyDeletionTests.m @@ -9,7 +9,7 @@ @interface TSPreKeyManager (Testing) -+ (void)clearSignedPreKeyRecordsWithKeyId:(NSNumber *)keyId success:(void (^_Nullable)(void))successHandler; ++ (void)clearSignedPreKeyRecordsWithKeyId:(NSNumber *)keyId; @end @@ -41,7 +41,10 @@ int secondsAgo = (i - days) * 24 * 60 * 60; NSAssert(secondsAgo <= 0, @"Time in past must be negative"); NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo]; - SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i keyPair:[Curve25519 generateKeyPair] signature:nil generatedAt:generatedAt]; + SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i + keyPair:[Curve25519 generateKeyPair] + signature:[NSData new] + generatedAt:generatedAt]; [[OWSPrimaryStorage sharedManager] storeSignedPreKey:i signedPreKeyRecord:record]; } @@ -49,21 +52,12 @@ // Sanity check XCTAssert(signedPreKeys.count == 21); - XCTestExpectation *expection = [self expectationWithDescription:@"successfully cleared old keys"]; - [TSPreKeyManager - clearSignedPreKeyRecordsWithKeyId:[NSNumber numberWithInt:lastPreKeyId] - success:^{ - XCTAssert( - [[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); + [TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)]; + XCTAssert([[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); - // We'll delete every key created 7 or more days ago. - NSArray *signedPreKeys = - [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; - XCTAssert(signedPreKeys.count == 7); - [expection fulfill]; - }]; - - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + // We'll delete every key created 7 or more days ago. + signedPreKeys = [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; + XCTAssert(signedPreKeys.count == 7); } - (void)testSignedPreKeyDeletionKeepsSomeOldKeys @@ -80,7 +74,7 @@ NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo]; SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i keyPair:[Curve25519 generateKeyPair] - signature:nil + signature:[NSData new] generatedAt:generatedAt]; // we only retain accepted keys [record markAsAcceptedByService]; @@ -92,22 +86,14 @@ // Sanity check XCTAssert(signedPreKeys.count == 11); - XCTestExpectation *expection = [self expectationWithDescription:@"successfully cleared old keys"]; - [TSPreKeyManager - clearSignedPreKeyRecordsWithKeyId:[NSNumber numberWithInt:lastPreKeyId] - success:^{ - XCTAssert( - [[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); + [TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)]; - NSArray *signedPreKeys = - [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; + XCTAssert([[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); - // We need to keep 3 "old" keys, plus the "current" key - XCTAssert(signedPreKeys.count == 4); - [expection fulfill]; - }]; + signedPreKeys = [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + // We need to keep 3 "old" keys, plus the "current" key + XCTAssert(signedPreKeys.count == 4); } - (void)testOlderRecordsNotDeletedIfNoReplacement { @@ -123,7 +109,10 @@ int secondsAgo = (i - days) * 24 * 60 * 60; NSAssert(secondsAgo <= 0, @"Time in past must be negative"); NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo]; - SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i keyPair:[Curve25519 generateKeyPair] signature:nil generatedAt:generatedAt]; + SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i + keyPair:[Curve25519 generateKeyPair] + signature:[NSData new] + generatedAt:generatedAt]; [[OWSPrimaryStorage sharedManager] storeSignedPreKey:i signedPreKeyRecord:record]; } @@ -131,20 +120,12 @@ // Sanity check XCTAssert(signedPreKeys.count == 4); - XCTestExpectation *expection = [self expectationWithDescription:@"successfully cleared old keys"]; - [TSPreKeyManager - clearSignedPreKeyRecordsWithKeyId:[NSNumber numberWithInt:lastPreKeyId] - success:^{ - XCTAssert( - [[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); - // All three records should still be stored. - NSArray *signedPreKeys = - [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; - XCTAssert(signedPreKeys.count == 4); - [expection fulfill]; - }]; + [TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)]; + XCTAssert([[OWSPrimaryStorage sharedManager] loadSignedPrekey:lastPreKeyId] != nil); - [self waitForExpectationsWithTimeout:5.0 handler:nil]; + // All three records should still be stored. + signedPreKeys = [[OWSPrimaryStorage sharedManager] loadSignedPreKeys]; + XCTAssert(signedPreKeys.count == 4); } #endif diff --git a/SignalServiceKit/tests/SSKSwiftTests.swift b/SignalServiceKit/tests/SSKSwiftTests.swift index 9ebb6c5b5..60d8d3aee 100644 --- a/SignalServiceKit/tests/SSKSwiftTests.swift +++ b/SignalServiceKit/tests/SSKSwiftTests.swift @@ -4,6 +4,10 @@ import XCTest +///// +// Swift Test vs. Cocoapods issue #1 +///// +// // Cocoapods-generated test targets (like this one) // fail to link if: // @@ -14,3 +18,23 @@ import XCTest // to our test target. // // See: https://github.com/CocoaPods/CocoaPods/issues/7170 + +///// +// Swift Test vs. Cocoapods issue #2 +///// +// +// XCode's test runner doesn't copy swift framework's required by dependencies into +// the running test bundle. +// It sounds similar to this issue: https://github.com/CocoaPods/CocoaPods/issues/7985 +// +// The error output looks like this: +// The bundle “SignalServiceKit-Unit-Tests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle. +// [...]/SignalServiceKit-Unit-Tests.xctest/SignalServiceKit-Unit-Tests): Library not loaded: @rpath/libswiftAVFoundation.dylib +// Referenced from: /Users/[...]/Build/Products/Debug-iphonesimulator/SignalServiceKit/SignalServiceKit.framework/SignalServiceKit +// Reason: image not found) +// Program ended with exit code: 82 +// +// A work around is to redundantly import any swift frameworks used by the dependencies of the test suite into this test file. +// The error message provides a hint, i.e. "Library not loaded: @rpath/libswiftAVFoundation.dylib" is fixed with `import AVFoundation` +import AVFoundation +import CloudKit