package com.mobify.astro.plugins.webviewplugin;

import android.os.Build;
import android.webkit.WebView;

import com.mobify.astro.ActivityTestBase;

import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

public class AstroWebViewClientTest extends ActivityTestBase {
    WebView webView;
    AstroWebViewClient.WebClientListener webClientListener;
    AstroWebViewClient webViewClient;

    // So we can mock Build.VERSION.SDK_INT for one of the tests
    static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("accessFlags");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, newValue);
    }

    @Before
    public void setup() {
        webView = mock(WebView.class);
        webClientListener = mock(AstroWebViewClient.WebClientListener.class);
        webViewClient = new AstroWebViewClient(webClientListener);
    }

    @Test
    public void testOnPageStarted() {
        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        verify(webClientListener).webClientPageStarted(webView, "http://mobify.com");
    }

    @Test
    public void testOnPageStartedIgnoresExcessiveCalls() {
        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        webViewClient.onPageStarted(webView, "http://google.com", null);
        verify(webClientListener).webClientPageStarted(webView, "http://mobify.com");
        verify(webClientListener, never()).webClientPageStarted(webView, "http://google.com");
    }

    @Test
    public void testOnPageFinished() {
        webViewClient.isCurrentlyLoading = true;
        webViewClient.onPageFinished(webView, "http://mobify.com");
        verify(webClientListener).webClientPageFinished(webView, "http://mobify.com");
    }

    @Test
    public void testOnPageFinishedIgnoresExcessiveCalls() {
        webViewClient.isCurrentlyLoading = true;
        webViewClient.onPageFinished(webView, "http://mobify.com");
        webViewClient.onPageFinished(webView, "http://google.com");
        verify(webClientListener).webClientPageFinished(webView, "http://mobify.com");
        verify(webClientListener, never()).webClientPageFinished(webView, "http://google.com");
    }

    @Test
    public void testShouldOverrideUrlLoading() {
        webViewClient.isCurrentlyLoading = true;
        webViewClient.shouldOverrideUrlLoading(webView, "http://mobify.com");
        verify(webClientListener).webClientNavigate(webView, "http://mobify.com", true);

        webViewClient.isCurrentlyLoading = false;
        webViewClient.shouldOverrideUrlLoading(webView, "http://google.com");
        verify(webClientListener).webClientNavigate(webView, "http://google.com", false);
    }

    @Test
    public void testIgnoreNextPageLifecycle() throws Exception {
        // This feature is only for older versions of Android. So let's mock
        // that we are running an older version of Android for the duration of the test.
        int originalSDKBuildVersion = Build.VERSION.SDK_INT;
        setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 20);

        webViewClient.ignoreNextPageLifecycle();

        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        webViewClient.onPageFinished(webView, "http://mobify.com");
        verify(webClientListener, never()).webClientPageStarted(webView, "http://mobify.com");
        verify(webClientListener, never()).webClientPageFinished(webView, "http://mobify.com");

        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        webViewClient.onPageFinished(webView, "http://mobify.com");
        verify(webClientListener).webClientPageStarted(webView, "http://mobify.com");
        verify(webClientListener).webClientPageFinished(webView, "http://mobify.com");

        setFinalStatic(Build.VERSION.class.getField("SDK_INT"), originalSDKBuildVersion);

        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        webViewClient.onPageFinished(webView, "http://mobify.com");
        verify(webClientListener, times(2)).webClientPageStarted(webView, "http://mobify.com");
        verify(webClientListener, times(2)).webClientPageFinished(webView, "http://mobify.com");

        webViewClient.onPageStarted(webView, "http://mobify.com", null);
        webViewClient.onPageFinished(webView, "http://mobify.com");
        verify(webClientListener, times(3)).webClientPageStarted(webView, "http://mobify.com");
        verify(webClientListener, times(3)).webClientPageFinished(webView, "http://mobify.com");
    }
}
