1 // Copyright 2017 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 <memory>
6 #include <utility>
7
8 #include "base/test/values_test_util.h"
9 #include "components/version_info/version_info.h"
10 #include "extensions/common/features/feature_channel.h"
11 #include "extensions/common/manifest_constants.h"
12 #include "extensions/common/manifest_handlers/action_handlers_handler.h"
13 #include "extensions/common/manifest_test.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace extensions {
17
18 namespace app_runtime = api::app_runtime;
19
20 namespace {
21
22 class ActionHandlersManifestTest : public ManifestTest {
23 protected:
CreateManifest(const std::string & action_handlers)24 ManifestData CreateManifest(const std::string& action_handlers) {
25 base::Value manifest = base::test::ParseJson(R"json({
26 "name": "test",
27 "version": "1",
28 "app": {
29 "background": {
30 "scripts": ["background.js"]
31 }
32 },
33 "manifest_version": 2,
34 "action_handlers": )json" +
35 action_handlers + "}");
36 return ManifestData(std::move(manifest), "test");
37 }
38
39 // Returns all action handlers associated with |extension|.
GetActionHandlers(const Extension * extension)40 std::set<app_runtime::ActionType> GetActionHandlers(
41 const Extension* extension) {
42 ActionHandlersInfo* info = static_cast<ActionHandlersInfo*>(
43 extension->GetManifestData(manifest_keys::kActionHandlers));
44 return info ? info->action_handlers : std::set<app_runtime::ActionType>();
45 }
46
47 // Returns all action handlers associated with |extension|.
GetLockScreenActionHandlers(const Extension * extension)48 std::set<app_runtime::ActionType> GetLockScreenActionHandlers(
49 const Extension* extension) {
50 ActionHandlersInfo* info = static_cast<ActionHandlersInfo*>(
51 extension->GetManifestData(manifest_keys::kActionHandlers));
52 return info ? info->lock_screen_action_handlers
53 : std::set<app_runtime::ActionType>();
54 }
55 };
56
57 } // namespace
58
TEST_F(ActionHandlersManifestTest,InvalidType)59 TEST_F(ActionHandlersManifestTest, InvalidType) {
60 LoadAndExpectError(CreateManifest("32"),
61 manifest_errors::kInvalidActionHandlersType);
62 LoadAndExpectError(CreateManifest("[true]"),
63 manifest_errors::kInvalidActionHandlersType);
64 LoadAndExpectError(CreateManifest(R"(["invalid_handler"])"),
65 manifest_errors::kInvalidActionHandlersActionType);
66 LoadAndExpectError(CreateManifest(R"(["invalid_handler"])"),
67 manifest_errors::kInvalidActionHandlersActionType);
68 LoadAndExpectError(CreateManifest("[{}]"),
69 manifest_errors::kInvalidActionHandlerDictionary);
70 LoadAndExpectError(CreateManifest(R"([{"enabled_on_lock_screen": false}])"),
71 manifest_errors::kInvalidActionHandlerDictionary);
72 LoadAndExpectError(CreateManifest(R"([{"action": "invalid_handler"}])"),
73 manifest_errors::kInvalidActionHandlersActionType);
74 }
75
TEST_F(ActionHandlersManifestTest,VerifyParse)76 TEST_F(ActionHandlersManifestTest, VerifyParse) {
77 scoped_refptr<Extension> none = LoadAndExpectSuccess(CreateManifest("[]"));
78 EXPECT_TRUE(GetActionHandlers(none.get()).empty());
79
80 EXPECT_FALSE(ActionHandlersInfo::HasActionHandler(
81 none.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
82 EXPECT_FALSE(ActionHandlersInfo::HasLockScreenActionHandler(
83 none.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
84
85 scoped_refptr<Extension> new_note =
86 LoadAndExpectSuccess(CreateManifest("[\"new_note\"]"));
87 EXPECT_EQ(
88 std::set<app_runtime::ActionType>{app_runtime::ACTION_TYPE_NEW_NOTE},
89 GetActionHandlers(new_note.get()));
90 EXPECT_TRUE(GetLockScreenActionHandlers(new_note.get()).empty());
91 EXPECT_TRUE(ActionHandlersInfo::HasActionHandler(
92 new_note.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
93 EXPECT_FALSE(ActionHandlersInfo::HasLockScreenActionHandler(
94 new_note.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
95 }
96
TEST_F(ActionHandlersManifestTest,ParseDictionaryActionValues)97 TEST_F(ActionHandlersManifestTest, ParseDictionaryActionValues) {
98 scoped_refptr<Extension> no_enabled_on_lock_screen_key =
99 LoadAndExpectSuccess(CreateManifest(R"([{"action": "new_note"}])"));
100 EXPECT_EQ(
101 std::set<app_runtime::ActionType>{app_runtime::ACTION_TYPE_NEW_NOTE},
102 GetActionHandlers(no_enabled_on_lock_screen_key.get()));
103 EXPECT_TRUE(
104 GetLockScreenActionHandlers(no_enabled_on_lock_screen_key.get()).empty());
105 EXPECT_TRUE(ActionHandlersInfo::HasActionHandler(
106 no_enabled_on_lock_screen_key.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
107 EXPECT_FALSE(ActionHandlersInfo::HasLockScreenActionHandler(
108 no_enabled_on_lock_screen_key.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
109
110 scoped_refptr<Extension> enabled_on_lock_screen_false =
111 LoadAndExpectSuccess(CreateManifest(
112 R"([{"action": "new_note", "enabled_on_lock_screen": false}])"));
113 EXPECT_EQ(
114 std::set<app_runtime::ActionType>{app_runtime::ACTION_TYPE_NEW_NOTE},
115 GetActionHandlers(enabled_on_lock_screen_false.get()));
116 EXPECT_TRUE(
117 GetLockScreenActionHandlers(enabled_on_lock_screen_false.get()).empty());
118 EXPECT_TRUE(ActionHandlersInfo::HasActionHandler(
119 enabled_on_lock_screen_false.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
120 EXPECT_FALSE(ActionHandlersInfo::HasLockScreenActionHandler(
121 enabled_on_lock_screen_false.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
122
123 scoped_refptr<Extension> enabled_on_lock_screen_true =
124 LoadAndExpectSuccess(CreateManifest(
125 R"([{"action": "new_note", "enabled_on_lock_screen": true}])"));
126 EXPECT_EQ(
127 std::set<app_runtime::ActionType>{app_runtime::ACTION_TYPE_NEW_NOTE},
128 GetActionHandlers(enabled_on_lock_screen_true.get()));
129 EXPECT_EQ(
130 std::set<app_runtime::ActionType>{app_runtime::ACTION_TYPE_NEW_NOTE},
131 GetLockScreenActionHandlers(enabled_on_lock_screen_true.get()));
132 EXPECT_TRUE(ActionHandlersInfo::HasActionHandler(
133 enabled_on_lock_screen_true.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
134 EXPECT_TRUE(ActionHandlersInfo::HasLockScreenActionHandler(
135 enabled_on_lock_screen_true.get(), app_runtime::ACTION_TYPE_NEW_NOTE));
136 }
137
TEST_F(ActionHandlersManifestTest,DuplicateHandlers)138 TEST_F(ActionHandlersManifestTest, DuplicateHandlers) {
139 LoadAndExpectError(CreateManifest(R"(["new_note", {"action": "new_note"}])"),
140 manifest_errors::kDuplicateActionHandlerFound);
141 LoadAndExpectError(CreateManifest(
142 R"(["new_note", {
143 "action": "new_note",
144 "enabled_on_lock_screen": true
145 }])"),
146 manifest_errors::kDuplicateActionHandlerFound);
147 LoadAndExpectError(CreateManifest(
148 R"(["new_note", {
149 "action": "new_note",
150 "enabled_on_lock_screen": false
151 }])"),
152 manifest_errors::kDuplicateActionHandlerFound);
153 LoadAndExpectError(CreateManifest(
154 R"([{
155 "action": "new_note"
156 }, {
157 "action": "new_note",
158 "enabled_on_lock_screen": false
159 }])"),
160 manifest_errors::kDuplicateActionHandlerFound);
161 LoadAndExpectError(CreateManifest(
162 R"([{
163 "action": "new_note",
164 "enabled_on_lock_screen": true
165 }, {
166 "action": "new_note",
167 "enabled_on_lock_screen": false
168 }])"),
169 manifest_errors::kDuplicateActionHandlerFound);
170 }
171
172 } // namespace extensions
173