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.test.suitebuilder.annotation.SmallTest;
8import android.webkit.ValueCallback;
9
10import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
11
12import org.chromium.android_webview.AwContents;
13import org.chromium.base.ThreadUtils;
14import org.chromium.base.test.util.Feature;
15import org.chromium.base.test.util.UrlUtils;
16
17import java.io.File;
18import java.util.concurrent.Semaphore;
19import java.util.concurrent.TimeUnit;
20import java.util.concurrent.atomic.AtomicReference;
21
22/**
23 * Test suite for the WebView.saveWebArchive feature.
24 */
25public class ArchiveTest extends AwTestBase {
26
27    private static final long TEST_TIMEOUT = scaleTimeout(20000L);
28
29    private static final String TEST_PAGE = UrlUtils.encodeHtmlDataUri(
30            "<html><head></head><body>test</body></html>");
31
32    private TestAwContentsClient mContentsClient = new TestAwContentsClient();
33    private AwTestContainerView mTestContainerView;
34
35    @Override
36    protected void setUp() throws Exception {
37        super.setUp();
38        mTestContainerView = createAwTestContainerViewOnMainSync(mContentsClient);
39    }
40
41    private void deleteFile(String path) {
42        File file = new File(path);
43        if (file.exists())
44            assertTrue(file.delete());
45        assertFalse(file.exists());
46    }
47
48    private void doArchiveTest(final AwContents contents, final String path,
49            final boolean autoName, String expectedPath) throws InterruptedException {
50        if (expectedPath != null) {
51            deleteFile(expectedPath);
52        }
53
54        // Set up a handler to handle the completion callback
55        final Semaphore s = new Semaphore(0);
56        final AtomicReference<String> msgPath = new AtomicReference<String>();
57        final ValueCallback<String> callback = new ValueCallback<String>() {
58            @Override
59            public void onReceiveValue(String path) {
60                msgPath.set(path);
61                s.release();
62            }
63        };
64
65        // Generate MHTML and wait for completion
66        ThreadUtils.runOnUiThread(new Runnable() {
67            @Override
68            public void run() {
69                contents.saveWebArchive(path, autoName, callback);
70            }
71        });
72        assertTrue(s.tryAcquire(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
73
74        assertEquals(expectedPath, msgPath.get());
75        if (expectedPath != null) {
76            File file = new File(expectedPath);
77            assertTrue(file.exists());
78            assertTrue(file.length() > 0);
79        } else {
80            // A path was provided, but the expected path was null. This means the save should have
81            // failed, and so there shouldn't be a file path path.
82            if (path != null) {
83                assertFalse(new File(path).exists());
84            }
85        }
86    }
87
88    @SmallTest
89    @Feature({"AndroidWebView"})
90    public void testExplicitGoodPath() throws Throwable {
91        final String path = new File(getActivity().getFilesDir(), "test.mht").getAbsolutePath();
92        deleteFile(path);
93
94        loadUrlSync(mTestContainerView.getAwContents(),
95                mContentsClient.getOnPageFinishedHelper(), TEST_PAGE);
96
97        doArchiveTest(mTestContainerView.getAwContents(), path, false, path);
98    }
99
100    @SmallTest
101    @Feature({"AndroidWebView"})
102    public void testAutoGoodPath() throws Throwable {
103        final String path = getActivity().getFilesDir().getAbsolutePath() + "/";
104
105        loadUrlSync(mTestContainerView.getAwContents(),
106                mContentsClient.getOnPageFinishedHelper(), TEST_PAGE);
107
108        // Create the first archive
109        {
110            String expectedPath = path + "index.mht";
111            doArchiveTest(mTestContainerView.getAwContents(), path, true, expectedPath);
112        }
113
114        // Create a second archive, making sure that the second archive's name is auto incremented.
115        {
116            String expectedPath = path + "index-1.mht";
117            doArchiveTest(mTestContainerView.getAwContents(), path, true, expectedPath);
118        }
119    }
120
121    @SmallTest
122    @Feature({"AndroidWebView"})
123    public void testExplicitBadPath() throws Throwable {
124        final String path = new File("/foo/bar/baz.mht").getAbsolutePath();
125        deleteFile(path);
126
127        loadUrlSync(mTestContainerView.getAwContents(),
128                mContentsClient.getOnPageFinishedHelper(), TEST_PAGE);
129
130        doArchiveTest(mTestContainerView.getAwContents(), path, false, null);
131    }
132
133    @SmallTest
134    @Feature({"AndroidWebView"})
135    public void testAutoBadPath() throws Throwable {
136        final String path = new File("/foo/bar/").getAbsolutePath();
137        deleteFile(path);
138
139        loadUrlSync(mTestContainerView.getAwContents(),
140                mContentsClient.getOnPageFinishedHelper(), TEST_PAGE);
141
142        doArchiveTest(mTestContainerView.getAwContents(), path, true, null);
143    }
144
145}
146