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

Side by Side Diff: extensions/renderer/declarative_event_unittest.cc

Issue 2947463002: [Extensions Bindings] Add a bindings/ subdirectory under renderer (Closed)
Patch Set: . Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « extensions/renderer/declarative_event.cc ('k') | extensions/renderer/event_emitter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "extensions/renderer/declarative_event.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/values.h"
13 #include "extensions/common/extension_api.h"
14 #include "extensions/renderer/api_binding_test.h"
15 #include "extensions/renderer/api_binding_test_util.h"
16 #include "extensions/renderer/api_bindings_system.h"
17 #include "extensions/renderer/api_bindings_system_unittest.h"
18 #include "extensions/renderer/api_last_error.h"
19 #include "extensions/renderer/api_request_handler.h"
20 #include "extensions/renderer/api_type_reference_map.h"
21 #include "extensions/renderer/argument_spec.h"
22 #include "gin/handle.h"
23
24 namespace extensions {
25
26 namespace {
27
28 const char kDeclarativeAPIName[] = "alpha";
29 const char kDeclarativeAPISpec[] =
30 "{"
31 " 'types': [{"
32 " 'id': 'alpha.objRef',"
33 " 'type': 'object',"
34 " 'properties': {"
35 " 'prop1': {'type': 'string'},"
36 " 'prop2': {'type': 'integer', 'optional': true}"
37 " }"
38 " }, {"
39 " 'id': 'alpha.enumRef',"
40 " 'type': 'string',"
41 " 'enum': ['cat', 'dog']"
42 " }],"
43 " 'events': [{"
44 " 'name': 'declarativeEvent',"
45 " 'options': {"
46 " 'supportsRules': true,"
47 " 'supportsListeners': false,"
48 " 'actions': ['alpha.enumRef'],"
49 " 'conditions': ['alpha.objRef']"
50 " }"
51 " }]"
52 "}";
53
54 } // namespace
55
56 class DeclarativeEventTest : public APIBindingTest {
57 public:
58 DeclarativeEventTest()
59 : type_refs_(APITypeReferenceMap::InitializeTypeCallback()) {}
60 ~DeclarativeEventTest() override {}
61
62 void OnRequest(std::unique_ptr<APIRequestHandler::Request> request,
63 v8::Local<v8::Context> context) {
64 last_request_ = std::move(request);
65 }
66
67 APITypeReferenceMap* type_refs() { return &type_refs_; }
68 APIRequestHandler* request_handler() { return request_handler_.get(); }
69 APIRequestHandler::Request* last_request() { return last_request_.get(); }
70 void reset_last_request() { last_request_.reset(); }
71
72 private:
73 void SetUp() override {
74 APIBindingTest::SetUp();
75
76 {
77 auto action1 = base::MakeUnique<ArgumentSpec>(ArgumentType::STRING);
78 action1->set_enum_values({"actionA"});
79 type_refs_.AddSpec("action1", std::move(action1));
80 auto action2 = base::MakeUnique<ArgumentSpec>(ArgumentType::STRING);
81 action2->set_enum_values({"actionB"});
82 type_refs_.AddSpec("action2", std::move(action2));
83 }
84
85 {
86 auto condition = base::MakeUnique<ArgumentSpec>(ArgumentType::OBJECT);
87 auto prop = base::MakeUnique<ArgumentSpec>(ArgumentType::STRING);
88 ArgumentSpec::PropertiesMap props;
89 props["url"] = std::move(prop);
90 condition->set_properties(std::move(props));
91 type_refs_.AddSpec("condition", std::move(condition));
92 }
93
94 request_handler_ = base::MakeUnique<APIRequestHandler>(
95 base::Bind(&DeclarativeEventTest::OnRequest, base::Unretained(this)),
96 base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
97 APILastError(APILastError::GetParent(),
98 APILastError::AddConsoleError()));
99 }
100
101 void TearDown() override {
102 request_handler_.reset();
103 APIBindingTest::TearDown();
104 }
105
106 APITypeReferenceMap type_refs_;
107 std::unique_ptr<APIRequestHandler> request_handler_;
108 std::unique_ptr<APIRequestHandler::Request> last_request_;
109
110 DISALLOW_COPY_AND_ASSIGN(DeclarativeEventTest);
111 };
112
113 // Test that the rules schema behaves properly. This is designed to be more of
114 // a sanity check than a comprehensive test, since it mostly delegates the logic
115 // out to ArgumentSpec.
116 TEST_F(DeclarativeEventTest, TestRulesSchema) {
117 v8::HandleScope handle_scope(isolate());
118 v8::Local<v8::Context> context = MainContext();
119
120 gin::Handle<DeclarativeEvent> emitter = gin::CreateHandle(
121 context->GetIsolate(),
122 new DeclarativeEvent("declEvent", type_refs(), request_handler(),
123 {"action1", "action2"}, {"condition"}, 0));
124
125 v8::Local<v8::Value> emitter_value = emitter.ToV8();
126
127 const char kAddRules[] =
128 "(function(event) {\n"
129 " var rules = %s;\n"
130 " event.addRules(rules);\n"
131 "})";
132
133 {
134 const char kGoodRules[] =
135 "[{id: 'rule', tags: ['tag'],"
136 " actions: ['actionA'],"
137 " conditions: [{url: 'example.com'}],"
138 " priority: 1}]";
139 v8::Local<v8::Function> function =
140 FunctionFromString(context, base::StringPrintf(kAddRules, kGoodRules));
141 v8::Local<v8::Value> args[] = {emitter_value};
142 RunFunctionOnGlobal(function, context, arraysize(args), args);
143
144 EXPECT_TRUE(last_request());
145 reset_last_request();
146 }
147
148 {
149 // Invalid action.
150 const char kBadRules1[] =
151 "[{id: 'rule', tags: ['tag'],"
152 " actions: ['notAnAction'],"
153 " conditions: [{url: 'example.com'}],"
154 " priority: 1}]";
155 // Missing required property: conditions.
156 const char kBadRules2[] =
157 "[{id: 'rule', tags: ['tag'],"
158 " actions: ['actionA'],"
159 " priority: 1}]";
160 // Missing required property: actions.
161 const char kBadRules3[] =
162 "[{id: 'rule', tags: ['tag'],"
163 " conditions: [{url: 'example.com'}],"
164 " priority: 1}]";
165 for (const char* rules : {kBadRules1, kBadRules2, kBadRules3}) {
166 v8::Local<v8::Function> function =
167 FunctionFromString(context, base::StringPrintf(kAddRules, rules));
168 v8::Local<v8::Value> args[] = {emitter_value};
169 RunFunctionAndExpectError(function, context, arraysize(args), args,
170 "Uncaught TypeError: Invalid invocation");
171 EXPECT_FALSE(last_request()) << rules;
172 reset_last_request();
173 }
174 }
175 }
176
177 class DeclarativeEventWithSchemaTest : public APIBindingsSystemTest {
178 protected:
179 DeclarativeEventWithSchemaTest() {}
180 ~DeclarativeEventWithSchemaTest() override {}
181
182 std::vector<FakeSpec> GetAPIs() override {
183 // events.removeRules and events.getRules are specified in the events.json
184 // schema, so we need to load that.
185 base::StringPiece events_schema =
186 ExtensionAPI::GetSharedInstance()->GetSchemaStringPiece("events");
187 return {{kDeclarativeAPIName, kDeclarativeAPISpec},
188 {"events", events_schema.data()}};
189 }
190 };
191
192 // Test all methods of declarative events.
193 TEST_F(DeclarativeEventWithSchemaTest, TestAllMethods) {
194 v8::HandleScope handle_scope(isolate());
195 v8::Local<v8::Context> context = MainContext();
196
197 v8::Local<v8::Object> api = bindings_system()->CreateAPIInstance(
198 kDeclarativeAPIName, context, nullptr);
199 ASSERT_FALSE(api.IsEmpty());
200
201 v8::Local<v8::Value> declarative_event =
202 GetPropertyFromObject(api, context, "declarativeEvent");
203 ASSERT_FALSE(declarative_event.IsEmpty());
204 ASSERT_TRUE(declarative_event->IsObject());
205 v8::Local<v8::Value> add_rules = GetPropertyFromObject(
206 declarative_event.As<v8::Object>(), context, "addRules");
207 ASSERT_FALSE(add_rules.IsEmpty());
208 ASSERT_TRUE(add_rules->IsFunction());
209
210 v8::Local<v8::Value> args[] = {api};
211
212 {
213 const char kAddRules[] =
214 R"((function(obj) {
215 obj.declarativeEvent.addRules(
216 [{
217 id: 'rule',
218 conditions: [{prop1: 'property'}],
219 actions: ['cat'],
220 }]);
221 }))";
222 v8::Local<v8::Function> add_rules = FunctionFromString(context, kAddRules);
223 RunFunctionOnGlobal(add_rules, context, arraysize(args), args);
224 ValidateLastRequest("events.addRules",
225 "['alpha.declarativeEvent',0,"
226 "[{'actions':['cat'],"
227 "'conditions':[{'prop1':'property'}],"
228 "'id':'rule'}]]");
229 reset_last_request();
230 }
231
232 {
233 const char kRemoveRules[] =
234 "(function(obj) {\n"
235 " obj.declarativeEvent.removeRules(['rule']);\n"
236 "})";
237 v8::Local<v8::Function> remove_rules =
238 FunctionFromString(context, kRemoveRules);
239 RunFunctionOnGlobal(remove_rules, context, arraysize(args), args);
240 ValidateLastRequest("events.removeRules",
241 "['alpha.declarativeEvent',0,['rule']]");
242 reset_last_request();
243 }
244
245 {
246 const char kGetRules[] =
247 "(function(obj) {\n"
248 " obj.declarativeEvent.getRules(function() {});\n"
249 "})";
250 v8::Local<v8::Function> remove_rules =
251 FunctionFromString(context, kGetRules);
252 RunFunctionOnGlobal(remove_rules, context, arraysize(args), args);
253 ValidateLastRequest("events.getRules", "['alpha.declarativeEvent',0,null]");
254 reset_last_request();
255 }
256 }
257
258 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/declarative_event.cc ('k') | extensions/renderer/event_emitter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698