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

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: Fix comments. 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_runloop(base::RunLoop* runloop) {
Sam McNally 2017/02/16 02:12:24 run_loop
Matt Giuca 2017/02/16 02:25:38 Done.
79 quit_runloop_ = runloop->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_runloop_.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_runloop_;
Sam McNally 2017/02/16 02:12:24 quit_run_loop_
Matt Giuca 2017/02/16 02:25:39 Done.
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,
161 base::Optional<std::string>(kManifestUrlLow)); 174 kUrlTemplate);
162 175 share_service_helper()->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
163 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName, 176 kUrlTemplate);
164 kUrlTemplate);
165 share_service_helper_->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
166 kUrlTemplate);
167 177
168 std::string expected_url = 178 std::string expected_url =
169 "https://www.example-low.com/target/" 179 "https://www.example-low.com/target/"
170 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." 180 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww."
171 "google.com%2F"; 181 "google.com%2F";
172
173 std::vector<std::pair<base::string16, GURL>> expected_targets{ 182 std::vector<std::pair<base::string16, GURL>> expected_targets{
Sam McNally 2017/02/16 02:12:24 Create these closer to where they're used. Also co
Matt Giuca 2017/02/16 02:25:39 Done.
174 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)), 183 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)),
175 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))}; 184 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
185
176 base::Callback<void(const base::Optional<std::string>&)> callback = 186 base::Callback<void(const base::Optional<std::string>&)> callback =
177 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), 187 base::Bind(&DidShare, base::Optional<std::string>());
178 expected_targets, expected_url, base::Optional<std::string>());
179 188
180 base::RunLoop run_loop; 189 base::RunLoop run_loop;
181 on_callback_ = run_loop.QuitClosure(); 190 share_service_helper()->set_runloop(&run_loop);
182 191
183 const GURL url(kUrlSpec); 192 const GURL url(kUrlSpec);
184 share_service_->Share(kTitle, kText, url, callback); 193 share_service()->Share(kTitle, kText, url, callback);
185 194
186 run_loop.Run(); 195 run_loop.Run();
196
197 EXPECT_EQ(expected_targets, share_service_helper()->GetTargetsInPicker());
198
199 // Pick example-low.com.
200 share_service_helper()->picker_callback().Run(
201 base::Optional<std::string>(kManifestUrlLow));
202
203 EXPECT_EQ(expected_url, share_service_helper()->GetLastUsedTargetURL());
187 } 204 }
188 205
189 // Tests the result of cancelling the share in the picker UI, that doesn't have 206 // Tests the result of cancelling the share in the picker UI, that doesn't have
190 // any targets. 207 // any targets.
191 TEST_F(ShareServiceImplUnittest, ShareCancelNoTargets) { 208 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. 209 // Expect an error message in response.
195 base::Callback<void(const base::Optional<std::string>&)> callback = 210 base::Callback<void(const base::Optional<std::string>&)> callback =
196 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), 211 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 212
200 base::RunLoop run_loop; 213 base::RunLoop run_loop;
201 on_callback_ = run_loop.QuitClosure(); 214 share_service_helper()->set_runloop(&run_loop);
202 215
203 const GURL url(kUrlSpec); 216 const GURL url(kUrlSpec);
204 share_service_->Share(kTitle, kText, url, callback); 217 share_service()->Share(kTitle, kText, url, callback);
205 218
206 run_loop.Run(); 219 run_loop.Run();
220
221 std::vector<std::pair<base::string16, GURL>> expected_targets; // Empty.
222 EXPECT_EQ(expected_targets, share_service_helper()->GetTargetsInPicker());
Sam McNally 2017/02/16 02:12:24 EXPECT_TRUE(share_service_helper()->GetTargetsInPi
Matt Giuca 2017/02/16 02:25:39 Done.
223
224 // Cancel the dialog.
225 share_service_helper()->picker_callback().Run(base::nullopt);
226
227 EXPECT_EQ(GURL(), share_service_helper()->GetLastUsedTargetURL());
207 } 228 }
208 229
209 // Tests the result of cancelling the share in the picker UI, that has targets. 230 // Tests the result of cancelling the share in the picker UI, that has targets.
210 TEST_F(ShareServiceImplUnittest, ShareCancelWithTargets) { 231 TEST_F(ShareServiceImplUnittest, ShareCancelWithTargets) {
211 // picker_result_ is set to nullopt by default, so this imitates the user 232 share_service_helper()->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName,
212 // cancelling a share. 233 kUrlTemplate);
213 share_service_helper_->AddShareTargetToPrefs(kManifestUrlHigh, kTargetName, 234 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
214 kUrlTemplate); 235 kUrlTemplate);
215 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
216 kUrlTemplate);
217 236
218 std::vector<std::pair<base::string16, GURL>> expected_targets{ 237 std::vector<std::pair<base::string16, GURL>> expected_targets{
219 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)), 238 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlHigh)),
220 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))}; 239 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
240
221 // Expect an error message in response. 241 // Expect an error message in response.
222 base::Callback<void(const base::Optional<std::string>&)> callback = 242 base::Callback<void(const base::Optional<std::string>&)> callback =
223 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), 243 base::Bind(&DidShare, base::Optional<std::string>("Share was cancelled"));
224 expected_targets, std::string(),
225 base::Optional<std::string>("Share was cancelled"));
226 244
227 base::RunLoop run_loop; 245 base::RunLoop run_loop;
228 on_callback_ = run_loop.QuitClosure(); 246 share_service_helper()->set_runloop(&run_loop);
229 247
230 const GURL url(kUrlSpec); 248 const GURL url(kUrlSpec);
231 share_service_->Share(kTitle, kText, url, callback); 249 share_service()->Share(kTitle, kText, url, callback);
232 250
233 run_loop.Run(); 251 run_loop.Run();
252
253 EXPECT_EQ(expected_targets, share_service_helper()->GetTargetsInPicker());
254
255 // Cancel the dialog.
256 share_service_helper()->picker_callback().Run(base::nullopt);
257
258 EXPECT_EQ(GURL(), share_service_helper()->GetLastUsedTargetURL());
Sam McNally 2017/02/16 02:12:24 EXPECT_TRUE(share_service_helper()->GetLastUsedTar
Matt Giuca 2017/02/16 02:25:39 Done.
234 } 259 }
235 260
236 // Test to check that only targets with enough engagement were in picker. 261 // Test to check that only targets with enough engagement were in picker.
237 TEST_F(ShareServiceImplUnittest, ShareWithSomeInsufficientlyEngagedTargets) { 262 TEST_F(ShareServiceImplUnittest, ShareWithSomeInsufficientlyEngagedTargets) {
238 std::string expected_url = 263 std::string expected_url =
239 "https://www.example-low.com/target/" 264 "https://www.example-low.com/target/"
240 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." 265 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww."
241 "google.com%2F"; 266 "google.com%2F";
267 std::vector<std::pair<base::string16, GURL>> expected_targets{
268 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
242 269
243 share_service_helper_->set_picker_result( 270 share_service_helper()->AddShareTargetToPrefs(kManifestUrlMin, kTargetName,
271 kUrlTemplate);
272 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
273 kUrlTemplate);
274
275 base::Callback<void(const base::Optional<std::string>&)> callback =
276 base::Bind(&DidShare, base::Optional<std::string>());
277
278 base::RunLoop run_loop;
279 share_service_helper()->set_runloop(&run_loop);
280
281 const GURL url(kUrlSpec);
282 share_service()->Share(kTitle, kText, url, callback);
283
284 run_loop.Run();
285
286 EXPECT_EQ(expected_targets, share_service_helper()->GetTargetsInPicker());
287
288 // Pick example-low.com.
289 share_service_helper()->picker_callback().Run(
244 base::Optional<std::string>(kManifestUrlLow)); 290 base::Optional<std::string>(kManifestUrlLow));
245 291
246 share_service_helper_->AddShareTargetToPrefs(kManifestUrlMin, kTargetName, 292 EXPECT_EQ(expected_url, share_service_helper()->GetLastUsedTargetURL());
247 kUrlTemplate); 293 }
248 share_service_helper_->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
249 kUrlTemplate);
250 294
295 // Test that deleting the share service while the picker is open does not crash
296 // (https://crbug.com/690775).
297 TEST_F(ShareServiceImplUnittest, ShareServiceDeletion) {
251 std::vector<std::pair<base::string16, GURL>> expected_targets{ 298 std::vector<std::pair<base::string16, GURL>> expected_targets{
252 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))}; 299 make_pair(base::UTF8ToUTF16(kTargetName), GURL(kManifestUrlLow))};
253 base::Callback<void(const base::Optional<std::string>&)> callback = 300
254 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), 301 share_service_helper()->AddShareTargetToPrefs(kManifestUrlLow, kTargetName,
255 expected_targets, expected_url, base::Optional<std::string>()); 302 kUrlTemplate);
256 303
257 base::RunLoop run_loop; 304 base::RunLoop run_loop;
258 on_callback_ = run_loop.QuitClosure(); 305 share_service_helper()->set_runloop(&run_loop);
259 306
260 const GURL url(kUrlSpec); 307 const GURL url(kUrlSpec);
261 share_service_->Share(kTitle, kText, url, callback); 308 // Expect the callback to never be called (since the share service is
309 // destroyed before the picker is closed).
310 // TODO(mgiuca): This probably should still complete the share, if not
311 // cancelled, even if the underlying tab is closed.
312 base::Callback<void(const base::Optional<std::string>&)> callback =
313 base::Bind([](const base::Optional<std::string>& error) { FAIL(); });
314 share_service()->Share(kTitle, kText, url, callback);
262 315
263 run_loop.Run(); 316 run_loop.Run();
317
318 EXPECT_EQ(expected_targets, share_service_helper()->GetTargetsInPicker());
319
320 const base::Callback<void(base::Optional<std::string>)> picker_callback =
321 share_service_helper()->picker_callback();
322
323 DeleteShareService();
324
325 // Pick example-low.com.
326 picker_callback.Run(base::Optional<std::string>(kManifestUrlLow));
264 } 327 }
265 328
266 // Replace various numbers of placeholders in various orders. Placeholders are 329 // Replace various numbers of placeholders in various orders. Placeholders are
267 // adjacent to eachother; there are no padding characters. 330 // adjacent to eachother; there are no padding characters.
268 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) { 331 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) {
269 const GURL url(kUrlSpec); 332 const GURL url(kUrlSpec);
270 std::string url_template_filled; 333 std::string url_template_filled;
271 bool succeeded; 334 bool succeeded;
272 335
273 // No placeholders 336 // No placeholders
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 EXPECT_TRUE(succeeded); 522 EXPECT_TRUE(succeeded);
460 EXPECT_EQ("%C3%A9", url_template_filled); 523 EXPECT_EQ("%C3%A9", url_template_filled);
461 524
462 // U+1F4A9 525 // U+1F4A9
463 url_template = "{title}"; 526 url_template = "{title}";
464 succeeded = ShareServiceImpl::ReplacePlaceholders( 527 succeeded = ShareServiceImpl::ReplacePlaceholders(
465 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled); 528 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled);
466 EXPECT_TRUE(succeeded); 529 EXPECT_TRUE(succeeded);
467 EXPECT_EQ("%F0%9F%92%A9", url_template_filled); 530 EXPECT_EQ("%F0%9F%92%A9", url_template_filled);
468 } 531 }
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