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