Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9406)

Unified Diff: chrome/common/extensions/permissions/chrome_permission_message_provider_unittest.cc

Issue 594003002: Added unit tests for ChromePermissionMessageProvider (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | extensions/common/test_util.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/extensions/permissions/chrome_permission_message_provider_unittest.cc
diff --git a/chrome/common/extensions/permissions/chrome_permission_message_provider_unittest.cc b/chrome/common/extensions/permissions/chrome_permission_message_provider_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..26e803824293f0d2cbf62fb4919a5c422589dae1
--- /dev/null
+++ b/chrome/common/extensions/permissions/chrome_permission_message_provider_unittest.cc
@@ -0,0 +1,333 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_service_test_base.h"
+#include "chrome/browser/extensions/permissions_updater.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/crx_file/id_util.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/extension_builder.h"
+#include "extensions/common/manifest.h"
+#include "extensions/common/manifest_handlers/permissions_parser.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
sashab 2014/09/23 04:52:56 Some of these #includes violate checkdeps rules:
scheib 2014/09/23 17:10:54 Looking into this raises a few questions: 1. Shou
sashab 2014/09/24 23:23:49 I'm actually really glad you brought this up - it
+
+namespace extensions {
+
+// Tests that ChromePermissionMessageProvider provides not only correct, but
+// meaningful permission messages.
+// There are two main types of permission messages generated that we need to
+// test:
+// 1. The full set of required permissions, displayed at install time (or when
+// the app has been disabled automatically and needs to be re-enabled)
+// 2. The various combinations of optional permissions, displayed in a prompt
+// when confirming the permission during runtime
+// 3. The split set of required/optional permissions, as displayed in the App
+// Info dialog, where the optional permissions are individually revokable.
+// Some of these tests are currently 'anti-tests' - they demonstrate existing
scheib 2014/09/23 17:10:54 Which ones? Can I search this file for TODO or 'An
sashab 2014/09/24 23:23:49 Preceded them with 'AntiTest_'.
+// problematic functionality. These tests will be changed as the correct
+// behaviour is implemented.
+class ChromePermissionMessageProviderUnittest
+ : public ExtensionServiceTestBase {
+ public:
+ ChromePermissionMessageProviderUnittest()
+ : message_provider_(new ChromePermissionMessageProvider()) {}
+ virtual ~ChromePermissionMessageProviderUnittest() {}
+
+ // Overridden from testing::Test:
+ virtual void SetUp() OVERRIDE {
+ ExtensionServiceTestBase::SetUp();
+ InitializeExtensionService(CreateDefaultInitParams());
+ InitializeProcessManager();
+ }
+
+ protected:
+ // Overridden from views::WidgetObserver:
+ void InstallApp(Profile* profile, const Extension* app) {
+ service()->AddExtension(app);
+ }
+
+ void UninstallApp(const std::string& app_id) {
+ service()->UninstallExtension(app_id,
+ UninstallReason::UNINSTALL_REASON_FOR_TESTING,
+ base::Closure(),
+ NULL);
+ }
+
+ void CreateAppWithPermissions(const std::string id_seed,
scheib 2014/09/23 17:10:54 Do we need an id_seed that varies between tests? C
sashab 2014/09/24 23:23:48 Now uses a constant.
+ ListBuilder& required_permissions,
+ ListBuilder& optional_permissions) {
+ app_ = test_util::BuildApp(ExtensionBuilder().Pass())
+ .MergeManifest(
+ DictionaryBuilder()
+ .Set("permissions", required_permissions)
+ .Set("optional_permissions", optional_permissions))
+ .SetID(crx_file::id_util::GenerateId(id_seed))
+ .SetLocation(Manifest::INTERNAL)
+ .Build();
+ }
+
+ void CreateExtensionWithPermissions(const std::string id_seed,
scheib 2014/09/23 17:10:54 ditto for id_seed here
sashab 2014/09/24 23:23:49 Done.
+ ListBuilder& required_permissions,
+ ListBuilder& optional_permissions) {
+ app_ = test_util::BuildExtension(ExtensionBuilder().Pass())
+ .MergeManifest(
+ DictionaryBuilder()
+ .Set("permissions", required_permissions)
+ .Set("optional_permissions", optional_permissions))
+ .SetID(crx_file::id_util::GenerateId(id_seed))
+ .SetLocation(Manifest::INTERNAL)
+ .Build();
+ }
+
+ scoped_refptr<PermissionSet> PermissionSetFromAPIPermissions(
+ APIPermissionSet& permissions) {
+ scoped_refptr<PermissionSet> permission_set = new PermissionSet(
+ permissions, ManifestPermissionSet(), URLPatternSet(), URLPatternSet());
+ return permission_set;
+ }
+
+ // Returns the permission messages that would display in the prompt that
+ // requests the given permissions for the current |app_|.
+ std::vector<base::string16> OptionalPermissionsRequestPromptMessages(
+ APIPermissionSet& permissions) {
+ scoped_refptr<PermissionSet> permission_set = new PermissionSet(
+ permissions, ManifestPermissionSet(), URLPatternSet(), URLPatternSet());
+ permission_set = PermissionSet::CreateDifference(
+ permission_set.get(), granted_permissions().get());
+ return message_provider_->GetWarningMessages(permission_set.get(),
+ app_->GetType());
+ }
+
+ void GrantPermissions(scoped_refptr<const PermissionSet> permissions) {
+ PermissionsUpdater perms_updater(profile());
+ perms_updater.AddPermissions(app_.get(), permissions.get());
+ }
+
+ scoped_refptr<const PermissionSet> active_permissions() {
+ return app_->permissions_data()->active_permissions();
+ }
+
+ scoped_refptr<const PermissionSet> withheld_permissions() {
+ return app_->permissions_data()->withheld_permissions();
+ }
+
+ scoped_refptr<const PermissionSet> granted_permissions() {
+ return ExtensionPrefs::Get(profile())->GetGrantedPermissions(app_->id());
+ }
+
+ scoped_refptr<const PermissionSet> required_permissions() {
+ return PermissionsParser::GetRequiredPermissions(app_.get());
+ }
+
+ scoped_refptr<const PermissionSet> optional_permissions() {
+ return PermissionsParser::GetOptionalPermissions(app_.get());
+ }
+
+ std::vector<base::string16> messages(
scheib 2014/09/23 17:10:54 Simplify test code by having the 'required_permiss
sashab 2014/09/24 23:23:48 Good idea. Done :)
+ scoped_refptr<const PermissionSet> permissions) {
+ return message_provider_->GetWarningMessages(permissions.get(),
+ app_->GetType());
+ }
+
+ scoped_ptr<ChromePermissionMessageProvider> message_provider_;
+ scoped_refptr<const Extension> app_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChromePermissionMessageProviderUnittest);
+};
+
+// If an app has both the 'serial' and 'USB' permission, they should coalesce
+// into a single permission message.
+TEST_F(ChromePermissionMessageProviderUnittest,
+ RequiredPermissionMessagesCoalesce) {
+ CreateAppWithPermissions("app",
+ ListBuilder().Append("serial").Append("usb").Pass(),
+ ListBuilder().Pass());
+ service()->AddExtension(app_.get());
+
+ std::vector<base::string16> required_permission_messages =
+ messages(required_permissions());
+ ASSERT_EQ(1U, required_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_USB_SERIAL),
+ base::UTF16ToUTF8(required_permission_messages[0]));
+
+ std::vector<base::string16> optional_permission_messages =
+ messages(optional_permissions());
+ ASSERT_EQ(0U, optional_permission_messages.size());
+}
+
+// If an app has both the 'history' and 'tabs' permission, one should hide the
+// other (the 'history' permission has superset permissions).
+TEST_F(ChromePermissionMessageProviderUnittest, HistoryHidesTabsMessage) {
+ CreateExtensionWithPermissions(
+ "app",
+ ListBuilder().Append("tabs").Append("history").Pass(),
+ ListBuilder().Pass());
+ service()->AddExtension(app_.get());
+
+ std::vector<base::string16> required_permission_messages =
+ messages(required_permissions());
+ ASSERT_EQ(1U, required_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(required_permission_messages[0]));
+
+ std::vector<base::string16> optional_permission_messages =
+ messages(optional_permissions());
+ ASSERT_EQ(0U, optional_permission_messages.size());
+}
+
+// If an app requests the 'history' permission, but already has the 'tabs'
+// permission, only the new coalesced message is displayed.
+TEST_F(ChromePermissionMessageProviderUnittest,
+ MixedPermissionMessagesCoalesceOnceGranted) {
+ CreateExtensionWithPermissions("app",
+ ListBuilder().Append("tabs").Pass(),
+ ListBuilder().Append("history").Pass());
+ service()->AddExtension(app_.get());
+
+ std::vector<base::string16> required_permission_messages =
+ messages(required_permissions());
+ ASSERT_EQ(1U, required_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(required_permission_messages[0]));
+
+ std::vector<base::string16> optional_permission_messages =
+ messages(optional_permissions());
+ ASSERT_EQ(1U, optional_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(optional_permission_messages[0]));
+
+ std::vector<base::string16> active_permission_messages =
+ messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+
+ APIPermissionSet requested_optional_permissions;
+ requested_optional_permissions.insert(APIPermission::kHistory);
+ std::vector<base::string16> requested_optional_permission_messages =
+ OptionalPermissionsRequestPromptMessages(requested_optional_permissions);
+ ASSERT_EQ(1U, requested_optional_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(requested_optional_permission_messages[0]));
+
+ GrantPermissions(
+ PermissionSetFromAPIPermissions(requested_optional_permissions));
+
+ active_permission_messages = messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+}
+
+// If an app requests the 'tabs' permission but already has the 'history'
+// permission, a prompt is displayed to request this permission, but it doesn't
+// appear in the final list of permissions since it is a subset of an already
+// granted permission.
+TEST_F(ChromePermissionMessageProviderUnittest,
+ PromptCanRequestSubsetOfAlreadyGrantedPermissions) {
+ CreateExtensionWithPermissions("app",
+ ListBuilder().Append("history").Pass(),
+ ListBuilder().Append("tabs").Pass());
+ service()->AddExtension(app_.get());
+
+ std::vector<base::string16> required_permission_messages =
+ messages(required_permissions());
+ ASSERT_EQ(1U, required_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(required_permission_messages[0]));
+
+ std::vector<base::string16> optional_permission_messages =
+ messages(optional_permissions());
+ ASSERT_EQ(1U, optional_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(optional_permission_messages[0]));
+
+ std::vector<base::string16> active_permission_messages =
+ messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+
+ APIPermissionSet requested_optional_permissions;
+ requested_optional_permissions.insert(APIPermission::kTab);
+ std::vector<base::string16> requested_optional_permission_messages =
+ OptionalPermissionsRequestPromptMessages(requested_optional_permissions);
+ // TODO(sashab): This prompt should display no permissions, since READ is a
+ // subset permission of WRITE.
+ ASSERT_EQ(1U, requested_optional_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(requested_optional_permission_messages[0]));
+
+ GrantPermissions(
+ PermissionSetFromAPIPermissions(requested_optional_permissions));
+
+ active_permission_messages = messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+}
+
+// If an app requests the 'sessions' permission, nothing is displayed in the
+// permission request prompt, but the required permissions for the app are
+// actually modified.
+TEST_F(ChromePermissionMessageProviderUnittest,
+ PromptCanBeEmptyButCausesChangeInPermissions) {
+ CreateExtensionWithPermissions("app",
+ ListBuilder().Append("tabs").Pass(),
+ ListBuilder().Append("sessions").Pass());
+ service()->AddExtension(app_.get());
+
+ std::vector<base::string16> required_permission_messages =
+ messages(required_permissions());
+ ASSERT_EQ(1U, required_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(required_permission_messages[0]));
+
+ std::vector<base::string16> optional_permission_messages =
+ messages(optional_permissions());
+ ASSERT_EQ(0U, optional_permission_messages.size());
+
+ std::vector<base::string16> active_permission_messages =
+ messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+
+ APIPermissionSet requested_optional_permissions;
+ requested_optional_permissions.insert(APIPermission::kSessions);
+ std::vector<base::string16> requested_optional_permission_messages =
+ OptionalPermissionsRequestPromptMessages(requested_optional_permissions);
+ // TODO(sashab): This prompt should display the sessions permission message,
+ // as well as warn the user that it can affect the existing 'tab' permission.
+ ASSERT_EQ(0U, requested_optional_permission_messages.size());
+
+ GrantPermissions(
+ PermissionSetFromAPIPermissions(requested_optional_permissions));
+
+ active_permission_messages = messages(active_permissions());
+ ASSERT_EQ(1U, active_permission_messages.size());
+ EXPECT_EQ(l10n_util::GetStringUTF8(
+ IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_AND_SESSIONS),
+ base::UTF16ToUTF8(active_permission_messages[0]));
+}
+
+} // namespace extensions
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | extensions/common/test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698