1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings/*
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * The contents of this file are subject to the terms of the Common Development and
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * Distribution License (the License). You may not use this file except in compliance with the
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * License.
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings *
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * specific language governing permission and limitations under the License.
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings *
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * When distributing Covered Software, include this CDDL Header Notice in each file and include
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * Header, with the fields enclosed by brackets [] replaced by your own identifying
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * information: "Portions copyright [year] [name of copyright owner]".
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings *
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings * Copyright 2016 ForgeRock AS.
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings */
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import <OCMock/OCMock.h>
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings#import <XCTest/XCTest.h>
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni#import "FRAHotpOathMechanism.h"
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings#import "FRAIdentity.h"
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import "FRAIdentityDatabase.h"
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings#import "FRAIdentityDatabaseSQLiteOperations.h"
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings#import "FRAIdentityModel.h"
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import "FRAModelObjectProtected.h"
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni#import "FRAModelsFromDatabase.h"
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import "FRANotification.h"
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import "FRANotificationHandler.h"
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell#import "FRAPushMechanism.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAFMDatabaseConnectionHelper.h"
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings@interface FRANotificationHandlerTest : XCTestCase
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings@end
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbingsstatic NSString *const TEST_USERNAME = @"Alice";
465ea459a87d4605e145d8f45b6a9c104b696e3bCraig McDonnellstatic NSString *const CHALLENGE = @"dGhlbGVnZW5kb2ZsdW5h";
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings@implementation FRANotificationHandlerTest {
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRANotificationHandler *handler;
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRAIdentityDatabase *database;
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRAIdentityModel *identityModel;
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRAIdentity *identity;
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRAPushMechanism *pushMechanism;
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni FRAHotpOathMechanism *oathMechanism;
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell UIApplication *mockApplication;
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni FRAFMDatabaseConnectionHelper *mockSqlDatabase;
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings id mockDatabaseOperations;
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni id mockModelsFromDatabase;
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings}
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings- (void)setUp {
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings [super setUp];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell mockApplication = OCMClassMock([UIApplication class]);
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni mockModelsFromDatabase = OCMClassMock([FRAModelsFromDatabase class]);
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni OCMStub([mockModelsFromDatabase allIdentitiesWithDatabase:[OCMArg any] identityDatabase:[OCMArg any] identityModel:[OCMArg any] error:[OCMArg anyObjectRef]]).andReturn(@[]);
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings mockDatabaseOperations = OCMClassMock([FRAIdentityDatabaseSQLiteOperations class]);
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings database = [[FRAIdentityDatabase alloc] initWithSqlOperations:mockDatabaseOperations];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // create object model
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott identityModel = [[FRAIdentityModel alloc] initWithDatabase:database sqlDatabase:mockSqlDatabase];
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni identity = [FRAIdentity identityWithDatabase:database identityModel:identityModel accountName:TEST_USERNAME issuer:@"ForgeRock" image:nil backgroundColor:nil];
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni pushMechanism = [[FRAPushMechanism alloc] initWithDatabase:database identityModel:identityModel];
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings [pushMechanism setValue:@"0" forKey:@"mechanismUID"];
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni oathMechanism = [[FRAHotpOathMechanism alloc] initWithDatabase:database identityModel:identityModel];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [identityModel addIdentity:identity error:nil];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [identity addMechanism:pushMechanism error:nil];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [identity addMechanism:oathMechanism error:nil];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // persist to object model database
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [database insertIdentity:identity error:nil];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings handler = [[FRANotificationHandler alloc] initWithDatabase:database identityModel:identityModel];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings}
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings- (void)tearDown {
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings [mockDatabaseOperations stopMocking];
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni [mockModelsFromDatabase stopMocking];
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings [super tearDown];
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings}
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell- (void)testCreatesNotificationObjectFromMessageAndSavesToIdentifiedPushMechanism {
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // Given
c0a2f8c6e84ddf9a597f19e5f161382b0e2cf81bDiego Colantoni NSDictionary *data = @{@"aps":@{@"messageId":@"123", @"data":@"eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.ew0KICAgICJjIjoiZEdobGJHVm5aVzVrYjJac2RXNWgiLA0KICAgICJsIjoiWVcxc1ltTnZiMnRwWlQxaGJXeGlZMjl2YTJsbFBUQXgiLA0KICAgICJ0IiA6IjEyMCIsDQogICAgInUiOiIwIg0KfQ==.1SAWJlT-5vjYRbpZ_57K-NpFRs4VZbSzZjAF_3RTu7k"}};
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // When
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell [handler application:mockApplication didReceiveRemoteNotification:data];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // Then
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell FRANotification *notification = [pushMechanism notificationWithMessageId:@"123"];
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertNotNil(notification, @"Mechanism did not contain expected Notification");
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertEqualObjects(notification.database, database, @"Notification not initialized with database");
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertEqualObjects(notification.messageId, @"123", @"Notification not initialized with messageId");
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings XCTAssertEqualObjects(notification.challenge, CHALLENGE, @"Notification not initialized with challenge");
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertNotNil(notification.timeReceived, @"Notification not initialized with timeReceived");
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertEqual(notification.timeToLive, 120, @"Notification not initialized with time to live");
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings}
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell- (void)testNotificationHandlingShouldBeIdempotent {
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings // Given
c0a2f8c6e84ddf9a597f19e5f161382b0e2cf81bDiego Colantoni NSDictionary *data = @{@"aps":@{@"messageId":@"123", @"data":@"eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.ew0KICAgICJjIjoiZEdobGJHVm5aVzVrYjJac2RXNWgiLA0KICAgICJsIjoiWVcxc1ltTnZiMnRwWlQxaGJXeGlZMjl2YTJsbFBUQXgiLA0KICAgICJ0IiA6IjEyMCIsDQogICAgInUiOiIwIg0KfQ==.1SAWJlT-5vjYRbpZ_57K-NpFRs4VZbSzZjAF_3RTu7k"}};
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings // When
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell [handler application:mockApplication didReceiveRemoteNotification:data];
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell [handler application:mockApplication didReceiveRemoteNotification:data];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings // Then
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertEqual([pushMechanism notifications].count, 1, @"Notification handling should be idempotent");
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell}
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell- (void)testOnlyHandlesNotificationsThatReferToPushMechanism {
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // Given
c0a2f8c6e84ddf9a597f19e5f161382b0e2cf81bDiego Colantoni NSDictionary *data = @{@"aps":@{@"messageId":@"123", @"data":@"eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiIH0.ew0KICAgICJjIjoiZEdobGJHVm5aVzVrYjJac2RXNWgiLA0KICAgICJsIjoiWVcxc1ltTnZiMnRwWlQxaGJXeGlZMjl2YTJsbFBUQXgiLA0KICAgICJ0IiA6IjEyMCIsDQogICAgInUiOiIwIg0KfQ==.1SAWJlT-5vjYRbpZ_57K-NpFRs4VZbSzZjAF_3RTu7k"}};
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // When
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell [handler application:mockApplication didReceiveRemoteNotification:data];
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell // Then
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell XCTAssertEqual([oathMechanism notifications].count, 0, @"Only Push-Mechanism notifications should be handled");
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott XCTAssertEqual([pushMechanism notifications].count, 1, @"Only Push-Mechanism notifications should be handled");
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings}
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings
1d464fc27913cfdeb6e09c8ab5d06ada64f94d55Ken Stubbings@end