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.
5 #include "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/values_test_util.h"
11 #include "chrome/browser/extensions/test_extension_environment.h"
12 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/permissions/permissions_data.h"
15 #include "extensions/common/switches.h"
16 #include "testing/gmock/include/gmock/gmock-matchers.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using testing::Contains
;
22 namespace extensions
{
24 // Tests that ChromePermissionMessageProvider produces the expected messages for
25 // various combinations of app/extension permissions.
26 class PermissionMessageCombinationsUnittest
: public testing::Test
{
28 PermissionMessageCombinationsUnittest()
29 : message_provider_(new ChromePermissionMessageProvider()) {}
30 ~PermissionMessageCombinationsUnittest() override
{}
32 // Overridden from testing::Test:
33 void SetUp() override
{
34 testing::Test::SetUp();
35 // Force creation of ExtensionPrefs before adding extensions.
36 env_
.GetExtensionPrefs();
40 // Create and install an app or extension with the given manifest JSON string.
41 // Single-quotes in the string will be replaced with double quotes.
42 void CreateAndInstall(const std::string
& json_manifest
) {
43 std::string json_manifest_with_double_quotes
= json_manifest
;
44 std::replace(json_manifest_with_double_quotes
.begin(),
45 json_manifest_with_double_quotes
.end(), '\'', '"');
46 app_
= env_
.MakeExtension(
47 *base::test::ParseJson(json_manifest_with_double_quotes
));
48 // Add the app to any whitelists so we can test all permissions.
49 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
50 switches::kWhitelistedExtensionID
, app_
->id());
53 // Checks whether the currently installed app or extension produces the given
54 // permission messages. Call this after installing an app with the expected
55 // permission messages. The messages are tested for existence in any order.
56 testing::AssertionResult
CheckManifestProducesPermissions() {
57 return CheckManifestProducesPermissions(
58 std::vector
<std::string
>(), GetPermissionMessages(),
59 GetCoalescedPermissionMessages(), "messages");
61 testing::AssertionResult
CheckManifestProducesPermissions(
62 const std::string
& expected_message_1
) {
63 std::vector
<std::string
> expected_messages
;
64 expected_messages
.push_back(expected_message_1
);
65 return CheckManifestProducesPermissions(
66 expected_messages
, GetPermissionMessages(),
67 GetCoalescedPermissionMessages(), "messages");
69 testing::AssertionResult
CheckManifestProducesPermissions(
70 const std::string
& expected_message_1
,
71 const std::string
& expected_message_2
) {
72 std::vector
<std::string
> expected_messages
;
73 expected_messages
.push_back(expected_message_1
);
74 expected_messages
.push_back(expected_message_2
);
75 return CheckManifestProducesPermissions(
76 expected_messages
, GetPermissionMessages(),
77 GetCoalescedPermissionMessages(), "messages");
79 testing::AssertionResult
CheckManifestProducesPermissions(
80 const std::string
& expected_message_1
,
81 const std::string
& expected_message_2
,
82 const std::string
& expected_message_3
) {
83 std::vector
<std::string
> expected_messages
;
84 expected_messages
.push_back(expected_message_1
);
85 expected_messages
.push_back(expected_message_2
);
86 expected_messages
.push_back(expected_message_3
);
87 return CheckManifestProducesPermissions(
88 expected_messages
, GetPermissionMessages(),
89 GetCoalescedPermissionMessages(), "messages");
91 testing::AssertionResult
CheckManifestProducesPermissions(
92 const std::string
& expected_message_1
,
93 const std::string
& expected_message_2
,
94 const std::string
& expected_message_3
,
95 const std::string
& expected_message_4
) {
96 std::vector
<std::string
> expected_messages
;
97 expected_messages
.push_back(expected_message_1
);
98 expected_messages
.push_back(expected_message_2
);
99 expected_messages
.push_back(expected_message_3
);
100 expected_messages
.push_back(expected_message_4
);
101 return CheckManifestProducesPermissions(
102 expected_messages
, GetPermissionMessages(),
103 GetCoalescedPermissionMessages(), "messages");
105 testing::AssertionResult
CheckManifestProducesPermissions(
106 const std::string
& expected_message_1
,
107 const std::string
& expected_message_2
,
108 const std::string
& expected_message_3
,
109 const std::string
& expected_message_4
,
110 const std::string
& expected_message_5
) {
111 std::vector
<std::string
> expected_messages
;
112 expected_messages
.push_back(expected_message_1
);
113 expected_messages
.push_back(expected_message_2
);
114 expected_messages
.push_back(expected_message_3
);
115 expected_messages
.push_back(expected_message_4
);
116 expected_messages
.push_back(expected_message_5
);
117 return CheckManifestProducesPermissions(
118 expected_messages
, GetPermissionMessages(),
119 GetCoalescedPermissionMessages(), "messages");
122 // Checks whether the currently installed app or extension produces the given
123 // host permission messages. Call this after installing an app with the
124 // expected permission messages. The messages are tested for existence in any
126 testing::AssertionResult
CheckManifestProducesHostPermissions() {
127 return CheckManifestProducesPermissions(
128 std::vector
<std::string
>(), GetHostPermissionMessages(),
129 GetCoalescedHostPermissionMessages(), "host messages");
131 testing::AssertionResult
CheckManifestProducesHostPermissions(
132 const std::string
& expected_message_1
) {
133 std::vector
<std::string
> expected_messages
;
134 expected_messages
.push_back(expected_message_1
);
135 return CheckManifestProducesPermissions(
136 expected_messages
, GetHostPermissionMessages(),
137 GetCoalescedHostPermissionMessages(), "host messages");
139 testing::AssertionResult
CheckManifestProducesHostPermissions(
140 const std::string
& expected_message_1
,
141 const std::string
& expected_message_2
) {
142 std::vector
<std::string
> expected_messages
;
143 expected_messages
.push_back(expected_message_1
);
144 expected_messages
.push_back(expected_message_2
);
145 return CheckManifestProducesPermissions(
146 expected_messages
, GetHostPermissionMessages(),
147 GetCoalescedHostPermissionMessages(), "host messages");
149 testing::AssertionResult
CheckManifestProducesHostPermissions(
150 const std::string
& expected_message_1
,
151 const std::string
& expected_message_2
,
152 const std::string
& expected_message_3
) {
153 std::vector
<std::string
> expected_messages
;
154 expected_messages
.push_back(expected_message_1
);
155 expected_messages
.push_back(expected_message_2
);
156 expected_messages
.push_back(expected_message_3
);
157 return CheckManifestProducesPermissions(
158 expected_messages
, GetHostPermissionMessages(),
159 GetCoalescedHostPermissionMessages(), "host messages");
161 testing::AssertionResult
CheckManifestProducesHostPermissions(
162 const std::string
& expected_message_1
,
163 const std::string
& expected_message_2
,
164 const std::string
& expected_message_3
,
165 const std::string
& expected_message_4
) {
166 std::vector
<std::string
> expected_messages
;
167 expected_messages
.push_back(expected_message_1
);
168 expected_messages
.push_back(expected_message_2
);
169 expected_messages
.push_back(expected_message_3
);
170 expected_messages
.push_back(expected_message_4
);
171 return CheckManifestProducesPermissions(
172 expected_messages
, GetHostPermissionMessages(),
173 GetCoalescedHostPermissionMessages(), "host messages");
175 testing::AssertionResult
CheckManifestProducesHostPermissions(
176 const std::string
& expected_message_1
,
177 const std::string
& expected_message_2
,
178 const std::string
& expected_message_3
,
179 const std::string
& expected_message_4
,
180 const std::string
& expected_message_5
) {
181 std::vector
<std::string
> expected_messages
;
182 expected_messages
.push_back(expected_message_1
);
183 expected_messages
.push_back(expected_message_2
);
184 expected_messages
.push_back(expected_message_3
);
185 expected_messages
.push_back(expected_message_4
);
186 expected_messages
.push_back(expected_message_5
);
187 return CheckManifestProducesPermissions(
188 expected_messages
, GetHostPermissionMessages(),
189 GetCoalescedHostPermissionMessages(), "host messages");
193 std::vector
<base::string16
> GetPermissionMessages() {
194 return app_
->permissions_data()->GetPermissionMessageStrings();
197 std::vector
<base::string16
> GetCoalescedPermissionMessages() {
198 CoalescedPermissionMessages messages
=
199 app_
->permissions_data()->GetCoalescedPermissionMessages();
200 std::vector
<base::string16
> message_strings
;
201 for (const auto& message
: messages
) {
202 message_strings
.push_back(message
.message());
204 return message_strings
;
207 std::vector
<base::string16
> GetHostPermissionMessages() {
208 std::vector
<base::string16
> details
=
209 app_
->permissions_data()->GetPermissionMessageDetailsStrings();
210 // If we have a host permission, exactly one message will contain the
212 for (const auto& host_string
: details
) {
213 if (!host_string
.empty()) {
214 // The host_string will be a newline-separated string of entries.
215 std::vector
<base::string16
> pieces
;
216 base::SplitString(host_string
, base::char16('\n'), &pieces
);
220 return std::vector
<base::string16
>();
223 std::vector
<base::string16
> GetCoalescedHostPermissionMessages() {
224 // If we have a host permission, exactly one message will contain the
226 CoalescedPermissionMessages messages
=
227 app_
->permissions_data()->GetCoalescedPermissionMessages();
228 for (const auto& message
: messages
) {
229 if (!message
.submessages().empty())
230 return message
.submessages();
232 return std::vector
<base::string16
>();
235 // TODO(sashab): Remove the legacy messages from this function once the legacy
236 // messages system is no longer used.
237 testing::AssertionResult
CheckManifestProducesPermissions(
238 const std::vector
<std::string
>& expected_messages
,
239 const std::vector
<base::string16
>& actual_legacy_messages
,
240 const std::vector
<base::string16
>& actual_messages
,
241 const std::string
& message_type_name
) {
242 // Check the new messages system matches the legacy one.
243 if (actual_legacy_messages
.size() != actual_messages
.size()) {
244 // Message: Got 2 messages in the legacy system { "Bar", "Baz" }, but 0 in
246 return testing::AssertionFailure()
247 << "Got " << actual_legacy_messages
.size() << " "
248 << message_type_name
<< " in the legacy system "
249 << MessagesVectorToString(actual_legacy_messages
) << ", but "
250 << actual_messages
.size() << " in the new system "
251 << MessagesVectorToString(actual_messages
);
254 for (const auto& actual_message
: actual_messages
) {
255 if (std::find(actual_legacy_messages
.begin(),
256 actual_legacy_messages
.end(),
257 actual_message
) == actual_legacy_messages
.end()) {
258 // Message: Got { "Foo" } in the legacy messages system, but { "Bar",
259 // "Baz" } in the new system
260 return testing::AssertionFailure()
261 << "Got " << MessagesVectorToString(actual_legacy_messages
)
262 << " in the legacy " << message_type_name
<< " system, but "
263 << MessagesVectorToString(actual_messages
)
264 << " in the new system";
268 // Check the non-legacy & actual messages are equal.
269 if (expected_messages
.size() != actual_messages
.size()) {
270 // Message: Expected 7 messages, got 5
271 return testing::AssertionFailure()
272 << "Expected " << expected_messages
.size() << " "
273 << message_type_name
<< ", got " << actual_messages
.size() << ": "
274 << MessagesVectorToString(actual_messages
);
277 for (const auto& expected_message
: expected_messages
) {
278 if (std::find(actual_messages
.begin(), actual_messages
.end(),
279 base::ASCIIToUTF16(expected_message
)) ==
280 actual_messages
.end()) {
281 // Message: Expected messages to contain "Foo", got { "Bar", "Baz" }
282 return testing::AssertionFailure()
283 << "Expected " << message_type_name
<< " to contain \""
284 << expected_message
<< "\", got "
285 << MessagesVectorToString(actual_messages
);
289 return testing::AssertionSuccess();
292 // Returns the vector of messages in a human-readable string format, e.g.:
294 base::string16
MessagesVectorToString(
295 const std::vector
<base::string16
>& messages
) {
296 if (messages
.empty())
297 return base::ASCIIToUTF16("{}");
298 return base::ASCIIToUTF16("{ \"") +
299 JoinString(messages
, base::ASCIIToUTF16("\", \"")) +
300 base::ASCIIToUTF16("\" }");
303 extensions::TestExtensionEnvironment env_
;
304 scoped_ptr
<ChromePermissionMessageProvider
> message_provider_
;
305 scoped_refptr
<const Extension
> app_
;
307 DISALLOW_COPY_AND_ASSIGN(PermissionMessageCombinationsUnittest
);
310 // Test that the USB, Bluetooth and Serial permissions do not coalesce on their
311 // own, but do coalesce when more than 1 is present.
312 TEST_F(PermissionMessageCombinationsUnittest
, USBSerialBluetoothCoalescing
) {
313 // Test that the USB permission does not coalesce on its own.
318 " 'scripts': ['background.js']"
322 " { 'usbDevices': [{ 'vendorId': 123, 'productId': 456 }] }"
325 ASSERT_TRUE(CheckManifestProducesPermissions(
326 "Access USB devices from an unknown vendor"));
327 ASSERT_TRUE(CheckManifestProducesHostPermissions());
333 " 'scripts': ['background.js']"
337 " { 'usbDevices': [{ 'vendorId': 123, 'productId': 456 }] }"
340 ASSERT_TRUE(CheckManifestProducesPermissions(
341 "Access USB devices from an unknown vendor"));
342 ASSERT_TRUE(CheckManifestProducesHostPermissions());
344 // Test that the serial permission does not coalesce on its own.
349 " 'scripts': ['background.js']"
356 ASSERT_TRUE(CheckManifestProducesPermissions("Access your serial devices"));
357 ASSERT_TRUE(CheckManifestProducesHostPermissions());
359 // Test that the bluetooth permission does not coalesce on its own.
364 " 'scripts': ['background.js']"
369 ASSERT_TRUE(CheckManifestProducesPermissions(
370 "Access information about Bluetooth devices paired with your system and "
371 "discover nearby Bluetooth devices."));
372 ASSERT_TRUE(CheckManifestProducesHostPermissions());
374 // Test that the bluetooth permission does not coalesce on its own, even
375 // when it specifies additional permissions.
380 " 'scripts': ['background.js']"
384 " 'uuids': ['1105', '1106']"
387 ASSERT_TRUE(CheckManifestProducesPermissions(
388 "Access information about Bluetooth devices paired with your system and "
389 "discover nearby Bluetooth devices."));
390 ASSERT_TRUE(CheckManifestProducesHostPermissions());
392 // Test that the USB and Serial permissions coalesce.
397 " 'scripts': ['background.js']"
401 " { 'usbDevices': [{ 'vendorId': 123, 'productId': 456 }] },"
405 ASSERT_TRUE(CheckManifestProducesPermissions(
406 "Access USB devices from an unknown vendor",
407 "Access your serial devices"));
408 ASSERT_TRUE(CheckManifestProducesHostPermissions());
410 // Test that the USB, Serial and Bluetooth permissions coalesce.
415 " 'scripts': ['background.js']"
419 " { 'usbDevices': [{ 'vendorId': 123, 'productId': 456 }] },"
424 ASSERT_TRUE(CheckManifestProducesPermissions(
425 "Access USB devices from an unknown vendor",
426 "Access your Bluetooth and Serial devices"));
427 ASSERT_TRUE(CheckManifestProducesHostPermissions());
429 // Test that the USB, Serial and Bluetooth permissions coalesce even when
430 // Bluetooth specifies multiple additional permissions.
435 " 'scripts': ['background.js']"
439 " { 'usbDevices': [{ 'vendorId': 123, 'productId': 456 }] },"
443 " 'uuids': ['1105', '1106'],"
445 " 'low_energy': true"
448 ASSERT_TRUE(CheckManifestProducesPermissions(
449 "Access USB devices from an unknown vendor",
450 "Access your Bluetooth and Serial devices"));
451 ASSERT_TRUE(CheckManifestProducesHostPermissions());
454 // Test that the History permission takes precedence over the Tabs permission,
455 // and that the Sessions permission modifies this final message.
456 TEST_F(PermissionMessageCombinationsUnittest
, TabsHistorySessionsCoalescing
) {
463 ASSERT_TRUE(CheckManifestProducesPermissions("Read your browsing history"));
464 ASSERT_TRUE(CheckManifestProducesHostPermissions());
469 " 'tabs', 'sessions'"
472 ASSERT_TRUE(CheckManifestProducesPermissions(
473 "Read your browsing history on all your signed-in devices"));
474 ASSERT_TRUE(CheckManifestProducesHostPermissions());
482 ASSERT_TRUE(CheckManifestProducesPermissions(
483 "Read and change your browsing history"));
484 ASSERT_TRUE(CheckManifestProducesHostPermissions());
489 " 'tabs', 'history', 'sessions'"
492 ASSERT_TRUE(CheckManifestProducesPermissions(
493 "Read and change your browsing history on all your signed-in devices"));
494 ASSERT_TRUE(CheckManifestProducesHostPermissions());
497 // Test that the fileSystem permission produces no messages by itself, unless it
498 // has both the 'write' and 'directory' additional permissions, in which case it
499 // displays a message.
500 TEST_F(PermissionMessageCombinationsUnittest
, FileSystemReadWriteCoalescing
) {
505 " 'scripts': ['background.js']"
512 ASSERT_TRUE(CheckManifestProducesPermissions());
513 ASSERT_TRUE(CheckManifestProducesHostPermissions());
519 " 'scripts': ['background.js']"
523 " 'fileSystem', {'fileSystem': ['retainEntries', 'write']}"
526 ASSERT_TRUE(CheckManifestProducesPermissions());
527 ASSERT_TRUE(CheckManifestProducesHostPermissions());
533 " 'scripts': ['background.js']"
537 " 'fileSystem', {'fileSystem': ["
538 " 'retainEntries', 'write', 'directory'"
542 ASSERT_TRUE(CheckManifestProducesPermissions(
543 "Write to files and folders that you open in the application"));
544 ASSERT_TRUE(CheckManifestProducesHostPermissions());
547 // Check that host permission messages are generated correctly when URLs are
548 // entered as permissions.
549 TEST_F(PermissionMessageCombinationsUnittest
, HostsPermissionMessages
) {
553 " 'http://www.blogger.com/',"
556 ASSERT_TRUE(CheckManifestProducesPermissions(
557 "Read and change your data on www.blogger.com"));
558 ASSERT_TRUE(CheckManifestProducesHostPermissions());
563 " 'http://*.google.com/',"
566 ASSERT_TRUE(CheckManifestProducesPermissions(
567 "Read and change your data on all google.com sites"));
568 ASSERT_TRUE(CheckManifestProducesHostPermissions());
573 " 'http://www.blogger.com/',"
574 " 'http://*.google.com/',"
577 ASSERT_TRUE(CheckManifestProducesPermissions(
578 "Read and change your data on all google.com sites and "
580 ASSERT_TRUE(CheckManifestProducesHostPermissions());
585 " 'http://www.blogger.com/',"
586 " 'http://*.google.com/',"
587 " 'http://*.news.com/',"
590 ASSERT_TRUE(CheckManifestProducesPermissions(
591 "Read and change your data on all google.com sites, all news.com sites, "
592 "and www.blogger.com"));
593 ASSERT_TRUE(CheckManifestProducesHostPermissions());
598 " 'http://www.blogger.com/',"
599 " 'http://*.google.com/',"
600 " 'http://*.news.com/',"
601 " 'http://www.foobar.com/',"
604 ASSERT_TRUE(CheckManifestProducesPermissions(
605 "Read and change your data on a number of websites"));
606 ASSERT_TRUE(CheckManifestProducesHostPermissions(
607 "All google.com sites", "All news.com sites", "www.blogger.com",
613 " 'http://www.blogger.com/',"
614 " 'http://*.google.com/',"
615 " 'http://*.news.com/',"
616 " 'http://www.foobar.com/',"
617 " 'http://*.go.com/',"
620 ASSERT_TRUE(CheckManifestProducesPermissions(
621 "Read and change your data on a number of websites"));
622 ASSERT_TRUE(CheckManifestProducesHostPermissions(
623 "All go.com sites", "All google.com sites", "All news.com sites",
624 "www.blogger.com", "www.foobar.com"));
629 " 'http://*.go.com/',"
630 " 'chrome://favicon/',"
633 ASSERT_TRUE(CheckManifestProducesPermissions(
634 "Read and change your data on all go.com sites",
635 "Read the icons of the websites you visit"));
636 ASSERT_TRUE(CheckManifestProducesHostPermissions());
638 // Having the 'all sites' permission doesn't change the permission message,
639 // since its pseudo-granted at runtime.
643 " 'http://*.go.com/',"
644 " 'chrome://favicon/',"
648 ASSERT_TRUE(CheckManifestProducesPermissions(
649 "Read and change your data on all go.com sites",
650 "Read the icons of the websites you visit"));
651 ASSERT_TRUE(CheckManifestProducesHostPermissions());
654 // Check that permission messages are generated correctly for
655 // SocketsManifestPermission, which has host-like permission messages.
656 TEST_F(PermissionMessageCombinationsUnittest
,
657 SocketsManifestPermissionMessages
) {
662 " 'scripts': ['background.js']"
666 " 'udp': {'send': '*'},"
669 ASSERT_TRUE(CheckManifestProducesPermissions(
670 "Exchange data with any computer on the local network or internet"));
671 ASSERT_TRUE(CheckManifestProducesHostPermissions());
677 " 'scripts': ['background.js']"
681 " 'udp': {'send': ':99'},"
684 ASSERT_TRUE(CheckManifestProducesPermissions(
685 "Exchange data with any computer on the local network or internet"));
686 ASSERT_TRUE(CheckManifestProducesHostPermissions());
692 " 'scripts': ['background.js']"
696 " 'tcp': {'connect': '127.0.0.1:80'},"
699 ASSERT_TRUE(CheckManifestProducesPermissions(
700 "Exchange data with the computer named 127.0.0.1"));
701 ASSERT_TRUE(CheckManifestProducesHostPermissions());
707 " 'scripts': ['background.js']"
711 " 'tcp': {'connect': 'www.example.com:23'},"
714 ASSERT_TRUE(CheckManifestProducesPermissions(
715 "Exchange data with the computer named www.example.com"));
716 ASSERT_TRUE(CheckManifestProducesHostPermissions());
722 " 'scripts': ['background.js']"
726 " 'tcpServer': {'listen': '127.0.0.1:80'}"
729 ASSERT_TRUE(CheckManifestProducesPermissions(
730 "Exchange data with the computer named 127.0.0.1"));
731 ASSERT_TRUE(CheckManifestProducesHostPermissions());
737 " 'scripts': ['background.js']"
741 " 'tcpServer': {'listen': ':8080'}"
744 ASSERT_TRUE(CheckManifestProducesPermissions(
745 "Exchange data with any computer on the local network or internet"));
746 ASSERT_TRUE(CheckManifestProducesHostPermissions());
752 " 'scripts': ['background.js']"
760 " 'www.example.com:*',"
761 " 'www.foo.com:200',"
767 ASSERT_TRUE(CheckManifestProducesPermissions(
768 "Exchange data with the computers named: 127.0.0.1 www.bar.com "
769 "www.example.com www.foo.com www.google.com"));
770 ASSERT_TRUE(CheckManifestProducesHostPermissions());
776 " 'scripts': ['background.js']"
783 " 'www.mywebsite.com:320',"
784 " 'www.freestuff.com',"
793 " 'www.example.com:*',"
794 " 'www.foo.com:200',"
799 ASSERT_TRUE(CheckManifestProducesPermissions(
800 "Exchange data with the computers named: 127.0.0.1 www.abc.com "
801 "www.example.com www.foo.com www.freestuff.com www.google.com "
802 "www.mywebsite.com www.test.com"));
803 ASSERT_TRUE(CheckManifestProducesHostPermissions());
809 " 'scripts': ['background.js']"
813 " 'tcp': {'send': '*:*'},"
814 " 'tcpServer': {'listen': '*:*'},"
817 ASSERT_TRUE(CheckManifestProducesPermissions(
818 "Exchange data with any computer on the local network or internet"));
819 ASSERT_TRUE(CheckManifestProducesHostPermissions());
822 // Check that permission messages are generated correctly for
823 // MediaGalleriesPermission (an API permission with custom messages).
824 TEST_F(PermissionMessageCombinationsUnittest
,
825 MediaGalleriesPermissionMessages
) {
830 " 'scripts': ['background.js']"
834 " { 'mediaGalleries': ['read'] }"
837 ASSERT_TRUE(CheckManifestProducesPermissions());
838 ASSERT_TRUE(CheckManifestProducesHostPermissions());
844 " 'scripts': ['background.js']"
848 " { 'mediaGalleries': ['read', 'allAutoDetected'] }"
851 ASSERT_TRUE(CheckManifestProducesPermissions(
852 "Access photos, music, and other media from your computer"));
853 ASSERT_TRUE(CheckManifestProducesHostPermissions());
855 // TODO(sashab): Add a test for the
856 // IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ_WRITE message (generated
857 // with the 'read' and 'copyTo' permissions, but not the 'delete' permission),
858 // if it's possible to get this message. Otherwise, remove it from the code.
864 " 'scripts': ['background.js']"
868 " { 'mediaGalleries': ['read', 'delete', 'allAutoDetected'] }"
871 ASSERT_TRUE(CheckManifestProducesPermissions(
872 "Read and delete photos, music, and other media from your computer"));
873 ASSERT_TRUE(CheckManifestProducesHostPermissions());
879 " 'scripts': ['background.js']"
883 " { 'mediaGalleries':"
884 " [ 'read', 'delete', 'copyTo', 'allAutoDetected' ] }"
887 ASSERT_TRUE(CheckManifestProducesPermissions(
888 "Read, change and delete photos, music, and other media from your "
890 ASSERT_TRUE(CheckManifestProducesHostPermissions());
892 // Without the allAutoDetected permission, there should be no install-time
893 // permission messages.
898 " 'scripts': ['background.js']"
902 " { 'mediaGalleries': ['read', 'delete', 'copyTo'] }"
905 ASSERT_TRUE(CheckManifestProducesPermissions());
906 ASSERT_TRUE(CheckManifestProducesHostPermissions());
909 // TODO(sashab): Add tests for SettingsOverrideAPIPermission (an API permission
910 // with custom messages).
912 // Check that permission messages are generated correctly for SocketPermission
913 // (an API permission with custom messages).
914 TEST_F(PermissionMessageCombinationsUnittest
, SocketPermissionMessages
) {
919 " 'scripts': ['background.js']"
923 " { 'socket': ['tcp-connect:*:*'] }"
926 ASSERT_TRUE(CheckManifestProducesPermissions(
927 "Exchange data with any computer on the local network or internet"));
928 ASSERT_TRUE(CheckManifestProducesHostPermissions());
934 " 'scripts': ['background.js']"
939 " 'tcp-connect:*:443',"
940 " 'tcp-connect:*:50032',"
941 " 'tcp-connect:*:23',"
945 ASSERT_TRUE(CheckManifestProducesPermissions(
946 "Exchange data with any computer on the local network or internet"));
947 ASSERT_TRUE(CheckManifestProducesHostPermissions());
953 " 'scripts': ['background.js']"
957 " { 'socket': ['tcp-connect:foo.example.com:443'] }"
960 ASSERT_TRUE(CheckManifestProducesPermissions(
961 "Exchange data with the computer named foo.example.com"));
962 ASSERT_TRUE(CheckManifestProducesHostPermissions());
968 " 'scripts': ['background.js']"
972 " { 'socket': ['tcp-connect:foo.example.com:443', 'udp-send-to'] }"
975 ASSERT_TRUE(CheckManifestProducesPermissions(
976 "Exchange data with any computer on the local network or internet"));
977 ASSERT_TRUE(CheckManifestProducesHostPermissions());
983 " 'scripts': ['background.js']"
988 " 'tcp-connect:foo.example.com:443',"
989 " 'udp-send-to:test.ping.com:50032',"
993 ASSERT_TRUE(CheckManifestProducesPermissions(
994 "Exchange data with the computers named: foo.example.com test.ping.com"));
995 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1001 " 'scripts': ['background.js']"
1006 " 'tcp-connect:foo.example.com:443',"
1007 " 'udp-send-to:test.ping.com:50032',"
1008 " 'udp-send-to:www.ping.com:50032',"
1009 " 'udp-send-to:test2.ping.com:50032',"
1010 " 'udp-bind:test.ping.com:50032',"
1014 ASSERT_TRUE(CheckManifestProducesPermissions(
1015 "Exchange data with the computers named: foo.example.com test.ping.com "
1016 "test2.ping.com www.ping.com"));
1017 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1023 " 'scripts': ['background.js']"
1028 " 'tcp-connect:foo.example.com:443',"
1029 " 'udp-send-to:test.ping.com:50032',"
1030 " 'tcp-connect:*:23',"
1034 ASSERT_TRUE(CheckManifestProducesPermissions(
1035 "Exchange data with any computer on the local network or internet"));
1036 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1039 // Check that permission messages are generated correctly for
1040 // USBDevicePermission (an API permission with custom messages).
1041 TEST_F(PermissionMessageCombinationsUnittest
, USBDevicePermissionMessages
) {
1046 " 'scripts': ['background.js']"
1050 " { 'usbDevices': ["
1051 " { 'vendorId': 0, 'productId': 0 },"
1055 ASSERT_TRUE(CheckManifestProducesPermissions(
1056 "Access USB devices from an unknown vendor"));
1057 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1063 " 'scripts': ['background.js']"
1067 " { 'usbDevices': ["
1068 " { 'vendorId': 4179, 'productId': 529 },"
1072 ASSERT_TRUE(CheckManifestProducesPermissions(
1073 "Access USB devices from Immanuel Electronics Co., Ltd"));
1074 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1080 " 'scripts': ['background.js']"
1084 " { 'usbDevices': ["
1085 " { 'vendorId': 6353, 'productId': 8192 },"
1090 CheckManifestProducesPermissions("Access USB devices from Google Inc."));
1091 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1097 " 'scripts': ['background.js']"
1101 " { 'usbDevices': ["
1102 " { 'vendorId': 4179, 'productId': 529 },"
1103 " { 'vendorId': 6353, 'productId': 8192 },"
1108 CheckManifestProducesPermissions("Access any of these USB devices"));
1110 // Although technically not host permissions, devices are currently stored in
1111 // the 'host permissions' (details list) for the USB permission, in the same
1113 // TODO(sashab): Rename host permissions to 'details list' or 'nested
1114 // permissions', and change this test system to allow specifying each message
1115 // as well as its corresponding nested messages, if any. Also add a test that
1116 // uses this to test an app with multiple nested permission lists (e.g. both
1117 // USB and host permissions).
1118 ASSERT_TRUE(CheckManifestProducesHostPermissions(
1119 "unknown devices from Immanuel Electronics Co., Ltd",
1120 "unknown devices from Google Inc."));
1122 // TODO(sashab): Add a test with a valid product/vendor USB device.
1125 // Test that hosted apps are not given any messages for host permissions.
1126 TEST_F(PermissionMessageCombinationsUnittest
,
1127 PackagedAppsHaveNoHostPermissions
) {
1132 " 'scripts': ['background.js']"
1136 " 'http://www.blogger.com/',"
1137 " 'http://*.google.com/',"
1140 ASSERT_TRUE(CheckManifestProducesPermissions());
1141 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1147 " 'scripts': ['background.js']"
1152 " 'http://www.blogger.com/',"
1153 " 'http://*.google.com/',"
1156 ASSERT_TRUE(CheckManifestProducesPermissions("Access your serial devices"));
1157 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1160 // Test various apps with lots of permissions, including those with no
1161 // permission messages, or those that only apply to apps or extensions even when
1162 // the given manifest is for a different type.
1163 TEST_F(PermissionMessageCombinationsUnittest
, PermissionMessageCombos
) {
1169 " 'http://www.blogger.com/',"
1170 " 'http://*.google.com/',"
1171 " 'unlimitedStorage',"
1174 ASSERT_TRUE(CheckManifestProducesPermissions(
1175 "Read and change your data on all google.com sites and www.blogger.com",
1176 "Read your browsing history", "Read and change your bookmarks"));
1177 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1185 " 'unlimitedStorage',"
1186 " 'syncFileSystem',"
1187 " 'http://www.blogger.com/',"
1188 " 'http://*.google.com/',"
1189 " 'http://*.news.com/',"
1190 " 'http://www.foobar.com/',"
1191 " 'http://*.go.com/',"
1194 ASSERT_TRUE(CheckManifestProducesPermissions(
1195 "Read your browsing history on all your signed-in devices",
1196 "Read and change your bookmarks",
1197 "Read and change your data on a number of websites"));
1198 ASSERT_TRUE(CheckManifestProducesHostPermissions(
1199 "All go.com sites", "All google.com sites", "All news.com sites",
1200 "www.blogger.com", "www.foobar.com"));
1208 " 'accessibilityFeatures.read',"
1209 " 'accessibilityFeatures.modify',"
1213 " 'desktopCapture',"
1217 " 'unlimitedStorage',"
1218 " 'syncFileSystem',"
1219 " 'http://www.blogger.com/',"
1220 " 'http://*.google.com/',"
1221 " 'http://*.news.com/',"
1222 " 'http://www.foobar.com/',"
1223 " 'http://*.go.com/',"
1227 ASSERT_TRUE(CheckManifestProducesPermissions(
1228 "Read your browsing history on all your signed-in devices",
1229 "Capture content of your screen", "Read and change your bookmarks",
1230 "Read and change your data on a number of websites",
1231 "Read and change your accessibility settings"));
1233 ASSERT_TRUE(CheckManifestProducesHostPermissions(
1234 "All go.com sites", "All google.com sites", "All news.com sites",
1235 "www.blogger.com", "www.foobar.com"));
1237 // Create an App instead, ensuring that the host permission messages are not
1243 " 'scripts': ['background.js']"
1249 " 'accessibilityFeatures.read',"
1250 " 'accessibilityFeatures.modify',"
1260 " 'unlimitedStorage',"
1261 " 'syncFileSystem',"
1262 " 'http://www.blogger.com/',"
1263 " 'http://*.google.com/',"
1264 " 'http://*.news.com/',"
1265 " 'http://www.foobar.com/',"
1266 " 'http://*.go.com/',"
1270 ASSERT_TRUE(CheckManifestProducesPermissions(
1271 "Access your serial devices", "Store data in your Google Drive account",
1272 "Read and change your accessibility settings"));
1274 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1277 // Tests that the 'plugin' manifest key produces the correct permission.
1278 TEST_F(PermissionMessageCombinationsUnittest
, PluginPermission
) {
1279 // Extensions can have plugins.
1283 " { 'path': 'extension_plugin.dll' }"
1288 ASSERT_TRUE(CheckManifestProducesPermissions());
1290 ASSERT_TRUE(CheckManifestProducesPermissions(
1291 "Read and change all your data on your computer and the websites you "
1295 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1297 // Apps can't have plugins.
1302 " 'scripts': ['background.js']"
1306 " { 'path': 'extension_plugin.dll' }"
1309 ASSERT_TRUE(CheckManifestProducesPermissions());
1310 ASSERT_TRUE(CheckManifestProducesHostPermissions());
1313 // TODO(sashab): Add a test that checks that messages are generated correctly
1314 // for withheld permissions, when an app is granted the 'all sites' permission.
1316 // TODO(sashab): Add a test that ensures that all permissions that can generate
1317 // a coalesced message can also generate a message on their own (i.e. ensure
1318 // that no permissions only modify other permissions).
1320 // TODO(sashab): Add a test for every permission message combination that can
1321 // generate a message.
1323 // TODO(aboxhall): Add tests for the automation API permission messages.
1325 } // namespace extensions