OLD | NEW |
---|---|
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" |
11 #include "chrome/browser/webshare/share_service_impl.h" | 11 #include "chrome/browser/webshare/share_service_impl.h" |
12 #include "chrome/common/pref_names.h" | |
12 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 13 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
14 #include "components/prefs/pref_registry_simple.h" | |
15 #include "components/prefs/scoped_user_pref_update.h" | |
16 #include "components/prefs/testing_pref_service.h" | |
13 #include "mojo/public/cpp/bindings/interface_request.h" | 17 #include "mojo/public/cpp/bindings/interface_request.h" |
14 #include "mojo/public/cpp/bindings/strong_binding.h" | 18 #include "mojo/public/cpp/bindings/strong_binding.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "url/gurl.h" | 20 #include "url/gurl.h" |
17 | 21 |
18 namespace { | 22 namespace { |
19 | 23 |
20 constexpr char kTitle[] = "My title"; | 24 constexpr char kTitle[] = "My title"; |
21 constexpr char kText[] = "My text"; | 25 constexpr char kText[] = "My text"; |
22 constexpr char kUrlSpec[] = "https://www.google.com/"; | 26 constexpr char kUrlSpec[] = "https://www.google.com/"; |
23 | 27 |
28 constexpr char kTargetName[] = "Share Target"; | |
29 constexpr char kUrlTemplate[] = "share?title={title}&text={text}&url={url}"; | |
30 constexpr char kManifestUrlHigh[] = | |
31 "https://www.example-high.com/target/manifest.json"; | |
32 constexpr char kManifestUrlLow[] = | |
33 "https://www.example-low.com/target/manifest.json"; | |
34 constexpr char kManifestUrlMin[] = | |
35 "https://www.example-min.com/target/manifest.json"; | |
36 | |
24 class ShareServiceTestImpl : public ShareServiceImpl { | 37 class ShareServiceTestImpl : public ShareServiceImpl { |
25 public: | 38 public: |
39 ShareServiceTestImpl() { | |
40 pref_service_.reset(new TestingPrefServiceSimple()); | |
41 pref_service_->registry()->RegisterDictionaryPref( | |
42 prefs::kWebShareVisitedTargets); | |
43 } | |
44 | |
26 static ShareServiceTestImpl* Create( | 45 static ShareServiceTestImpl* Create( |
27 blink::mojom::ShareServiceRequest request) { | 46 blink::mojom::ShareServiceRequest request) { |
28 std::unique_ptr<ShareServiceTestImpl> share_service_helper = | 47 std::unique_ptr<ShareServiceTestImpl> share_service_helper = |
29 base::MakeUnique<ShareServiceTestImpl>(); | 48 base::MakeUnique<ShareServiceTestImpl>(); |
30 ShareServiceTestImpl* share_service_helper_raw = share_service_helper.get(); | 49 ShareServiceTestImpl* share_service_helper_raw = share_service_helper.get(); |
31 mojo::MakeStrongBinding(std::move(share_service_helper), | 50 mojo::MakeStrongBinding(std::move(share_service_helper), |
32 std::move(request)); | 51 std::move(request)); |
33 return share_service_helper_raw; | 52 return share_service_helper_raw; |
34 } | 53 } |
35 | 54 |
36 void set_picker_result(base::Optional<std::string> result) { | 55 void set_picker_result(base::Optional<std::string> result) { |
37 picker_result_ = result; | 56 picker_result_ = result; |
38 } | 57 } |
39 | 58 |
59 void AddShareTarget(const std::string& manifest_url, | |
Matt Giuca
2017/02/09 00:24:27
nit: Maybe call this AddShareTargetToPrefs.
constantina
2017/02/09 05:40:11
Done.
| |
60 const std::string& name, | |
61 const std::string& url_template) { | |
62 constexpr char kUrlTemplateKey[] = "url_template"; | |
63 constexpr char kNameKey[] = "name"; | |
64 | |
65 DictionaryPrefUpdate update(GetPrefService(), | |
66 prefs::kWebShareVisitedTargets); | |
67 base::DictionaryValue* share_target_dict = update.Get(); | |
68 | |
69 std::unique_ptr<base::DictionaryValue> origin_dict( | |
70 new base::DictionaryValue); | |
71 | |
72 origin_dict->SetStringWithoutPathExpansion(kUrlTemplateKey, url_template); | |
73 origin_dict->SetStringWithoutPathExpansion(kNameKey, name); | |
74 | |
75 share_target_dict->SetWithoutPathExpansion(manifest_url, | |
76 std::move(origin_dict)); | |
77 } | |
78 | |
79 void SetEngagementForTarget(const std::string& manifest_url, | |
80 blink::mojom::EngagementLevel level) { | |
81 engagement_map_[manifest_url] = level; | |
82 } | |
83 | |
40 const std::string& GetLastUsedTargetURL() { return last_used_target_url_; } | 84 const std::string& GetLastUsedTargetURL() { return last_used_target_url_; } |
41 | 85 |
86 const std::vector<std::pair<base::string16, GURL>>& GetTargetsInPicker() { | |
87 return targets_in_picker_; | |
88 } | |
89 | |
42 private: | 90 private: |
43 base::Optional<std::string> picker_result_; | 91 base::Optional<std::string> picker_result_; |
44 std::string last_used_target_url_; | 92 std::string last_used_target_url_; |
93 std::unique_ptr<TestingPrefServiceSimple> pref_service_; | |
94 std::map<std::string, blink::mojom::EngagementLevel> engagement_map_; | |
95 std::vector<std::pair<base::string16, GURL>> targets_in_picker_; | |
45 | 96 |
46 void ShowPickerDialog( | 97 void ShowPickerDialog( |
Sam McNally
2017/02/09 02:10:39
Methods before fields.
constantina
2017/02/09 05:40:11
Done.
| |
47 const std::vector<std::pair<base::string16, GURL>>& targets, | 98 const std::vector<std::pair<base::string16, GURL>>& targets, |
48 const base::Callback<void(base::Optional<std::string>)>& callback) | 99 const base::Callback<void(base::Optional<std::string>)>& callback) |
49 override { | 100 override { |
101 targets_in_picker_ = targets; | |
50 callback.Run(picker_result_); | 102 callback.Run(picker_result_); |
51 } | 103 } |
52 | 104 |
53 void OpenTargetURL(const GURL& target_url) override { | 105 void OpenTargetURL(const GURL& target_url) override { |
54 last_used_target_url_ = target_url.spec(); | 106 last_used_target_url_ = target_url.spec(); |
55 } | 107 } |
108 | |
109 PrefService* GetPrefService() override { return pref_service_.get(); } | |
110 | |
111 blink::mojom::EngagementLevel GetEngagementLevel(const GURL& url) override { | |
112 return engagement_map_[url.spec()]; | |
113 } | |
56 }; | 114 }; |
57 | 115 |
58 class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness { | 116 class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness { |
59 public: | 117 public: |
60 ShareServiceImplUnittest() = default; | 118 ShareServiceImplUnittest() = default; |
61 ~ShareServiceImplUnittest() override = default; | 119 ~ShareServiceImplUnittest() override = default; |
62 | 120 |
63 void SetUp() override { | 121 void SetUp() override { |
64 ChromeRenderViewHostTestHarness::SetUp(); | 122 ChromeRenderViewHostTestHarness::SetUp(); |
65 | 123 |
66 share_service_helper_ = | 124 share_service_helper_ = |
67 ShareServiceTestImpl::Create(mojo::MakeRequest(&share_service_)); | 125 ShareServiceTestImpl::Create(mojo::MakeRequest(&share_service_)); |
126 | |
127 share_service_helper_->SetEngagementForTarget( | |
128 kManifestUrlHigh, blink::mojom::EngagementLevel::HIGH); | |
129 share_service_helper_->SetEngagementForTarget( | |
130 kManifestUrlMin, blink::mojom::EngagementLevel::MINIMAL); | |
131 share_service_helper_->SetEngagementForTarget( | |
132 kManifestUrlLow, blink::mojom::EngagementLevel::LOW); | |
68 } | 133 } |
69 | 134 |
70 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } | 135 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } |
71 | 136 |
72 void DidShare(const std::string& expected_target_url, | 137 void DidShare(const std::vector<std::pair<base::string16, GURL>>& |
73 const base::Optional<std::string>& expected_param, | 138 expected_targets_in_picker, |
74 const base::Optional<std::string>& param) { | 139 const std::string& expected_target_url, |
75 EXPECT_EQ(expected_param, param); | 140 const base::Optional<std::string>& expected_error, |
141 const base::Optional<std::string>& error) { | |
142 std::vector<std::pair<base::string16, GURL>> targets_in_picker = | |
143 share_service_helper_->GetTargetsInPicker(); | |
144 EXPECT_EQ(expected_targets_in_picker, targets_in_picker); | |
145 | |
76 std::string target_url = share_service_helper_->GetLastUsedTargetURL(); | 146 std::string target_url = share_service_helper_->GetLastUsedTargetURL(); |
77 EXPECT_EQ(expected_target_url, target_url); | 147 EXPECT_EQ(expected_target_url, target_url); |
78 | 148 |
149 EXPECT_EQ(expected_error, error); | |
150 | |
79 if (!on_callback_.is_null()) | 151 if (!on_callback_.is_null()) |
80 on_callback_.Run(); | 152 on_callback_.Run(); |
81 } | 153 } |
82 | 154 |
83 blink::mojom::ShareServicePtr share_service_; | 155 blink::mojom::ShareServicePtr share_service_; |
84 ShareServiceTestImpl* share_service_helper_; | 156 ShareServiceTestImpl* share_service_helper_; |
85 base::Closure on_callback_; | 157 base::Closure on_callback_; |
86 }; | 158 }; |
87 | 159 |
88 } // namespace | 160 } // namespace |
89 | 161 |
90 // Basic test to check the Share method calls the callback with the expected | 162 // Basic test to check the Share method calls the callback with the expected |
91 // parameters. | 163 // parameters. |
92 TEST_F(ShareServiceImplUnittest, ShareCallbackParams) { | 164 TEST_F(ShareServiceImplUnittest, ShareCallbackParams) { |
165 share_service_helper_->set_picker_result( | |
166 base::Optional<std::string>(kManifestUrlLow)); | |
167 | |
168 share_service_helper_->AddShareTarget(kManifestUrlLow, kTargetName, | |
169 kUrlTemplate); | |
170 share_service_helper_->AddShareTarget(kManifestUrlHigh, kTargetName, | |
171 kUrlTemplate); | |
172 | |
93 std::string expected_url = | 173 std::string expected_url = |
94 "https://wicg.github.io/web-share-target/demos/" | 174 "https://www.example-low.com/target/" |
95 "sharetarget.html?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." | 175 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." |
96 "google.com%2F"; | 176 "google.com%2F"; |
97 share_service_helper_->set_picker_result(base::Optional<std::string>( | |
98 "https://wicg.github.io/web-share-target/demos/")); | |
99 | 177 |
100 const GURL url(kUrlSpec); | 178 std::vector<std::pair<base::string16, GURL>> expected_targets{ |
179 make_pair(base::UTF8ToUTF16(kTargetName), kManifestUrlHigh), | |
180 make_pair(base::UTF8ToUTF16(kTargetName), kManifestUrlLow)}; | |
101 base::Callback<void(const base::Optional<std::string>&)> callback = | 181 base::Callback<void(const base::Optional<std::string>&)> callback = |
102 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), | 182 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), |
103 expected_url, base::Optional<std::string>()); | 183 expected_targets, expected_url, base::Optional<std::string>()); |
104 | 184 |
105 base::RunLoop run_loop; | 185 base::RunLoop run_loop; |
106 on_callback_ = run_loop.QuitClosure(); | 186 on_callback_ = run_loop.QuitClosure(); |
107 | 187 |
188 const GURL url(kUrlSpec); | |
108 share_service_->Share(kTitle, kText, url, callback); | 189 share_service_->Share(kTitle, kText, url, callback); |
109 | 190 |
110 run_loop.Run(); | 191 run_loop.Run(); |
111 } | 192 } |
112 | 193 |
113 // Tests the result of cancelling the share in the picker UI. | 194 // Tests the result of cancelling the share in the picker UI, that doesn't have |
114 TEST_F(ShareServiceImplUnittest, ShareCancel) { | 195 // any targets. |
196 TEST_F(ShareServiceImplUnittest, ShareCancelNoTargets) { | |
115 // picker_result_ is set to nullopt by default, so this imitates the user | 197 // picker_result_ is set to nullopt by default, so this imitates the user |
116 // cancelling a share. | 198 // cancelling a share. |
117 // Expect an error message in response. | 199 // Expect an error message in response. |
118 base::Callback<void(const base::Optional<std::string>&)> callback = | 200 base::Callback<void(const base::Optional<std::string>&)> callback = |
119 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), | 201 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), |
120 std::string(), | 202 std::vector<std::pair<base::string16, GURL>>(), std::string(), |
121 base::Optional<std::string>("Share was cancelled")); | 203 base::Optional<std::string>("Share was cancelled")); |
122 | 204 |
123 base::RunLoop run_loop; | 205 base::RunLoop run_loop; |
206 on_callback_ = run_loop.QuitClosure(); | |
207 | |
208 const GURL url(kUrlSpec); | |
209 share_service_->Share(kTitle, kText, url, callback); | |
210 | |
211 run_loop.Run(); | |
212 } | |
213 | |
214 // Tests the result of cancelling the share in the picker UI, that has targets. | |
215 TEST_F(ShareServiceImplUnittest, ShareCancelWithTargets) { | |
216 // picker_result_ is set to nullopt by default, so this imitates the user | |
217 // cancelling a share. | |
218 share_service_helper_->AddShareTarget(kManifestUrlHigh, kTargetName, | |
219 kUrlTemplate); | |
220 share_service_helper_->AddShareTarget(kManifestUrlLow, kTargetName, | |
221 kUrlTemplate); | |
222 | |
223 std::vector<std::pair<base::string16, GURL>> expected_targets{ | |
224 make_pair(base::UTF8ToUTF16(kTargetName), kManifestUrlHigh), | |
225 make_pair(base::UTF8ToUTF16(kTargetName), kManifestUrlLow)}; | |
226 // Expect an error message in response. | |
227 base::Callback<void(const base::Optional<std::string>&)> callback = | |
228 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), | |
229 expected_targets, std::string(), | |
230 base::Optional<std::string>("Share was cancelled")); | |
231 | |
232 base::RunLoop run_loop; | |
124 on_callback_ = run_loop.QuitClosure(); | 233 on_callback_ = run_loop.QuitClosure(); |
125 | 234 |
126 const GURL url(kUrlSpec); | 235 const GURL url(kUrlSpec); |
127 share_service_->Share(kTitle, kText, url, callback); | 236 share_service_->Share(kTitle, kText, url, callback); |
128 | 237 |
129 run_loop.Run(); | 238 run_loop.Run(); |
130 } | 239 } |
131 | 240 |
241 // Test to check that only targets with enough engagement were in picker. | |
242 TEST_F(ShareServiceImplUnittest, ShareWithSomeInsuffientlyEngagedTargets) { | |
Matt Giuca
2017/02/09 00:24:27
s/Insuffiently/Insufficiently !
constantina
2017/02/09 05:40:11
Oops! Done!
| |
243 std::string expected_url = | |
244 "https://www.example-low.com/target/" | |
245 "share?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." | |
246 "google.com%2F"; | |
247 | |
248 share_service_helper_->set_picker_result( | |
249 base::Optional<std::string>(kManifestUrlLow)); | |
250 | |
251 share_service_helper_->AddShareTarget(kManifestUrlMin, kTargetName, | |
252 kUrlTemplate); | |
253 share_service_helper_->AddShareTarget(kManifestUrlLow, kTargetName, | |
254 kUrlTemplate); | |
255 | |
256 std::vector<std::pair<base::string16, GURL>> expected_targets{ | |
257 make_pair(base::UTF8ToUTF16(kTargetName), kManifestUrlLow)}; | |
258 base::Callback<void(const base::Optional<std::string>&)> callback = | |
259 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), | |
260 expected_targets, expected_url, base::Optional<std::string>()); | |
261 | |
262 base::RunLoop run_loop; | |
263 on_callback_ = run_loop.QuitClosure(); | |
264 | |
265 const GURL url(kUrlSpec); | |
266 share_service_->Share(kTitle, kText, url, callback); | |
267 | |
268 run_loop.Run(); | |
269 } | |
270 | |
132 // Replace various numbers of placeholders in various orders. Placeholders are | 271 // Replace various numbers of placeholders in various orders. Placeholders are |
133 // adjacent to eachother; there are no padding characters. | 272 // adjacent to eachother; there are no padding characters. |
134 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) { | 273 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) { |
135 const GURL url(kUrlSpec); | 274 const GURL url(kUrlSpec); |
136 std::string url_template_filled; | 275 std::string url_template_filled; |
137 bool succeeded; | 276 bool succeeded; |
138 | 277 |
139 // No placeholders | 278 // No placeholders |
140 std::string url_template = "blank"; | 279 std::string url_template = "blank"; |
141 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, | 280 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
325 EXPECT_TRUE(succeeded); | 464 EXPECT_TRUE(succeeded); |
326 EXPECT_EQ("%C3%A9", url_template_filled); | 465 EXPECT_EQ("%C3%A9", url_template_filled); |
327 | 466 |
328 // U+1F4A9 | 467 // U+1F4A9 |
329 url_template = "{title}"; | 468 url_template = "{title}"; |
330 succeeded = ShareServiceImpl::ReplacePlaceholders( | 469 succeeded = ShareServiceImpl::ReplacePlaceholders( |
331 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled); | 470 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled); |
332 EXPECT_TRUE(succeeded); | 471 EXPECT_TRUE(succeeded); |
333 EXPECT_EQ("%F0%9F%92%A9", url_template_filled); | 472 EXPECT_EQ("%F0%9F%92%A9", url_template_filled); |
334 } | 473 } |
OLD | NEW |