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

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

Issue 2960103002: Improve add to homescreen data fetcher unit tests. (Closed)
Patch Set: Self nits Created 3 years, 5 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 | « no previous file | chrome/browser/installable/installable_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h" 5 #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 9
10 #include "base/callback_forward.h"
11 #include "base/files/file_path.h"
12 #include "base/macros.h" 10 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
14 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 13 #include "base/run_loop.h"
17 #include "base/strings/nullable_string16.h" 14 #include "base/strings/nullable_string16.h"
18 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h"
21 #include "chrome/browser/installable/installable_manager.h" 17 #include "chrome/browser/installable/installable_manager.h"
22 #include "chrome/common/web_application_info.h" 18 #include "chrome/common/web_application_info.h"
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 19 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
24 #include "chrome/test/base/testing_profile.h" 20 #include "chrome/test/base/testing_profile.h"
25 #include "content/browser/service_worker/embedded_worker_test_helper.h"
26 #include "content/browser/service_worker/service_worker_context_core.h"
27 #include "content/common/service_worker/service_worker_status_code.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/site_instance.h"
30 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/manifest.h" 22 #include "content/public/common/manifest.h"
32 #include "content/test/test_web_contents.h"
33 #include "net/http/http_status_code.h"
34 #include "third_party/WebKit/public/platform/WebDisplayMode.h" 23 #include "third_party/WebKit/public/platform/WebDisplayMode.h"
35 #include "ui/gfx/image/image_unittest_util.h" 24 #include "ui/gfx/image/image_unittest_util.h"
36 #include "url/gurl.h" 25 #include "url/gurl.h"
37 26
38 namespace { 27 namespace {
39 28
40 const char* kWebApplicationInfoTitle = "Meta Title"; 29 const char* kWebApplicationInfoTitle = "Meta Title";
41 const char* kDefaultManifestUrl = "https://www.example.com/manifest.json"; 30 const char* kDefaultManifestUrl = "https://www.example.com/manifest.json";
31 const char* kDefaultIconUrl = "https://www.example.com/icon.png";
42 const char* kDefaultManifestName = "Default Name"; 32 const char* kDefaultManifestName = "Default Name";
43 const char* kDefaultManifestShortName = "Default Short Name"; 33 const char* kDefaultManifestShortName = "Default Short Name";
44 const char* kDefaultStartUrl = "https://www.example.com/index.html"; 34 const char* kDefaultStartUrl = "https://www.example.com/index.html";
45 const blink::WebDisplayMode kDefaultManifestDisplayMode = 35 const blink::WebDisplayMode kDefaultManifestDisplayMode =
46 blink::kWebDisplayModeStandalone; 36 blink::kWebDisplayModeStandalone;
37 const int kIconSizePx = 144;
47 38
48 // WebContents subclass which mocks out image and manifest fetching. 39 // Tracks which of the AddToHomescreenDataFetcher::Observer methods have been
49 class MockWebContents : public content::TestWebContents {
50 public:
51 explicit MockWebContents(content::BrowserContext* browser_context)
52 : content::TestWebContents(browser_context),
53 should_image_time_out_(false),
54 should_manifest_time_out_(false) {}
55
56 ~MockWebContents() override {}
57
58 void SetManifest(const GURL& manifest_url,
59 const content::Manifest& manifest) {
60 manifest_url_ = manifest_url;
61 manifest_ = manifest;
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 if (should_image_time_out_)
70 return 0;
71
72 const int kIconSizePx = 144;
73 SkBitmap icon = gfx::test::CreateBitmap(kIconSizePx, kIconSizePx);
74 std::vector<SkBitmap> icons(1u, icon);
75 std::vector<gfx::Size> pixel_sizes(1u, gfx::Size(kIconSizePx, kIconSizePx));
76 content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
77 ->PostTask(FROM_HERE, base::Bind(callback, 0, net::HTTP_OK, url, icons,
78 pixel_sizes));
79 return 0;
80 }
81
82 void GetManifest(const GetManifestCallback& callback) override {
83 if (should_manifest_time_out_)
84 return;
85
86 content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
87 ->PostTask(FROM_HERE, base::Bind(callback, manifest_url_, manifest_));
88 }
89
90 void SetShouldImageTimeOut(bool should_time_out) {
91 should_image_time_out_ = should_time_out;
92 }
93
94 void SetShouldManifestTimeOut(bool should_time_out) {
95 should_manifest_time_out_ = should_time_out;
96 }
97
98 private:
99 GURL manifest_url_;
100 content::Manifest manifest_;
101 bool should_image_time_out_;
102 bool should_manifest_time_out_;
103
104 DISALLOW_COPY_AND_ASSIGN(MockWebContents);
105 };
106
107 // Tracks which of the AddToHomescreenDataFetcher::Observer callbacks have been
108 // called. 40 // called.
109 class ObserverWaiter : public AddToHomescreenDataFetcher::Observer { 41 class ObserverWaiter : public AddToHomescreenDataFetcher::Observer {
110 public: 42 public:
111 ObserverWaiter() 43 ObserverWaiter()
112 : is_webapk_compatible_(false), 44 : is_webapk_compatible_(false),
113 determined_webapk_compatibility_(false), 45 determined_webapk_compatibility_(false),
114 title_available_(false), 46 title_available_(false),
115 data_available_(false) {} 47 data_available_(false) {}
116 ~ObserverWaiter() override {} 48 ~ObserverWaiter() override {}
117 49
118 // Waits till the OnDataAvailable() callback is called. 50 // Waits till the OnDataAvailable() callback is called.
119 void WaitForDataAvailable() { 51 void WaitForDataAvailable() {
120 if (data_available_) 52 if (data_available_)
121 return; 53 return;
122 54
123 base::RunLoop run_loop; 55 base::RunLoop run_loop;
124 quit_closure_ = run_loop.QuitClosure(); 56 quit_closure_ = run_loop.QuitClosure();
125 run_loop.Run(); 57 run_loop.Run();
126 } 58 }
127 59
128 void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override { 60 void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override {
61 // This should only be called once.
62 EXPECT_FALSE(determined_webapk_compatibility_);
129 EXPECT_FALSE(title_available_); 63 EXPECT_FALSE(title_available_);
130 determined_webapk_compatibility_ = true; 64 determined_webapk_compatibility_ = true;
131 is_webapk_compatible_ = is_webapk_compatible; 65 is_webapk_compatible_ = is_webapk_compatible;
132 } 66 }
133 67
134 void OnUserTitleAvailable(const base::string16& title) override { 68 void OnUserTitleAvailable(const base::string16& title) override {
69 // This should only be called once.
70 EXPECT_FALSE(title_available_);
135 EXPECT_FALSE(data_available_); 71 EXPECT_FALSE(data_available_);
136 title_available_ = true; 72 title_available_ = true;
137 title_ = title; 73 title_ = title;
138 } 74 }
139 75
140 void OnDataAvailable(const ShortcutInfo& info, 76 void OnDataAvailable(const ShortcutInfo& info,
141 const SkBitmap& primary_icon, 77 const SkBitmap& primary_icon,
142 const SkBitmap& badge_icon) override { 78 const SkBitmap& badge_icon) override {
79 // This should only be called once.
80 EXPECT_FALSE(data_available_);
143 EXPECT_TRUE(title_available_); 81 EXPECT_TRUE(title_available_);
144 data_available_ = true; 82 data_available_ = true;
145 if (!quit_closure_.is_null()) 83 if (!quit_closure_.is_null())
146 quit_closure_.Run(); 84 quit_closure_.Run();
147 } 85 }
148 86
149 base::string16 title() const { return title_; } 87 base::string16 title() const { return title_; }
150 bool is_webapk_compatible() const { return is_webapk_compatible_; } 88 bool is_webapk_compatible() const { return is_webapk_compatible_; }
151 bool determined_webapk_compatibility() const { 89 bool determined_webapk_compatibility() const {
152 return determined_webapk_compatibility_; 90 return determined_webapk_compatibility_;
153 } 91 }
154 bool title_available() const { return title_available_; } 92 bool title_available() const { return title_available_; }
155 93
156 private: 94 private:
157 base::string16 title_; 95 base::string16 title_;
158 bool is_webapk_compatible_; 96 bool is_webapk_compatible_;
159 bool determined_webapk_compatibility_; 97 bool determined_webapk_compatibility_;
160 bool title_available_; 98 bool title_available_;
161 bool data_available_; 99 bool data_available_;
162 base::Closure quit_closure_; 100 base::Closure quit_closure_;
163 101
164 DISALLOW_COPY_AND_ASSIGN(ObserverWaiter); 102 DISALLOW_COPY_AND_ASSIGN(ObserverWaiter);
165 }; 103 };
166 104
167 // Builds non-null base::NullableString16 from a UTF8 string. 105 // Builds non-null base::NullableString16 from a UTF8 string.
168 base::NullableString16 NullableStringFromUTF8(const std::string& value) { 106 base::NullableString16 NullableStringFromUTF8(const std::string& value) {
169 return base::NullableString16(base::UTF8ToUTF16(value), false); 107 return base::NullableString16(base::UTF8ToUTF16(value), false);
170 } 108 }
171 109
172 content::Manifest BuildEmptyManifest() {
173 return content::Manifest();
174 }
175
176 // Builds WebAPK compatible content::Manifest. 110 // Builds WebAPK compatible content::Manifest.
177 content::Manifest BuildDefaultManifest() { 111 content::Manifest BuildDefaultManifest() {
178 content::Manifest manifest; 112 content::Manifest manifest;
179 manifest.name = NullableStringFromUTF8(kDefaultManifestName); 113 manifest.name = NullableStringFromUTF8(kDefaultManifestName);
180 manifest.short_name = NullableStringFromUTF8(kDefaultManifestShortName); 114 manifest.short_name = NullableStringFromUTF8(kDefaultManifestShortName);
181 manifest.start_url = GURL(kDefaultStartUrl); 115 manifest.start_url = GURL(kDefaultStartUrl);
182 manifest.display = kDefaultManifestDisplayMode; 116 manifest.display = kDefaultManifestDisplayMode;
183 117
184 content::Manifest::Icon primary_icon; 118 content::Manifest::Icon primary_icon;
185 primary_icon.type = base::ASCIIToUTF16("image/png"); 119 primary_icon.type = base::ASCIIToUTF16("image/png");
186 primary_icon.sizes.push_back(gfx::Size(144, 144)); 120 primary_icon.sizes.push_back(gfx::Size(144, 144));
187 primary_icon.purpose.push_back(content::Manifest::Icon::IconPurpose::ANY); 121 primary_icon.purpose.push_back(content::Manifest::Icon::IconPurpose::ANY);
188 primary_icon.src = GURL("https://www.google.com/image.png"); 122 primary_icon.src = GURL(kDefaultIconUrl);
189 manifest.icons.push_back(primary_icon); 123 manifest.icons.push_back(primary_icon);
190 124
191 return manifest; 125 return manifest;
192 } 126 }
193 127
194 } // anonymous namespace 128 } // anonymous namespace
195 129
130 class TestInstallableManager : public InstallableManager {
131 public:
132 explicit TestInstallableManager(content::WebContents* web_contents)
133 : InstallableManager(web_contents) {}
134
135 void GetData(const InstallableParams& params,
136 const InstallableCallback& callback) override {
137 if (should_manifest_time_out_ ||
138 (params.check_installable && should_installable_time_out_)) {
139 return;
140 }
141
142 InstallableStatusCode code = NO_ERROR_DETECTED;
143 bool is_installable = is_installable_;
144 if (params.fetch_valid_primary_icon && !primary_icon_) {
145 code = NO_ACCEPTABLE_ICON;
146 is_installable = false;
147 } else if (params.check_installable) {
148 if (!IsManifestValidForWebApp(manifest_)) {
149 code = valid_manifest_->error;
150 is_installable = false;
151 } else if (!is_installable_) {
152 code = NOT_OFFLINE_CAPABLE;
153 is_installable = false;
154 }
155 }
156
157 callback.Run(
158 {code, GURL(kDefaultManifestUrl), manifest_,
159 params.fetch_valid_primary_icon ? primary_icon_url_ : GURL(),
160 params.fetch_valid_primary_icon ? primary_icon_.get() : nullptr,
161 params.fetch_valid_badge_icon ? badge_icon_url_ : GURL(),
162 params.fetch_valid_badge_icon ? badge_icon_.get() : nullptr,
163 params.check_installable ? is_installable : false});
164 }
165
166 void SetInstallable(bool is_installable) { is_installable_ = is_installable; }
167
168 void SetManifest(const content::Manifest& manifest) {
169 manifest_ = manifest;
170
171 if (!manifest.icons.empty()) {
172 primary_icon_url_ = manifest_.icons[0].src;
173 primary_icon_.reset(
174 new SkBitmap(gfx::test::CreateBitmap(kIconSizePx, kIconSizePx)));
175
176 badge_icon_url_ = manifest_.icons[0].src;
177 badge_icon_.reset(
178 new SkBitmap(gfx::test::CreateBitmap(kIconSizePx, kIconSizePx)));
179 }
180 }
181
182 void SetShouldManifestTimeOut(bool should_time_out) {
183 should_manifest_time_out_ = should_time_out;
184 }
185
186 void SetShouldInstallableTimeOut(bool should_time_out) {
187 should_installable_time_out_ = should_time_out;
188 }
189
190 private:
191 content::Manifest manifest_;
192 GURL primary_icon_url_;
193 GURL badge_icon_url_;
194 std::unique_ptr<SkBitmap> primary_icon_;
195 std::unique_ptr<SkBitmap> badge_icon_;
196
197 bool is_installable_ = true;
198
199 bool should_manifest_time_out_ = false;
200 bool should_installable_time_out_ = false;
201 };
202
196 // Tests AddToHomescreenDataFetcher. These tests should be browser tests but 203 // Tests AddToHomescreenDataFetcher. These tests should be browser tests but
197 // Android does not support browser tests yet (crbug.com/611756). 204 // Android does not support browser tests yet (crbug.com/611756).
198 class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness { 205 class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness {
199 public: 206 public:
200 AddToHomescreenDataFetcherTest() {} 207 AddToHomescreenDataFetcherTest() {}
201 ~AddToHomescreenDataFetcherTest() override {} 208 ~AddToHomescreenDataFetcherTest() override {}
202 209
203 void SetUp() override { 210 void SetUp() override {
204 ChromeRenderViewHostTestHarness::SetUp(); 211 ChromeRenderViewHostTestHarness::SetUp();
205 212
206 ASSERT_TRUE(profile()->CreateHistoryService(false, true)); 213 ASSERT_TRUE(profile()->CreateHistoryService(false, true));
207 profile()->CreateFaviconService(); 214 profile()->CreateFaviconService();
208 215
209 embedded_worker_test_helper_.reset( 216 // Manually inject the TestInstallableManager as a "InstallableManager"
210 new content::EmbeddedWorkerTestHelper(base::FilePath())); 217 // WebContentsUserData. We can't directly call ::CreateForWebContents due to
211 218 // typing issues since TestInstallableManager doesn't directly inherit from
212 scoped_refptr<content::SiteInstance> site_instance = 219 // WebContentsUserData.
213 content::SiteInstance::Create(browser_context()); 220 web_contents()->SetUserData(
214 site_instance->GetProcess()->Init(); 221 TestInstallableManager::UserDataKey(),
215 MockWebContents* mock_web_contents = new MockWebContents(browser_context()); 222 base::WrapUnique(new TestInstallableManager(web_contents())));
216 mock_web_contents->Init(content::WebContents::CreateParams( 223 installable_manager_ = static_cast<TestInstallableManager*>(
217 browser_context(), std::move(site_instance))); 224 web_contents()->GetUserData(TestInstallableManager::UserDataKey()));
218 InstallableManager::CreateForWebContents(mock_web_contents);
219 SetContents(mock_web_contents);
220 NavigateAndCommit(GURL(kDefaultStartUrl));
221 }
222
223 void TearDown() override {
224 embedded_worker_test_helper_.reset();
225 ChromeRenderViewHostTestHarness::TearDown();
226 } 225 }
227 226
228 std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher( 227 std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher(
229 bool check_webapk_compatible, 228 bool check_webapk_compatible,
230 AddToHomescreenDataFetcher::Observer* observer) { 229 AddToHomescreenDataFetcher::Observer* observer) {
231 return base::MakeUnique<AddToHomescreenDataFetcher>( 230 return base::MakeUnique<AddToHomescreenDataFetcher>(
232 web_contents(), 1, 1, 1, 1, 1, 500, check_webapk_compatible, observer); 231 web_contents(), 1, 1, 1, 1, 1, 500, check_webapk_compatible, observer);
233 } 232 }
234 233
235 // Set the manifest to be returned as a result of WebContents::GetManifest(). 234 void RunFetcher(AddToHomescreenDataFetcher* fetcher,
236 void SetManifest(const GURL& manifest_url, 235 ObserverWaiter& waiter,
237 const content::Manifest& manifest) { 236 const char* expected_title,
238 MockWebContents* mock_web_contents = 237 blink::WebDisplayMode display_mode,
239 static_cast<MockWebContents*>(web_contents()); 238 bool is_webapk_compatible) {
240 mock_web_contents->SetManifest(manifest_url, manifest); 239 WebApplicationInfo web_application_info;
240 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
241
242 fetcher->OnDidGetWebApplicationInfo(web_application_info);
243 waiter.WaitForDataAvailable();
244
245 EXPECT_EQ(check_webapk_compatibility(),
246 waiter.determined_webapk_compatibility());
247 EXPECT_EQ(is_webapk_compatible, waiter.is_webapk_compatible());
248 EXPECT_TRUE(waiter.title_available());
249 EXPECT_TRUE(base::EqualsASCII(waiter.title(), expected_title));
250 EXPECT_TRUE(
251 base::EqualsASCII(fetcher->shortcut_info().user_title, expected_title));
252 EXPECT_EQ(display_mode, fetcher->shortcut_info().display);
241 } 253 }
242 254
243 void SetShouldImageTimeOut(bool should_time_out) { 255 void SetManifest(const content::Manifest& manifest) {
244 MockWebContents* mock_web_contents = 256 installable_manager_->SetManifest(manifest);
245 static_cast<MockWebContents*>(web_contents()); 257 }
246 mock_web_contents->SetShouldImageTimeOut(should_time_out); 258
259 void SetInstallable(bool is_installable) {
260 installable_manager_->SetInstallable(is_installable);
247 } 261 }
248 262
249 void SetShouldManifestTimeOut(bool should_time_out) { 263 void SetShouldManifestTimeOut(bool should_time_out) {
250 MockWebContents* mock_web_contents = 264 installable_manager_->SetShouldManifestTimeOut(should_time_out);
251 static_cast<MockWebContents*>(web_contents());
252 mock_web_contents->SetShouldManifestTimeOut(should_time_out);
253 } 265 }
254 266
255 // Registers service worker at |url|. Blocks till the service worker is 267 void SetShouldInstallableTimeOut(bool should_time_out) {
256 // registered. 268 installable_manager_->SetShouldInstallableTimeOut(should_time_out);
257 void RegisterServiceWorker(const GURL& url) {
258 base::RunLoop run_loop;
259 embedded_worker_test_helper_->context()->RegisterServiceWorker(
260 GURL(url.spec() + "/service_worker.js"),
261 content::ServiceWorkerRegistrationOptions(url), nullptr,
262 base::Bind(&AddToHomescreenDataFetcherTest::OnServiceWorkerRegistered,
263 base::Unretained(this), run_loop.QuitClosure()));
264 } 269 }
265 270
271 virtual bool check_webapk_compatibility() { return true; }
272
266 private: 273 private:
267 // Callback for RegisterServiceWorker() for when service worker registration 274 TestInstallableManager* installable_manager_;
268 // has completed.
269 void OnServiceWorkerRegistered(const base::Closure& callback,
270 content::ServiceWorkerStatusCode status,
271 const std::string& status_message,
272 int64_t registration_id) {
273 ASSERT_EQ(content::SERVICE_WORKER_OK, status)
274 << content::ServiceWorkerStatusToString(status);
275 callback.Run();
276 }
277
278 std::unique_ptr<content::EmbeddedWorkerTestHelper>
279 embedded_worker_test_helper_;
280 275
281 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTest); 276 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTest);
282 }; 277 };
283 278
284 // Class for tests which should be run with AddToHomescreenDataFetcher built 279 // Class for tests which should be run with AddToHomescreenDataFetcher built
285 // with both true and false values of |check_webapk_compatible|. 280 // with both true and false values of |check_webapk_compatible|.
286 class AddToHomescreenDataFetcherTestCommon 281 class AddToHomescreenDataFetcherTestCommon
287 : public AddToHomescreenDataFetcherTest, 282 : public AddToHomescreenDataFetcherTest,
288 public testing::WithParamInterface<bool> { 283 public testing::WithParamInterface<bool> {
289 public: 284 public:
290 AddToHomescreenDataFetcherTestCommon() {} 285 AddToHomescreenDataFetcherTestCommon() {}
291 ~AddToHomescreenDataFetcherTestCommon() override {} 286 ~AddToHomescreenDataFetcherTestCommon() override {}
292 287
293 std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher( 288 std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher(
294 AddToHomescreenDataFetcher::Observer* observer) { 289 AddToHomescreenDataFetcher::Observer* observer) {
295 return AddToHomescreenDataFetcherTest::BuildFetcher( 290 return AddToHomescreenDataFetcherTest::BuildFetcher(
296 check_webapk_compatibility(), observer); 291 check_webapk_compatibility(), observer);
297 } 292 }
298 293
299 // The value of |check_webapk_compatible| used when building the 294 // The value of |check_webapk_compatible| used when building the
300 // AddToHomescreenDataFetcher. 295 // AddToHomescreenDataFetcher.
301 bool check_webapk_compatibility() { return GetParam(); } 296 bool check_webapk_compatibility() override { return GetParam(); }
302 297
303 private: 298 private:
304 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTestCommon); 299 DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTestCommon);
305 }; 300 };
306 301
307 // Checks that AddToHomescreenDataFetcher::Observer::OnUserTitleAvailable() is
308 // called when the web manifest returned is empty. The add-to-homescreen dialog
309 // makes the dialog's text field editable once OnUserTitleAvailable() is called.
310 TEST_P(AddToHomescreenDataFetcherTestCommon, EmptyManifest) { 302 TEST_P(AddToHomescreenDataFetcherTestCommon, EmptyManifest) {
311 WebApplicationInfo web_application_info; 303 // Check that an empty manifest has the appropriate methods run.
312 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle); 304 ObserverWaiter waiter;
305 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
306 RunFetcher(fetcher.get(), waiter, kWebApplicationInfoTitle,
307 blink::kWebDisplayModeBrowser, false);
308 }
313 309
314 SetManifest(GURL(kDefaultManifestUrl), BuildEmptyManifest()); 310 TEST_P(AddToHomescreenDataFetcherTestCommon, NoIconManifest) {
311 // Test a manifest with no icons. This should use the short name and have
312 // a generated icon (empty icon url).
313 content::Manifest manifest = BuildDefaultManifest();
314 manifest.icons.clear();
315 SetManifest(manifest);
315 316
316 ObserverWaiter waiter; 317 ObserverWaiter waiter;
317 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); 318 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
318 fetcher->OnDidGetWebApplicationInfo(web_application_info); 319 RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
319 waiter.WaitForDataAvailable(); 320 blink::kWebDisplayModeStandalone, false);
320 321
321 EXPECT_EQ(check_webapk_compatibility(), 322 EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty());
322 waiter.determined_webapk_compatibility()); 323 EXPECT_TRUE(fetcher->badge_icon().drawsNothing());
323 EXPECT_FALSE(waiter.is_webapk_compatible()); 324 EXPECT_TRUE(fetcher->shortcut_info().best_badge_icon_url.is_empty());
324 EXPECT_TRUE(waiter.title_available());
325 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
326 } 325 }
327 326
328 // Test that when the manifest provides Manifest::short_name but not 327 TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOut) {
329 // Manifest::name that Manifest::short_name is used as the name instead of 328 // Check that the AddToHomescreenDataFetcher::Observer methods are called
330 // WebApplicationInfo::title. 329 // if the first call to InstallableManager::GetData() times out. This should
331 TEST_P(AddToHomescreenDataFetcherTestCommon, 330 // fall back to the metadata title and have an empty icon.
332 ManifestShortNameClobbersWebApplicationName) { 331 SetShouldManifestTimeOut(true);
333 WebApplicationInfo web_application_info; 332 SetManifest(BuildDefaultManifest());
334 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
335 333
334 // Check a site with no offline-capable service worker.
335 SetInstallable(false);
336 ObserverWaiter waiter;
337 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
338 RunFetcher(fetcher.get(), waiter, kWebApplicationInfoTitle,
339 blink::kWebDisplayModeBrowser, false);
340
341 EXPECT_TRUE(fetcher->primary_icon().drawsNothing());
342 EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty());
343 }
344
345 TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOut) {
346 // Check that the AddToHomescreenDataFetcher::Observer methods are called if
347 // the service worker check times out on a page that is installable (i.e. it's
348 // taken too long). This should use the short_name and icon from the manifest,
349 // but not be WebAPK-compatible. Only relevant when checking WebAPK
350 // compatibility.
351 SetManifest(BuildDefaultManifest());
352 SetShouldInstallableTimeOut(true);
353
354 ObserverWaiter waiter;
355 std::unique_ptr<AddToHomescreenDataFetcher> fetcher =
356 BuildFetcher(true, &waiter);
357 RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
358 blink::kWebDisplayModeStandalone, false);
359
360 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
361 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
362 GURL(kDefaultIconUrl));
363 }
364
365 TEST_P(AddToHomescreenDataFetcherTestCommon, InstallableManifest) {
366 // Test a site that has an offline-capable service worker.
336 content::Manifest manifest(BuildDefaultManifest()); 367 content::Manifest manifest(BuildDefaultManifest());
337 manifest.name = base::NullableString16(); 368 SetManifest(manifest);
338
339 RegisterServiceWorker(GURL(kDefaultStartUrl));
340 SetManifest(GURL(kDefaultManifestUrl), manifest);
341 369
342 ObserverWaiter waiter; 370 ObserverWaiter waiter;
343 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); 371 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
344 fetcher->OnDidGetWebApplicationInfo(web_application_info); 372 RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
345 waiter.WaitForDataAvailable(); 373 blink::kWebDisplayModeStandalone, check_webapk_compatibility());
346 374
347 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kDefaultManifestShortName)); 375 // There should always be a primary icon.
348 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name, 376 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
349 kDefaultManifestShortName)); 377 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
378 GURL(kDefaultIconUrl));
379
380 // Check that the badge icon is requested only when AddToHomescreenDataFetcher
381 // checks for WebAPK compatibility.
382 if (check_webapk_compatibility()) {
383 EXPECT_FALSE(fetcher->badge_icon().drawsNothing());
384 EXPECT_EQ(fetcher->shortcut_info().best_badge_icon_url,
385 GURL(kDefaultIconUrl));
386 } else {
387 EXPECT_TRUE(fetcher->badge_icon().drawsNothing());
388 EXPECT_TRUE(fetcher->shortcut_info().best_badge_icon_url.is_empty());
389 }
350 } 390 }
351 391
352 // Test that when the manifest does not provide either Manifest::short_name nor 392 TEST_P(AddToHomescreenDataFetcherTestCommon,
353 // Manifest::name that: 393 ManifestNameClobbersWebApplicationName) {
354 // - The page is not WebAPK compatible. 394 // Test that when the manifest provides Manifest::name but not
355 // - WebApplicationInfo::title is used as the "name". 395 // Manifest::short_name that Manifest::name is used as the title.
396 {
397 // Check the case where we have no icons.
398 content::Manifest manifest = BuildDefaultManifest();
399 manifest.icons.clear();
400 manifest.short_name = base::NullableString16();
401 SetManifest(manifest);
402
403 ObserverWaiter waiter;
404 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
405 RunFetcher(fetcher.get(), waiter, kDefaultManifestName,
406 blink::kWebDisplayModeStandalone, false);
407
408 EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty());
409 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name,
410 kDefaultManifestName));
411 }
412
413 content::Manifest manifest(BuildDefaultManifest());
414 manifest.short_name = base::NullableString16();
415 SetManifest(manifest);
416
417 {
418 // Check a site with no offline-capable service worker.
419 SetInstallable(false);
420 ObserverWaiter waiter;
421 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
422 RunFetcher(fetcher.get(), waiter, kDefaultManifestName,
423 blink::kWebDisplayModeStandalone, false);
424
425 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
426 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
427 GURL(kDefaultIconUrl));
428 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name,
429 kDefaultManifestName));
430 }
431
432 {
433 // Check a site where we time out waiting for the service worker.
434 SetShouldInstallableTimeOut(true);
435 ObserverWaiter waiter;
436 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
437 RunFetcher(fetcher.get(), waiter, kDefaultManifestName,
438 blink::kWebDisplayModeStandalone, false);
439
440 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
441 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
442 GURL(kDefaultIconUrl));
443 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name,
444 kDefaultManifestName));
445 }
446
447 {
448 // Check a site with an offline-capaable service worker.
449 SetInstallable(true);
450 SetShouldInstallableTimeOut(false);
451 ObserverWaiter waiter;
452 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
453 RunFetcher(fetcher.get(), waiter, kDefaultManifestName,
454 blink::kWebDisplayModeStandalone, check_webapk_compatibility());
455
456 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
457 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
458 GURL(kDefaultIconUrl));
459 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name,
460 kDefaultManifestName));
461 }
462 }
463
356 TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestNoNameNoShortName) { 464 TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestNoNameNoShortName) {
357 WebApplicationInfo web_application_info; 465 // Test that when the manifest does not provide either Manifest::short_name
358 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle); 466 // nor Manifest::name that:
359 467 // - The page is not WebAPK compatible.
468 // - WebApplicationInfo::title is used as the "name".
469 // - We still use the icons from the manifest.
360 content::Manifest manifest(BuildDefaultManifest()); 470 content::Manifest manifest(BuildDefaultManifest());
361 manifest.name = base::NullableString16(); 471 manifest.name = base::NullableString16();
362 manifest.short_name = base::NullableString16(); 472 manifest.short_name = base::NullableString16();
363 473
364 RegisterServiceWorker(GURL(kDefaultStartUrl)); 474 // Check the case where we don't time out waiting for the service worker.
365 SetManifest(GURL(kDefaultManifestUrl), manifest); 475 SetManifest(manifest);
366
367 ObserverWaiter waiter; 476 ObserverWaiter waiter;
368 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); 477 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
369 fetcher->OnDidGetWebApplicationInfo(web_application_info); 478 RunFetcher(fetcher.get(), waiter, kWebApplicationInfoTitle,
370 waiter.WaitForDataAvailable(); 479 blink::kWebDisplayModeStandalone, false);
371 480
372 EXPECT_EQ(check_webapk_compatibility(),
373 waiter.determined_webapk_compatibility());
374 EXPECT_FALSE(waiter.is_webapk_compatible());
375 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
376 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name, 481 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name,
377 kWebApplicationInfoTitle)); 482 kWebApplicationInfoTitle));
378 } 483 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name,
379 484 kWebApplicationInfoTitle));
380 // Checks that the AddToHomescreenDataFetcher::Observer callbacks are called 485 EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
381 // when the manifest fetch times out. 486 EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
382 TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOut) { 487 GURL(kDefaultIconUrl));
383 WebApplicationInfo web_application_info;
384 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
385
386 RegisterServiceWorker(GURL(kDefaultStartUrl));
387 SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
388 SetShouldManifestTimeOut(true);
389 SetShouldImageTimeOut(false);
390
391 ObserverWaiter waiter;
392 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
393 fetcher->OnDidGetWebApplicationInfo(web_application_info);
394 waiter.WaitForDataAvailable();
395
396 EXPECT_EQ(check_webapk_compatibility(),
397 waiter.determined_webapk_compatibility());
398 EXPECT_FALSE(waiter.is_webapk_compatible());
399 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
400 EXPECT_TRUE(waiter.title_available());
401 }
402
403 // Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
404 // when the image fetch times out.
405 TEST_P(AddToHomescreenDataFetcherTestCommon, ImageFetchTimesOut) {
406 WebApplicationInfo web_application_info;
407 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
408
409 RegisterServiceWorker(GURL(kDefaultStartUrl));
410 SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
411 SetShouldManifestTimeOut(false);
412 SetShouldImageTimeOut(true);
413
414 ObserverWaiter waiter;
415 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
416 fetcher->OnDidGetWebApplicationInfo(web_application_info);
417 waiter.WaitForDataAvailable();
418
419 EXPECT_EQ(check_webapk_compatibility(),
420 waiter.determined_webapk_compatibility());
421 EXPECT_FALSE(waiter.is_webapk_compatible());
422 EXPECT_TRUE(waiter.title_available());
423 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
424 }
425
426 // Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
427 // when the service worker check times out.
428 TEST_P(AddToHomescreenDataFetcherTestCommon, ServiceWorkerCheckTimesOut) {
429 WebApplicationInfo web_application_info;
430 web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
431
432 // Not registering a service worker means we'll wait and time out for the
433 // worker.
434 SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
435 SetShouldManifestTimeOut(false);
436 SetShouldImageTimeOut(false);
437
438 ObserverWaiter waiter;
439 std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
440 fetcher->OnDidGetWebApplicationInfo(web_application_info);
441 waiter.WaitForDataAvailable();
442
443 EXPECT_EQ(check_webapk_compatibility(),
444 waiter.determined_webapk_compatibility());
445 EXPECT_FALSE(waiter.is_webapk_compatible());
446 EXPECT_TRUE(waiter.title_available());
447 EXPECT_TRUE(base::EqualsASCII(waiter.title(), kDefaultManifestShortName));
448 EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().user_title,
449 kDefaultManifestShortName));
450 } 488 }
451 489
452 INSTANTIATE_TEST_CASE_P(CheckWebApkCompatibility, 490 INSTANTIATE_TEST_CASE_P(CheckWebApkCompatibility,
453 AddToHomescreenDataFetcherTestCommon, 491 AddToHomescreenDataFetcherTestCommon,
454 ::testing::Values(false, true)); 492 ::testing::Values(false, true));
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/installable/installable_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698