//
//  HeaderContentTests.swift
//  Astro
//
//  Created by Jeremy Wiebe on 2016-09-02.
//  Copyright © 2016 Mobify Research & Development Inc. All rights reserved.
//

import XCTest
@testable import Astro

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

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

    func testHeaderContentCanBeCreatedFromJson() {
        let headerContentJson: JSONObject = [
            "leftIcon": [
                "id": "leftIcon",
                "imageUrl": "file:///astro-logo.png"
            ],
            "centerIcon": [
                "id": "centerIcon",
                "imageUrl": "file:///astro-logo.png"
            ],
            "rightIcon": [
                "id": "rightIcon",
                "imageUrl": "file:///astro-logo.png"
            ]
        ]
        let headerContent = HeaderContent(jsonObject: headerContentJson, pluginResolver: pluginResolver, respond: capturedResult.callback)

        AssertNotNil(headerContent?.leftIcon)
        AssertNotNil(headerContent?.centerIcon)
        AssertNotNil(headerContent?.rightIcon)

        XCTAssert(capturedResult.isEmpty, "result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error?.debugDescription ?? "No error")")
    }

    func testHeaderContentItemsCanBeOmitted() {
        let headerContent = HeaderContent(jsonObject:JSONObject(), pluginResolver: pluginResolver, respond: capturedResult.callback)

        AssertNil(headerContent?.leftIcon)
        AssertNil(headerContent?.centerIcon)
        AssertNil(headerContent?.rightIcon)

        XCTAssert(capturedResult.isEmpty, "result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error ?? "No error")")
    }

    func testHeaderContentItemWithImageCanBeCreatedFromJson() {
        let itemJson: JSONObject = [
            "id": "leftIcon",
            "imageUrl": "file:///astro-logo.png"
        ]

        _ = HeaderContentItem(jsonObject: itemJson, pluginResolver: pluginResolver, respond: capturedResult.callback)

        XCTAssert(capturedResult.isEmpty, "result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error ?? "No error")")
    }

    func testHeaderContentItemWithTitleCanBeCreatedFromJson() {
        let itemJson: JSONObject = [
            "id": "leftIcon",
            "title": "Title"
        ]

        _ = HeaderContentItem(jsonObject: itemJson, pluginResolver: pluginResolver, respond: capturedResult.callback)

        XCTAssert(capturedResult.isEmpty, "result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error ?? "No error")")
    }

    func testHeaderContentItemWithPluginAddressCanBeCreatedFromJson() {
        let imageViewPluginAddress = "ImageViewPlugin:0"
        let imageViewPlugin = ImageViewPlugin(address: imageViewPluginAddress, messageBus: messageBus, pluginResolver: pluginResolver, options: nil)
        pluginResolver.addPlugin(imageViewPlugin)

        let itemJson: JSONObject = [
            "id": "leftIcon",
            "pluginAddress": imageViewPluginAddress
        ]

        _ = HeaderContentItem(jsonObject: itemJson, pluginResolver: pluginResolver, respond: capturedResult.callback)

        XCTAssert(capturedResult.isEmpty, "result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error ?? "No error")")
    }

    func testAnErrorIsReturnedForInvalidHeaderContentItemJson() {
        let invalidItemJson: [String:JSONObject] = [
            "missing id": [
                "imageUrl": "file:///astro-logo.png"
            ],
            "missing image and title": [
                "id": "leftIcon"
            ],
            "invalid image": [
                "id": "leftIcon",
                "imageUrl": "file:///some_invalid_filename.png"
            ]
        ]

        for (testName, itemJson) in invalidItemJson {
            let item = HeaderContentItem(jsonObject: itemJson, pluginResolver: pluginResolver, respond: capturedResult.callback)

            AssertNil(item)
            XCTAssert(capturedResult.hasError, "\(testName)  result: \(capturedResult.result ?? "No result")  error: \(capturedResult.error ?? "No error")")
        }
    }
}
