Skip to content

Commit

Permalink
Merge pull request #999 from esl/muc-light-empty-message-handling
Browse files Browse the repository at this point in the history
MUC Light empty message handling
  • Loading branch information
chrisballinger authored Nov 13, 2017
2 parents 7fcf4c4 + 9e299d9 commit 0ec4785
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 10 deletions.
1 change: 1 addition & 0 deletions Extensions/XMPPMUCLight/XMPPRoomLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
@property (readonly, nonatomic, strong, nonnull) XMPPJID *roomJID;
@property (readonly, nonatomic, strong, nonnull) NSString *domain;
@property (nonatomic, assign) BOOL shouldStoreAffiliationChangeMessages;
@property (assign) BOOL shouldHandleMemberMessagesWithoutBody;

- (nonnull NSString *)roomname;
- (nonnull NSString *)subject;
Expand Down
34 changes: 31 additions & 3 deletions Extensions/XMPPMUCLight/XMPPRoomLight.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

@interface XMPPRoomLight() {
BOOL shouldStoreAffiliationChangeMessages;
BOOL shouldHandleMemberMessagesWithoutBody;
NSString *roomname;
NSString *subject;
NSArray<NSXMLElement*> *knownMembersList;
Expand Down Expand Up @@ -105,6 +106,33 @@ - (void)setShouldStoreAffiliationChangeMessages:(BOOL)newValue
dispatch_async(moduleQueue, block);
}

- (BOOL)shouldHandleMemberMessagesWithoutBody
{
__block BOOL result;
dispatch_block_t block = ^{ @autoreleasepool {
result = shouldHandleMemberMessagesWithoutBody;
}};

if (dispatch_get_specific(moduleQueueTag))
block();
else
dispatch_sync(moduleQueue, block);

return result;
}

- (void)setShouldHandleMemberMessagesWithoutBody:(BOOL)newValue
{
dispatch_block_t block = ^{ @autoreleasepool {
shouldHandleMemberMessagesWithoutBody = newValue;
}};

if (dispatch_get_specific(moduleQueueTag))
block();
else
dispatch_async(moduleQueue, block);
}

- (nonnull NSString *)roomname {
@synchronized(roomname) {
return [roomname copy];
Expand Down Expand Up @@ -668,9 +696,9 @@ - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
// Is this a message we need to store (a chat message)?
//
// We store messages that from is full room-id@domain/user-who-sends-message
// and that have something in the body
// and that have something in the body (unless empty messages are allowed)

if ([from isFull] && [message isGroupChatMessageWithBody]) {
if ([from isFull] && [message isGroupChatMessage] && (self.shouldHandleMemberMessagesWithoutBody || [message isMessageWithBody])) {
[xmppRoomLightStorage handleIncomingMessage:message room:self];
[multicastDelegate xmppRoomLight:self didReceiveMessage:message];
}else if(destroyRoom){
Expand Down Expand Up @@ -700,7 +728,7 @@ - (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
// A message to all recipients MUST be of type groupchat.
// A message to an individual recipient would have a <body/>.

if ([message isGroupChatMessageWithBody]){
if ([message isGroupChatMessage] && (self.shouldHandleMemberMessagesWithoutBody || [message isMessageWithBody])) {
[xmppRoomLightStorage handleOutgoingMessage:message room:self];
}
}
Expand Down
71 changes: 64 additions & 7 deletions Xcode/Testing-Shared/XMPPRoomLightCoreDataStorageTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ - (void)testReceiveMessageWithoutStorage{
[roomLight addDelegate:self delegateQueue:dispatch_get_main_queue()];
[roomLight activate:streamTest];

[streamTest fakeMessageResponse:[self fakeIncomingMessage]];
[streamTest fakeMessageResponse:[self fakeIncomingMessageWithBody:YES]];
[self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) {
if(error){
XCTFail(@"Expectation Failed with error: %@", error);
Expand All @@ -53,7 +53,7 @@ - (void)testReceiveMessageWithStorage{
[roomLight addDelegate:self delegateQueue:dispatch_get_main_queue()];
[roomLight activate:streamTest];

[streamTest fakeMessageResponse:[self fakeIncomingMessage]];
[streamTest fakeMessageResponse:[self fakeIncomingMessageWithBody:YES]];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [storage mainThreadManagedObjectContext];
Expand Down Expand Up @@ -135,6 +135,52 @@ - (void)testReceiveAffiliationMessageWithStorage {
}];
}

- (void)testReceiveMessageWithoutBody {
self.checkDelegate = false;

XCTestExpectation *expectation = [self expectationWithDescription:@"receive message without body and correctly stored"];

XMPPRoomLightCoreDataStorage *storage = [[XMPPRoomLightCoreDataStorage alloc] initWithDatabaseFilename:@"testReceiveMessageWithoutBody.sqlite"
storeOptions:nil];
storage.autoRemovePreviousDatabaseFile = YES;

XMPPMockStream *streamTest = [[XMPPMockStream alloc] init];
streamTest.myJID = [XMPPJID jidWithString:@"[email protected]"];
XMPPJID *jid = [XMPPJID jidWithString:@"[email protected]"];
XMPPRoomLight *roomLight = [[XMPPRoomLight alloc] initWithRoomLightStorage:storage jid:jid roomname:@"test" dispatchQueue:nil];
roomLight.shouldHandleMemberMessagesWithoutBody = YES;
[roomLight activate:streamTest];

[streamTest fakeMessageResponse:[self fakeIncomingMessageWithBody:NO]];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [storage mainThreadManagedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"XMPPRoomLightMessageCoreDataStorageObject"
inManagedObjectContext:context];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"roomJIDStr = %@", jid.full];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
request.predicate = predicate;

NSError *error;
XMPPRoomLightMessageCoreDataStorageObject *roomMessage = [[context executeFetchRequest:request error:&error] firstObject];
XCTAssertNil(error);
XCTAssertEqualObjects(roomMessage.jid.full, @"[email protected]/[email protected]");
XCTAssertNil(roomMessage.body);
XCTAssertEqualObjects(roomMessage.nickname, @"[email protected]");

[expectation fulfill];
});

[self waitForExpectationsWithTimeout:3 handler:^(NSError * _Nullable error) {
if(error){
XCTFail(@"Expectation Failed with error: %@", error);
}
}];
}

- (void)testImportMessage {
self.checkDelegate = false;

Expand All @@ -148,7 +194,10 @@ - (void)testImportMessage {
XMPPJID *jid = [XMPPJID jidWithString:@"[email protected]"];
XMPPRoomLight *roomLight = [[XMPPRoomLight alloc] initWithRoomLightStorage:storage jid:jid roomname:@"test" dispatchQueue:nil];

[storage importRemoteArchiveMessage:[self fakeIncomingMessage] withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0] inRoom:roomLight fromStream:streamTest];
[storage importRemoteArchiveMessage:[self fakeIncomingMessageWithBody:YES]
withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0]
inRoom:roomLight
fromStream:streamTest];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [storage mainThreadManagedObjectContext];
Expand Down Expand Up @@ -194,8 +243,14 @@ - (void)testImportMessageUniquing {
XMPPJID *jid = [XMPPJID jidWithString:@"[email protected]"];
XMPPRoomLight *roomLight = [[XMPPRoomLight alloc] initWithRoomLightStorage:storage jid:jid roomname:@"test" dispatchQueue:nil];

[storage importRemoteArchiveMessage:[self fakeIncomingMessage] withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0] inRoom:roomLight fromStream:streamTest];
[storage importRemoteArchiveMessage:[self fakeIncomingMessage] withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0] inRoom:roomLight fromStream:streamTest];
[storage importRemoteArchiveMessage:[self fakeIncomingMessageWithBody:YES]
withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0]
inRoom:roomLight
fromStream:streamTest];
[storage importRemoteArchiveMessage:[self fakeIncomingMessageWithBody:YES]
withTimestamp:[NSDate dateWithTimeIntervalSinceReferenceDate:0]
inRoom:roomLight
fromStream:streamTest];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [storage mainThreadManagedObjectContext];
Expand Down Expand Up @@ -231,14 +286,16 @@ - (void)xmppRoomLight:(XMPPRoomLight *)sender didReceiveMessage:(XMPPMessage *)m
}
}

- (XMPPMessage *)fakeIncomingMessage{
- (XMPPMessage *)fakeIncomingMessageWithBody:(BOOL)shouldIncludeBody {
NSMutableString *s = [NSMutableString string];
[s appendString: @"<message xmlns='jabber:client' \
from='[email protected]/[email protected]' \
to='[email protected]' \
id='C7A969D8-C711-4516-9313-10EA9927B39B' \
type='groupchat'>"];
[s appendString: @" <body>Yo! 13</body>'"];
if (shouldIncludeBody) {
[s appendString: @"<body>Yo! 13</body>'"];
}
[s appendString: @"</message>"];

NSError *error;
Expand Down

0 comments on commit 0ec4785

Please sign in to comment.