721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott/*
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * The contents of this file are subject to the terms of the Common Development and
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Distribution License (the License). You may not use this file except in compliance with the
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * License.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * specific language governing permission and limitations under the License.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * When distributing Covered Software, include this CDDL Header Notice in each file and include
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Header, with the fields enclosed by brackets [] replaced by your own identifying
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * information: "Portions copyright [year] [name of copyright owner]".
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Copyright 2016 ForgeRock AS.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott */
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import <XCTest/XCTest.h>
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import <OCMock/OCMock.h>
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRADatabaseConfiguration.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAFMDatabaseConnectionHelper.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAFMDatabaseFactory.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FMDatabase.h"
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni#import "FRAError.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshottstatic NSString * const DatabaseFilePath = @"/database/path";
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshottstatic NSString * const SchemaFilePath = @"/schema/file/path";
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott@interface FRAFMDatabaseConnectionHelperTest : XCTestCase
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott@end
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott/*!
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * A series of tests which will demonstrate the public interface of the
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * database code, and demonstrate that it throws exceptions for conditions
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * we consider to be exceptional.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott */
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott@implementation FRAFMDatabaseConnectionHelperTest {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott id mockConfig;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott id mockFactory;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott id mockDatabase;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott id mockSchemaResults;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSMutableArray *schemaResultsList;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott}
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott- (void)setUp {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [super setUp];
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott mockConfig = OCMClassMock([FRADatabaseConfiguration class]);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott mockFactory = OCMClassMock([FRAFMDatabaseFactory class]);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott mockSchemaResults = OCMClassMock([FMResultSet class]);
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni mockDatabase = OCMClassMock([FMDatabase class]);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott OCMStub([mockSchemaResults next])
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott .andCall(self, @selector(mockSchemaResultsListHasNext));
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott OCMStub([mockSchemaResults stringForColumnIndex:1])
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott .andCall(self, @selector(mockSchemaResultsListGetStringForColumnIndex));
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott}
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott- (void)initialiseSchemaResultsListWith:(NSString *)first, ... {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott schemaResultsList = [[NSMutableArray alloc] init];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott va_list args;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott va_start(args, first);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott for (NSString *arg = first; arg != nil; arg = va_arg(args, NSString*)) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [schemaResultsList addObject:arg];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott va_end(args);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott}
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni- (BOOL)mockSchemaResultsListHasNext {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return [schemaResultsList count] != 0;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott}
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni- (NSString*)mockSchemaResultsListGetStringForColumnIndex {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString* value = [schemaResultsList objectAtIndex:0];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [schemaResultsList removeObjectAtIndex:0];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return value;
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni}
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni- (void)tearDown {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni [mockConfig stopMocking];
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni [mockFactory stopMocking];
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni [mockDatabase stopMocking];
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni [mockSchemaResults stopMocking];
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni [super tearDown];
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni}
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni- (void)testGetConnectionReturnsNilIfNotInitialised {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni FRAFMDatabaseConnectionHelper *database = [FRAFMDatabaseConnectionHelper alloc];
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni FMDatabase *connection = [database getConnectionWithError:nil];
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni XCTAssertNil(connection);
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni}
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni- (void)testGetConnectionReturnsNilIfCantFindDatabasePath {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(nil);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantCreateConnection {
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(nil);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantOpenConnection {
FMDatabase *cannotOpenDatabase = OCMClassMock([FMDatabase class]);
OCMStub([mockConfig getDatabasePathWithError:[OCMArg anyObjectRef]]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:[OCMArg anyObjectRef]]).andReturn(cannotOpenDatabase);
OCMStub([cannotOpenDatabase open]).andReturn(NO);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
NSError *error;
FMDatabase *connection = [database getConnectionWithError:&error];
XCTAssertNil(connection);
XCTAssertNotNil(error);
}
- (void)testGetConnectionReturnsNilIfCantFindInitCheckDatabaseSchema {
id bundle = OCMClassMock([NSBundle class]);
OCMStub([bundle mainBundle]).andReturn(bundle);
OCMStub([bundle pathForResource:@"init_check" ofType:@"sql"]).andReturn(nil);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantReadInitCheckSchemaFileContents {
id bundle = OCMClassMock([NSBundle class]);
OCMStub([bundle mainBundle]).andReturn(bundle);
OCMStub([bundle pathForResource:@"init_check" ofType:@"sql"]).andReturn(SchemaFilePath);
id mockString = OCMClassMock([NSString class]);
OCMStub([mockString initWithContentsOfFile:SchemaFilePath encoding:NSUTF8StringEncoding error:nil]).andReturn(nil);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantExecuteQueryOnDatabase {
FMDatabase *cannotExecuteQueryDatabase = OCMClassMock([FMDatabase class]);
OCMStub([cannotExecuteQueryDatabase open]).andReturn(YES);
OCMStub([cannotExecuteQueryDatabase executeQuery:[OCMArg any]]).andReturn(nil);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(cannotExecuteQueryDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantFindDatabaseSchema {
[self initialiseSchemaResultsListWith:@"unknown", nil];
id bundle = OCMPartialMock([NSBundle mainBundle]);
OCMStub([bundle pathForResource:@"schema" ofType:@"sql"]).andReturn(nil);
FMDatabase *cannotInitialiseDatabase = OCMClassMock([FMDatabase class]);
OCMStub([cannotInitialiseDatabase open]).andReturn(YES);
OCMStub([cannotInitialiseDatabase executeQuery:[OCMArg any]]).andReturn(mockSchemaResults);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(cannotInitialiseDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantReadSchemaFileContents {
[self initialiseSchemaResultsListWith:@"unknown", nil];
id bundle = OCMPartialMock([NSBundle mainBundle]);
OCMStub([bundle pathForResource:@"schema" ofType:@"sql"]).andReturn(SchemaFilePath);
id mockString = OCMClassMock([NSString class]);
OCMStub([mockString initWithContentsOfFile:SchemaFilePath encoding:NSUTF8StringEncoding error:nil]).andReturn(nil);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsNilIfCantInitialiseDatabase {
[self initialiseSchemaResultsListWith:@"unknown", nil];
id sqlDatabase = OCMClassMock([FMDatabase class]);
OCMStub([sqlDatabase executeStatements:[OCMArg any]]).andReturn(NO);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNil(connection);
}
- (void)testGetConnectionReturnsDatabaseConnection {
[self initialiseSchemaResultsListWith:@"identity", @"mechanism", @"notification", nil];
OCMStub([(FMDatabase *)mockDatabase open]).andReturn(YES);
OCMStub([mockDatabase executeQuery:[OCMArg any]]).andReturn(mockSchemaResults);
OCMStub([mockConfig getDatabasePathWithError:nil]).andReturn(DatabaseFilePath);
OCMStub([mockFactory createDatabaseFor:DatabaseFilePath withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *database = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
FMDatabase *connection = [database getConnectionWithError:nil];
XCTAssertNotNil(connection);
}
- (void)testThatDatabaseClosesWhenClosed {
OCMStub([mockFactory createDatabaseFor:[OCMArg any] withError:nil]).andReturn(mockDatabase);
FRAFMDatabaseConnectionHelper *sqlDatabase = [[FRAFMDatabaseConnectionHelper alloc] initWithConfiguration:mockConfig databaseFactory:mockFactory];
[sqlDatabase closeConnectionToDatabase:mockDatabase];
OCMVerify([(FMDatabase *)mockDatabase close]);
}
@end