Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc

Issue 2354363007: Add unit tests for AddToHomescreenDataFetcher (Closed)
Patch Set: Merge branch 'master' into remove_unneeded_var2.9 Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/webapps/DEPS ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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
5 #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "base/callback_forward.h"
11 #include "base/files/file_path.h"
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/nullable_string16.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h"
19 #include "chrome/common/web_application_info.h"
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "content/browser/service_worker/embedded_worker_test_helper.h"
23 #include "content/browser/service_worker/service_worker_context_core.h"
24 #include "content/common/service_worker/service_worker_status_code.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/site_instance.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/manifest.h"
29 #include "content/test/test_web_contents.h"
30 #include "net/http/http_status_code.h"
31 #include "third_party/WebKit/public/platform/WebDisplayMode.h"
32 #include "ui/gfx/image/image_unittest_util.h"
33 #include "url/gurl.h"
34
35 namespace {
36
37 const char* kDefaultManifestUrl = "https://www.example.com/manifest.json";
38 const char* kDefaultManifestName = "Default Name";
39 const char* kDefaultManifestShortName = "Default Short Name";
40 const char* kDefaultStartUrl = "https://www.example.com/index.html";
41 const blink::WebDisplayMode kDefaultManifestDisplayMode =
42 blink::WebDisplayModeStandalone;
43
44 // WebContents subclass which mocks out image and manifest fetching.
45 class MockWebContents : public content::TestWebContents {
46 public:
47 explicit MockWebContents(content::BrowserContext* browser_context)
48 : content::TestWebContents(browser_context) {}
49
50 ~MockWebContents() override {
51 }
52
53 // Sets the manifest to be returned by GetManifest().
54 // |fetch_delay_ms| is the time in milliseconds that the simulated fetch of
55 // the web manifest should take.
56 void SetManifest(const GURL& manifest_url,
57 const content::Manifest& manifest,
58 int fetch_delay_ms) {
59 manifest_url_ = manifest_url;
60 manifest_ = manifest;
61 manifest_fetch_delay_ms_ = fetch_delay_ms;
62 }
63
64 int DownloadImage(const GURL& url,
65 bool is_favicon,
66 uint32_t max_bitmap_size,
67 bool bypass_cache,
68 const ImageDownloadCallback& callback) override {
69 const int kIconSizePx = 144;
70 SkBitmap icon = gfx::test::CreateBitmap(kIconSizePx, kIconSizePx);
71 std::vector<SkBitmap> icons(1u, icon);
72 std::vector<gfx::Size> pixel_sizes(1u, gfx::Size(kIconSizePx, kIconSizePx));
73 content::BrowserThread::PostTask(
74 content::BrowserThread::UI,
75 FROM_HERE,
76 base::Bind(callback, 0, net::HTTP_OK, url, icons, pixel_sizes));
77 return 0;
78 }
79
80 void GetManifest(const GetManifestCallback& callback) override {
81 content::BrowserThread::PostDelayedTask(
82 content::BrowserThread::UI, FROM_HERE,
83 base::Bind(callback, manifest_url_, manifest_),
84 base::TimeDelta::FromMilliseconds(manifest_fetch_delay_ms_));
85 }
86
87 private:
88 GURL manifest_url_;
89 content::Manifest manifest_;
90 int manifest_fetch_delay_ms_;
91
92 DISALLOW_COPY_AND_ASSIGN(MockWebContents);
93 };
94
95 // Tracks which of the AddToHomescreenDataFetcher::Observer callbacks have been
96 // called.
97 class ObserverWaiter : public AddToHomescreenDataFetcher::Observer {
98 public:
99 ObserverWaiter() {}
100 ~ObserverWaiter() override {}
101
102 // Waits till the OnDataAvailable() callback is called.
103 void WaitForDataAvailable() {
104 if (data_available_)
105 return;
106
107 base::RunLoop run_loop;
108 quit_closure_ = run_loop.QuitClosure();
109 run_loop.Run();
110 }
111
112 void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override {
113 determined_webapk_compatibility_ = true;
114 is_webapk_compatible_ = is_webapk_compatible;
115 }
116
117 void OnUserTitleAvailable(const base::string16& title) override {
118 title_available_ = true;
119 }
120
121 SkBitmap FinalizeLauncherIconInBackground(const SkBitmap& icon,
122 const GURL& url,
123 bool* is_generated) override {
124 *is_generated = false;
125 return icon;
126 }
127
128 void OnDataAvailable(const ShortcutInfo& info,
129 const SkBitmap& icon) override {
130 data_available_ = true;
131 if (!quit_closure_.is_null())
132 quit_closure_.Run();
133 }
134
135 bool is_webapk_compatible() const { return is_webapk_compatible_; }
136 bool determined_webapk_compatibility() const {
137 return determined_webapk_compatibility_;
138 }
139 bool title_available() const { return title_available_; }
140
141 private:
142 bool is_webapk_compatible_;
143 bool determined_webapk_compatibility_;
144 bool title_available_;
145 bool data_available_;
146 base::Closure quit_closure_;
147
148 DISALLOW_COPY_AND_ASSIGN(ObserverWaiter);
149 };
150
151 // Builds non-null base::NullableString16 from a UTF8 string.
152 base::NullableString16 NullableStringFromUTF8(const std::string& value) {
153 return base::NullableString16(base::UTF8ToUTF16(value), false);
154 }
155
156 // Builds WebAPK compatible content::Manifest.
157 content::Manifest BuildDefaultManifest() {
158 content::Manifest manifest;
159 manifest.name = NullableStringFromUTF8(kDefaultManifestName);
160 manifest.short_name = NullableStringFromUTF8(kDefaultManifestShortName);
161 manifest.start_url = GURL(kDefaultStartUrl);
162 manifest.display = kDefaultManifestDisplayMode;
163 return manifest;
164 }
165
166 } // anonymous namespace
167
168 // Tests AddToHomescreenDataFetcher. These tests should be browser tests but
169 // Android does not support browser tests yet (crbug.com/611756).
170 class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness {
171 public:
172 AddToHomescreenDataFetcherTest() {}
173 ~AddToHomescreenDataFetcherTest() override {}
174
175 void SetUp() override {
176 ChromeRenderViewHostTestHarness::SetUp();
177
178 ASSERT_TRUE(profile()->CreateHistoryService(false, true));
179 profile()->CreateFaviconService();
180
181 embedded_worker_test_helper_.reset(
182 new content::EmbeddedWorkerTestHelper(base::FilePath()));
183
184 scoped_refptr<content::SiteInstance> site_instance =
185 content::SiteInstance::Create(browser_context());
186 site_instance->GetProcess()->Init();
187 MockWebContents* mock_web_contents = new MockWebContents(browser_context());
188 mock_web_contents->Init(content::WebContents::CreateParams(
189 browser_context(), std::move(site_instance)));
190 SetContents(mock_web_contents);
191 }
192
193 scoped_refptr<AddToHomescreenDataFetcher> BuildFetcher(
194 bool check_webapk_compatible,
195 AddToHomescreenDataFetcher::Observer* observer) {
196 return new AddToHomescreenDataFetcher(web_contents(), 1, 1, 1, 1,
197 check_webapk_compatible, observer);
198 }
199
200 // Set the manifest to be returned as a result of WebContents::GetManifest().
201 void SetManifest(const GURL& manifest_url,
202 const content::Manifest& manifest,
203 int fetch_delay_ms) {
204 MockWebContents* mock_web_contents =
205 static_cast<MockWebContents*>(web_contents());
206 mock_web_contents->SetManifest(manifest_url, manifest, fetch_delay_ms);
207 }
208
209 // Registers service worker at |url|. Blocks till the service worker is
210 // registered.
211 void RegisterServiceWorker(const GURL& url) {
212 base::RunLoop run_loop;
213 embedded_worker_test_helper_->context()->RegisterServiceWorker(
214 url, GURL(url.spec() + "/service_worker.js"), nullptr,
215 base::Bind(&AddToHomescreenDataFetcherTest::OnServiceWorkerRegistered,
216 base::Unretained(this), run_loop.QuitClosure()));
217 }
218
219 private:
220 // Callback for RegisterServiceWorker() for when service worker registration
221 // has completed.
222 void OnServiceWorkerRegistered(const base::Closure& callback,
223 content::ServiceWorkerStatusCode status,
224 const std::string& status_message,
225 int64_t registration_id) {
226 ASSERT_EQ(content::SERVICE_WORKER_OK, status)
227 << content::ServiceWorkerStatusToString(status);
228 callback.Run();
229 }
230
231 std::unique_ptr<content::EmbeddedWorkerTestHelper>
232 embedded_worker_test_helper_;
233
234 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTest);
235 };
236
237 // Checks that AddToHomescreenDataFetcher::Observer::OnUserTitleAvailable() is
238 // called when the web manifest fetch times out. The add-to-homescreen dialog
239 // makes the dialog's text field editable once OnUserTitleAvailable() is called.
240 TEST_F(AddToHomescreenDataFetcherTest, ManifestFetchTimesOutNoServiceWorker) {
241 SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest(), 10000);
242
243 ObserverWaiter waiter;
244 scoped_refptr<AddToHomescreenDataFetcher> fetcher(
245 BuildFetcher(false, &waiter));
246 fetcher->OnDidGetWebApplicationInfo(WebApplicationInfo());
247 waiter.WaitForDataAvailable();
248
249 EXPECT_FALSE(waiter.determined_webapk_compatibility());
250 EXPECT_TRUE(waiter.title_available());
251
252 fetcher->set_weak_observer(nullptr);
253 }
254
255 // Class for tests which should be run with AddToHomescreenDataFetcher built
256 // with both true and false values of |check_webapk_compatible|.
257 class AddToHomescreenDataFetcherTestCommon
258 : public AddToHomescreenDataFetcherTest,
259 public testing::WithParamInterface<bool> {
260 public:
261 AddToHomescreenDataFetcherTestCommon() {}
262 ~AddToHomescreenDataFetcherTestCommon() override {}
263
264 scoped_refptr<AddToHomescreenDataFetcher> BuildFetcher(
265 AddToHomescreenDataFetcher::Observer* observer) {
266 return AddToHomescreenDataFetcherTest::BuildFetcher(
267 check_webapk_compatibility(), observer);
268 }
269
270 // The value of |check_webapk_compatible| used when building the
271 // AddToHomescreenDataFetcher.
272 bool check_webapk_compatibility() { return GetParam(); }
273
274 private:
275 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTestCommon);
276 };
277
278 // Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
279 // when a service worker is registered and the manifest fetch times out.
280 TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOut) {
281 RegisterServiceWorker(GURL(kDefaultStartUrl));
282 SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest(), 10000);
283
284 ObserverWaiter waiter;
285 scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
286 fetcher->OnDidGetWebApplicationInfo(WebApplicationInfo());
287 waiter.WaitForDataAvailable();
288
289 if (check_webapk_compatibility()) {
290 EXPECT_TRUE(waiter.determined_webapk_compatibility());
291 EXPECT_FALSE(waiter.is_webapk_compatible());
292 } else {
293 EXPECT_FALSE(waiter.determined_webapk_compatibility());
294 }
295 // This callback enables the text field in the add-to-homescreen dialog.
296 EXPECT_TRUE(waiter.title_available());
297
298 fetcher->set_weak_observer(nullptr);
299 }
300
301 INSTANTIATE_TEST_CASE_P(CheckWebApkCompatibility,
302 AddToHomescreenDataFetcherTestCommon,
303 ::testing::Values(false, true));
OLDNEW
« no previous file with comments | « chrome/browser/android/webapps/DEPS ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698