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

Side by Side Diff: ios/web/webui/mojo_facade_unittest.mm

Issue 1956113002: [ios Mojo] iOS facade class for Mojo API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tests for Read/Write/Watch Created 4 years, 7 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 | « ios/web/webui/mojo_facade.mm ('k') | no next file » | 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 2016 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 #import "ios/web/webui/mojo_facade.h"
6
7 #include <memory>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/test/ios/wait_util.h"
12 #include "ios/web/test/mojo_test.mojom.h"
13 #include "ios/web/test/web_test.h"
14 #include "ipc/ipc_channel.h"
15 #include "mojo/edk/embedder/embedder.h"
16 #include "mojo/public/cpp/bindings/binding_set.h"
17 #include "services/shell/public/cpp/interface_factory.h"
18 #include "services/shell/public/cpp/interface_registry.h"
19 #import "testing/gtest_mac.h"
20 #import "third_party/ocmock/OCMock/OCMock.h"
21
22 namespace web {
23
24 namespace {
25
26 // Serializes the given |object| to JSON string.
27 std::string GetJson(id object) {
28 NSData* json_as_data =
29 [NSJSONSerialization dataWithJSONObject:object options:0 error:nil];
30 base::scoped_nsobject<NSString> json_as_string([[NSString alloc]
31 initWithData:json_as_data
32 encoding:NSUTF8StringEncoding]);
33 return base::SysNSStringToUTF8(json_as_string);
34 }
35
36 // Deserializes the given |json| to an object.
37 id GetObject(const std::string& json) {
38 NSData* json_as_data =
39 [base::SysUTF8ToNSString(json) dataUsingEncoding:NSUTF8StringEncoding];
40 return [NSJSONSerialization JSONObjectWithData:json_as_data
41 options:0
42 error:nil];
43 }
44
45 // Test mojo handler factory.
46 class TestUIHandlerFactory : public shell::InterfaceFactory<TestUIHandlerMojo> {
47 public:
48 ~TestUIHandlerFactory() override {}
49
50 private:
51 // shell::InterfaceFactory overrides.
52 void Create(shell::Connection* connection,
53 mojo::InterfaceRequest<TestUIHandlerMojo> request) override {}
54 };
55
56 } // namespace
57
58 // A test fixture to test MojoFacade class.
59 class MojoFacadeTest : public WebTest {
60 protected:
61 MojoFacadeTest() {
62 // Initialize Mojo for testing.
63 static dispatch_once_t once_token;
64 dispatch_once(&once_token, ^{
65 mojo::edk::SetMaxMessageSize(IPC::Channel::kMaximumMessageSize);
66 mojo::edk::Init();
Ken Rockot(use gerrit already) 2016/05/15 02:06:41 Please remove these EDK calls from this file and c
Eugene But (OOO till 7-30) 2016/05/16 16:14:57 1.) Moved Mojo initialization to ios/web/test/run_
67 });
68
69 interface_registry_.reset(new shell::InterfaceRegistry(nullptr));
70 interface_registry_->AddInterface(&ui_handler_factory_);
71 evaluator_.reset([[OCMockObject
72 mockForProtocol:@protocol(CRWJSInjectionEvaluator)] retain]);
73 facade_.reset(new MojoFacade(
74 interface_registry_.get(),
75 static_cast<id<CRWJSInjectionEvaluator>>(evaluator_.get())));
76 }
77
78 OCMockObject* evaluator() { return evaluator_.get(); }
79 MojoFacade* facade() { return facade_.get(); }
80
81 private:
82 TestUIHandlerFactory ui_handler_factory_;
83 std::unique_ptr<shell::InterfaceRegistry> interface_registry_;
84 base::scoped_nsobject<OCMockObject> evaluator_;
85 std::unique_ptr<MojoFacade> facade_;
86 };
87
88 // Tests connecting to existing service and closing the handle.
89 TEST_F(MojoFacadeTest, ConnectToServiceAndCloseHandle) {
90 // Connect to the service.
91 NSDictionary* connect = @{
92 @"name" : @"service_provider.connectToService",
93 @"args" : @{
94 @"serviceName" : @"::TestUIHandlerMojo",
95 },
96 };
97
98 std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect));
99 EXPECT_FALSE(handle_as_string.empty());
100 int handle = 0;
101 EXPECT_TRUE(base::StringToInt(handle_as_string, &handle));
102
103 // Close the handle.
104 NSDictionary* close = @{
105 @"name" : @"core.close",
106 @"args" : @{
107 @"handle" : @(handle),
108 },
109 };
110 std::string result_as_string = facade()->HandleMojoMessage(GetJson(close));
111 EXPECT_FALSE(result_as_string.empty());
112 int result = 0;
113 EXPECT_TRUE(base::StringToInt(result_as_string, &result));
114 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
115 }
116
117 // Tests creating a message pipe without options.
118 TEST_F(MojoFacadeTest, CreateMessagePipeWithoutOptions) {
119 // Create a message pipe.
120 NSDictionary* create = @{
121 @"name" : @"core.createMessagePipe",
122 @"args" : @{
123 @"optionsDict" : [NSNull null],
124 },
125 };
126 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
127
128 // Verify handles.
129 EXPECT_FALSE(response_as_string.empty());
130 NSDictionary* response_as_dict = GetObject(response_as_string);
131 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
132 id handle0 = response_as_dict[@"handle0"];
133 EXPECT_TRUE(handle0);
134 id handle1 = response_as_dict[@"handle1"];
135 EXPECT_TRUE(handle1);
136
137 // Close handle0.
138 NSDictionary* close0 = @{
139 @"name" : @"core.close",
140 @"args" : @{
141 @"handle" : handle0,
142 },
143 };
144 std::string result0_as_string = facade()->HandleMojoMessage(GetJson(close0));
145 EXPECT_FALSE(result0_as_string.empty());
146 int result0 = 0;
147 EXPECT_TRUE(base::StringToInt(result0_as_string, &result0));
148 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result0));
149
150 // Close handle1.
151 NSDictionary* close1 = @{
152 @"name" : @"core.close",
153 @"args" : @{
154 @"handle" : handle1,
155 },
156 };
157 std::string result1_as_string = facade()->HandleMojoMessage(GetJson(close1));
158 EXPECT_FALSE(result1_as_string.empty());
159 int result1 = 0;
160 EXPECT_TRUE(base::StringToInt(result1_as_string, &result1));
161 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result1));
162 }
163
164 // Tests watching the pipe.
165 TEST_F(MojoFacadeTest, Watch) {
166 // Create a message pipe.
167 NSDictionary* create = @{
168 @"name" : @"core.createMessagePipe",
169 @"args" : @{
170 @"optionsDict" : [NSNull null],
171 },
172 };
173 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
174
175 // Verify handles.
176 EXPECT_FALSE(response_as_string.empty());
177 NSDictionary* response_as_dict = GetObject(response_as_string);
178 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
179 id handle0 = response_as_dict[@"handle0"];
180 EXPECT_TRUE(handle0);
181 id handle1 = response_as_dict[@"handle1"];
182 EXPECT_TRUE(handle1);
183
184 // Start watching one end of the pipe.
185 int callback_id = 99;
186 NSDictionary* watch = @{
187 @"name" : @"support.watch",
188 @"args" : @{
189 @"handle" : handle0,
190 @"signals" : @(MOJO_HANDLE_SIGNAL_READABLE),
191 @"callbackId" : @(callback_id),
192 },
193 };
194 std::string watch_id_as_string = facade()->HandleMojoMessage(GetJson(watch));
195 EXPECT_FALSE(watch_id_as_string.empty());
196 int watch_id = 0;
197 EXPECT_TRUE(base::StringToInt(watch_id_as_string, &watch_id));
198
199 // Start waiting for the watch callback.
200 __block bool callback_received = false;
201 NSString* expected_script =
202 [NSString stringWithFormat:@"__crWeb.mojo.signalWatch(%d, %d)",
203 callback_id, MOJO_RESULT_OK];
204 [[[evaluator() expect] andDo:^(NSInvocation*) {
205 callback_received = true;
206 }] executeJavaScript:expected_script completionHandler:nil];
207
208 // Write to the other end of the pipe.
209 NSDictionary* write = @{
210 @"name" : @"core.writeMessage",
211 @"args" : @{
212 @"handle" : handle1,
213 @"handles" : @[],
214 @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE),
215 @"buffer" : @{@"0" : @0}
216 },
217 };
218 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write));
219 EXPECT_FALSE(result_as_string.empty());
220 int result = 0;
221 EXPECT_TRUE(base::StringToInt(result_as_string, &result));
222 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
223
224 base::test::ios::WaitUntilCondition(^{
225 return callback_received;
226 }, base::MessageLoop::current(), base::TimeDelta());
227 }
228
229 // Tests reading the message from the pipe.
230 TEST_F(MojoFacadeTest, ReadWrite) {
231 // Create a message pipe.
232 NSDictionary* create = @{
233 @"name" : @"core.createMessagePipe",
234 @"args" : @{
235 @"optionsDict" : [NSNull null],
236 },
237 };
238 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create));
239
240 // Verify handles.
241 EXPECT_FALSE(response_as_string.empty());
242 NSDictionary* response_as_dict = GetObject(response_as_string);
243 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]);
244 id handle0 = response_as_dict[@"handle0"];
245 EXPECT_TRUE(handle0);
246 id handle1 = response_as_dict[@"handle1"];
247 EXPECT_TRUE(handle1);
248
249 // Write to the other end of the pipe.
250 NSDictionary* write = @{
251 @"name" : @"core.writeMessage",
252 @"args" : @{
253 @"handle" : handle1,
254 @"handles" : @[],
255 @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE),
256 @"buffer" : @{@"0" : @9, @"1" : @2, @"2" : @2008}
257 },
258 };
259 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write));
260 EXPECT_FALSE(result_as_string.empty());
261 int result = 0;
262 EXPECT_TRUE(base::StringToInt(result_as_string, &result));
263 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result));
264
265 // Read the message from the pipe.
266 NSDictionary* read = @{
267 @"name" : @"core.readMessage",
268 @"args" : @{
269 @"handle" : handle0,
270 @"flags" : @(MOJO_READ_MESSAGE_FLAG_NONE),
271 },
272 };
273 NSDictionary* message = GetObject(facade()->HandleMojoMessage(GetJson(read)));
274 EXPECT_TRUE([message isKindOfClass:[NSDictionary class]]);
275 EXPECT_TRUE(message);
276 NSArray* expected_message = @[ @9, @2, @216 ]; // 2008 does not fit 8-bit.
277 EXPECT_NSEQ(expected_message, message[@"buffer"]);
278 EXPECT_FALSE([message[@"handles"] count]);
279 EXPECT_EQ(MOJO_RESULT_OK, [message[@"result"] unsignedIntValue]);
280 }
281
282 } // namespace web
OLDNEW
« no previous file with comments | « ios/web/webui/mojo_facade.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698