487 lines
18 KiB
Objective-C
487 lines
18 KiB
Objective-C
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
#import <Foundation/Foundation.h>
|
|
#import <OCMock/OCMock.h>
|
|
|
|
#import "OCTRealmTests.h"
|
|
|
|
#import "OCTSubmanagerChatsImpl.h"
|
|
#import "OCTRealmManager.h"
|
|
#import "OCTTox.h"
|
|
#import "OCTMessageAbstract.h"
|
|
#import "OCTMessageText.h"
|
|
|
|
@interface OCTSubmanagerChatsImplTests : OCTRealmTests
|
|
|
|
@property (strong, nonatomic) OCTSubmanagerChatsImpl *submanager;
|
|
@property (strong, nonatomic) NSNotificationCenter *notificationCenter;
|
|
@property (strong, nonatomic) id dataSource;
|
|
@property (strong, nonatomic) id tox;
|
|
|
|
@end
|
|
|
|
@implementation OCTSubmanagerChatsImplTests
|
|
|
|
- (void)setUp
|
|
{
|
|
[super setUp];
|
|
self.notificationCenter = [[NSNotificationCenter alloc] init];
|
|
|
|
self.dataSource = OCMProtocolMock(@protocol(OCTSubmanagerDataSource));
|
|
OCMStub([self.dataSource managerGetNotificationCenter]).andReturn(self.notificationCenter);
|
|
|
|
OCMStub([self.dataSource managerGetRealmManager]).andReturn(self.realmManager);
|
|
|
|
self.tox = OCMClassMock([OCTTox class]);
|
|
OCMStub([self.dataSource managerGetTox]).andReturn(self.tox);
|
|
|
|
self.submanager = [OCTSubmanagerChatsImpl new];
|
|
self.submanager.dataSource = self.dataSource;
|
|
[self.submanager configure];
|
|
}
|
|
|
|
- (void)tearDown
|
|
{
|
|
self.dataSource = nil;
|
|
self.tox = nil;
|
|
self.submanager = nil;
|
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
|
[super tearDown];
|
|
}
|
|
|
|
- (void)testGetOrCreateChatWithFriend
|
|
{
|
|
OCTFriend *friend = [self createFriendWithFriendNumber:5];
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
[self.realmManager.realm addObject:friend];
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
OCTChat *first = [self.realmManager getOrCreateChatWithFriend:friend];
|
|
OCTChat *second = [self.realmManager getOrCreateChatWithFriend:friend];
|
|
|
|
XCTAssertEqualObjects(first, second);
|
|
XCTAssertEqualObjects([first.friends firstObject], friend);
|
|
}
|
|
|
|
- (void)testRemoveMessages
|
|
{
|
|
XCTestExpectation *expect = [self expectationWithDescription:@""];
|
|
[self.notificationCenter addObserverForName:kOCTScheduleFileTransferCleanupNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
|
|
[expect fulfill];
|
|
}];
|
|
|
|
NSArray *messages = [NSArray new];
|
|
OCMExpect([self.realmManager removeMessages:messages]);
|
|
|
|
[self.submanager removeMessages:messages];
|
|
|
|
[self waitForExpectationsWithTimeout:0.0 handler:nil];
|
|
OCMVerifyAll((id)self.realmManager);
|
|
}
|
|
|
|
- (void)testRemoveMessagesWithChat
|
|
{
|
|
XCTestExpectation *expect = [self expectationWithDescription:@""];
|
|
[self.notificationCenter addObserverForName:kOCTScheduleFileTransferCleanupNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
|
|
[expect fulfill];
|
|
}];
|
|
|
|
OCTChat *chat = [OCTChat new];
|
|
|
|
OCMExpect([self.realmManager removeAllMessagesInChat:chat removeChat:YES]);
|
|
|
|
[self.submanager removeAllMessagesInChat:chat removeChat:YES];
|
|
|
|
[self waitForExpectationsWithTimeout:0.0 handler:nil];
|
|
OCMVerifyAll((id)self.realmManager);
|
|
}
|
|
|
|
- (void)testSendMessageToChatSuccess
|
|
{
|
|
id message = OCMClassMock([OCTMessageAbstract class]);
|
|
|
|
id friend = OCMClassMock([OCTFriend class]);
|
|
OCMStub([friend friendNumber]).andReturn(5);
|
|
NSArray *friends = @[friend];
|
|
|
|
id chat = OCMClassMock([OCTChat class]);
|
|
OCMStub([chat friends]).andReturn(friends);
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:5
|
|
type:OCTToxMessageTypeAction
|
|
message:@"text"
|
|
error:[OCMArg anyObjectRef]]).andReturn(7);
|
|
OCMExpect([self.realmManager addMessageWithText:@"text"
|
|
type:OCTToxMessageTypeAction
|
|
chat:chat
|
|
sender:nil
|
|
messageId:7]).andReturn(message);
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@""];
|
|
|
|
[self.submanager sendMessageToChat:chat text:@"text" type:OCTToxMessageTypeAction successBlock:^(OCTMessageAbstract *theMessage) {
|
|
OCMVerifyAll((id)self.realmManager);
|
|
XCTAssertEqualObjects(message, theMessage);
|
|
[expectation fulfill];
|
|
|
|
} failureBlock:^(NSError *error) {
|
|
XCTAssertTrue(false, @"This block shouldn't be called");
|
|
}];
|
|
|
|
[self waitForExpectationsWithTimeout:0.2 handler:nil];
|
|
}
|
|
|
|
- (void)testSendMessageToChatFailure
|
|
{
|
|
id friend = OCMClassMock([OCTFriend class]);
|
|
OCMStub([friend friendNumber]).andReturn(5);
|
|
NSArray *friends = @[friend];
|
|
|
|
id chat = OCMClassMock([OCTChat class]);
|
|
OCMStub([chat friends]).andReturn(friends);
|
|
|
|
NSError *error2 = OCMClassMock([NSError class]);
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:5
|
|
type:OCTToxMessageTypeAction
|
|
message:@"text"
|
|
error:[OCMArg setTo:error2]]).andReturn(0);
|
|
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@""];
|
|
|
|
[self.submanager sendMessageToChat:chat text:@"text" type:OCTToxMessageTypeAction successBlock:^(OCTMessageAbstract *theMessage) {
|
|
XCTAssertTrue(false, @"This block shouldn't be called");
|
|
|
|
} failureBlock:^(NSError *error) {
|
|
OCMVerifyAll((id)self.realmManager);
|
|
XCTAssertEqualObjects(error, error2);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectationsWithTimeout:0.2 handler:nil];
|
|
}
|
|
|
|
- (void)testSendMessageToChatFauxEnabled
|
|
{
|
|
OCMStub([self.dataSource managerUseFauxOfflineMessaging]).andReturn(YES);
|
|
|
|
id message = OCMClassMock([OCTMessageAbstract class]);
|
|
|
|
id friend = OCMClassMock([OCTFriend class]);
|
|
OCMStub([friend friendNumber]).andReturn(5);
|
|
NSArray *friends = @[friend];
|
|
|
|
id chat = OCMClassMock([OCTChat class]);
|
|
OCMStub([chat friends]).andReturn(friends);
|
|
|
|
NSError *error2 = OCMClassMock([NSError class]);
|
|
OCMStub(error2.code).andReturn(OCTToxErrorFriendSendMessageFriendNotConnected);
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:5
|
|
type:OCTToxMessageTypeAction
|
|
message:@"text"
|
|
error:[OCMArg setTo:error2]]).andReturn(0);
|
|
OCMExpect([self.realmManager addMessageWithText:@"text"
|
|
type:OCTToxMessageTypeAction
|
|
chat:chat
|
|
sender:nil
|
|
messageId:-1]).andReturn(message);
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@""];
|
|
|
|
[self.submanager sendMessageToChat:chat text:@"text" type:OCTToxMessageTypeAction successBlock:^(OCTMessageAbstract *theMessage) {
|
|
OCMVerifyAll((id)self.realmManager);
|
|
XCTAssertEqualObjects(message, theMessage);
|
|
[expectation fulfill];
|
|
|
|
} failureBlock:^(NSError *error) {
|
|
XCTAssertTrue(false, @"This block shouldn't be called");
|
|
}];
|
|
|
|
[self waitForExpectationsWithTimeout:0.2 handler:nil];
|
|
}
|
|
|
|
- (void)testSendMessageToChatFauxDisabled
|
|
{
|
|
OCMStub([self.dataSource managerUseFauxOfflineMessaging]).andReturn(NO);
|
|
|
|
id friend = OCMClassMock([OCTFriend class]);
|
|
OCMStub([friend friendNumber]).andReturn(5);
|
|
NSArray *friends = @[friend];
|
|
|
|
id chat = OCMClassMock([OCTChat class]);
|
|
OCMStub([chat friends]).andReturn(friends);
|
|
|
|
NSError *error2 = OCMClassMock([NSError class]);
|
|
OCMStub(error2.code).andReturn(OCTToxErrorFriendSendMessageFriendNotConnected);
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:5
|
|
type:OCTToxMessageTypeAction
|
|
message:@"text"
|
|
error:[OCMArg setTo:error2]]).andReturn(0);
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@""];
|
|
|
|
[self.submanager sendMessageToChat:chat text:@"text" type:OCTToxMessageTypeAction successBlock:^(OCTMessageAbstract *theMessage) {
|
|
XCTAssertTrue(false, @"This block shouldn't be called");
|
|
|
|
} failureBlock:^(NSError *error) {
|
|
OCMVerifyAll((id)self.realmManager);
|
|
XCTAssertEqualObjects(error, error2);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectationsWithTimeout:0.2 handler:nil];
|
|
}
|
|
|
|
- (void)testSetIsTyping
|
|
{
|
|
id friend = OCMClassMock([OCTFriend class]);
|
|
OCMStub([friend friendNumber]).andReturn(5);
|
|
NSArray *friends = @[friend];
|
|
|
|
id chat = OCMClassMock([OCTChat class]);
|
|
OCMStub([chat friends]).andReturn(friends);
|
|
|
|
NSError *error;
|
|
NSError *error2 = OCMClassMock([NSError class]);
|
|
|
|
OCMExpect([self.tox setUserIsTyping:YES forFriendNumber:5 error:[OCMArg setTo:error2]]).andReturn(NO);
|
|
|
|
XCTAssertFalse([self.submanager setIsTyping:YES inChat:chat error:&error]);
|
|
|
|
XCTAssertEqual(error, error2);
|
|
OCMVerifyAll(self.tox);
|
|
}
|
|
|
|
- (void)testResendUndeliveredMessages
|
|
{
|
|
NSArray * (^createMessages)(OCTChat *, OCTToxMessageId) = ^(OCTChat *chat, OCTToxMessageId number) {
|
|
NSMutableArray *array = [NSMutableArray new];
|
|
|
|
for (OCTToxMessageId index = 0; index < number; index++) {
|
|
BOOL outgoing = index % 2;
|
|
OCTMessageAbstract *message = [self createTextMessageInChat:chat outgoing:outgoing messageId:index];
|
|
[array addObject:message];
|
|
}
|
|
|
|
return [array copy];
|
|
};
|
|
|
|
OCTToxFriendNumber friendNumber = 1;
|
|
|
|
OCTFriend *friend1 = [self createFriendWithFriendNumber:friendNumber++];
|
|
OCTFriend *friend2 = [self createFriendWithFriendNumber:friendNumber++];
|
|
|
|
NSString *publicKey1 = friend1.publicKey;
|
|
NSString *publicKey2 = friend2.publicKey;
|
|
|
|
OCMStub([self.tox publicKeyFromFriendNumber:friend1.friendNumber error:nil]).andReturn(publicKey1);
|
|
OCMStub([self.tox publicKeyFromFriendNumber:friend2.friendNumber error:nil]).andReturn(publicKey2);
|
|
|
|
OCTChat *chat1 = [self createChatWithFriend:friend1];
|
|
OCTChat *chat2 = [self createChatWithFriend:friend2];
|
|
|
|
NSArray *messages1 = createMessages(chat1, 10);
|
|
NSArray *messages2 = createMessages(chat2, 2);
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
[self.realmManager.realm addObject:chat1];
|
|
[self.realmManager.realm addObject:chat2];
|
|
[self.realmManager.realm addObjects:messages1];
|
|
[self.realmManager.realm addObjects:messages2];
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"1" error:[OCMArg anyObjectRef]]).andReturn(101);
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"3" error:[OCMArg anyObjectRef]]).andReturn(103);
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"5" error:[OCMArg anyObjectRef]]).andReturn(105);
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"7" error:[OCMArg anyObjectRef]]).andReturn(107);
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"9" error:[OCMArg anyObjectRef]]).andReturn(109);
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
friend1.connectionStatus = OCTToxConnectionStatusUDP;
|
|
friend1.isConnected = YES;
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
[self.notificationCenter postNotificationName:kOCTFriendConnectionStatusChangeNotification object:friend1];
|
|
|
|
#define VERIFY_MESSAGE(__array, __index, __messageId, __delivered) \
|
|
{ \
|
|
NSString *identifier = [__array[__index] uniqueIdentifier]; \
|
|
OCTMessageAbstract *message = [self.realmManager objectWithUniqueIdentifier:identifier class:[OCTMessageAbstract class]]; \
|
|
XCTAssertEqual(message.messageText.messageId, __messageId); \
|
|
XCTAssertEqual(message.messageText.isDelivered, __delivered); \
|
|
}
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@""];
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
|
VERIFY_MESSAGE(messages1, 0, 0, NO);
|
|
VERIFY_MESSAGE(messages1, 1, 101, NO);
|
|
VERIFY_MESSAGE(messages1, 2, 2, NO);
|
|
VERIFY_MESSAGE(messages1, 3, 103, NO);
|
|
VERIFY_MESSAGE(messages1, 4, 4, NO);
|
|
VERIFY_MESSAGE(messages1, 5, 105, NO);
|
|
VERIFY_MESSAGE(messages1, 6, 6, NO);
|
|
VERIFY_MESSAGE(messages1, 7, 107, NO);
|
|
VERIFY_MESSAGE(messages1, 8, 8, NO);
|
|
VERIFY_MESSAGE(messages1, 9, 109, NO);
|
|
|
|
VERIFY_MESSAGE(messages2, 0, 0, NO);
|
|
VERIFY_MESSAGE(messages2, 1, 1, NO);
|
|
|
|
[expectation fulfill];
|
|
});
|
|
|
|
[self waitForExpectationsWithTimeout:0.3 handler:nil];
|
|
|
|
|
|
// Deliver some messages, then resend all left again.
|
|
|
|
[self.submanager tox:self.tox messageDelivered:101 friendNumber:1];
|
|
[self.submanager tox:self.tox messageDelivered:103 friendNumber:1];
|
|
[self.submanager tox:self.tox messageDelivered:105 friendNumber:1];
|
|
|
|
{
|
|
OCTMessageAbstract *message;
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
|
|
message = messages1[7];
|
|
message.messageText.text = @"107";
|
|
message = messages1[9];
|
|
message.messageText.text = @"109";
|
|
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
}
|
|
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"107" error:[OCMArg anyObjectRef]]).andReturn(207);
|
|
OCMStub([self.tox sendMessageWithFriendNumber:1 type:OCTToxMessageTypeNormal message:@"109" error:[OCMArg anyObjectRef]]).andReturn(209);
|
|
|
|
[self.notificationCenter postNotificationName:kOCTFriendConnectionStatusChangeNotification object:friend1];
|
|
|
|
XCTestExpectation *expectation2 = [self expectationWithDescription:@""];
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
|
VERIFY_MESSAGE(messages1, 0, 0, NO);
|
|
VERIFY_MESSAGE(messages1, 1, 101, YES);
|
|
VERIFY_MESSAGE(messages1, 2, 2, NO);
|
|
VERIFY_MESSAGE(messages1, 3, 103, YES);
|
|
VERIFY_MESSAGE(messages1, 4, 4, NO);
|
|
VERIFY_MESSAGE(messages1, 5, 105, YES);
|
|
VERIFY_MESSAGE(messages1, 6, 6, NO);
|
|
VERIFY_MESSAGE(messages1, 7, 207, NO);
|
|
VERIFY_MESSAGE(messages1, 8, 8, NO);
|
|
VERIFY_MESSAGE(messages1, 9, 209, NO);
|
|
|
|
VERIFY_MESSAGE(messages2, 0, 0, NO);
|
|
VERIFY_MESSAGE(messages2, 1, 1, NO);
|
|
|
|
[expectation2 fulfill];
|
|
});
|
|
|
|
[self waitForExpectationsWithTimeout:0.3 handler:nil];
|
|
}
|
|
|
|
#pragma mark - OCTToxDelegate
|
|
|
|
- (void)testFriendMessage
|
|
{
|
|
OCTFriend *friend = [self createFriendWithFriendNumber:5];
|
|
NSString *publicKey = friend.publicKey;
|
|
OCMStub([self.tox publicKeyFromFriendNumber:friend.friendNumber error:nil]).andReturn(publicKey);
|
|
|
|
OCTChat *chat = [OCTChat new];
|
|
[chat.friends addObject:friend];
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
[self.realmManager.realm addObject:chat];
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
[self.submanager tox:nil friendMessage:@"message" type:OCTToxMessageTypeAction friendNumber:5];
|
|
|
|
RLMResults *results = [OCTMessageAbstract allObjectsInRealm:self.realmManager.realm];
|
|
XCTAssertEqual(results.count, 1);
|
|
|
|
OCTMessageAbstract *message = [results firstObject];
|
|
XCTAssertEqualObjects(message.senderUniqueIdentifier, friend.uniqueIdentifier);
|
|
XCTAssertEqualObjects(message.chatUniqueIdentifier, chat.uniqueIdentifier);
|
|
XCTAssertNotNil(message.messageText);
|
|
XCTAssertEqualObjects(message.messageText.text, @"message");
|
|
XCTAssertEqual(message.messageText.type, OCTToxMessageTypeAction);
|
|
}
|
|
|
|
- (void)testMessageDelivered
|
|
{
|
|
OCTFriend *friend = [self createFriendWithFriendNumber:5];
|
|
NSString *publicKey = friend.publicKey;
|
|
OCMStub([self.tox publicKeyFromFriendNumber:friend.friendNumber error:nil]).andReturn(publicKey);
|
|
|
|
OCTChat *chat = [OCTChat new];
|
|
[chat.friends addObject:friend];
|
|
|
|
OCTMessageAbstract *message = [OCTMessageAbstract new];
|
|
message.chatUniqueIdentifier = chat.uniqueIdentifier;
|
|
message.dateInterval = [[NSDate date] timeIntervalSince1970];
|
|
message.messageText = [OCTMessageText new];
|
|
message.messageText.text = @"";
|
|
message.messageText.messageId = 10;
|
|
message.messageText.isDelivered = NO;
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
[self.realmManager.realm addObject:friend];
|
|
[self.realmManager.realm addObject:chat];
|
|
[self.realmManager.realm addObject:message];
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
[self.submanager tox:self.tox messageDelivered:10 friendNumber:5];
|
|
|
|
XCTAssertTrue(message.messageText.isDelivered);
|
|
|
|
OCTMessageAbstract *anotherMessageSameId = [OCTMessageAbstract new];
|
|
anotherMessageSameId.chatUniqueIdentifier = chat.uniqueIdentifier;
|
|
anotherMessageSameId.dateInterval = [[NSDate date] timeIntervalSince1970];
|
|
anotherMessageSameId.messageText = [OCTMessageText new];
|
|
anotherMessageSameId.messageText.text = @"";
|
|
anotherMessageSameId.messageText.messageId = 10;
|
|
anotherMessageSameId.messageText.isDelivered = NO;
|
|
|
|
[self.realmManager.realm beginWriteTransaction];
|
|
[self.realmManager.realm addObject:anotherMessageSameId];
|
|
[self.realmManager.realm commitWriteTransaction];
|
|
|
|
[self.submanager tox:self.tox messageDelivered:10 friendNumber:5];
|
|
|
|
XCTAssertTrue(anotherMessageSameId.messageText.isDelivered);
|
|
}
|
|
|
|
- (OCTChat *)createChatWithFriend:(OCTFriend *)friend
|
|
{
|
|
OCTChat *chat = [OCTChat new];
|
|
[chat.friends addObject:friend];
|
|
|
|
return chat;
|
|
}
|
|
|
|
- (OCTMessageAbstract *)createTextMessageInChat:(OCTChat *)chat outgoing:(BOOL)outgoing messageId:(OCTToxMessageId)messageId
|
|
{
|
|
OCTMessageAbstract *message = [OCTMessageAbstract new];
|
|
message.chatUniqueIdentifier = chat.uniqueIdentifier;
|
|
message.messageText = [OCTMessageText new];
|
|
message.messageText.text = [NSString stringWithFormat:@"%d", messageId];
|
|
message.messageText.messageId = messageId;
|
|
|
|
if (! outgoing) {
|
|
OCTFriend *friend = chat.friends.lastObject;
|
|
message.senderUniqueIdentifier = friend.uniqueIdentifier;
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
@end
|