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> |
| 6 |
5 #include "base/bind.h" | 7 #include "base/bind.h" |
6 #include "base/callback.h" | 8 #include "base/callback.h" |
7 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
8 #include "chrome/browser/webshare/share_service_impl.h" | 10 #include "chrome/browser/webshare/share_service_impl.h" |
9 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 11 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
10 #include "mojo/public/cpp/bindings/interface_request.h" | 12 #include "mojo/public/cpp/bindings/interface_request.h" |
| 13 #include "mojo/public/cpp/bindings/strong_binding.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "url/gurl.h" | 15 #include "url/gurl.h" |
13 | 16 |
14 class ShareServiceTest : public ChromeRenderViewHostTestHarness { | 17 namespace { |
| 18 |
| 19 constexpr char kTitle[] = "My title"; |
| 20 constexpr char kText[] = "My text"; |
| 21 constexpr char kUrlSpec[] = "https://www.google.com/"; |
| 22 |
| 23 class ShareServiceTestImpl : public ShareServiceImpl { |
15 public: | 24 public: |
16 ShareServiceTest() = default; | 25 static ShareServiceTestImpl* Create( |
17 ~ShareServiceTest() override = default; | 26 blink::mojom::ShareServiceRequest request) { |
| 27 std::unique_ptr<ShareServiceTestImpl> share_service_helper = |
| 28 base::MakeUnique<ShareServiceTestImpl>(); |
| 29 ShareServiceTestImpl* share_service_helper_raw = share_service_helper.get(); |
| 30 mojo::MakeStrongBinding(std::move(share_service_helper), |
| 31 std::move(request)); |
| 32 return share_service_helper_raw; |
| 33 } |
| 34 |
| 35 const std::string& GetLastUsedTargetURL() { return last_used_target_url_; } |
| 36 |
| 37 private: |
| 38 std::string last_used_target_url_; |
| 39 |
| 40 void OpenTargetURL(const GURL& target_url) override { |
| 41 last_used_target_url_ = target_url.spec(); |
| 42 } |
| 43 }; |
| 44 |
| 45 class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness { |
| 46 public: |
| 47 ShareServiceImplUnittest() = default; |
| 48 ~ShareServiceImplUnittest() override = default; |
18 | 49 |
19 void SetUp() override { | 50 void SetUp() override { |
20 ChromeRenderViewHostTestHarness::SetUp(); | 51 ChromeRenderViewHostTestHarness::SetUp(); |
21 | 52 |
22 ShareServiceImpl::Create(mojo::MakeRequest(&share_service_)); | 53 share_service_helper_ = |
23 } | 54 ShareServiceTestImpl::Create(mojo::MakeRequest(&share_service_)); |
24 | 55 } |
25 void TearDown() override { | 56 |
26 ChromeRenderViewHostTestHarness::TearDown(); | 57 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } |
27 } | 58 |
28 | 59 void DidShare(const std::string& expected_target_url, |
29 void DidShare(const base::Optional<std::string>& expected, | 60 const base::Optional<std::string>& expected_param, |
30 const base::Optional<std::string>& str) { | 61 const base::Optional<std::string>& param) { |
31 EXPECT_EQ(expected, str); | 62 EXPECT_EQ(expected_param, param); |
| 63 std::string target_url = share_service_helper_->GetLastUsedTargetURL(); |
| 64 EXPECT_EQ(expected_target_url, target_url); |
32 | 65 |
33 if (!on_callback_.is_null()) | 66 if (!on_callback_.is_null()) |
34 on_callback_.Run(); | 67 on_callback_.Run(); |
35 } | 68 } |
36 | 69 |
37 blink::mojom::ShareServicePtr share_service_; | 70 blink::mojom::ShareServicePtr share_service_; |
| 71 ShareServiceTestImpl* share_service_helper_; |
38 base::Closure on_callback_; | 72 base::Closure on_callback_; |
39 }; | 73 }; |
40 | 74 |
| 75 } // namespace |
| 76 |
41 // Basic test to check the Share method calls the callback with the expected | 77 // Basic test to check the Share method calls the callback with the expected |
42 // parameters. | 78 // parameters. |
43 TEST_F(ShareServiceTest, ShareCallbackParams) { | 79 TEST_F(ShareServiceImplUnittest, ShareCallbackParams) { |
44 const GURL url("https://www.google.com"); | 80 std::string expected_url = |
| 81 "https://wicg.github.io/web-share-target/demos/" |
| 82 "sharetarget.html?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww." |
| 83 "google.com%2F"; |
| 84 |
| 85 const GURL url(kUrlSpec); |
| 86 base::Callback<void(const base::Optional<std::string>&)> callback = |
| 87 base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this), |
| 88 expected_url, base::Optional<std::string>()); |
45 | 89 |
46 base::RunLoop run_loop; | 90 base::RunLoop run_loop; |
47 on_callback_ = run_loop.QuitClosure(); | 91 on_callback_ = run_loop.QuitClosure(); |
48 | 92 |
49 base::Callback<void(const base::Optional<std::string>&)> callback = | 93 share_service_->Share(kTitle, kText, url, callback); |
50 base::Bind( | |
51 &ShareServiceTest::DidShare, base::Unretained(this), | |
52 base::Optional<std::string>("Not implemented: navigator.share")); | |
53 share_service_->Share("title", "text", url, callback); | |
54 | 94 |
55 run_loop.Run(); | 95 run_loop.Run(); |
56 } | 96 } |
| 97 |
| 98 // Replace various numbers of placeholders in various orders. Placeholders are |
| 99 // adjacent to eachother; there are no padding characters. |
| 100 TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) { |
| 101 const GURL url(kUrlSpec); |
| 102 std::string url_template_filled; |
| 103 bool succeeded; |
| 104 |
| 105 // No placeholders |
| 106 std::string url_template = "blank"; |
| 107 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 108 url, &url_template_filled); |
| 109 EXPECT_TRUE(succeeded); |
| 110 EXPECT_EQ("blank", url_template_filled); |
| 111 |
| 112 // Empty |url_template| |
| 113 url_template = ""; |
| 114 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 115 url, &url_template_filled); |
| 116 EXPECT_TRUE(succeeded); |
| 117 EXPECT_EQ("", url_template_filled); |
| 118 |
| 119 // One title placeholder. |
| 120 url_template = "{title}"; |
| 121 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 122 url, &url_template_filled); |
| 123 EXPECT_TRUE(succeeded); |
| 124 EXPECT_EQ("My%20title", url_template_filled); |
| 125 |
| 126 // One text placeholder. |
| 127 url_template = "{text}"; |
| 128 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 129 url, &url_template_filled); |
| 130 EXPECT_TRUE(succeeded); |
| 131 EXPECT_EQ("My%20text", url_template_filled); |
| 132 |
| 133 // One url placeholder. |
| 134 url_template = "{url}"; |
| 135 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 136 url, &url_template_filled); |
| 137 EXPECT_TRUE(succeeded); |
| 138 EXPECT_EQ("https%3A%2F%2Fwww.google.com%2F", url_template_filled); |
| 139 |
| 140 // One of each placeholder, in title, text, url order. |
| 141 url_template = "{title}{text}{url}"; |
| 142 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 143 url, &url_template_filled); |
| 144 EXPECT_TRUE(succeeded); |
| 145 EXPECT_EQ("My%20titleMy%20texthttps%3A%2F%2Fwww.google.com%2F", |
| 146 url_template_filled); |
| 147 |
| 148 // One of each placeholder, in url, text, title order. |
| 149 url_template = "{url}{text}{title}"; |
| 150 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 151 url, &url_template_filled); |
| 152 EXPECT_TRUE(succeeded); |
| 153 EXPECT_EQ("https%3A%2F%2Fwww.google.com%2FMy%20textMy%20title", |
| 154 url_template_filled); |
| 155 |
| 156 // Two of each placeholder, some next to each other, others not. |
| 157 url_template = "{title}{url}{text}{text}{title}{url}"; |
| 158 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 159 url, &url_template_filled); |
| 160 EXPECT_TRUE(succeeded); |
| 161 EXPECT_EQ( |
| 162 "My%20titlehttps%3A%2F%2Fwww.google.com%2FMy%20textMy%20textMy%20" |
| 163 "titlehttps%3A%2F%2Fwww.google.com%2F", |
| 164 url_template_filled); |
| 165 |
| 166 // Placeholders are in a query string, as values. The expected use case. |
| 167 // Two of each placeholder, some next to each other, others not. |
| 168 url_template = |
| 169 "?title={title}&url={url}&text={text}&text={text}&" |
| 170 "title={title}&url={url}"; |
| 171 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 172 url, &url_template_filled); |
| 173 EXPECT_TRUE(succeeded); |
| 174 EXPECT_EQ( |
| 175 "?title=My%20title&url=https%3A%2F%2Fwww.google.com%2F&text=My%20text&" |
| 176 "text=My%20text&title=My%20title&url=https%3A%2F%2Fwww.google.com%2F", |
| 177 url_template_filled); |
| 178 |
| 179 // Badly nested placeholders. |
| 180 url_template = "{"; |
| 181 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 182 url, &url_template_filled); |
| 183 EXPECT_FALSE(succeeded); |
| 184 |
| 185 url_template = "{title"; |
| 186 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 187 url, &url_template_filled); |
| 188 EXPECT_FALSE(succeeded); |
| 189 |
| 190 url_template = "{title{text}}"; |
| 191 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 192 url, &url_template_filled); |
| 193 EXPECT_FALSE(succeeded); |
| 194 |
| 195 url_template = "{title{}"; |
| 196 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 197 url, &url_template_filled); |
| 198 EXPECT_FALSE(succeeded); |
| 199 |
| 200 url_template = "{title}}"; |
| 201 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 202 url, &url_template_filled); |
| 203 EXPECT_FALSE(succeeded); |
| 204 |
| 205 // Placeholder with non-identifier character. |
| 206 url_template = "{title?}"; |
| 207 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 208 url, &url_template_filled); |
| 209 EXPECT_FALSE(succeeded); |
| 210 |
| 211 // Placeholder with digit character. |
| 212 url_template = "{title1}"; |
| 213 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 214 url, &url_template_filled); |
| 215 EXPECT_TRUE(succeeded); |
| 216 EXPECT_EQ("", url_template_filled); |
| 217 |
| 218 // Empty placeholder. |
| 219 url_template = "{}"; |
| 220 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 221 url, &url_template_filled); |
| 222 EXPECT_TRUE(succeeded); |
| 223 EXPECT_EQ("", url_template_filled); |
| 224 |
| 225 // Unexpected placeholders. |
| 226 url_template = "{nonexistentplaceholder}"; |
| 227 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 228 url, &url_template_filled); |
| 229 EXPECT_TRUE(succeeded); |
| 230 EXPECT_EQ("", url_template_filled); |
| 231 |
| 232 // |url_template| with % escapes. |
| 233 url_template = "%20{title}%20"; |
| 234 succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText, |
| 235 url, &url_template_filled); |
| 236 EXPECT_TRUE(succeeded); |
| 237 EXPECT_EQ("%20My%20title%20", url_template_filled); |
| 238 |
| 239 // Share data that contains percent escapes. |
| 240 url_template = "{title}"; |
| 241 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 242 url_template, "My%20title", kText, url, &url_template_filled); |
| 243 EXPECT_TRUE(succeeded); |
| 244 EXPECT_EQ("My%2520title", url_template_filled); |
| 245 |
| 246 // Share data that contains placeholders. These should not be replaced. |
| 247 url_template = "{title}"; |
| 248 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 249 url_template, "{title}", kText, url, &url_template_filled); |
| 250 EXPECT_TRUE(succeeded); |
| 251 EXPECT_EQ("%7Btitle%7D", url_template_filled); |
| 252 |
| 253 // All characters that shouldn't be escaped. |
| 254 url_template = "{title}"; |
| 255 succeeded = |
| 256 ShareServiceImpl::ReplacePlaceholders(url_template, |
| 257 "-_.!~*'()0123456789" |
| 258 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 259 "abcdefghijklmnopqrstuvwxyz", |
| 260 kText, url, &url_template_filled); |
| 261 EXPECT_TRUE(succeeded); |
| 262 EXPECT_EQ( |
| 263 "-_.!~*'()0123456789" |
| 264 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 265 "abcdefghijklmnopqrstuvwxyz", |
| 266 url_template_filled); |
| 267 |
| 268 // All characters that should be escaped. |
| 269 url_template = "{title}"; |
| 270 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 271 url_template, " \"#$%&+,/:;<=>?@[\\]^`{|}", kText, url, |
| 272 &url_template_filled); |
| 273 EXPECT_TRUE(succeeded); |
| 274 EXPECT_EQ( |
| 275 "%20%22%23%24%25%26%2B%2C%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%60%7B%7C%" |
| 276 "7D", |
| 277 url_template_filled); |
| 278 |
| 279 // Unicode chars. |
| 280 // U+263B |
| 281 url_template = "{title}"; |
| 282 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 283 url_template, "\xe2\x98\xbb", kText, url, &url_template_filled); |
| 284 EXPECT_TRUE(succeeded); |
| 285 EXPECT_EQ("%E2%98%BB", url_template_filled); |
| 286 |
| 287 // U+00E9 |
| 288 url_template = "{title}"; |
| 289 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 290 url_template, "\xc3\xa9", kText, url, &url_template_filled); |
| 291 EXPECT_TRUE(succeeded); |
| 292 EXPECT_EQ("%C3%A9", url_template_filled); |
| 293 |
| 294 // U+1F4A9 |
| 295 url_template = "{title}"; |
| 296 succeeded = ShareServiceImpl::ReplacePlaceholders( |
| 297 url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled); |
| 298 EXPECT_TRUE(succeeded); |
| 299 EXPECT_EQ("%F0%9F%92%A9", url_template_filled); |
| 300 } |
OLD | NEW |