OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "base/memory/scoped_ptr.h" | |
6 #include "chrome/browser/extensions/extension_service.h" | |
7 #include "chrome/browser/extensions/extension_service_test_base.h" | |
8 #include "chrome/browser/extensions/permissions_updater.h" | |
9 #include "chrome/browser/profiles/profile.h" | |
10 #include "chrome/common/extensions/permissions/chrome_permission_message_provide r.h" | |
11 #include "chrome/grit/generated_resources.h" | |
12 #include "components/crx_file/id_util.h" | |
13 #include "extensions/browser/extension_prefs.h" | |
14 #include "extensions/browser/extension_registry.h" | |
15 #include "extensions/common/extension_builder.h" | |
16 #include "extensions/common/manifest.h" | |
17 #include "extensions/common/manifest_handlers/permissions_parser.h" | |
18 #include "extensions/common/permissions/permissions_data.h" | |
19 #include "extensions/common/test_util.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 #include "ui/base/l10n/l10n_util.h" | |
22 | |
23 namespace extensions { | |
24 | |
25 // Tests that ChromePermissionMessageProvider provides not only correct, but | |
26 // meaningful permission messages that coalesce correctly where appropriate. | |
27 // There are 3 types of permission messages that need to be tested: | |
28 // 1. The combined list of active permissions, displayed at install time (or | |
29 // when the app has been disabled automatically and needs to be re-enabled) | |
30 // 2. The split list of active permissions, displayed in the App Info dialog, | |
31 // where the optional permissions are individually revokable | |
32 // 3. The list of requested optional permissions, displayed in a prompt to the | |
33 // user when the app requests these during runtime | |
34 // Some of these tests are currently 'anti-tests' - they demonstrate existing | |
scheib
2014/09/25 17:55:44
Call out the naming convention:
"Some of these tes
sashab
2014/09/29 08:03:35
Done.
| |
35 // problematic functionality. These tests are prefixed with AntiTest_ and will | |
36 // be changed as the correct behaviour is implemented. TODOs in the test explain | |
37 // the currently problematic behaviour. | |
38 class PermissionMessagesUnittest : public ExtensionServiceTestBase { | |
scheib
2014/09/25 17:55:44
Cite the existence of this test suite at the top o
sashab
2014/09/29 08:03:36
Good idea. Done.
| |
39 public: | |
40 PermissionMessagesUnittest() | |
41 : message_provider_(new ChromePermissionMessageProvider()) {} | |
42 virtual ~PermissionMessagesUnittest() {} | |
43 | |
44 // Overridden from testing::Test: | |
45 virtual void SetUp() OVERRIDE { | |
46 ExtensionServiceTestBase::SetUp(); | |
47 InitializeExtensionService(CreateDefaultInitParams()); | |
48 InitializeProcessManager(); | |
49 } | |
50 | |
51 protected: | |
52 void CreateAndInstallAppWithPermissions(ListBuilder& required_permissions, | |
53 ListBuilder& optional_permissions) { | |
54 app_ = test_util::BuildApp(ExtensionBuilder().Pass()) | |
55 .MergeManifest( | |
56 DictionaryBuilder() | |
57 .Set("permissions", required_permissions) | |
58 .Set("optional_permissions", optional_permissions)) | |
59 .SetID(crx_file::id_util::GenerateId("app")) | |
60 .SetLocation(Manifest::INTERNAL) | |
61 .Build(); | |
62 service()->AddExtension(app_.get()); | |
63 } | |
64 | |
65 void CreateAndInstallExtensionWithPermissions( | |
66 ListBuilder& required_permissions, | |
67 ListBuilder& optional_permissions) { | |
68 app_ = test_util::BuildExtension(ExtensionBuilder().Pass()) | |
69 .MergeManifest( | |
70 DictionaryBuilder() | |
71 .Set("permissions", required_permissions) | |
72 .Set("optional_permissions", optional_permissions)) | |
73 .SetID(crx_file::id_util::GenerateId("extension")) | |
74 .SetLocation(Manifest::INTERNAL) | |
75 .Build(); | |
76 service()->AddExtension(app_.get()); | |
77 } | |
78 | |
79 // Returns the permission messages that would display in the prompt that | |
80 // requests all the optional permissions for the current |app_|. | |
81 std::vector<base::string16> RequestOptionalPermissions() { | |
scheib
2014/09/25 17:55:44
This name seems a tad confusing to me still. Perha
sashab
2014/09/29 08:03:35
Changed to GetOptionalPermissionMessages() :)
| |
82 scoped_refptr<const PermissionSet> granted_permissions = | |
83 ExtensionPrefs::Get(profile())->GetGrantedPermissions(app_->id()); | |
84 scoped_refptr<const PermissionSet> optional_permissions = | |
85 PermissionsParser::GetOptionalPermissions(app_.get()); | |
86 scoped_refptr<const PermissionSet> requested_permissions = | |
87 PermissionSet::CreateDifference(optional_permissions.get(), | |
88 granted_permissions.get()); | |
89 return GetMessages(requested_permissions); | |
90 } | |
91 | |
92 void GrantOptionalPermissions() { | |
93 PermissionsUpdater perms_updater(profile()); | |
94 perms_updater.AddPermissions( | |
95 app_.get(), | |
96 PermissionsParser::GetOptionalPermissions(app_.get()).get()); | |
97 } | |
98 | |
99 std::vector<base::string16> active_permissions() { | |
100 return GetMessages(app_->permissions_data()->active_permissions()); | |
101 } | |
102 | |
103 std::vector<base::string16> withheld_permissions() { | |
104 return GetMessages(app_->permissions_data()->withheld_permissions()); | |
105 } | |
106 | |
107 std::vector<base::string16> granted_permissions() { | |
108 return GetMessages( | |
109 ExtensionPrefs::Get(profile())->GetGrantedPermissions(app_->id())); | |
110 } | |
111 | |
112 std::vector<base::string16> required_permissions() { | |
113 return GetMessages(PermissionsParser::GetRequiredPermissions(app_.get())); | |
114 } | |
115 | |
116 std::vector<base::string16> optional_permissions() { | |
117 return GetMessages(PermissionsParser::GetOptionalPermissions(app_.get())); | |
118 } | |
119 | |
120 private: | |
121 std::vector<base::string16> GetMessages( | |
122 scoped_refptr<const PermissionSet> permissions) { | |
123 return message_provider_->GetWarningMessages(permissions.get(), | |
124 app_->GetType()); | |
125 } | |
126 | |
127 scoped_ptr<ChromePermissionMessageProvider> message_provider_; | |
128 scoped_refptr<const Extension> app_; | |
129 | |
130 DISALLOW_COPY_AND_ASSIGN(PermissionMessagesUnittest); | |
131 }; | |
132 | |
133 // If an app has both the 'serial' and 'USB' permission, they should coalesce | |
134 // into a single permission message. | |
135 TEST_F(PermissionMessagesUnittest, RequiredPermissionMessagesCoalesce) { | |
136 CreateAndInstallAppWithPermissions( | |
137 ListBuilder().Append("serial").Append("usb").Pass(), | |
138 ListBuilder().Pass()); | |
139 | |
140 ASSERT_EQ(1U, required_permissions().size()); | |
141 EXPECT_EQ(l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL), | |
142 required_permissions()[0]); | |
143 | |
144 ASSERT_EQ(0U, optional_permissions().size()); | |
145 } | |
146 | |
147 // If an app has both the 'history' and 'tabs' permission, one should hide the | |
148 // other (the 'history' permission has superset permissions). | |
149 TEST_F(PermissionMessagesUnittest, HistoryHidesTabsMessage) { | |
150 CreateAndInstallExtensionWithPermissions( | |
151 ListBuilder().Append("tabs").Append("history").Pass(), | |
152 ListBuilder().Pass()); | |
153 | |
154 ASSERT_EQ(1U, required_permissions().size()); | |
155 EXPECT_EQ( | |
156 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
157 required_permissions()[0]); | |
158 | |
159 ASSERT_EQ(0U, optional_permissions().size()); | |
160 } | |
161 | |
162 // If an app requests the 'history' permission, but already has the 'tabs' | |
163 // permission, only the new coalesced message is displayed. | |
164 TEST_F(PermissionMessagesUnittest, MixedPermissionMessagesCoalesceOnceGranted) { | |
165 CreateAndInstallExtensionWithPermissions( | |
166 ListBuilder().Append("tabs").Pass(), | |
167 ListBuilder().Append("history").Pass()); | |
168 | |
169 ASSERT_EQ(1U, required_permissions().size()); | |
170 EXPECT_EQ( | |
171 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
172 required_permissions()[0]); | |
173 | |
174 ASSERT_EQ(1U, optional_permissions().size()); | |
175 EXPECT_EQ( | |
176 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
177 optional_permissions()[0]); | |
178 | |
179 ASSERT_EQ(1U, active_permissions().size()); | |
180 EXPECT_EQ( | |
181 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
182 active_permissions()[0]); | |
183 | |
184 ASSERT_EQ(1U, RequestOptionalPermissions().size()); | |
185 EXPECT_EQ( | |
186 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
187 RequestOptionalPermissions()[0]); | |
188 | |
189 GrantOptionalPermissions(); | |
190 | |
191 ASSERT_EQ(1U, active_permissions().size()); | |
192 EXPECT_EQ( | |
193 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
194 active_permissions()[0]); | |
195 } | |
196 | |
197 // If an app requests the 'tabs' permission but already has the 'history' | |
198 // permission, a prompt is displayed to request this permission, but it doesn't | |
199 // appear in the final list of permissions since it is a subset of an already | |
200 // granted permission. | |
scheib
2014/09/25 17:55:44
Call out more explicitly what is 'AntiTest' about
sashab
2014/09/29 08:03:36
Thanks. Updated both.
| |
201 TEST_F(PermissionMessagesUnittest, | |
202 AntiTest_PromptCanRequestSubsetOfAlreadyGrantedPermissions) { | |
203 CreateAndInstallExtensionWithPermissions( | |
204 ListBuilder().Append("history").Pass(), | |
205 ListBuilder().Append("tabs").Pass()); | |
206 | |
207 ASSERT_EQ(1U, required_permissions().size()); | |
208 EXPECT_EQ( | |
209 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
210 required_permissions()[0]); | |
211 | |
212 ASSERT_EQ(1U, optional_permissions().size()); | |
213 EXPECT_EQ( | |
214 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
215 optional_permissions()[0]); | |
216 | |
217 ASSERT_EQ(1U, active_permissions().size()); | |
218 EXPECT_EQ( | |
219 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
220 active_permissions()[0]); | |
221 | |
222 // TODO(sashab): This prompt should display no permissions, since READ is a | |
223 // subset permission of WRITE. | |
224 ASSERT_EQ(1U, RequestOptionalPermissions().size()); | |
225 EXPECT_EQ( | |
226 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
227 RequestOptionalPermissions()[0]); | |
228 | |
229 GrantOptionalPermissions(); | |
230 | |
231 ASSERT_EQ(1U, active_permissions().size()); | |
232 EXPECT_EQ( | |
233 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE), | |
234 active_permissions()[0]); | |
235 } | |
236 | |
237 // If an app requests the 'sessions' permission, nothing is displayed in the | |
238 // permission request prompt, but the required permissions for the app are | |
239 // actually modified. | |
240 TEST_F(PermissionMessagesUnittest, | |
241 AntiTest_PromptCanBeEmptyButCausesChangeInPermissions) { | |
242 CreateAndInstallExtensionWithPermissions( | |
243 ListBuilder().Append("tabs").Pass(), | |
244 ListBuilder().Append("sessions").Pass()); | |
245 | |
246 ASSERT_EQ(1U, required_permissions().size()); | |
247 EXPECT_EQ( | |
248 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
249 required_permissions()[0]); | |
250 | |
251 ASSERT_EQ(0U, optional_permissions().size()); | |
252 | |
253 ASSERT_EQ(1U, active_permissions().size()); | |
254 EXPECT_EQ( | |
255 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ), | |
256 active_permissions()[0]); | |
257 | |
258 // TODO(sashab): This prompt should display the sessions permission message, | |
259 // as well as warn the user that it can affect the existing 'tab' permission. | |
260 ASSERT_EQ(0U, RequestOptionalPermissions().size()); | |
261 | |
262 GrantOptionalPermissions(); | |
263 | |
264 ASSERT_EQ(1U, active_permissions().size()); | |
265 EXPECT_EQ(l10n_util::GetStringUTF16( | |
266 IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS), | |
267 active_permissions()[0]); | |
268 } | |
269 | |
270 } // namespace extensions | |
OLD | NEW |