//
//  WebClientCookieTests.swift
//  Astro
//
//  Created by Kerr Miller on 2016-11-10.
//  Copyright © 2016 Mobify Research & Development Inc. All rights reserved.
//

import XCTest
import WebKit
@testable import Astro

class WebClientCookieTests: AstroTestCase {
    private var uiWebViewDelegate: WebClientDelegate?   //swiftlint:disable:this weak_delegate
    private var wkWebViewDelegate: WebClientDelegate?   //swiftlint:disable:this weak_delegate

    override func setUp() {
        super.setUp()
        uiWebViewDelegate = nil
        wkWebViewDelegate = nil
    }

    func buildCookieTestUIWebViewAdaptor(complete: @escaping (UIWebViewAdaptor) -> Void) {
        let uiWebViewClient = UIWebViewAdaptor(webView: UIWebView())
        let delegate = TestWebClientDelegate()
        delegate.didFinishLoadingClosure = {
            complete(uiWebViewClient)
        }
        uiWebViewDelegate = delegate
        uiWebViewClient.webClientDelegate = uiWebViewDelegate
        uiWebViewClient.loadUrlRequest(RequestBuilder.makeGETRequest(for: testUrl("cookies.html")))
    }

    func buildCookieTestWKWebViewAdaptor(complete: @escaping (WKWebViewAdaptor) -> Void) {
        let wkWebViewClient = WKWebViewAdaptor(webView: WKWebView())
        let delegate = TestWebClientDelegate()
        delegate.didFinishLoadingClosure = {
            complete(wkWebViewClient)
        }
        wkWebViewDelegate = delegate
        wkWebViewClient.webClientDelegate = wkWebViewDelegate
        wkWebViewClient.loadUrlRequest(RequestBuilder.makeGETRequest(for: testUrl("cookies.html")))
    }

    func testGetBasicCookie() {
        expectAssertionWithDelay { expectation in
            buildCookieTestUIWebViewAdaptor { uiWebViewClient in
                uiWebViewClient.getCookie("foo") { (cookieValue, error) -> Void in
                    AssertEqual(cookieValue, b: "bar", message: "UIWebView: get non-nil cookie")
                    AssertNil(error, message: "UIWebView: get non-nil cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }

        expectAssertionWithDelay { expectation in
            buildCookieTestWKWebViewAdaptor { wkWebClient in
                wkWebClient.getCookie("foo") { (cookieValue, error) -> Void in
                    AssertEqual(cookieValue, b: "bar", message: "WKWebView: get non-nil cookie")
                    AssertNil(error, message: "WKWebView: get non-nil cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }
    }

    func testGetUndefinedCookie() {
        expectAssertionWithDelay { expectation in
            buildCookieTestUIWebViewAdaptor { uiWebViewClient in
                uiWebViewClient.getCookie("blah") { (cookieValue, error) -> Void in
                    AssertNil(cookieValue, message: "UIWebView: get undefined cookie")
                    AssertNil(error, message: "UIWebView: get undefined cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }

        expectAssertionWithDelay { expectation in
            buildCookieTestWKWebViewAdaptor { wkWebViewClient in
                wkWebViewClient.getCookie("blah") { (cookieValue, error) -> Void in
                    AssertNil(cookieValue, message: "UIWebView: get undefined cookie")
                    AssertNil(error, message: "WKWebView: get undefined cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }
    }

    func testGetEmptyCookie() {
        expectAssertionWithDelay { expectation in
            buildCookieTestUIWebViewAdaptor { uiWebViewClient in
                uiWebViewClient.getCookie("boo") { (cookieValue, error) -> Void in
                    AssertEqual(cookieValue, b: "", message: "UIWebView: get empty string cookie")
                    AssertNil(error, message: "UIWebView: get undefined cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }

        expectAssertionWithDelay { expectation in
            buildCookieTestWKWebViewAdaptor { wkWebViewClient in
                wkWebViewClient.getCookie("boo") { (cookieValue, error) -> Void in
                    AssertEqual(cookieValue, b: "", message: "WKWebView: get empty string cookie")
                    AssertNil(error, message: "WKWebView: get undefined cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }
    }

    func testDeleteCookie() {
        let uiWebViewClient = buildCookieTestUIWebViewAdaptor()
        expectAssertionWithDelay { expectation in
            uiWebViewClient.deleteCookie(named: "foo") {
                uiWebViewClient.getCookie(named: "foo") { (cookieValue, error) -> Void in
                    AssertNil(cookieValue)
                    AssertNil(error, message: "UIWebView: get deleted cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }

        let wkWebViewClient = buildCookieTestWKWebViewAdaptor()
        expectAssertionWithDelay { expectation in
            wkWebViewClient.deleteCookie(named: "foo") {
                wkWebViewClient.getCookie(named: "foo") { (cookieValue, error) -> Void in
                    AssertNil(cookieValue)
                    AssertNil(error, message: "WKWebView: get deleted cookie returned an error: \(error != nil ? error! : "")")
                    expectation.fulfill()
                }
            }
        }
    }
}
