org.chromium.android_webview.test.LoadUrlTest.java Source code

Java tutorial

Introduction

Here is the source code for org.chromium.android_webview.test.LoadUrlTest.java

Source

// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.android_webview.test;

import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;

import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.LoadUrlParams;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.HistoryUtils;
import org.chromium.net.test.util.TestWebServer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Test suite for loadUrl().
 */
public class LoadUrlTest extends AwTestBase {
    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testDataUrl() throws Throwable {
        final String expectedTitle = "dataUrlTest";
        final String data = "<html><head><title>" + expectedTitle + "</title></head><body>foo</body></html>";

        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();
        loadDataSync(awContents, contentsClient.getOnPageFinishedHelper(), data, "text/html", false);
        assertEquals(expectedTitle, getTitleOnUiThread(awContents));
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testDataUrlBase64() throws Throwable {
        final String expectedTitle = "dataUrlTestBase64";
        final String data = "PGh0bWw+PGhlYWQ+PHRpdGxlPmRhdGFVcmxUZXN0QmFzZTY0PC90aXRsZT48" + "L2hlYWQ+PC9odG1sPg==";

        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();
        loadDataSync(awContents, contentsClient.getOnPageFinishedHelper(), data, "text/html", true);
        assertEquals(expectedTitle, getTitleOnUiThread(awContents));
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testDataUrlCharset() throws Throwable {
        // Note that the \u00a3 (pound sterling) is the important character in the following
        // string as it's not in the US_ASCII character set.
        final String expectedTitle = "You win \u00a3100!";
        final String data = "<html><head><title>" + expectedTitle + "</title></head><body>foo</body></html>";
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();
        loadDataSyncWithCharset(awContents, contentsClient.getOnPageFinishedHelper(), data, "text/html", false,
                "UTF-8");
        assertEquals(expectedTitle, getTitleOnUiThread(awContents));
    }

    /**
     * Loads url on the UI thread and blocks until onPageFinished is called.
     */
    protected void loadUrlWithExtraHeadersSync(final AwContents awContents, CallbackHelper onPageFinishedHelper,
            final String url, final Map<String, String> extraHeaders) throws Throwable {
        int currentCallCount = onPageFinishedHelper.getCallCount();
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                LoadUrlParams params = new LoadUrlParams(url);
                params.setExtraHeaders(extraHeaders);
                awContents.loadUrl(params);
            }
        });
        onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
    }

    private static List<Pair<String, String>> createHeadersList(String[] namesAndValues) {
        List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
        for (int i = 0; i < namesAndValues.length; i += 2)
            result.add(Pair.create(namesAndValues[i], namesAndValues[i + 1]));
        return result;
    }

    private static Map<String, String> createHeadersMap(String[] namesAndValues) {
        Map<String, String> result = new HashMap<String, String>();
        for (int i = 0; i < namesAndValues.length; i += 2)
            result.put(namesAndValues[i], namesAndValues[i + 1]);
        return result;
    }

    private void validateRequestHeaders(String[] refNamesAndValues, HttpRequest request) {
        for (int i = 0; i < refNamesAndValues.length; i += 2) {
            Header[] matchingHeaders = request.getHeaders(refNamesAndValues[i]);
            assertEquals(1, matchingHeaders.length);

            Header header = matchingHeaders[0];
            assertEquals(refNamesAndValues[i].toLowerCase(Locale.ENGLISH), header.getName());
            assertEquals(refNamesAndValues[i + 1], header.getValue());
        }
    }

    private void validateNoRequestHeaders(String[] refNamesAndValues, HttpRequest request) {
        for (int i = 0; i < refNamesAndValues.length; i += 2) {
            Header[] matchingHeaders = request.getHeaders(refNamesAndValues[i]);
            assertEquals(0, matchingHeaders.length);
        }
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testLoadUrlWithExtraHeaders() throws Throwable {
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();

        TestWebServer webServer = null;
        try {
            webServer = new TestWebServer(false);
            final String imagePath = "/" + CommonResources.FAVICON_FILENAME;
            webServer.setResponseBase64(imagePath, CommonResources.FAVICON_DATA_BASE64,
                    CommonResources.getImagePngHeaders(true));
            final String path = "/load_url_with_extra_headers_test.html";
            final String url = webServer.setResponse(path,
                    CommonResources.getOnImageLoadedHtml(CommonResources.FAVICON_FILENAME), null);
            String[] extraHeaders = { "X-ExtraHeaders1", "extra-header-data1", "x-extraHeaders2",
                    "EXTRA-HEADER-DATA2" };

            loadUrlWithExtraHeadersSync(awContents, contentsClient.getOnPageFinishedHelper(), url,
                    createHeadersMap(extraHeaders));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
            // Verify that extra headers are only passed for the main resource.
            validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(imagePath));
        } finally {
            if (webServer != null)
                webServer.shutdown();
        }
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testNoOverridingOfExistingHeaders() throws Throwable {
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();

        TestWebServer webServer = null;
        try {
            webServer = new TestWebServer(false);
            final String path = "/no_overriding_of_existing_headers_test.html";
            final String url = webServer.setResponse(path, "<html><body>foo</body></html>", null);
            String[] extraHeaders = { "user-agent", "007" };

            loadUrlWithExtraHeadersSync(awContents, contentsClient.getOnPageFinishedHelper(), url,
                    createHeadersMap(extraHeaders));
            Header[] matchingHeaders = webServer.getLastRequest(path).getHeaders(extraHeaders[0]);
            assertEquals(1, matchingHeaders.length);
            Header header = matchingHeaders[0];
            assertEquals(extraHeaders[0].toLowerCase(Locale.ENGLISH), header.getName().toLowerCase(Locale.ENGLISH));
            // Just check that the value is there, and it's not the one we provided.
            assertTrue(header.getValue().length() > 0);
            assertFalse(extraHeaders[1].equals(header.getValue()));
        } finally {
            if (webServer != null)
                webServer.shutdown();
        }
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testReloadWithExtraHeaders() throws Throwable {
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();

        TestWebServer webServer = null;
        try {
            webServer = new TestWebServer(false);
            final String path = "/reload_with_extra_headers_test.html";
            final String url = webServer.setResponse(path, "<html><body>foo</body></html>",
                    createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
            String[] extraHeaders = { "X-ExtraHeaders1", "extra-header-data1", "x-extraHeaders2",
                    "EXTRA-HEADER-DATA2" };

            loadUrlWithExtraHeadersSync(awContents, contentsClient.getOnPageFinishedHelper(), url,
                    createHeadersMap(extraHeaders));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));

            reloadSync(awContents, contentsClient.getOnPageFinishedHelper());
            assertEquals(2, webServer.getRequestCount(path));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
        } finally {
            if (webServer != null)
                webServer.shutdown();
        }
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testRedirectAndReloadWithExtraHeaders() throws Throwable {
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();

        TestWebServer webServer = null;
        try {
            webServer = new TestWebServer(false);
            final String path = "/redirect_and_reload_with_extra_headers_test.html";
            final String url = webServer.setResponse(path, "<html><body>foo</body></html>",
                    createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
            final String redirectedPath = "/redirected.html";
            final String redirectedUrl = webServer.setRedirect(redirectedPath, path);
            String[] extraHeaders = { "X-ExtraHeaders1", "extra-header-data1", "x-extraHeaders2",
                    "EXTRA-HEADER-DATA2" };

            loadUrlWithExtraHeadersSync(awContents, contentsClient.getOnPageFinishedHelper(), redirectedUrl,
                    createHeadersMap(extraHeaders));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(redirectedPath));

            // WebView will only reload the main page.
            reloadSync(awContents, contentsClient.getOnPageFinishedHelper());
            assertEquals(2, webServer.getRequestCount(path));
            // No extra headers. This is consistent with legacy behavior.
            validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(path));
        } finally {
            if (webServer != null)
                webServer.shutdown();
        }
    }

    @SmallTest
    @Feature({ "AndroidWebView" })
    public void testRendererNavigationAndGoBackWithExtraHeaders() throws Throwable {
        final TestAwContentsClient contentsClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView = createAwTestContainerViewOnMainSync(contentsClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings settings = getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);

        TestWebServer webServer = null;
        try {
            webServer = new TestWebServer(false);
            final String nextPath = "/next.html";
            final String nextUrl = webServer.setResponse(nextPath, "<html><body>Next!</body></html>", null);
            final String path = "/renderer_nav_and_go_back_with_extra_headers_test.html";
            final String url = webServer.setResponse(path,
                    "<html><body><a id=\"next\" href=\"next.html\">Next!</a></body></html>",
                    createHeadersList(new String[] { "cache-control", "no-cache, no-store" }));
            String[] extraHeaders = { "X-ExtraHeaders1", "extra-header-data1", "x-extraHeaders2",
                    "EXTRA-HEADER-DATA2" };

            loadUrlWithExtraHeadersSync(awContents, contentsClient.getOnPageFinishedHelper(), url,
                    createHeadersMap(extraHeaders));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));

            int currentCallCount = contentsClient.getOnPageFinishedHelper().getCallCount();
            JSUtils.clickOnLinkUsingJs(this, awContents, contentsClient.getOnEvaluateJavaScriptResultHelper(),
                    "next");
            contentsClient.getOnPageFinishedHelper().waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_MS,
                    TimeUnit.MILLISECONDS);
            // No extra headers for the page navigated via clicking.
            validateNoRequestHeaders(extraHeaders, webServer.getLastRequest(nextPath));

            HistoryUtils.goBackSync(getInstrumentation(), awContents.getContentViewCore(),
                    contentsClient.getOnPageFinishedHelper());
            assertEquals(2, webServer.getRequestCount(path));
            validateRequestHeaders(extraHeaders, webServer.getLastRequest(path));
        } finally {
            if (webServer != null)
                webServer.shutdown();
        }
    }
}