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

Side by Side Diff: chrome/browser/webshare/share_service_impl_unittest.cc

Issue 2688413006: Fixed crash if tab closes while WebShare picker dialog is open. (Closed)
Patch Set: Do Sam's suggestions. Created 3 years, 10 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/webshare/share_service_impl.cc ('k') | no next file » | 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 <memory> 5 #include <memory>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 16 matching lines...) Expand all
27 27
28 constexpr char kTargetName[] = "Share Target"; 28 constexpr char kTargetName[] = "Share Target";
29 constexpr char kUrlTemplate[] = "share?title={title}&text={text}&url={url}"; 29 constexpr char kUrlTemplate[] = "share?title={title}&text={text}&url={url}";
30 constexpr char kManifestUrlHigh[] = 30 constexpr char kManifestUrlHigh[] =
31 "https://www.example-high.com/target/manifest.json"; 31 "https://www.example-high.com/target/manifest.json";
32 constexpr char kManifestUrlLow[] = 32 constexpr char kManifestUrlLow[] =
33 "https://www.example-low.com/target/manifest.json"; 33 "https://www.example-low.com/target/manifest.json";
34 constexpr char kManifestUrlMin[] = 34 constexpr char kManifestUrlMin[] =
35 "https://www.example-min.com/target/manifest.json"; 35 "https://www.example-min.com/target/manifest.json";
36 36
37 void DidShare(const base::Optional<std::string>& expected_error,
38 const base::Optional<std::string>& error) {
39 EXPECT_EQ(expected_error, error);
40 }
41
37 class ShareServiceTestImpl : public ShareServiceImpl { 42 class ShareServiceTestImpl : public ShareServiceImpl {
38 public: 43 public:
39 explicit ShareServiceTestImpl(blink::mojom::ShareServiceRequest request) 44 explicit ShareServiceTestImpl(blink::mojom::ShareServiceRequest request)
40 : binding_(this) { 45 : binding_(this) {
41 binding_.Bind(std::move(request)); 46 binding_.Bind(std::move(request));
42 47
43 pref_service_.reset(new TestingPrefServiceSimple()); 48 pref_service_.reset(new TestingPrefServiceSimple());
44 pref_service_->registry()->RegisterDictionaryPref( 49 pref_service_->registry()->RegisterDictionaryPref(
45 prefs::kWebShareVisitedTargets); 50 prefs::kWebShareVisitedTargets);
46 } 51 }
47 52
48 void set_picker_result(base::Optional<std::string> result) {
49 picker_result_ = result;
50 }
51
52 void AddShareTargetToPrefs(const std::string& manifest_url, 53 void AddShareTargetToPrefs(const std::string& manifest_url,
53 const std::string& name, 54 const std::string& name,
54 const std::string& url_template) { 55 const std::string& url_template) {
55 constexpr char kUrlTemplateKey[] = "url_template"; 56 constexpr char kUrlTemplateKey[] = "url_template";
56 constexpr char kNameKey[] = "name"; 57 constexpr char kNameKey[] = "name";
57 58
58 DictionaryPrefUpdate update(GetPrefService(), 59 DictionaryPrefUpdate update(GetPrefService(),
59 prefs::kWebShareVisitedTargets); 60 prefs::kWebShareVisitedTargets);
60 base::DictionaryValue* share_target_dict = update.Get(); 61 base::DictionaryValue* share_target_dict = update.Get();
61 62
62 std::unique_ptr<base::DictionaryValue> origin_dict( 63 std::unique_ptr<base::DictionaryValue> origin_dict(
63 new base::DictionaryValue); 64 new base::DictionaryValue);
64 65
65 origin_dict->SetStringWithoutPathExpansion(kUrlTemplateKey, url_template); 66 origin_dict->SetStringWithoutPathExpansion(kUrlTemplateKey, url_template);
66 origin_dict->SetStringWithoutPathExpansion(kNameKey, name); 67 origin_dict->SetStringWithoutPathExpansion(kNameKey, name);
67 68
68 share_target_dict->SetWithoutPathExpansion(manifest_url, 69 share_target_dict->SetWithoutPathExpansion(manifest_url,
69 std::move(origin_dict)); 70 std::move(origin_dict));
70 } 71 }
71 72
72 void SetEngagementForTarget(const std::string& manifest_url, 73 void SetEngagementForTarget(const std::string& manifest_url,
73 blink::mojom::EngagementLevel level) { 74 blink::mojom::EngagementLevel level) {
74 engagement_map_[manifest_url] = level; 75 engagement_map_[manifest_url] = level;
75 } 76 }
76 77
78 void set_run_loop(base::RunLoop* run_loop) {
79 quit_run_loop_ = run_loop->QuitClosure();
80 }
81
77 const std::string& GetLastUsedTargetURL() { return last_used_target_url_; } 82 const std::string& GetLastUsedTargetURL() { return last_used_target_url_; }
78 83
79 const std::vector<std::pair<base::string16, GURL>>& GetTargetsInPicker() { 84 const std::vector<std::pair<base::string16, GURL>>& GetTargetsInPicker() {
80 return targets_in_picker_; 85 return targets_in_picker_;
81 } 86 }
82 87
88 const base::Callback<void(base::Optional<std::string>)>& picker_callback() {
89 return picker_callback_;
90 }
91
83 private: 92 private:
84 void ShowPickerDialog( 93 void ShowPickerDialog(
85 const std::vector<std::pair<base::string16, GURL>>& targets, 94 const std::vector<std::pair<base::string16, GURL>>& targets,
86 const base::Callback<void(base::Optional<std::string>)>& callback) 95 const base::Callback<void(base::Optional<std::string>)>& callback)
87 override { 96 override {
97 // Store the arguments passed to the picker dialog.
88 targets_in_picker_ = targets; 98 targets_in_picker_ = targets;
89 callback.Run(picker_result_); 99 picker_callback_ = callback;
100
101 // Quit the test's run loop. It is the test's responsibility to call the
102 // callback, to simulate the user's choice.
103 quit_run_loop_.Run();
90 } 104 }
91 105
92 void OpenTargetURL(const GURL& target_url) override { 106 void OpenTargetURL(const GURL& target_url) override {
93 last_used_target_url_ = target_url.spec(); 107 last_used_target_url_ = target_url.spec();
94 } 108 }
95 109
96 PrefService* GetPrefService() override { return pref_service_.get(); } 110 PrefService* GetPrefService() override { return pref_service_.get(); }
97 111
98 blink::mojom::EngagementLevel GetEngagementLevel(const GURL& url) override { 112 blink::mojom::EngagementLevel GetEngagementLevel(const GURL& url) override {
99 return engagement_map_[url.spec()]; 113 return engagement_map_[url.spec()];
100 } 114 }
101 115
102 mojo::Binding<blink::mojom::ShareService> binding_; 116 mojo::Binding<blink::mojom::ShareService> binding_;
117 std::unique_ptr<TestingPrefServiceSimple> pref_service_;
103 118
104 base::Optional<std::string> picker_result_; 119 std::map<std::string, blink::mojom::EngagementLevel> engagement_map_;
120 // Closure to quit the test's run loop.
121 base::Closure quit_run_loop_;
122
123 // The last URL passed to OpenTargetURL.
105 std::string last_used_target_url_; 124 std::string last_used_target_url_;
106 std::unique_ptr<TestingPrefServiceSimple> pref_service_; 125 // The targets passed to ShowPickerDialog.
107 std::map<std::string, blink::mojom::EngagementLevel> engagement_map_;
108 std::vector<std::pair<base::string16, GURL>> targets_in_picker_; 126 std::vector<std::pair<base::string16, GURL>> targets_in_picker_;
127 // The callback passed to ShowPickerDialog (which is supposed to be called
128 // with the user's chosen result, or nullopt if cancelled).
129 base::Callback<void(base::Optional<std::string>)> picker_callback_;
109 }; 130 };
110 131
111 class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness { 132 class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness {
112 public: 133 public:
113 ShareServiceImplUnittest() = default; 134 ShareServiceImplUnittest() = default;
114 ~ShareServiceImplUnittest() override = default; 135 ~ShareServiceImplUnittest() override = default;
115 136
116 void SetUp() override { 137 void SetUp() override {
117 ChromeRenderViewHostTestHarness::SetUp(); 138 ChromeRenderViewHostTestHarness::SetUp();
118 139
119 share_service_helper_ = base::MakeUnique<ShareServiceTestImpl>( 140 share_service_helper_ = base::MakeUnique<ShareServiceTestImpl>(
120 mojo::MakeRequest(&share_service_)); 141 mojo::MakeRequest(&share_service_));
121 142
122 share_service_helper_->SetEngagementForTarget( 143 share_service_helper_->SetEngagementForTarget(
123 kManifestUrlHigh, blink::mojom::EngagementLevel::HIGH); 144 kManifestUrlHigh, blink::mojom::EngagementLevel::HIGH);
124 share_service_helper_->SetEngagementForTarget( 145 share_service_helper_->SetEngagementForTarget(
125 kManifestUrlMin, blink::mojom::EngagementLevel::MINIMAL); 146 kManifestUrlMin, blink::mojom::EngagementLevel::MINIMAL);
126 share_service_helper_->SetEngagementForTarget( 147 share_service_helper_->SetEngagementForTarget(
127 kManifestUrlLow, blink::mojom::EngagementLevel::LOW); 148 kManifestUrlLow, blink::mojom::EngagementLevel::LOW);
128 } 149 }
129 150
130 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } 151 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); }
131 152
132 void DidShare(const std::vector<std::pair<base::string16, GURL>>& 153 blink::mojom::ShareService* share_service() const {
133 expected_targets_in_picker, 154 return share_service_.get();
134 const std::string& expected_target_url,
135 const base::Optional<std::string>& expected_error,
136 const base::Optional<std::string>& error) {
137 std::vector<std::pair<base::string16, GURL>> targets_in_picker =
138 share_service_helper_->GetTargetsInPicker();
139 EXPECT_EQ(expected_targets_in_picker, targets_in_picker);
140
141 std::string target_url = share_service_helper_->GetLastUsedTargetURL();
142 EXPECT_EQ(expected_target_url, target_url);
143
144 EXPECT_EQ(expected_error, error);
145
146 if (!on_callback_.is_null())
147 on_callback_.Run();
148 } 155 }
149 156
157 ShareServiceTestImpl* share_service_helper() const {
158 return share_service_helper_.get();
159 }
160
161 void DeleteShareService() { share_service_helper_.reset(); }
162
163 private:
150 blink::mojom::ShareServicePtr share_service_; 164 blink::mojom::ShareServicePtr share_service_;
151 std::unique_ptr<ShareServiceTestImpl> share_service_helper_; 165 std::unique_ptr<ShareServiceTestImpl> share_service_helper_;
152 base::Closure on_callback_;
153 }; 166 };
154 167
155 } // namespace 168 } // namespace
156 169
157 // Basic test to check the Share method calls the callback with the expected 170 // Basic test to check the Share method calls the callback with the expected
158 // parameters. 171 // parameters.
159 TEST_F(ShareServiceImplUnittest, ShareCallbackParams) { 172 TEST_F(ShareServiceImplUnittest, ShareCallbackParams) {
160 share_service_helper_->set_picker_result( 173 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
174 kUrlTemplate);
175 share_service_helper()->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
176 kUrlTemplate);
177
178 base::Callback<void(const base::Optional<std::string>&)> callback =
179 base::Bind(&DidShare, base::Optional<std::string>());
180
181 base::RunLoop run_loop;
182 share_service_helper()->set_run_loop(&run_loop);
183
184 const GURL url(kUrlSpec);
185 share_service()->Share(kTitle, kText, url, callback);
186
187 run_loop.Run();
188
189 const std::vector<std::pair<base::string16, GURL>> kExpectedTargets{
190 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)),
191 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
192 EXPECT_EQ(kExpectedTargets, share_service_helper()->GetTargetsInPicker());
193
194 // Pick example-low.com.
195 share_service_helper()->picker_callback().Run(
161 base::Optional<std::string>(kManifestUrlLow)); 196 base::Optional<std::string>(kManifestUrlLow));
162 197
163 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName, 198 const char kExpectedURL[] =
164 kUrlTemplate);
165 share_service_helper_->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
166 kUrlTemplate);
167
168 std::string expected_url =
169 "https://www.example-low.com/target/" 199 "https://www.example-low.com/target/"
170 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." 200 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww."
171 "google.com%2F"; 201 "google.com%2F";
172 202 EXPECT_EQ(kExpectedURL, share_service_helper()->GetLastUsedTargetURL());
173 std::vector<std::pair<base::string16, GURL>> expected_targets{
174 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)),
175 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
176 base::Callback<void(const base::Optional<std::string>&)> callback =
177 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this),
178 expected_targets, expected_url, base::Optional<std::string>());
179
180 base::RunLoop run_loop;
181 on_callback_ = run_loop.QuitClosure();
182
183 const GURL url(kUrlSpec);
184 share_service_->Share(kTitle, kText, url, callback);
185
186 run_loop.Run();
187 } 203 }
188 204
189 // Tests the result of cancelling the share in the picker UI, that doesn't have 205 // Tests the result of cancelling the share in the picker UI, that doesn't have
190 // any targets. 206 // any targets.
191 TEST_F(ShareServiceImplUnittest, ShareCancelNoTargets) { 207 TEST_F(ShareServiceImplUnittest, ShareCancelNoTargets) {
192 // picker_result_ is set to nullopt by default, so this imitates the user
193 // cancelling a share.
194 // Expect an error message in response. 208 // Expect an error message in response.
195 base::Callback<void(const base::Optional<std::string>&)> callback = 209 base::Callback<void(const base::Optional<std::string>&)> callback =
196 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), 210 base::Bind(&DidShare, base::Optional<std::string>("Share was cancelled"));
197 std::vector<std::pair<base::string16, GURL>>(), std::string(),
198 base::Optional<std::string>("Share was cancelled"));
199 211
200 base::RunLoop run_loop; 212 base::RunLoop run_loop;
201 on_callback_ = run_loop.QuitClosure(); 213 share_service_helper()->set_run_loop(&run_loop);
202 214
203 const GURL url(kUrlSpec); 215 const GURL url(kUrlSpec);
204 share_service_->Share(kTitle, kText, url, callback); 216 share_service()->Share(kTitle, kText, url, callback);
205 217
206 run_loop.Run(); 218 run_loop.Run();
219
220 EXPECT_TRUE(share_service_helper()->GetTargetsInPicker().empty());
221
222 // Cancel the dialog.
223 share_service_helper()->picker_callback().Run(base::nullopt);
224
225 EXPECT_TRUE(share_service_helper()->GetLastUsedTargetURL().empty());
207 } 226 }
208 227
209 // Tests the result of cancelling the share in the picker UI, that has targets. 228 // Tests the result of cancelling the share in the picker UI, that has targets.
210 TEST_F(ShareServiceImplUnittest, ShareCancelWithTargets) { 229 TEST_F(ShareServiceImplUnittest, ShareCancelWithTargets) {
211 // picker_result_ is set to nullopt by default, so this imitates the user 230 share_service_helper()->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
212 // cancelling a share. 231 kUrlTemplate);
213 share_service_helper_->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName, 232 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
214 kUrlTemplate); 233 kUrlTemplate);
215 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
216 kUrlTemplate);
217 234
218 std::vector<std::pair<base::string16, GURL>> expected_targets{ 235 // Expect an error message in response.
236 base::Callback<void(const base::Optional<std::string>&)> callback =
237 base::Bind(&DidShare, base::Optional<std::string>("Share was cancelled"));
238
239 base::RunLoop run_loop;
240 share_service_helper()->set_run_loop(&run_loop);
241
242 const GURL url(kUrlSpec);
243 share_service()->Share(kTitle, kText, url, callback);
244
245 run_loop.Run();
246
247 const std::vector<std::pair<base::string16, GURL>> kExpectedTargets{
219 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)), 248 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)),
220 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))}; 249 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
221 // Expect an error message in response. 250 EXPECT_EQ(kExpectedTargets, share_service_helper()->GetTargetsInPicker());
222 base::Callback<void(const base::Optional<std::string>&)> callback =
223 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this),
224 expected_targets, std::string(),
225 base::Optional<std::string>("Share was cancelled"));
226 251
227 base::RunLoop run_loop; 252 // Cancel the dialog.
228 on_callback_ = run_loop.QuitClosure(); 253 share_service_helper()->picker_callback().Run(base::nullopt);
229 254
230 const GURL url(kUrlSpec); 255 EXPECT_TRUE(share_service_helper()->GetLastUsedTargetURL().empty());
231 share_service_->Share(kTitle, kText, url, callback);
232
233 run_loop.Run();
234 } 256 }
235 257
236 // Test to check that only targets with enough engagement were in picker. 258 // Test to check that only targets with enough engagement were in picker.
237 TEST_F(ShareServiceImplUnittest, ShareWithSomeInsufficientlyEngagedTargets) { 259 TEST_F(ShareServiceImplUnittest, ShareWithSomeInsufficientlyEngagedTargets) {
238 std::string expected_url = 260 share_service_helper()->AddShareTargetToPrefs(kManifestUrlMin, kTargetName,
261 kUrlTemplate);
262 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
263 kUrlTemplate);
264
265 base::Callback<void(const base::Optional<std::string>&)> callback =
266 base::Bind(&DidShare, base::Optional<std::string>());
267
268 base::RunLoop run_loop;
269 share_service_helper()->set_run_loop(&run_loop);
270
271 const GURL url(kUrlSpec);
272 share_service()->Share(kTitle, kText, url, callback);
273
274 run_loop.Run();
275
276 const std::vector<std::pair<base::string16, GURL>> kExpectedTargets{
277 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
278 EXPECT_EQ(kExpectedTargets, share_service_helper()->GetTargetsInPicker());
279
280 // Pick example-low.com.
281 share_service_helper()->picker_callback().Run(
282 base::Optional<std::string>(kManifestUrlLow));
283
284 const char kExpectedURL[] =
239 "https://www.example-low.com/target/" 285 "https://www.example-low.com/target/"
240 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." 286 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww."
241 "google.com%2F"; 287 "google.com%2F";
288 EXPECT_EQ(kExpectedURL, share_service_helper()->GetLastUsedTargetURL());
289 }
242 290
243 share_service_helper_->set_picker_result( 291 // Test that deleting the share service while the picker is open does not crash
244 base::Optional<std::string>(kManifestUrlLow)); 292 // (https://crbug.com/690775).
245 293 TEST_F(ShareServiceImplUnittest, ShareServiceDeletion) {
246 share_service_helper_->AddShareTargetToPrefs(kManifestUrlMin, kTargetName, 294 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
247 kUrlTemplate); 295 kUrlTemplate);
248 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
249 kUrlTemplate);
250
251 std::vector<std::pair<base::string16, GURL>> expected_targets{
252 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
253 base::Callback<void(const base::Optional<std::string>&)> callback =
254 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this),
255 expected_targets, expected_url, base::Optional<std::string>());
256 296
257 base::RunLoop run_loop; 297 base::RunLoop run_loop;
258 on_callback_ = run_loop.QuitClosure(); 298 share_service_helper()->set_run_loop(&run_loop);
259 299
260 const GURL url(kUrlSpec); 300 const GURL url(kUrlSpec);
261 share_service_->Share(kTitle, kText, url, callback); 301 // Expect the callback to never be called (since the share service is
302 // destroyed before the picker is closed).
303 // TODO(mgiuca): This probably should still complete the share, if not
304 // cancelled, even if the underlying tab is closed.
305 base::Callback<void(const base::Optional<std::string>&)> callback =
306 base::Bind([](const base::Optional<std::string>& error) { FAIL(); });
307 share_service()->Share(kTitle, kText, url, callback);
262 308
263 run_loop.Run(); 309 run_loop.Run();
310
311 const std::vector<std::pair<base::string16, GURL>> kExpectedTargets{
312 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
313 EXPECT_EQ(kExpectedTargets, share_service_helper()->GetTargetsInPicker());
314
315 const base::Callback<void(base::Optional<std::string>)> picker_callback =
316 share_service_helper()->picker_callback();
317
318 DeleteShareService();
319
320 // Pick example-low.com.
321 picker_callback.Run(base::Optional<std::string>(kManifestUrlLow));
264 } 322 }
265 323
266 // Replace various numbers of placeholders in various orders. Placeholders are 324 // Replace various numbers of placeholders in various orders. Placeholders are
267 // adjacent to eachother; there are no padding characters. 325 // adjacent to eachother; there are no padding characters.
268 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) { 326 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) {
269 const GURL url(kUrlSpec); 327 const GURL url(kUrlSpec);
270 std::string url_template_filled; 328 std::string url_template_filled;
271 bool succeeded; 329 bool succeeded;
272 330
273 // No placeholders 331 // No placeholders
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 EXPECT_TRUE(succeeded); 517 EXPECT_TRUE(succeeded);
460 EXPECT_EQ("%C3%A9", url_template_filled); 518 EXPECT_EQ("%C3%A9", url_template_filled);
461 519
462 // U+1F4A9 520 // U+1F4A9
463 url_template = "{title}"; 521 url_template = "{title}";
464 succeeded = ShareServiceImpl::ReplacePlaceholders( 522 succeeded = ShareServiceImpl::ReplacePlaceholders(
465 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled); 523 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled);
466 EXPECT_TRUE(succeeded); 524 EXPECT_TRUE(succeeded);
467 EXPECT_EQ("%F0%9F%92%A9", url_template_filled); 525 EXPECT_EQ("%F0%9F%92%A9", url_template_filled);
468 } 526 }
OLDNEW
« no previous file with comments | « chrome/browser/webshare/share_service_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698