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 "chrome/common/extensions/features/feature_channel.h"
8 #include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
9 #include "extensions/common/error_utils.h"
10 #include "extensions/common/manifest_constants.h"
11 #include "extensions/common/manifest_handlers/externally_connectable.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 ExtensionManifestTest {
23 ExternallyConnectableTest() : channel_(chrome::VersionInfo::CHANNEL_DEV) {}
26 ExternallyConnectableInfo* GetExternallyConnectableInfo(
27 scoped_refptr<Extension> extension) {
28 return static_cast<ExternallyConnectableInfo*>(
29 extension->GetManifestData(manifest_keys::kExternallyConnectable));
33 ScopedCurrentChannel channel_;
36 TEST_F(ExternallyConnectableTest, IDsAndMatches) {
37 scoped_refptr<Extension> extension =
38 LoadAndExpectSuccess("externally_connectable_ids_and_matches.json");
39 ASSERT_TRUE(extension.get());
41 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
43 ExternallyConnectableInfo* info =
44 ExternallyConnectableInfo::Get(extension.get());
47 EXPECT_THAT(info->ids,
48 ElementsAre("abcdefghijklmnopabcdefghijklmnop",
49 "ponmlkjihgfedcbaponmlkjihgfedcba"));
51 EXPECT_FALSE(info->all_ids);
53 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
54 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
55 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
57 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
58 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
59 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
60 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
61 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
62 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
63 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
65 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
66 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
68 info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
69 EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
70 EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
72 info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
74 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
75 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
77 // TLD-style patterns should match just the TLD.
78 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://appspot.com/foo.html")));
79 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://com")));
80 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://go/here")));
82 // TLD-style patterns should *not* match any subdomains of the TLD.
84 info->matches.MatchesURL(GURL("http://codereview.appspot.com/foo.html")));
86 info->matches.MatchesURL(GURL("http://chromium.com/index.html")));
87 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://here.go/somewhere")));
89 // Paths that don't have any wildcards should match the exact domain, but
90 // ignore the trailing slash. This is kind of a corner case, so let's test it.
91 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path")));
92 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path/")));
94 info->matches.MatchesURL(GURL("http://no.wildcard.path/index.html")));
97 TEST_F(ExternallyConnectableTest, IDs) {
98 scoped_refptr<Extension> extension =
99 LoadAndExpectSuccess("externally_connectable_ids.json");
100 ASSERT_TRUE(extension.get());
102 EXPECT_FALSE(extension->HasAPIPermission(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->HasAPIPermission(APIPermission::kWebConnectable));
124 ExternallyConnectableInfo* info =
125 ExternallyConnectableInfo::Get(extension.get());
128 EXPECT_THAT(info->ids, ElementsAre());
130 EXPECT_FALSE(info->all_ids);
132 EXPECT_FALSE(info->accepts_tls_channel_id);
134 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
135 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
136 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
138 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
139 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
140 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
141 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
142 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
143 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
144 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
146 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
147 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
149 info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
150 EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
151 EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
153 info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
155 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
156 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
159 TEST_F(ExternallyConnectableTest, MatchesWithTlsChannelId) {
160 scoped_refptr<Extension> extension = LoadAndExpectSuccess(
161 "externally_connectable_matches_tls_channel_id.json");
162 ASSERT_TRUE(extension.get());
164 EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
166 ExternallyConnectableInfo* info =
167 ExternallyConnectableInfo::Get(extension.get());
170 EXPECT_THAT(info->ids, ElementsAre());
172 EXPECT_FALSE(info->all_ids);
174 EXPECT_TRUE(info->accepts_tls_channel_id);
176 // The matches portion of the manifest is identical to those in
177 // externally_connectable_matches, so only a subset of the Matches tests is
179 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
180 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
183 TEST_F(ExternallyConnectableTest, AllIDs) {
184 scoped_refptr<Extension> extension =
185 LoadAndExpectSuccess("externally_connectable_all_ids.json");
186 ASSERT_TRUE(extension.get());
188 EXPECT_FALSE(extension->HasAPIPermission(APIPermission::kWebConnectable));
190 ExternallyConnectableInfo* info =
191 ExternallyConnectableInfo::Get(extension.get());
194 EXPECT_THAT(info->ids,
195 ElementsAre("abcdefghijklmnopabcdefghijklmnop",
196 "ponmlkjihgfedcbaponmlkjihgfedcba"));
198 EXPECT_TRUE(info->all_ids);
200 EXPECT_FALSE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
203 TEST_F(ExternallyConnectableTest, IdCanConnect) {
204 // Not in order to test that ExternallyConnectableInfo sorts it.
205 std::string matches_ids_array[] = {"g", "h", "c", "i", "a", "z", "b"};
206 std::vector<std::string> matches_ids(
207 matches_ids_array, matches_ids_array + arraysize(matches_ids_array));
209 std::string nomatches_ids_array[] = {"2", "3", "1"};
213 ExternallyConnectableInfo info(URLPatternSet(), matches_ids, false, false);
214 for (size_t i = 0; i < matches_ids.size(); ++i)
215 EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
216 for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
217 EXPECT_FALSE(info.IdCanConnect(nomatches_ids_array[i]));
222 ExternallyConnectableInfo info(URLPatternSet(), matches_ids, true, false);
223 for (size_t i = 0; i < matches_ids.size(); ++i)
224 EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
225 for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
226 EXPECT_TRUE(info.IdCanConnect(nomatches_ids_array[i]));
230 TEST_F(ExternallyConnectableTest, ErrorWrongFormat) {
231 LoadAndExpectError("externally_connectable_error_wrong_format.json",
232 "expected dictionary, got string");
235 TEST_F(ExternallyConnectableTest, ErrorBadID) {
237 "externally_connectable_bad_id.json",
238 ErrorUtils::FormatErrorMessage(errors::kErrorInvalidId, "badid"));
241 TEST_F(ExternallyConnectableTest, ErrorBadMatches) {
242 LoadAndExpectError("externally_connectable_error_bad_matches.json",
243 ErrorUtils::FormatErrorMessage(
244 errors::kErrorInvalidMatchPattern, "www.yahoo.com"));
247 TEST_F(ExternallyConnectableTest, WarningNoAllURLs) {
248 scoped_refptr<Extension> extension = LoadAndExpectWarning(
249 "externally_connectable_error_all_urls.json",
250 ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
252 ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
253 EXPECT_FALSE(info->matches.ContainsPattern(
254 URLPattern(URLPattern::SCHEME_ALL, "<all_urls>")));
255 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
256 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
259 TEST_F(ExternallyConnectableTest, WarningWildcardHost) {
260 scoped_refptr<Extension> extension = LoadAndExpectWarning(
261 "externally_connectable_error_wildcard_host.json",
262 ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
264 ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
265 EXPECT_FALSE(info->matches.ContainsPattern(
266 URLPattern(URLPattern::SCHEME_ALL, "http://*/*")));
267 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
268 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
271 TEST_F(ExternallyConnectableTest, WarningNoTLD) {
272 scoped_refptr<Extension> extension = LoadAndExpectWarning(
273 "externally_connectable_error_tld.json",
274 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
276 "http://*.co.uk/*"));
277 ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
278 EXPECT_FALSE(info->matches.ContainsPattern(
279 URLPattern(URLPattern::SCHEME_ALL, "http://*.co.uk/*")));
280 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
281 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
284 TEST_F(ExternallyConnectableTest, WarningNoEffectiveTLD) {
285 scoped_refptr<Extension> extension = LoadAndExpectWarning(
286 "externally_connectable_error_effective_tld.json",
287 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
289 "http://*.appspot.com/*"));
290 ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
291 EXPECT_FALSE(info->matches.ContainsPattern(
292 URLPattern(URLPattern::SCHEME_ALL, "http://*.appspot.com/*")));
293 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
294 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
297 TEST_F(ExternallyConnectableTest, WarningUnknownTLD) {
298 scoped_refptr<Extension> extension = LoadAndExpectWarning(
299 "externally_connectable_error_unknown_tld.json",
300 ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
302 "http://*.notatld/*"));
303 ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
304 EXPECT_FALSE(info->matches.ContainsPattern(
305 URLPattern(URLPattern::SCHEME_ALL, "http://*.notatld/*")));
306 EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
307 EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
310 TEST_F(ExternallyConnectableTest, WarningNothingSpecified) {
311 LoadAndExpectWarning("externally_connectable_nothing_specified.json",
312 errors::kErrorNothingSpecified);
315 } // namespace extensions