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 "chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h"
7 #include "apps/saved_files_service.h"
8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/test_extension_system.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "extensions/common/extension_builder.h"
17 #include "extensions/common/manifest.h"
18 #include "extensions/common/permissions/permission_set.h"
19 #include "extensions/common/permissions/permissions_data.h"
20 #include "grit/extensions_strings.h"
21 #include "testing/gmock/include/gmock/gmock-matchers.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/base/l10n/l10n_util.h"
27 const char kTestExtensionId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
32 using testing::Contains;
35 class AppInfoPermissionsPanelTest : public testing::Test {
37 AppInfoPermissionsPanelTest() {}
39 scoped_ptr<base::DictionaryValue> ValidAppManifest() {
40 return extensions::DictionaryBuilder()
41 .Set("name", "Test App Name")
42 .Set("version", "2.0")
43 .Set("manifest_version", 2)
45 extensions::DictionaryBuilder().Set(
47 extensions::DictionaryBuilder().Set(
49 extensions::ListBuilder().Append("background.js"))))
53 TestingProfile profile_;
55 // We need the UI thread in order to construct UI elements in the view.
56 content::TestBrowserThreadBundle thread_bundle_;
59 // Tests that an app with no permissions is treated correctly.
60 TEST_F(AppInfoPermissionsPanelTest, NoPermissionsObtainedCorrectly) {
61 scoped_refptr<const extensions::Extension> app =
62 extensions::ExtensionBuilder()
63 .SetManifest(ValidAppManifest())
64 .SetID(kTestExtensionId)
66 AppInfoPermissionsPanel panel(&profile_, app.get());
68 EXPECT_TRUE(panel.GetActivePermissionMessages().empty());
69 EXPECT_TRUE(panel.GetRetainedFilePaths().empty());
72 // Tests that an app's required permissions are detected and converted to
73 // messages correctly.
74 TEST_F(AppInfoPermissionsPanelTest, RequiredPermissionsObtainedCorrectly) {
75 scoped_refptr<const extensions::Extension> app =
76 extensions::ExtensionBuilder()
77 .SetManifest(ValidAppManifest())
78 .MergeManifest(extensions::DictionaryBuilder().Set(
80 extensions::ListBuilder()
81 .Append("desktopCapture") // A valid permission with a
83 .Append("bad_perm") // An invalid permission
84 .Append("notifications") // An valid permission with
86 .Append("serial"))) // Another valid permission with
88 .SetID(kTestExtensionId)
90 AppInfoPermissionsPanel panel(&profile_, app.get());
92 const std::vector<PermissionStringAndDetailsPair> permission_messages =
93 panel.GetActivePermissionMessages();
94 ASSERT_EQ(2U, permission_messages.size());
96 l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_DESKTOP_CAPTURE),
97 base::UTF16ToUTF8(permission_messages[0].first));
98 EXPECT_EQ(0U, permission_messages[0].second.size());
99 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_SERIAL),
100 base::UTF16ToUTF8(permission_messages[1].first));
101 EXPECT_EQ(0U, permission_messages[1].second.size());
104 // Tests that an app's optional permissions are detected and converted to
105 // messages correctly.
106 TEST_F(AppInfoPermissionsPanelTest, OptionalPermissionsObtainedCorrectly) {
107 scoped_refptr<const extensions::Extension> app =
108 extensions::ExtensionBuilder()
109 .SetManifest(ValidAppManifest())
110 .MergeManifest(extensions::DictionaryBuilder().Set(
111 "optional_permissions",
112 extensions::ListBuilder()
113 .Append("clipboardRead") // A valid permission with a
115 .Append("bad_perm") // An invalid permission
116 .Append("idle") // A valid permission with
118 .Append("serial"))) // Another valid permission with
120 .SetID(kTestExtensionId)
122 AppInfoPermissionsPanel panel(&profile_, app.get());
124 // Optional permissions don't appear until they are 'activated' at runtime.
125 // TODO(sashab): Activate the optional permissions and ensure they are
126 // successfully added to the dialog.
127 EXPECT_TRUE(panel.GetActivePermissionMessages().empty());
128 EXPECT_TRUE(panel.GetRetainedFilePaths().empty());
131 // Tests that an app's retained files are detected and converted to paths
133 TEST_F(AppInfoPermissionsPanelTest, RetainedFilePermissionsObtainedCorrectly) {
134 scoped_refptr<const extensions::Extension> app =
135 extensions::ExtensionBuilder()
136 .SetManifest(ValidAppManifest())
137 .MergeManifest(extensions::DictionaryBuilder().Set(
139 extensions::ListBuilder().Append(
140 extensions::DictionaryBuilder().Set(
142 extensions::ListBuilder().Append("retainEntries")))))
143 .SetID(kTestExtensionId)
145 AppInfoPermissionsPanel panel(&profile_, app.get());
146 apps::SavedFilesService* files_service =
147 apps::SavedFilesService::Get(&profile_);
148 files_service->RegisterFileEntry(
149 app->id(), "file_id_1", FilePath(FILE_PATH_LITERAL("file_1.ext")), false);
150 files_service->RegisterFileEntry(
151 app->id(), "file_id_2", FilePath(FILE_PATH_LITERAL("file_2.ext")), false);
152 files_service->RegisterFileEntry(
153 app->id(), "file_id_3", FilePath(FILE_PATH_LITERAL("file_3.ext")), false);
155 ASSERT_TRUE(panel.GetActivePermissionMessages().empty());
157 // Since we have no guarantees on the order of retained files, make sure the
158 // list is the expected length and all required entries are present.
159 const std::vector<base::string16> retained_file_paths =
160 panel.GetRetainedFilePaths();
161 ASSERT_EQ(3U, retained_file_paths.size());
162 EXPECT_THAT(retained_file_paths,
163 Contains(Eq(base::UTF8ToUTF16("file_1.ext"))));
164 EXPECT_THAT(retained_file_paths,
165 Contains(Eq(base::UTF8ToUTF16("file_2.ext"))));
166 EXPECT_THAT(retained_file_paths,
167 Contains(Eq(base::UTF8ToUTF16("file_3.ext"))));