Fix disappearing messages don't become consistent after reinstall (#52)

Fixes the bug wherein:

Given the sender had disappearing messages enabled
And the receiver thinks it's disabled (this can happen due to re-install)
When we receive a disappearing message
The message does start expiring timer and disappear
But you see a notice "<sender> disabled disappearing messages"
Rather than the expected "<Sender> set disappearing messages timer to X".

// FREEBIE
This commit is contained in:
Michael Kirk 2016-10-24 15:24:06 -04:00 committed by GitHub
parent 31bd1d07a3
commit 3e10a49258
5 changed files with 108 additions and 2 deletions

View File

@ -20,7 +20,10 @@ extern const uint32_t OWSDisappearingMessagesConfigurationDefaultExpirationDurat
@property (nonatomic, readonly) BOOL dictionaryValueDidChange;
@property (readonly, getter=isNewRecord) BOOL newRecord;
+ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId;
+ (NSArray<NSNumber *> *)validDurationsSeconds;
+ (NSString *)stringForDurationSeconds:(uint32_t)durationSeconds;
@end

View File

@ -49,6 +49,16 @@ const uint32_t OWSDisappearingMessagesConfigurationDefaultExpirationDuration = 6
return self;
}
+ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId
{
OWSDisappearingMessagesConfiguration *savedConfiguration = [self fetchObjectWithUniqueID:threadId];
if (savedConfiguration) {
return savedConfiguration;
} else {
return [[self alloc] initDefaultWithThreadId:threadId];
}
}
+ (NSString *)stringForDurationSeconds:(uint32_t)durationSeconds
{
NSString *amountFormat;

View File

@ -164,7 +164,7 @@ NS_ASSUME_NONNULL_BEGIN
// Become eventually consistent in the case that the remote changed their settings at the same time.
// Also in case remote doesn't support expiring messages
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:message.uniqueThreadId];
[OWSDisappearingMessagesConfiguration fetchOrCreateDefaultWithThreadId:message.uniqueThreadId];
BOOL changed = NO;
if (message.expiresInSeconds == 0) {

View File

@ -2,8 +2,10 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "NSDate+millisecondTimeStamp.h"
#import "OWSDisappearingMessagesConfiguration.h"
#import "OWSDisappearingMessagesFinder.h"
#import "OWSDisappearingMessagesJob.h"
#import "OWSFakeContactsManager.h"
#import "TSMessage.h"
#import "TSStorageManager.h"
#import "TSThread.h"
@ -68,6 +70,59 @@ NS_ASSUME_NONNULL_BEGIN
XCTAssertEqual(2, [TSMessage numberOfKeysInCollection]);
}
- (void)testBecomeConsistentWithMessageConfiguration
{
TSThread *thread = [[TSThread alloc] initWithUniqueId:@"fake-thread-id"];
[thread save];
OWSDisappearingMessagesJob *job =
[[OWSDisappearingMessagesJob alloc] initWithStorageManager:[TSStorageManager sharedManager]];
OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
[configuration remove];
TSMessage *expiringMessage = [[TSMessage alloc] initWithTimestamp:1
inThread:thread
messageBody:@"notYetExpiredMessage"
attachmentIds:@[]
expiresInSeconds:20
expireStartedAt:0];
[expiringMessage save];
[job becomeConsistentWithConfigurationForMessage:expiringMessage contactsManager:[OWSFakeContactsManager new]];
configuration = [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
XCTAssertNotNil(configuration);
XCTAssert(configuration.isEnabled);
XCTAssertEqual(20, configuration.durationSeconds);
}
- (void)testBecomeConsistentWithUnexpiringMessageConfiguration
{
TSThread *thread = [[TSThread alloc] initWithUniqueId:@"fake-thread-id"];
[thread save];
OWSDisappearingMessagesJob *job =
[[OWSDisappearingMessagesJob alloc] initWithStorageManager:[TSStorageManager sharedManager]];
OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
[configuration remove];
TSMessage *unExpiringMessage = [[TSMessage alloc] initWithTimestamp:1
inThread:thread
messageBody:@"unexpiringMessage"
attachmentIds:@[]
expiresInSeconds:0
expireStartedAt:0];
[unExpiringMessage save];
[job becomeConsistentWithConfigurationForMessage:unExpiringMessage contactsManager:[OWSFakeContactsManager new]];
XCTAssertNil([OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]);
}
@end
NS_ASSUME_NONNULL_END

View File

@ -2,6 +2,7 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "Cryptography.h"
#import "OWSDisappearingMessagesConfiguration.h"
#import "OWSError.h"
#import "OWSFakeContactsManager.h"
#import "OWSFakeContactsUpdater.h"
@ -173,6 +174,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) TSThread *thread;
@property (nonatomic) TSOutgoingMessage *expiringMessage;
@property (nonatomic) TSOutgoingMessage *unexpiringMessage;
@property (nonatomic) OWSMessageSenderFakeNetworkManager *networkManager;
@property (nonatomic) OWSMessageSender *successfulMessageSender;
@property (nonatomic) OWSMessageSender *unsuccessfulMessageSender;
@ -191,6 +193,13 @@ NS_ASSUME_NONNULL_BEGIN
self.thread = [[TSContactThread alloc] initWithUniqueId:@"fake-thread-id"];
[self.thread save];
self.unexpiringMessage = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"outgoing message"
attachmentIds:[NSMutableArray new]
expiresInSeconds:0];
[self.unexpiringMessage save];
self.expiringMessage = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"outgoing message"
@ -217,8 +226,11 @@ NS_ASSUME_NONNULL_BEGIN
contactsUpdater:contactsUpdater];
}
- (void)testExpiringMessageTimerStartsOnSuccess
- (void)testExpiringMessageTimerStartsOnSuccessWhenDisappearingMessagesEnabled
{
[[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:self.thread.uniqueId enabled:YES durationSeconds:10]
save];
OWSMessageSender *messageSender = self.successfulMessageSender;
// Sanity Check
@ -243,6 +255,32 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (void)testExpiringMessageTimerDoesNotStartsWhenDisabled
{
[[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:self.thread.uniqueId enabled:NO durationSeconds:10]
save];
OWSMessageSender *messageSender = self.successfulMessageSender;
XCTestExpectation *messageDidNotStartExpiration = [self expectationWithDescription:@"messageDidNotStartExpiration"];
[messageSender sendMessage:self.unexpiringMessage
success:^() {
if (self.unexpiringMessage.isExpiringMessage || self.unexpiringMessage.expiresAt > 0) {
XCTFail(@"Message expiration was not supposed to start.");
} else {
[messageDidNotStartExpiration fulfill];
}
}
failure:^(NSError *error) {
XCTFail(@"Message failed to send");
}];
[self waitForExpectationsWithTimeout:5
handler:^(NSError *error) {
NSLog(@"Expiration timer not set in time.");
}];
}
- (void)testExpiringMessageTimerDoesNotStartsOnFailure
{
OWSMessageSender *messageSender = self.unsuccessfulMessageSender;