1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.android_webview.test;
6
7import android.os.Message;
8import android.test.suitebuilder.annotation.SmallTest;
9
10import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
11
12import org.apache.http.util.EncodingUtils;
13import org.chromium.android_webview.AwContents;
14import org.chromium.base.test.util.DisabledTest;
15import org.chromium.base.test.util.Feature;
16import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
17import org.chromium.net.test.util.TestWebServer;
18
19import java.util.concurrent.TimeUnit;
20import java.util.concurrent.TimeoutException;
21
22/**
23 * Tests if resubmission of post data is handled properly.
24 */
25public class AwContentsClientOnFormResubmissionTest extends AwTestBase {
26
27    private static class TestAwContentsClient
28            extends org.chromium.android_webview.test.TestAwContentsClient {
29
30        // Number of times onFormResubmit is called.
31        private int mResubmissions = 0;
32        // Whether to resubmit Post data on reload.
33        private boolean mResubmit = false;
34
35        public int getResubmissions() {
36            return mResubmissions;
37        }
38        public void setResubmit(boolean resubmit) {
39            mResubmit = resubmit;
40        }
41        @Override
42        public void onFormResubmission(Message dontResend, Message resend) {
43            mResubmissions++;
44            if (mResubmit) {
45                resend.sendToTarget();
46            } else {
47                dontResend.sendToTarget();
48            }
49        }
50    }
51
52    // Server responses for load and reload of posts.
53    private static final String LOAD_RESPONSE =
54            "<html><head><title>Load</title></head><body>HELLO</body></html>";
55    private static final String RELOAD_RESPONSE =
56            "<html><head><title>Reload</title></head><body>HELLO</body></html>";
57
58    // Server timeout in seconds. Used to detect dontResend case.
59    private static final long TIMEOUT = scaleTimeout(3);
60
61    // The web server.
62    private TestWebServer mServer;
63    // The mock client.
64    private TestAwContentsClient mContentsClient;
65    private AwContents mAwContents;
66
67    @Override
68    public void setUp() throws Exception {
69        super.setUp();
70        mServer = new TestWebServer(false);
71        mContentsClient = new TestAwContentsClient();
72        final AwTestContainerView testContainerView =
73                createAwTestContainerViewOnMainSync(mContentsClient);
74        mAwContents = testContainerView.getAwContents();
75    }
76
77    @Override
78    public void tearDown() throws Exception {
79        mServer.shutdown();
80        super.tearDown();
81    }
82
83    /*
84    @SmallTest
85    @Feature({"AndroidWebView", "Navigation"})
86    */
87    @DisabledTest
88    public void testResend() throws Throwable {
89        mContentsClient.setResubmit(true);
90        doReload();
91        assertEquals(1, mContentsClient.getResubmissions());
92        assertEquals("Reload", getTitleOnUiThread(mAwContents));
93    }
94
95    @SmallTest
96    @Feature({"AndroidWebView", "Navigation"})
97    public void testDontResend() throws Throwable {
98        mContentsClient.setResubmit(false);
99        doReload();
100        assertEquals(1, mContentsClient.getResubmissions());
101        assertEquals("Load", getTitleOnUiThread(mAwContents));
102    }
103
104    protected void doReload() throws Throwable {
105        String url = mServer.setResponse("/form", LOAD_RESPONSE, null);
106        String postData = "content=blabla";
107        byte[] data = EncodingUtils.getBytes(postData, "BASE64");
108        postUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url, data);
109        assertEquals(0, mContentsClient.getResubmissions());
110        assertEquals("Load", getTitleOnUiThread(mAwContents));
111        // Verify reload works as expected.
112        mServer.setResponse("/form", RELOAD_RESPONSE, null);
113        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
114                mContentsClient.getOnPageFinishedHelper();
115        int callCount = onPageFinishedHelper.getCallCount();
116        // Run reload on UI thread.
117        getInstrumentation().runOnMainSync(new Runnable() {
118            @Override
119            public void run() {
120                mAwContents.getNavigationController().reload(true);
121            }
122        });
123        try {
124            // Wait for page finished callback, or a timeout. A timeout is necessary
125            // to detect a dontResend response.
126            onPageFinishedHelper.waitForCallback(callCount, 1, TIMEOUT, TimeUnit.SECONDS);
127        } catch (TimeoutException e) {
128            // Exception expected from testDontResend case.
129        }
130    }
131}
132