You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/SignalServiceKit/tests/Messages/OWSMessageSenderTest.m

512 lines
18 KiB
Matlab

//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "Cryptography.h"
#import "OWSDisappearingMessagesConfiguration.h"
#import "OWSError.h"
#import "OWSFakeContactsManager.h"
#import "OWSFakeContactsUpdater.h"
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
#import "OWSFakeNetworkManager.h"
#import "OWSMessageSender.h"
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
#import "OWSUploadingService.h"
#import "TSAccountManager.h"
#import "TSContactThread.h"
#import "TSGroupModel.h"
#import "TSGroupThread.h"
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
#import "TSMessagesManager.h"
#import "TSNetworkManager.h"
#import "TSOutgoingMessage.h"
#import "TSStorageManager.h"
#import <AxolotlKit/AxolotlExceptions.h>
#import <AxolotlKit/SessionBuilder.h>
#import <XCTest/XCTest.h>
NS_ASSUME_NONNULL_BEGIN
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
@interface OWSMessageSender (Testing)
@property (nonatomic) OWSUploadingService *uploadingService;
@property (nonatomic) ContactsUpdater *contactsUpdater;
// Private Methods to test
- (NSArray<SignalRecipient *> *)getRecipients:(NSArray<NSString *> *)identifiers error:(NSError **)error;
@end
@implementation OWSMessageSender (Testing)
- (NSArray<NSDictionary *> *)deviceMessages:(TSOutgoingMessage *)message
forRecipient:(SignalRecipient *)recipient
inThread:(TSThread *)thread
{
NSLog(@"[OWSFakeMessagesManager] Faking deviceMessages.");
return @[];
}
- (void)setContactsUpdater:(ContactsUpdater *)contactsUpdater
{
_contactsUpdater = contactsUpdater;
}
- (ContactsUpdater *)contactsUpdater
{
return _contactsUpdater;
}
- (void)setUploadingService:(OWSUploadingService *)uploadingService
{
_uploadingService = uploadingService;
}
- (OWSUploadingService *)uploadingService
{
return _uploadingService;
}
@end
@interface OWSFakeUploadingService : OWSUploadingService
@property (nonatomic, readonly) BOOL shouldSucceed;
@end
@implementation OWSFakeUploadingService
- (instancetype)initWithSuccess:(BOOL)flag
{
self = [super initWithNetworkManager:[OWSFakeNetworkManager new]];
if (!self) {
return self;
}
_shouldSucceed = flag;
return self;
}
- (void)uploadAttachmentStream:(TSAttachmentStream *)attachmentStream
message:(TSOutgoingMessage *)outgoingMessage
success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler
{
if (self.shouldSucceed) {
successHandler();
} else {
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
[error setIsRetryable:NO];
failureHandler(error);
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
}
}
@end
@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
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
@interface OWSMessageSenderFakeNetworkManager : OWSFakeNetworkManager
- (instancetype)init;
- (instancetype)initWithSuccess:(BOOL)shouldSucceed NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) BOOL shouldSucceed;
@end
@implementation OWSMessageSenderFakeNetworkManager
- (instancetype)initWithSuccess:(BOOL)shouldSucceed
{
self = [self init];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
if (!self) {
return self;
}
_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 {
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[super makeRequest:request success:success failure:failure];
}
}
@end
@interface TSAccountManager (Testing)
- (void)storeLocalNumber:(NSString *)localNumber;
@end
@interface OWSMessageSenderTest : XCTestCase
@property (nonatomic) TSThread *thread;
@property (nonatomic) TSOutgoingMessage *expiringMessage;
@property (nonatomic) TSOutgoingMessage *unexpiringMessage;
@property (nonatomic) OWSMessageSenderFakeNetworkManager *networkManager;
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
@property (nonatomic) OWSMessageSender *successfulMessageSender;
@property (nonatomic) OWSMessageSender *unsuccessfulMessageSender;
@end
@implementation OWSMessageSenderTest
- (void)setUp
{
[super setUp];
// Hack to make sure we don't explode when sending sync message.
[[TSAccountManager sharedInstance] storeLocalNumber:@"+13231231234"];
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"
attachmentIds:[NSMutableArray new]
expiresInSeconds:30];
[self.expiringMessage save];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
TSStorageManager *storageManager = [TSStorageManager sharedManager];
OWSFakeContactsManager *contactsManager = [OWSFakeContactsManager new];
OWSFakeContactsUpdater *contactsUpdater = [OWSFakeContactsUpdater new];
// Successful Sending
TSNetworkManager *successfulNetworkManager = [[OWSMessageSenderFakeNetworkManager alloc] initWithSuccess:YES];
self.successfulMessageSender = [[OWSMessageSender alloc] initWithNetworkManager:successfulNetworkManager
storageManager:storageManager
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
// Unsuccessful Sending
TSNetworkManager *unsuccessfulNetworkManager = [[OWSMessageSenderFakeNetworkManager alloc] initWithSuccess:NO];
self.unsuccessfulMessageSender = [[OWSMessageSender alloc] initWithNetworkManager:unsuccessfulNetworkManager
storageManager:storageManager
contactsManager:contactsManager
contactsUpdater:contactsUpdater];
}
- (void)testExpiringMessageTimerStartsOnSuccessWhenDisappearingMessagesEnabled
{
[[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:self.thread.uniqueId enabled:YES durationSeconds:10]
save];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
OWSMessageSender *messageSender = self.successfulMessageSender;
// Sanity Check
XCTAssertEqual(0, self.expiringMessage.expiresAt);
XCTestExpectation *messageStartedExpiration = [self expectationWithDescription:@"messageStartedExpiration"];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[messageSender sendMessage:self.expiringMessage
success:^() {
//FIXME remove sleep hack in favor of expiringMessage completion handler
sleep(2);
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
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)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
{
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
OWSMessageSender *messageSender = self.unsuccessfulMessageSender;
// Sanity Check
XCTAssertEqual(0, self.expiringMessage.expiresAt);
XCTestExpectation *messageDidNotStartExpiration = [self expectationWithDescription:@"messageStartedExpiration"];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[messageSender sendMessage:self.expiringMessage
success:^() {
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.");
}
}];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testTextMessageIsMarkedAsSentOnSuccess
{
OWSMessageSender *messageSender = self.successfulMessageSender;
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsSent = [self expectationWithDescription:@"markedAsSent"];
[messageSender sendMessage:message
success:^() {
if (message.messageState == TSOutgoingMessageStateSentToService) {
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[markedAsSent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}
failure:^(NSError *error) {
XCTFail(@"sendMessage should succeed.");
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testMediaMessageIsMarkedAsSentOnSuccess
{
OWSMessageSender *messageSender = self.successfulMessageSender;
messageSender.uploadingService = [[OWSFakeUploadingService alloc] initWithSuccess:YES];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsSent = [self expectationWithDescription:@"markedAsSent"];
[messageSender sendAttachmentData:[NSData new]
contentType:@"image/gif"
sourceFilename:nil
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
inMessage:message
success:^() {
if (message.messageState == TSOutgoingMessageStateSentToService) {
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[markedAsSent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}
failure:^(NSError *error) {
XCTFail(@"sendMessage should succeed.");
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testTextMessageIsMarkedAsUnsentOnFailure
{
OWSMessageSender *messageSender = self.unsuccessfulMessageSender;
messageSender.uploadingService = [[OWSFakeUploadingService alloc] initWithSuccess:YES];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsUnsent = [self expectationWithDescription:@"markedAsUnsent"];
[messageSender sendMessage:message
success:^() {
XCTFail(@"sendMessage should fail.");
}
failure:^(NSError *error) {
if (message.messageState == TSOutgoingMessageStateUnsent) {
[markedAsUnsent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testMediaMessageIsMarkedAsUnsentOnFailureToSend
{
OWSMessageSender *messageSender = self.unsuccessfulMessageSender;
// Assume that upload will go well, but that failure happens elsewhere in message sender.
messageSender.uploadingService = [[OWSFakeUploadingService alloc] initWithSuccess:YES];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsUnsent = [self expectationWithDescription:@"markedAsUnsent"];
[messageSender sendAttachmentData:[NSData new]
contentType:@"image/gif"
sourceFilename:nil
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
inMessage:message
success:^{
XCTFail(@"sendMessage should fail.");
}
failure:^(NSError *_Nonnull error) {
if (message.messageState == TSOutgoingMessageStateUnsent) {
[markedAsUnsent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testMediaMessageIsMarkedAsUnsentOnFailureToUpload
{
OWSMessageSender *messageSender = self.successfulMessageSender;
// Assume that upload fails, but other sending stuff would succeed.
messageSender.uploadingService = [[OWSFakeUploadingService alloc] initWithSuccess:NO];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:self.thread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsUnsent = [self expectationWithDescription:@"markedAsUnsent"];
[messageSender sendAttachmentData:[NSData new]
contentType:@"image/gif"
sourceFilename:nil
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
inMessage:message
success:^{
XCTFail(@"sendMessage should fail.");
}
failure:^(NSError *_Nonnull error) {
if (message.messageState == TSOutgoingMessageStateUnsent) {
[markedAsUnsent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
- (void)testGroupSend
{
OWSMessageSender *messageSender = self.successfulMessageSender;
NSData *groupIdData = [Cryptography generateRandomBytes:32];
SignalRecipient *successfulRecipient =
[[SignalRecipient alloc] initWithTextSecureIdentifier:@"successful-recipient-id" relay:nil];
SignalRecipient *successfulRecipient2 =
[[SignalRecipient alloc] initWithTextSecureIdentifier:@"successful-recipient-id2" relay:nil];
TSGroupModel *groupModel = [[TSGroupModel alloc]
initWithTitle:@"group title"
memberIds:[@[ successfulRecipient.uniqueId, successfulRecipient2.uniqueId ] mutableCopy]
image:nil
groupId:groupIdData];
TSGroupThread *groupThread = [TSGroupThread getOrCreateThreadWithGroupModel:groupModel];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:1
inThread:groupThread
messageBody:@"We want punks in the palace."];
XCTestExpectation *markedAsSent = [self expectationWithDescription:@"markedAsSent"];
[messageSender sendMessage:message
success:^{
if (message.messageState == TSOutgoingMessageStateSentToService) {
[markedAsSent fulfill];
} else {
XCTFail(@"Unexpected message state");
}
}
failure:^(NSError *_Nonnull error) {
XCTFail(@"sendMessage should not fail.");
}];
[self waitForExpectationsWithTimeout:5 handler:nil];
}
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
- (void)testGetRecipients
{
SignalRecipient *recipient = [[SignalRecipient alloc] initWithTextSecureIdentifier:@"fake-recipient-id" relay:nil];
Explain send failures for text and media messages Motivation ---------- We were often swallowing errors or yielding generic errors when it would be better to provide specific errors. We also didn't create an attachment when attachments failed to send, making it impossible to show the user what was happening with an in-progress or failed attachment. Primary Changes --------------- - Funnel all message sending through MessageSender, and remove message sending from MessagesManager. - Record most recent sending error so we can expose it in the UI - Can resend attachments. - Update message status for attachments, just like text messages - Extracted UploadingService from MessagesManager - Saving attachment stream before uploading gives uniform API for send vs. resend - update status for downloading transcript attachments - TSAttachments have a local id, separate from the server allocated id This allows us to save the attachment before the allocation request. Which is is good because: 1. can show feedback to user faster. 2. allows us to show an error when allocation fails. Code Cleanup ------------ - Replaced a lot of global singleton access with injected dependencies to make for easier testing. - Never save group meta messages. Rather than checking before (hopefully) every save, do it in the save method. - Don't use callbacks for sync code. - Handle errors on writing attachment data - Fix old long broken tests that weren't even running. =( - Removed dead code - Use constants vs define - Port flaky travis fixes from Signal-iOS // FREEBIE
9 years ago
[recipient save];
OWSMessageSender *messageSender = self.successfulMessageSender;
// At the time of writing this test, the ContactsUpdater was relying on global singletons. So if this test
// later fails due to network access that could be why.
messageSender.contactsUpdater = [ContactsUpdater sharedUpdater];
NSError *error;
NSArray<SignalRecipient *> *recipients = [messageSender getRecipients:@[ recipient.uniqueId ] error:&error];
XCTAssertNil(error);
XCTAssertEqualObjects(recipient, recipients.firstObject);
}
@end
NS_ASSUME_NONNULL_END