//
//  SecureStorePluginTests.swift
//  Astro
//
//  Created by Justin Vaillancourt on 2015-09-24.
//  Copyright (c) 2015 Mobify Research & Development Inc. All rights reserved.
//

import XCTest
@testable import Astro

class SecureStorePluginTests: AstroTestCase {
    var messageBus: MessageBus!
    var pluginResolver: StubPluginResolver!
    var capturedResult: CapturedRpcMethodResult!

    var secureStorePlugin: SecureStorePlugin!

    override func setUp() {
        messageBus = MessageBus()
        pluginResolver = StubPluginResolver()
        capturedResult = CapturedRpcMethodResult()

        secureStorePlugin = SecureStorePlugin(address: "SecureStorePlugin:0", messageBus: messageBus, pluginResolver: pluginResolver, options: nil)
        secureStorePlugin.clear(capturedResult.callback)
    }

    //TODO: This needs the entitlements for keychain sharing
    func testSetKeyHasValue() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.set("some key", value: "some other value", respond: self.capturedResult.callback)
            self.secureStorePlugin.get("some key", respond: CapturedRpcMethodResult.generateSuccessCallback { value in
                XCTAssertEqual(value as? String, "some other value")
                expectation.fulfill()
            })
        }
    }

    func testGetUnsetKey() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.get("some key", respond: CapturedRpcMethodResult.generateSuccessCallback { value in
                XCTAssertEqual(value as? NSNull, NSNull())
                expectation.fulfill()
            })
        }
    }

    func testSetKeyCallsRespondWithEmptyResult() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.set("some key", value: "some value", respond: CapturedRpcMethodResult.generateSuccessCallback { value in
                XCTAssertEqual(value as? NSNull, NSNull())
                expectation.fulfill()
            })
        }
    }

    func testGetWithEmptyKey() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.get("", respond: CapturedRpcMethodResult.generateFailureCallback { value in
                XCTAssertEqual(value, "Empty keys are not valid")
                expectation.fulfill()
            })
        }
    }

    func testSetWithEmptyKey() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.set("", value: "a value for an empty key", respond: CapturedRpcMethodResult.generateFailureCallback { value in
                XCTAssertEqual(value, "Cannot store an empty key")
                expectation.fulfill()
            })
        }
    }

    func testDeleteWithEmptyKey() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.delete("", respond: CapturedRpcMethodResult.generateFailureCallback { value in
                XCTAssertEqual(value, "Empty keys are not valid")
                expectation.fulfill()
            })
        }
    }

    func testDeleteAKeyThatDoesntExist() {
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.delete("a key that doesn't exist", respond: CapturedRpcMethodResult.generateSuccessCallback { deleteValue in
                XCTAssertTrue(deleteValue is NSNull)
                expectation.fulfill()
            })
        }
    }

    func testDeleteAKeyThatExists() {
        let key = "a key that does exist"
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.set(key, value: "a value", respond: CapturedRpcMethodResult.generateSuccessCallback { setValue in
                XCTAssertTrue(setValue is NSNull)
                self.secureStorePlugin.delete(key, respond: CapturedRpcMethodResult.generateSuccessCallback { deleteExistValue in
                    XCTAssertTrue(deleteExistValue is NSNull)
                    self.secureStorePlugin.get(key, respond: CapturedRpcMethodResult.generateSuccessCallback { getValue in
                        XCTAssertTrue(getValue is NSNull)
                        expectation.fulfill()
                    })
                })
            })

        }
    }

    func testClear() {
        let aKey = "a key"
        let anotherKey = "anotherKey"
        expectAssertionWithDelay { expectation in
            self.secureStorePlugin.clear(CapturedRpcMethodResult.generateSuccessCallback { clearValue in
                XCTAssertTrue(clearValue is NSNull)
                self.secureStorePlugin.set(aKey, value: "a value", respond: CapturedRpcMethodResult.generateSuccessCallback { setAKeyValue in
                    XCTAssertTrue(setAKeyValue is NSNull)
                    self.secureStorePlugin.set(anotherKey, value: "another value", respond: CapturedRpcMethodResult.generateSuccessCallback { setAnotherValue in
                        XCTAssertTrue(setAnotherValue is NSNull)
                        self.secureStorePlugin.clear(CapturedRpcMethodResult.generateSuccessCallback { clear2Value in
                            XCTAssertTrue(clear2Value is NSNull)
                            self.secureStorePlugin.get(aKey, respond: CapturedRpcMethodResult.generateSuccessCallback { getValue in
                                XCTAssertTrue(getValue is NSNull)
                                self.secureStorePlugin.get(anotherKey, respond: CapturedRpcMethodResult.generateSuccessCallback { getAnotherValue in
                                    XCTAssertTrue(getAnotherValue is NSNull)
                                    expectation.fulfill()
                                })
                            })
                        })
                    })
                })
            })
        }
    }
}
