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

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

Powered by Google App Engine
This is Rietveld 408576698