Don't start expiration timer until message is sent.

Started extracting a MessageSender class from TSMessagesManager+send for
easier testability and in hopes of further slimming down that son of a
gun.

// FREEBIE
pull/1/head
Michael Kirk 9 years ago
parent 0b4d81002f
commit 8fed13f9bb

@ -12,6 +12,9 @@
450E3C9A1D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */; }; 450E3C9A1D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */; };
452EE6CF1D4A754C00E934BA /* TSThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 452EE6CE1D4A754C00E934BA /* TSThreadTest.m */; }; 452EE6CF1D4A754C00E934BA /* TSThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 452EE6CE1D4A754C00E934BA /* TSThreadTest.m */; };
452EE6D51D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 452EE6D41D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m */; }; 452EE6D51D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 452EE6D41D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m */; };
453E1FCF1DA8313100DDD7B7 /* OWSMessageSenderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 453E1FCE1DA8313100DDD7B7 /* OWSMessageSenderTest.m */; };
453E1FD81DA83E1000DDD7B7 /* OWSFakeContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 453E1FD71DA83E1000DDD7B7 /* OWSFakeContactsManager.m */; };
453E1FDB1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 453E1FDA1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m */; };
454021ED1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */; }; 454021ED1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */; };
45458B751CC342B600A02153 /* SignedPreKeyDeletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B6A1CC342B600A02153 /* SignedPreKeyDeletionTests.m */; }; 45458B751CC342B600A02153 /* SignedPreKeyDeletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B6A1CC342B600A02153 /* SignedPreKeyDeletionTests.m */; };
45458B761CC342B600A02153 /* TSAttachmentsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B6C1CC342B600A02153 /* TSAttachmentsTest.m */; }; 45458B761CC342B600A02153 /* TSAttachmentsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B6C1CC342B600A02153 /* TSAttachmentsTest.m */; };
@ -21,6 +24,7 @@
45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */; }; 45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */; };
45458B7B1CC342B600A02153 /* CryptographyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B731CC342B600A02153 /* CryptographyTests.m */; }; 45458B7B1CC342B600A02153 /* CryptographyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B731CC342B600A02153 /* CryptographyTests.m */; };
45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B741CC342B600A02153 /* MessagePaddingTests.m */; }; 45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45458B741CC342B600A02153 /* MessagePaddingTests.m */; };
45731A6C1DA87AA1007E22AA /* TSOutgoingMessageTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45731A6B1DA87AA1007E22AA /* TSOutgoingMessageTest.m */; };
459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */; }; 459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */; };
45A856AC1D220BFF0056CD4D /* TSAttributesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */; }; 45A856AC1D220BFF0056CD4D /* TSAttributesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */; };
45B700971D9841E400269FFD /* OWSDisappearingMessagesConfigurationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45B700961D9841E400269FFD /* OWSDisappearingMessagesConfigurationTest.m */; }; 45B700971D9841E400269FFD /* OWSDisappearingMessagesConfigurationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45B700961D9841E400269FFD /* OWSDisappearingMessagesConfigurationTest.m */; };
@ -56,6 +60,11 @@
450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSDisappearingMessagesJobTest.m; path = ../../../tests/Messages/OWSDisappearingMessagesJobTest.m; sourceTree = "<group>"; }; 450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSDisappearingMessagesJobTest.m; path = ../../../tests/Messages/OWSDisappearingMessagesJobTest.m; sourceTree = "<group>"; };
452EE6CE1D4A754C00E934BA /* TSThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSThreadTest.m; path = ../../../tests/Contacts/TSThreadTest.m; sourceTree = "<group>"; }; 452EE6CE1D4A754C00E934BA /* TSThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSThreadTest.m; path = ../../../tests/Contacts/TSThreadTest.m; sourceTree = "<group>"; };
452EE6D41D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOrphanedDataCleanerTest.m; sourceTree = "<group>"; }; 452EE6D41D4AC43300E934BA /* OWSOrphanedDataCleanerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOrphanedDataCleanerTest.m; sourceTree = "<group>"; };
453E1FCE1DA8313100DDD7B7 /* OWSMessageSenderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSMessageSenderTest.m; path = ../../../tests/Messages/OWSMessageSenderTest.m; sourceTree = "<group>"; };
453E1FD61DA83E1000DDD7B7 /* OWSFakeContactsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSFakeContactsManager.h; path = ../../../tests/TestSupport/Fakes/OWSFakeContactsManager.h; sourceTree = "<group>"; };
453E1FD71DA83E1000DDD7B7 /* OWSFakeContactsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSFakeContactsManager.m; path = ../../../tests/TestSupport/Fakes/OWSFakeContactsManager.m; sourceTree = "<group>"; };
453E1FD91DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSFakeContactsUpdater.h; path = ../../../tests/TestSupport/Fakes/OWSFakeContactsUpdater.h; sourceTree = "<group>"; };
453E1FDA1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSFakeContactsUpdater.m; path = ../../../tests/TestSupport/Fakes/OWSFakeContactsUpdater.m; sourceTree = "<group>"; };
454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSDisappearingMessageFinderTest.m; path = ../../../tests/Messages/OWSDisappearingMessageFinderTest.m; sourceTree = "<group>"; }; 454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSDisappearingMessageFinderTest.m; path = ../../../tests/Messages/OWSDisappearingMessageFinderTest.m; sourceTree = "<group>"; };
45458B6A1CC342B600A02153 /* SignedPreKeyDeletionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignedPreKeyDeletionTests.m; sourceTree = "<group>"; }; 45458B6A1CC342B600A02153 /* SignedPreKeyDeletionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignedPreKeyDeletionTests.m; sourceTree = "<group>"; };
45458B6C1CC342B600A02153 /* TSAttachmentsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentsTest.m; sourceTree = "<group>"; }; 45458B6C1CC342B600A02153 /* TSAttachmentsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentsTest.m; sourceTree = "<group>"; };
@ -65,6 +74,7 @@
45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSStorageSignedPreKeyStore.m; sourceTree = "<group>"; }; 45458B711CC342B600A02153 /* TSStorageSignedPreKeyStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSStorageSignedPreKeyStore.m; sourceTree = "<group>"; };
45458B731CC342B600A02153 /* CryptographyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptographyTests.m; sourceTree = "<group>"; }; 45458B731CC342B600A02153 /* CryptographyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptographyTests.m; sourceTree = "<group>"; };
45458B741CC342B600A02153 /* MessagePaddingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagePaddingTests.m; sourceTree = "<group>"; }; 45458B741CC342B600A02153 /* MessagePaddingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagePaddingTests.m; sourceTree = "<group>"; };
45731A6B1DA87AA1007E22AA /* TSOutgoingMessageTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSOutgoingMessageTest.m; path = ../../../tests/Messages/Interactions/TSOutgoingMessageTest.m; sourceTree = "<group>"; };
459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PhoneNumberTest.m; path = ../../../tests/Contacts/PhoneNumberTest.m; sourceTree = "<group>"; }; 459850C01D22C6F2006FFEDB /* PhoneNumberTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PhoneNumberTest.m; path = ../../../tests/Contacts/PhoneNumberTest.m; sourceTree = "<group>"; };
459FE0DA1D4AD49E00E1071A /* TSKitiOSTestApp-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TSKitiOSTestApp-Prefix.pch"; sourceTree = "<group>"; }; 459FE0DA1D4AD49E00E1071A /* TSKitiOSTestApp-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TSKitiOSTestApp-Prefix.pch"; sourceTree = "<group>"; };
45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttributesTest.m; sourceTree = "<group>"; }; 45A856AB1D220BFF0056CD4D /* TSAttributesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttributesTest.m; sourceTree = "<group>"; };
@ -111,6 +121,25 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
453E1FD41DA83DD500DDD7B7 /* TestSupport */ = {
isa = PBXGroup;
children = (
453E1FD51DA83DDC00DDD7B7 /* Fakes */,
);
name = TestSupport;
sourceTree = "<group>";
};
453E1FD51DA83DDC00DDD7B7 /* Fakes */ = {
isa = PBXGroup;
children = (
453E1FD61DA83E1000DDD7B7 /* OWSFakeContactsManager.h */,
453E1FD71DA83E1000DDD7B7 /* OWSFakeContactsManager.m */,
453E1FD91DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.h */,
453E1FDA1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m */,
);
name = Fakes;
sourceTree = "<group>";
};
45458B691CC342B600A02153 /* Account */ = { 45458B691CC342B600A02153 /* Account */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -178,6 +207,7 @@
45C6A0981D2F0264007D8AC0 /* Interactions */, 45C6A0981D2F0264007D8AC0 /* Interactions */,
45046FDF1D95A6130015EFF2 /* TSMessagesManagerTest.m */, 45046FDF1D95A6130015EFF2 /* TSMessagesManagerTest.m */,
454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */, 454021EC1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m */,
453E1FCE1DA8313100DDD7B7 /* OWSMessageSenderTest.m */,
); );
name = Messages; name = Messages;
sourceTree = "<group>"; sourceTree = "<group>";
@ -186,6 +216,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
45C6A0991D2F029B007D8AC0 /* TSMessageTest.m */, 45C6A0991D2F029B007D8AC0 /* TSMessageTest.m */,
45731A6B1DA87AA1007E22AA /* TSOutgoingMessageTest.m */,
); );
name = Interactions; name = Interactions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -268,6 +299,7 @@
B6273DED1C13A2E500738558 /* TSKitiOSTestAppTests */ = { B6273DED1C13A2E500738558 /* TSKitiOSTestAppTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
453E1FD41DA83DD500DDD7B7 /* TestSupport */,
45458B691CC342B600A02153 /* Account */, 45458B691CC342B600A02153 /* Account */,
45458B6B1CC342B600A02153 /* Attachments */, 45458B6B1CC342B600A02153 /* Attachments */,
459850BF1D22C6C4006FFEDB /* Contacts */, 459850BF1D22C6C4006FFEDB /* Contacts */,
@ -503,13 +535,17 @@
452EE6CF1D4A754C00E934BA /* TSThreadTest.m in Sources */, 452EE6CF1D4A754C00E934BA /* TSThreadTest.m in Sources */,
45458B761CC342B600A02153 /* TSAttachmentsTest.m in Sources */, 45458B761CC342B600A02153 /* TSAttachmentsTest.m in Sources */,
45C6A09A1D2F029B007D8AC0 /* TSMessageTest.m in Sources */, 45C6A09A1D2F029B007D8AC0 /* TSMessageTest.m in Sources */,
453E1FCF1DA8313100DDD7B7 /* OWSMessageSenderTest.m in Sources */,
459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */, 459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */,
45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */, 45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */,
453E1FDB1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m in Sources */,
453E1FD81DA83E1000DDD7B7 /* OWSFakeContactsManager.m in Sources */,
454021ED1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m in Sources */, 454021ED1D960ABF00F2126D /* OWSDisappearingMessageFinderTest.m in Sources */,
45458B771CC342B600A02153 /* TSMessageStorageTests.m in Sources */, 45458B771CC342B600A02153 /* TSMessageStorageTests.m in Sources */,
45046FE01D95A6130015EFF2 /* TSMessagesManagerTest.m in Sources */, 45046FE01D95A6130015EFF2 /* TSMessagesManagerTest.m in Sources */,
45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */, 45458B7C1CC342B600A02153 /* MessagePaddingTests.m in Sources */,
45A856AC1D220BFF0056CD4D /* TSAttributesTest.m in Sources */, 45A856AC1D220BFF0056CD4D /* TSAttributesTest.m in Sources */,
45731A6C1DA87AA1007E22AA /* TSOutgoingMessageTest.m in Sources */,
6323E339D5B8F4CB77EB3ED4 /* SignalRecipientTest.m in Sources */, 6323E339D5B8F4CB77EB3ED4 /* SignalRecipientTest.m in Sources */,
6323E1F7730289398452E5C5 /* OWSFingerprintTest.m in Sources */, 6323E1F7730289398452E5C5 /* OWSFingerprintTest.m in Sources */,
); );

@ -26,6 +26,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
@property (nonatomic) uint64_t expireStartedAt; @property (nonatomic) uint64_t expireStartedAt;
@property (nonatomic, readonly) uint64_t expiresAt; @property (nonatomic, readonly) uint64_t expiresAt;
@property (nonatomic, readonly) BOOL isExpiringMessage; @property (nonatomic, readonly) BOOL isExpiringMessage;
@property (nonatomic, readonly) BOOL shouldStartExpireTimer;
- (instancetype)initWithTimestamp:(uint64_t)timestamp; - (instancetype)initWithTimestamp:(uint64_t)timestamp;

@ -146,6 +146,11 @@ static const NSUInteger OWSMessageSchemaVersion = 3;
[self updateExpiresAt]; [self updateExpiresAt];
} }
- (BOOL)shouldStartExpireTimer
{
return self.isExpiringMessage;
}
// TODO a downloaded media doesn't start counting until download is complete. // TODO a downloaded media doesn't start counting until download is complete.
- (void)updateExpiresAt - (void)updateExpiresAt
{ {

@ -52,13 +52,12 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
{ {
uint64_t now = [NSDate ows_millisecondTimeStamp];
return [self initWithTimestamp:timestamp return [self initWithTimestamp:timestamp
inThread:thread inThread:thread
messageBody:body messageBody:body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds expiresInSeconds:expiresInSeconds
expireStartedAt:now]; expireStartedAt:0];
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initWithTimestamp:(uint64_t)timestamp
@ -95,6 +94,18 @@ NS_ASSUME_NONNULL_BEGIN
return self.thread.contactIdentifier; return self.thread.contactIdentifier;
} }
- (BOOL)shouldStartExpireTimer
{
switch (self.messageState) {
case TSOutgoingMessageStateSent:
case TSOutgoingMessageStateDelivered:
return self.isExpiringMessage;
case TSOutgoingMessageStateAttemptingOut:
case TSOutgoingMessageStateUnsent:
return NO;
}
}
- (OWSSignalServiceProtosDataMessageBuilder *)dataMessageBuilder - (OWSSignalServiceProtosDataMessageBuilder *)dataMessageBuilder
{ {
TSThread *thread = self.thread; TSThread *thread = self.thread;

@ -4,6 +4,7 @@
#import "OWSDisappearingMessagesFinder.h" #import "OWSDisappearingMessagesFinder.h"
#import "NSDate+millisecondTimeStamp.h" #import "NSDate+millisecondTimeStamp.h"
#import "TSMessage.h" #import "TSMessage.h"
#import "TSOutgoingMessage.h"
#import "TSStorageManager.h" #import "TSStorageManager.h"
#import "TSThread.h" #import "TSThread.h"
#import <YapDatabase/YapDatabaseConnection.h> #import <YapDatabase/YapDatabaseConnection.h>
@ -14,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
static NSString *const OWSDisappearingMessageFinderThreadIdColumn = @"thread_id"; static NSString *const OWSDisappearingMessageFinderThreadIdColumn = @"thread_id";
static NSString *const OWSDisappearingMessageFinderExpiresAtColumn = @"expires_at"; static NSString *const OWSDisappearingMessageFinderExpiresAtColumn = @"expires_at";
static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_messages_on_expires_at_and_thread_id"; static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_messages_on_expires_at_and_thread_id_v2";
@interface OWSDisappearingMessagesFinder () @interface OWSDisappearingMessagesFinder ()
@ -184,13 +185,17 @@ static NSString *const OWSDisappearingMessageFinderExpiresAtIndex = @"index_mess
NSString *collection, NSString *collection,
NSString *key, NSString *key,
id object) { id object) {
if ([object isKindOfClass:[TSMessage class]]) { if (![object isKindOfClass:[TSMessage class]]) {
TSMessage *message = (TSMessage *)object; return;
if (message.expiresInSeconds > 0) {
dict[OWSDisappearingMessageFinderExpiresAtColumn] = @(message.expiresAt);
dict[OWSDisappearingMessageFinderThreadIdColumn] = message.uniqueThreadId;
} // else don't index non-expiring messages.
} }
TSMessage *message = (TSMessage *)object;
if (!message.shouldStartExpireTimer) {
return;
}
dict[OWSDisappearingMessageFinderExpiresAtColumn] = @(message.expiresAt);
dict[OWSDisappearingMessageFinderThreadIdColumn] = message.uniqueThreadId;
}]; }];
return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler]; return [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler];

@ -0,0 +1,24 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
NS_ASSUME_NONNULL_BEGIN
@class TSOutgoingMessage;
@class TSNetworkManager;
@class TSStorageManager;
@class ContactsUpdater;
@protocol ContactsManagerProtocol;
@interface OWSMessageSender : NSObject
- (instancetype)initWithMessage:(TSOutgoingMessage *)message
networkManager:(TSNetworkManager *)networkManager
storageManager:(TSStorageManager *)storageManager
contactsManager:(id<ContactsManagerProtocol>)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater;
- (void)sendWithSuccess:(void (^)())successBlock failure:(void (^)(NSError *error))failureBlock;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,60 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSMessageSender.h"
#import "OWSError.h"
#import "TSMessagesManager+sendMessages.h"
#import "TSNetworkManager.h"
#import "TSOutgoingMessage.h"
#import "TSThread.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSMessageSender ()
@property (nonatomic, readonly) TSOutgoingMessage *message;
@property (nonatomic, readonly) TSNetworkManager *networkManager;
@property (nonatomic, readonly) TSMessagesManager *messagesManager;
@end
@implementation OWSMessageSender
- (instancetype)initWithMessage:(TSOutgoingMessage *)message
networkManager:(TSNetworkManager *)networkManager
storageManager:(TSStorageManager *)storageManager
contactsManager:(id<ContactsManagerProtocol>)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater
{
self = [super init];
if (!self) {
return self;
}
_message = message;
_networkManager = networkManager;
_messagesManager = [[TSMessagesManager alloc] initWithNetworkManager:networkManager
storageManager:storageManager
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
return self;
}
- (void)sendWithSuccess:(void (^)())successBlock failure:(void (^)(NSError *error))failureBlock
{
[self.messagesManager sendMessage:self.message
inThread:self.message.thread
success:^{
successBlock();
}
failure:^{
NSString *localizedError
= NSLocalizedString(@"NOTIFICATION_SEND_FAILED", @"Generic notice when message failed to send.");
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToSendOutgoingMessage, localizedError);
failureBlock(error);
}];
}
@end
NS_ASSUME_NONNULL_END

@ -137,12 +137,8 @@ dispatch_queue_t sendingQueue() {
? [TSAccountManager localNumber] ? [TSAccountManager localNumber]
: contactThread.contactIdentifier; : contactThread.contactIdentifier;
__block SignalRecipient *recipient; __block SignalRecipient *recipient =
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [SignalRecipient recipientWithTextSecureIdentifier:recipientContactId];
recipient = [SignalRecipient recipientWithTextSecureIdentifier:recipientContactId
withTransaction:transaction];
}];
if (!recipient) { if (!recipient) {
[self.contactsUpdater synchronousLookup:contactThread.contactIdentifier [self.contactsUpdater synchronousLookup:contactThread.contactIdentifier
success:^(SignalRecipient *recip) { success:^(SignalRecipient *recip) {
@ -258,7 +254,7 @@ dispatch_queue_t sendingQueue() {
self.logTag, self.logTag,
exception); exception);
[self processException:exception outgoingMessage:message inThread:thread]; [self processException:exception outgoingMessage:message inThread:thread];
return; BLOCK_SAFE_RUN(failureBlock);
} }
} }
@ -317,6 +313,7 @@ dispatch_queue_t sendingQueue() {
if (!responseData) { if (!responseData) {
DDLogWarn(@"Stale devices but server didn't specify devices in response."); DDLogWarn(@"Stale devices but server didn't specify devices in response.");
BLOCK_SAFE_RUN(failureBlock);
return; return;
} }

@ -3,6 +3,7 @@
@class PhoneNumber; @class PhoneNumber;
@class Contact; @class Contact;
@class UIImage;
@protocol ContactsManagerProtocol <NSObject> @protocol ContactsManagerProtocol <NSObject>

@ -10,8 +10,8 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeFailedToDecodeJson = 13, OWSErrorCodeFailedToDecodeJson = 13,
OWSErrorCodeFailedToEncodeJson = 14, OWSErrorCodeFailedToEncodeJson = 14,
OWSErrorCodeFailedToDecodeQR = 15, OWSErrorCodeFailedToDecodeQR = 15,
OWSErrorCodePrivacyVerificationFailure = 20 OWSErrorCodePrivacyVerificationFailure = 20,
OWSErrorCodeFailedToSendOutgoingMessage = 30
}; };
extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description); extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description);

@ -0,0 +1,77 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "TSContactThread.h"
#import "TSOutgoingMessage.h"
#import <XCTest/XCTest.h>
NS_ASSUME_NONNULL_BEGIN
@interface TSOutgoingMessageTest : XCTestCase
@property (nonatomic) TSContactThread *thread;
@end
@implementation TSOutgoingMessageTest
- (void)setUp
{
[super setUp];
self.thread = [[TSContactThread alloc] initWithUniqueId:@"fake-thread-id"];
}
- (void)testShouldNotStartExpireTimerWithMessageThatDoesNotExpire
{
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:100 inThread:self.thread messageBody:nil];
XCTAssertFalse(message.shouldStartExpireTimer);
}
- (void)testShouldStartExpireTimerWithSentMessage
{
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:100
inThread:self.thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:10];
message.messageState = TSOutgoingMessageStateSent;
XCTAssert(message.shouldStartExpireTimer);
}
- (void)testShouldStartExpireTimerWithDeliveredMessage
{
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:100
inThread:self.thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:10];
message.messageState = TSOutgoingMessageStateDelivered;
XCTAssert(message.shouldStartExpireTimer);
}
- (void)testShouldNotStartExpireTimerWithUnsentMessage
{
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:100
inThread:self.thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:10];
message.messageState = TSOutgoingMessageStateUnsent;
XCTAssertFalse(message.shouldStartExpireTimer);
}
- (void)testShouldNotStartExpireTimerWithAttemptingOutMessage
{
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:100
inThread:self.thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:10];
message.messageState = TSOutgoingMessageStateAttemptingOut;
XCTAssertFalse(message.shouldStartExpireTimer);
}
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,170 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSError.h"
#import "OWSFakeContactsManager.h"
#import "OWSFakeContactsUpdater.h"
#import "OWSMessageSender.h"
#import "TSContactThread.h"
#import "TSNetworkManager.h"
#import "TSOutgoingMessage.h"
#import "TSStorageManager.h"
#import <XCTest/XCTest.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSFakeURLSessionDataTask : NSURLSessionDataTask
@property (copy) NSHTTPURLResponse *response;
- (instancetype)initWithStatusCode:(long)statusCode;
@end
@implementation OWSFakeURLSessionDataTask
@synthesize response = _response;
- (instancetype)initWithStatusCode:(long)statusCode
{
self = [super init];
if (!self) {
return self;
}
NSURL *fakeURL = [NSURL URLWithString:@"http://127.0.0.1"];
_response = [[NSHTTPURLResponse alloc] initWithURL:fakeURL statusCode:statusCode HTTPVersion:nil headerFields:nil];
return self;
}
@end
@interface OWSMessageSenderFakeNetworkManager : TSNetworkManager
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithSuccess:(BOOL)shouldSucceed NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) BOOL shouldSucceed;
@end
@implementation OWSMessageSenderFakeNetworkManager
- (instancetype)initWithSuccess:(BOOL)shouldSucceed
{
// intentionally skipping super init which explodes without setup.
_shouldSucceed = shouldSucceed;
return self;
}
- (void)makeRequest:(TSRequest *)request
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
if ([request isKindOfClass:[TSSubmitMessageRequest class]]) {
if (self.shouldSucceed) {
success([NSURLSessionDataTask new], @{});
} else {
NSError *error
= OWSErrorWithCodeDescription(OWSErrorCodeFailedToSendOutgoingMessage, @"fake error description");
OWSFakeURLSessionDataTask *task = [[OWSFakeURLSessionDataTask alloc] initWithStatusCode:500];
failure(task, error);
}
} else {
NSLog(@"Ignoring unhandled request: %@", request);
}
}
@end
@interface OWSMessageSenderTest : XCTestCase
@property (nonatomic) TSThread *thread;
@property (nonatomic) TSOutgoingMessage *expiringMessage;
@property (nonatomic) OWSMessageSenderFakeNetworkManager *networkManager;
@end
@implementation OWSMessageSenderTest
- (void)setUp
{
[super setUp];
self.thread = [[TSContactThread alloc] initWithUniqueId:@"fake-thread-id"];
[self.thread save];
self.expiringMessage = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"outgoing message"
attachmentIds:[NSMutableArray new]
expiresInSeconds:30];
[self.expiringMessage save];
}
- (void)testExpiringMessageTimerStartsOnSuccess
{
TSNetworkManager *networkManager = [[OWSMessageSenderFakeNetworkManager alloc] initWithSuccess:YES];
OWSMessageSender *messageSender = [[OWSMessageSender alloc] initWithMessage:self.expiringMessage
networkManager:networkManager
storageManager:[TSStorageManager sharedManager]
contactsManager:[OWSFakeContactsManager new]
contactsUpdater:[OWSFakeContactsUpdater new]];
// Sanity Check
XCTAssertEqual(0, self.expiringMessage.expiresAt);
XCTestExpectation *messageStartedExpiration = [self expectationWithDescription:@"messageStartedExpiration"];
[messageSender sendWithSuccess:^() {
if (self.expiringMessage.expiresAt > 0) {
[messageStartedExpiration fulfill];
} else {
XCTFail(@"Message expiration was supposed to start.");
}
}
failure:^(NSError *error) {
XCTFail(@"Message failed to send");
}];
[self waitForExpectationsWithTimeout:5
handler:^(NSError *error) {
NSLog(@"Expiration timer not set in time.");
}];
}
- (void)testExpiringMessageTimerDoesNotStartsOnFailure
{
TSNetworkManager *networkManager = [[OWSMessageSenderFakeNetworkManager alloc] initWithSuccess:NO];
OWSMessageSender *messageSender = [[OWSMessageSender alloc] initWithMessage:self.expiringMessage
networkManager:networkManager
storageManager:[TSStorageManager sharedManager]
contactsManager:[OWSFakeContactsManager new]
contactsUpdater:[OWSFakeContactsUpdater new]];
// Sanity Check
XCTAssertEqual(0, self.expiringMessage.expiresAt);
XCTestExpectation *messageDidNotStartExpiration = [self expectationWithDescription:@"messageStartedExpiration"];
[messageSender sendWithSuccess:^() {
XCTFail(@"Message sending was supposed to fail.");
}
failure:^(NSError *error) {
if (self.expiringMessage.expiresAt == 0) {
[messageDidNotStartExpiration fulfill];
} else {
XCTFail(@"Message expiration was not supposed to start.");
}
}];
[self waitForExpectationsWithTimeout:5
handler:^(NSError *error) {
NSLog(@"Wasn't able to verify.");
}];
}
@end
NS_ASSUME_NONNULL_END

@ -3,12 +3,14 @@
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import "ContactsManagerProtocol.h"
#import "ContactsUpdater.h" #import "ContactsUpdater.h"
#import "OWSFakeContactsManager.h"
#import "OWSFakeContactsUpdater.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
#import "TSMessagesManager.h" #import "TSMessagesManager.h"
#import "TSNetworkManager.h" #import "TSNetworkManager.h"
#import "TSStorageManager.h" #import "TSStorageManager.h"
#import "ContactsManagerProtocol.h"
#import "objc/runtime.h" #import "objc/runtime.h"
@interface TSMessagesManagerTest : XCTestCase @interface TSMessagesManagerTest : XCTestCase
@ -93,15 +95,15 @@
- (instancetype)initWithExpectation:(XCTestExpectation *)messageWasSubmitted; - (instancetype)initWithExpectation:(XCTestExpectation *)messageWasSubmitted;
@property XCTestExpectation *messageWasSubmitted; @property XCTestExpectation *expectation;
@end @end
@implementation OWSTSMessagesManagerTestNetworkManager @implementation OWSTSMessagesManagerTestNetworkManager
- (instancetype)initWithExpectation:(XCTestExpectation *)messageWasSubmitted - (instancetype)initWithExpectation:(XCTestExpectation *)expectation
{ {
_messageWasSubmitted = messageWasSubmitted; _expectation = expectation;
return self; return self;
} }
@ -114,7 +116,7 @@
NSDictionary *fakeResponse = @{ @"id" : @(1234), @"location" : @"fake-location" }; NSDictionary *fakeResponse = @{ @"id" : @(1234), @"location" : @"fake-location" };
success(nil, fakeResponse); success(nil, fakeResponse);
} else if ([request isKindOfClass:[TSSubmitMessageRequest class]]) { } else if ([request isKindOfClass:[TSSubmitMessageRequest class]]) {
[self.messageWasSubmitted fulfill]; [self.expectation fulfill];
} else { } else {
NSLog(@"Ignoring unhandled request: %@", request); NSLog(@"Ignoring unhandled request: %@", request);
} }
@ -122,56 +124,6 @@
@end @end
@interface OWSFakeContactsUpdater : ContactsUpdater
@end
@implementation OWSFakeContactsUpdater
- (void)synchronousLookup:(NSString *)identifier
success:(void (^)(SignalRecipient *))success
failure:(void (^)(NSError *error))failure
{
NSLog(@"Fake contact lookup.");
SignalRecipient *fakeRecipient =
[[SignalRecipient alloc] initWithTextSecureIdentifier:@"fake-recipient-id" relay:nil supportsVoice:YES];
success(fakeRecipient);
}
@end
@interface OWSFakeContactsManager : NSObject <ContactsManagerProtocol>
@end
/**
* I don't know that this test relys on any of the specific behavior in this implementation.
* We're just trying to avoid setting up/accessing the TSEnv global. ~mjk
*/
@implementation OWSFakeContactsManager
- (NSString *)nameStringForPhoneIdentifier:(NSString *)phoneNumber
{
return @"Fake name";
}
- (NSArray<Contact *> *)signalContacts
{
return @[];
}
+ (BOOL)name:(NSString *)nameString matchesQuery:(NSString *)queryString
{
return YES;
}
- (UIImage *)imageForPhoneIdentifier:(NSString *)phoneNumber
{
return nil;
}
@end
@implementation TSMessagesManagerTest @implementation TSMessagesManagerTest
- (void)testIncomingSyncContactMessage - (void)testIncomingSyncContactMessage
@ -202,5 +154,4 @@
}]; }];
} }
@end @end

@ -0,0 +1,12 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "ContactsManagerProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSFakeContactsManager : NSObject <ContactsManagerProtocol>
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,34 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSFakeContactsManager.h"
NS_ASSUME_NONNULL_BEGIN
@class UIImage;
@implementation OWSFakeContactsManager
- (NSString *)nameStringForPhoneIdentifier:(NSString *)phoneNumber
{
return @"Fake name";
}
- (NSArray<Contact *> *)signalContacts
{
return @[];
}
+ (BOOL)name:(NSString *)nameString matchesQuery:(NSString *)queryString
{
return YES;
}
- (nullable UIImage *)imageForPhoneIdentifier:(NSString *)phoneNumber
{
return nil;
}
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,12 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "ContactsUpdater.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSFakeContactsUpdater : ContactsUpdater
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,23 @@
// Created by Michael Kirk on 10/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSFakeContactsUpdater.h"
#import "SignalRecipient.h"
NS_ASSUME_NONNULL_BEGIN
@implementation OWSFakeContactsUpdater
- (void)synchronousLookup:(NSString *)identifier
success:(void (^)(SignalRecipient *))success
failure:(void (^)(NSError *error))failure
{
NSLog(@"[OWSFakeContactsUpdater] Faking contact lookup.");
SignalRecipient *fakeRecipient =
[[SignalRecipient alloc] initWithTextSecureIdentifier:@"fake-recipient-id" relay:nil supportsVoice:YES];
success(fakeRecipient);
}
@end
NS_ASSUME_NONNULL_END
Loading…
Cancel
Save