1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "extensions/common/error_utils.h"
8 #include "extensions/common/manifest_constants.h"
9 #include "extensions/common/manifest_handlers/externally_connectable.h"
10 #include "extensions/common/manifest_test.h"
11 #include "extensions/common/permissions/permissions_data.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 using testing::ElementsAre
;
17 namespace extensions
{
19 namespace errors
= externally_connectable_errors
;
21 class ExternallyConnectableTest
: public ManifestTest
{
23 ExternallyConnectableTest() {}
24 ~ExternallyConnectableTest() override
{}
27 ExternallyConnectableInfo
* GetExternallyConnectableInfo(
28 scoped_refptr
<Extension
> extension
) {
29 return static_cast<ExternallyConnectableInfo
*>(
30 extension
->GetManifestData(manifest_keys::kExternallyConnectable
));
34 TEST_F(ExternallyConnectableTest
, IDsAndMatches
) {
35 scoped_refptr
<Extension
> extension
=
36 LoadAndExpectSuccess("externally_connectable_ids_and_matches.json");
37 ASSERT_TRUE(extension
.get());
39 EXPECT_TRUE(extension
->permissions_data()->HasAPIPermission(
40 APIPermission::kWebConnectable
));
42 ExternallyConnectableInfo
* info
=
43 ExternallyConnectableInfo::Get(extension
.get());
46 EXPECT_THAT(info
->ids
,
47 ElementsAre("abcdefghijklmnopabcdefghijklmnop",
48 "ponmlkjihgfedcbaponmlkjihgfedcba"));
50 EXPECT_FALSE(info
->all_ids
);
52 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://example.com")));
53 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://example.com/")));
54 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://example.com/index.html")));
56 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com")));
57 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com/")));
58 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com/index.html")));
59 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://www.google.com")));
60 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://www.google.com/")));
61 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://google.com")));
62 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://google.com/")));
64 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
65 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org/")));
67 info
->matches
.MatchesURL(GURL("http://build.chromium.org/index.html")));
68 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("https://build.chromium.org")));
69 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("https://build.chromium.org/")));
71 info
->matches
.MatchesURL(GURL("http://foo.chromium.org/index.html")));
73 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://yahoo.com")));
74 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://yahoo.com/")));
76 // TLD-style patterns should match just the TLD.
77 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://appspot.com/foo.html")));
78 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://com")));
79 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://go/here")));
81 // TLD-style patterns should *not* match any subdomains of the TLD.
83 info
->matches
.MatchesURL(GURL("http://codereview.appspot.com/foo.html")));
85 info
->matches
.MatchesURL(GURL("http://chromium.com/index.html")));
86 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://here.go/somewhere")));
88 // Paths that don't have any wildcards should match the exact domain, but
89 // ignore the trailing slash. This is kind of a corner case, so let's test it.
90 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://no.wildcard.path")));
91 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://no.wildcard.path/")));
93 info
->matches
.MatchesURL(GURL("http://no.wildcard.path/index.html")));
96 TEST_F(ExternallyConnectableTest
, IDs
) {
97 scoped_refptr
<Extension
> extension
=
98 LoadAndExpectSuccess("externally_connectable_ids.json");
99 ASSERT_TRUE(extension
.get());
101 EXPECT_FALSE(extension
->permissions_data()->HasAPIPermission(
102 APIPermission::kWebConnectable
));
104 ExternallyConnectableInfo
* info
=
105 ExternallyConnectableInfo::Get(extension
.get());
108 EXPECT_THAT(info
->ids
,
109 ElementsAre("abcdefghijklmnopabcdefghijklmnop",
110 "ponmlkjihgfedcbaponmlkjihgfedcba"));
112 EXPECT_FALSE(info
->all_ids
);
114 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://google.com/index.html")));
117 TEST_F(ExternallyConnectableTest
, Matches
) {
118 scoped_refptr
<Extension
> extension
=
119 LoadAndExpectSuccess("externally_connectable_matches.json");
120 ASSERT_TRUE(extension
.get());
122 EXPECT_TRUE(extension
->permissions_data()->HasAPIPermission(
123 APIPermission::kWebConnectable
));
125 ExternallyConnectableInfo
* info
=
126 ExternallyConnectableInfo::Get(extension
.get());
129 EXPECT_THAT(info
->ids
, ElementsAre());
131 EXPECT_FALSE(info
->all_ids
);
133 EXPECT_FALSE(info
->accepts_tls_channel_id
);
135 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://example.com")));
136 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://example.com/")));
137 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://example.com/index.html")));
139 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com")));
140 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com/")));
141 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://google.com/index.html")));
142 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://www.google.com")));
143 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://www.google.com/")));
144 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://google.com")));
145 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://google.com/")));
147 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
148 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org/")));
150 info
->matches
.MatchesURL(GURL("http://build.chromium.org/index.html")));
151 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("https://build.chromium.org")));
152 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("https://build.chromium.org/")));
154 info
->matches
.MatchesURL(GURL("http://foo.chromium.org/index.html")));
156 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://yahoo.com")));
157 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://yahoo.com/")));
160 TEST_F(ExternallyConnectableTest
, MatchesWithTlsChannelId
) {
161 scoped_refptr
<Extension
> extension
= LoadAndExpectSuccess(
162 "externally_connectable_matches_tls_channel_id.json");
163 ASSERT_TRUE(extension
.get());
165 EXPECT_TRUE(extension
->permissions_data()->HasAPIPermission(
166 APIPermission::kWebConnectable
));
168 ExternallyConnectableInfo
* info
=
169 ExternallyConnectableInfo::Get(extension
.get());
172 EXPECT_THAT(info
->ids
, ElementsAre());
174 EXPECT_FALSE(info
->all_ids
);
176 EXPECT_TRUE(info
->accepts_tls_channel_id
);
178 // The matches portion of the manifest is identical to those in
179 // externally_connectable_matches, so only a subset of the Matches tests is
181 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://example.com")));
182 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://example.com/index.html")));
185 TEST_F(ExternallyConnectableTest
, AllIDs
) {
186 scoped_refptr
<Extension
> extension
=
187 LoadAndExpectSuccess("externally_connectable_all_ids.json");
188 ASSERT_TRUE(extension
.get());
190 EXPECT_FALSE(extension
->permissions_data()->HasAPIPermission(
191 APIPermission::kWebConnectable
));
193 ExternallyConnectableInfo
* info
=
194 ExternallyConnectableInfo::Get(extension
.get());
197 EXPECT_THAT(info
->ids
,
198 ElementsAre("abcdefghijklmnopabcdefghijklmnop",
199 "ponmlkjihgfedcbaponmlkjihgfedcba"));
201 EXPECT_TRUE(info
->all_ids
);
203 EXPECT_FALSE(info
->matches
.MatchesURL(GURL("http://google.com/index.html")));
206 TEST_F(ExternallyConnectableTest
, IdCanConnect
) {
207 // Not in order to test that ExternallyConnectableInfo sorts it.
208 std::string matches_ids_array
[] = {"g", "h", "c", "i", "a", "z", "b"};
209 std::vector
<std::string
> matches_ids(
210 matches_ids_array
, matches_ids_array
+ arraysize(matches_ids_array
));
212 std::string nomatches_ids_array
[] = {"2", "3", "1"};
216 ExternallyConnectableInfo
info(URLPatternSet(), matches_ids
, false, false);
217 for (size_t i
= 0; i
< matches_ids
.size(); ++i
)
218 EXPECT_TRUE(info
.IdCanConnect(matches_ids
[i
]));
219 for (size_t i
= 0; i
< arraysize(nomatches_ids_array
); ++i
)
220 EXPECT_FALSE(info
.IdCanConnect(nomatches_ids_array
[i
]));
225 ExternallyConnectableInfo
info(URLPatternSet(), matches_ids
, true, false);
226 for (size_t i
= 0; i
< matches_ids
.size(); ++i
)
227 EXPECT_TRUE(info
.IdCanConnect(matches_ids
[i
]));
228 for (size_t i
= 0; i
< arraysize(nomatches_ids_array
); ++i
)
229 EXPECT_TRUE(info
.IdCanConnect(nomatches_ids_array
[i
]));
233 TEST_F(ExternallyConnectableTest
, ErrorWrongFormat
) {
234 LoadAndExpectError("externally_connectable_error_wrong_format.json",
235 "expected dictionary, got string");
238 TEST_F(ExternallyConnectableTest
, ErrorBadID
) {
240 "externally_connectable_bad_id.json",
241 ErrorUtils::FormatErrorMessage(errors::kErrorInvalidId
, "badid"));
244 TEST_F(ExternallyConnectableTest
, ErrorBadMatches
) {
245 LoadAndExpectError("externally_connectable_error_bad_matches.json",
246 ErrorUtils::FormatErrorMessage(
247 errors::kErrorInvalidMatchPattern
, "www.yahoo.com"));
250 TEST_F(ExternallyConnectableTest
, WarningNoAllURLs
) {
251 scoped_refptr
<Extension
> extension
= LoadAndExpectWarning(
252 "externally_connectable_error_all_urls.json",
253 ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed
,
255 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
256 EXPECT_FALSE(info
->matches
.MatchesAllURLs());
257 EXPECT_FALSE(info
->matches
.ContainsPattern(
258 URLPattern(URLPattern::SCHEME_ALL
, "<all_urls>")));
259 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
260 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
263 TEST_F(ExternallyConnectableTest
, AllURLsNotWhitelisted
) {
264 scoped_refptr
<Extension
> extension
= LoadAndExpectSuccess(
265 "externally_connectable_all_urls_not_whitelisted.json");
266 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
267 EXPECT_FALSE(info
->matches
.MatchesAllURLs());
270 TEST_F(ExternallyConnectableTest
, AllURLsWhitelisted
) {
271 scoped_refptr
<Extension
> extension
=
272 LoadAndExpectSuccess("externally_connectable_all_urls_whitelisted.json");
273 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
274 EXPECT_TRUE(info
->matches
.MatchesAllURLs());
275 URLPattern
pattern(URLPattern::SCHEME_ALL
, "<all_urls>");
276 EXPECT_TRUE(info
->matches
.ContainsPattern(pattern
));
277 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
278 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
281 TEST_F(ExternallyConnectableTest
, WarningWildcardHost
) {
282 scoped_refptr
<Extension
> extension
= LoadAndExpectWarning(
283 "externally_connectable_error_wildcard_host.json",
284 ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed
,
286 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
287 EXPECT_FALSE(info
->matches
.ContainsPattern(
288 URLPattern(URLPattern::SCHEME_ALL
, "http://*/*")));
289 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
290 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
293 TEST_F(ExternallyConnectableTest
, WarningNoTLD
) {
294 scoped_refptr
<Extension
> extension
= LoadAndExpectWarning(
295 "externally_connectable_error_tld.json",
296 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed
,
298 "http://*.co.uk/*"));
299 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
300 EXPECT_FALSE(info
->matches
.ContainsPattern(
301 URLPattern(URLPattern::SCHEME_ALL
, "http://*.co.uk/*")));
302 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
303 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
306 TEST_F(ExternallyConnectableTest
, WarningNoEffectiveTLD
) {
307 scoped_refptr
<Extension
> extension
= LoadAndExpectWarning(
308 "externally_connectable_error_effective_tld.json",
309 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed
,
311 "http://*.appspot.com/*"));
312 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
313 EXPECT_FALSE(info
->matches
.ContainsPattern(
314 URLPattern(URLPattern::SCHEME_ALL
, "http://*.appspot.com/*")));
315 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
316 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
319 TEST_F(ExternallyConnectableTest
, WarningUnknownTLD
) {
320 scoped_refptr
<Extension
> extension
= LoadAndExpectWarning(
321 "externally_connectable_error_unknown_tld.json",
322 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed
,
324 "http://*.notatld/*"));
325 ExternallyConnectableInfo
* info
= GetExternallyConnectableInfo(extension
);
326 EXPECT_FALSE(info
->matches
.ContainsPattern(
327 URLPattern(URLPattern::SCHEME_ALL
, "http://*.notatld/*")));
328 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("https://example.com")));
329 EXPECT_TRUE(info
->matches
.MatchesURL(GURL("http://build.chromium.org")));
332 TEST_F(ExternallyConnectableTest
, WarningNothingSpecified
) {
333 LoadAndExpectWarning("externally_connectable_nothing_specified.json",
334 errors::kErrorNothingSpecified
);
337 } // namespace extensions