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