Chromium Code Reviews| Index: ios/web/webui/mojo_facade_unittest.mm |
| diff --git a/ios/web/webui/mojo_facade_unittest.mm b/ios/web/webui/mojo_facade_unittest.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..69141dc1e838cc2342a3f21fa7d94e1c1fe88e05 |
| --- /dev/null |
| +++ b/ios/web/webui/mojo_facade_unittest.mm |
| @@ -0,0 +1,353 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "ios/web/webui/mojo_facade.h" |
| + |
| +#include <memory> |
| + |
| +#include "base/strings/string_number_conversions.h" |
| +#include "base/strings/sys_string_conversions.h" |
| +#include "ios/web/test/mojo_test.mojom.h" |
| +#include "ios/web/test/web_test.h" |
| +#include "ipc/ipc_channel.h" |
| +#include "mojo/edk/embedder/embedder.h" |
| +#include "mojo/public/cpp/bindings/binding_set.h" |
| +#include "services/shell/public/cpp/interface_factory.h" |
| +#include "services/shell/public/cpp/interface_registry.h" |
| +#import "third_party/ocmock/OCMock/OCMockObject.h" |
| + |
| +namespace web { |
| + |
| +namespace { |
| + |
| +// Serializes the given |object| to JSON string. |
| +std::string GetJson(id object) { |
| + NSData* json_as_data = |
| + [NSJSONSerialization dataWithJSONObject:object options:0 error:nil]; |
| + base::scoped_nsobject<NSString> json_as_string([[NSString alloc] |
| + initWithData:json_as_data |
| + encoding:NSUTF8StringEncoding]); |
| + return base::SysNSStringToUTF8(json_as_string); |
| +} |
| + |
| +// Deserializes the given |json| to an object. |
| +id GetObject(const std::string& json) { |
| + NSData* json_as_data = |
| + [base::SysUTF8ToNSString(json) dataUsingEncoding:NSUTF8StringEncoding]; |
| + return [NSJSONSerialization JSONObjectWithData:json_as_data |
| + options:0 |
| + error:nil]; |
| +} |
| + |
| +// Test mojo handler factory. |
| +class TestUIHandlerFactory : public shell::InterfaceFactory<TestUIHandlerMojo> { |
| + public: |
| + ~TestUIHandlerFactory() override {} |
| + |
| + private: |
| + // shell::InterfaceFactory overrides. |
| + void Create(shell::Connection* connection, |
| + mojo::InterfaceRequest<TestUIHandlerMojo> request) override {} |
| +}; |
| + |
| +} // namespace |
| + |
| +// A test fixture to test MojoFacade class. |
| +class MojoFacadeTest : public WebTest { |
| + protected: |
| + MojoFacadeTest() { |
| + // Initialize Mojo for testing. |
| + static dispatch_once_t once_token; |
| + dispatch_once(&once_token, ^{ |
| + mojo::edk::SetMaxMessageSize(IPC::Channel::kMaximumMessageSize); |
| + mojo::edk::Init(); |
| + }); |
| + |
| + interface_registry_.reset(new shell::InterfaceRegistry(nullptr)); |
| + interface_registry_->AddInterface(&ui_handler_factory_); |
| + evaluator_.reset([[OCMockObject |
| + mockForProtocol:@protocol(CRWJSInjectionEvaluator)] retain]); |
| + facade_.reset(new MojoFacade( |
| + interface_registry_.get(), |
| + static_cast<id<CRWJSInjectionEvaluator>>(evaluator_.get()))); |
| + } |
| + |
| + MojoFacade* facade() { return facade_.get(); } |
| + |
| + private: |
| + TestUIHandlerFactory ui_handler_factory_; |
| + std::unique_ptr<shell::InterfaceRegistry> interface_registry_; |
| + base::scoped_nsobject<OCMockObject> evaluator_; |
| + std::unique_ptr<MojoFacade> facade_; |
| +}; |
| + |
| +// Tests that empty response is returned for an empty message. |
| +TEST_F(MojoFacadeTest, EmptyMessage) { |
| + EXPECT_TRUE(facade()->HandleMojoMessage("").empty()); |
| +} |
| + |
| +// Tests that empty response is returned for non-dict message. |
| +TEST_F(MojoFacadeTest, NonDictMessage) { |
| + id message = @[]; |
| + EXPECT_TRUE(facade()->HandleMojoMessage(GetJson(message)).empty()); |
| +} |
| + |
| +// Tests that empty response is returned for message without "name" key. |
| +TEST_F(MojoFacadeTest, MessageWithoutNameKey) { |
| + id message = @{ |
| + @"args" : @{}, |
| + }; |
| + EXPECT_TRUE(facade()->HandleMojoMessage(GetJson(message)).empty()); |
| +} |
| + |
| +// Tests that empty response is returned for message without "args" key. |
| +TEST_F(MojoFacadeTest, MessageWithoutArgsKey) { |
| + id message = @{ |
| + @"name" : @"", |
| + }; |
| + EXPECT_TRUE(facade()->HandleMojoMessage(GetJson(message)).empty()); |
| +} |
| + |
| +// Tests service_provider.connectToService message without args. |
| +TEST_F(MojoFacadeTest, ConnectToServiceWithoutArgs) { |
| + NSDictionary* connect = @{ |
| + @"name" : @"service_provider.connectToService", |
| + @"args" : @{}, |
| + }; |
| + |
| + std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect)); |
| + EXPECT_TRUE(handle_as_string.empty()); |
| +} |
| + |
| +// Tests connecting to existing service and closing the handle. |
| +TEST_F(MojoFacadeTest, ConnectToServiceAndCloseHandle) { |
| + // Connect to the service. |
| + NSDictionary* connect = @{ |
| + @"name" : @"service_provider.connectToService", |
| + @"args" : @{ |
| + @"serviceName" : @"::TestUIHandlerMojo", |
| + }, |
| + }; |
| + |
| + std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect)); |
| + EXPECT_FALSE(handle_as_string.empty()); |
| + int handle = 0; |
| + EXPECT_TRUE(base::StringToInt(handle_as_string, &handle)); |
| + |
| + // Close the handle. |
| + NSDictionary* close = @{ |
| + @"name" : @"core.close", |
| + @"args" : @{ |
| + @"handle" : @(handle), |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(close)); |
| + EXPECT_FALSE(result_as_string.empty()); |
| + int result = 0; |
| + EXPECT_TRUE(base::StringToInt(result_as_string, &result)); |
| + EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); |
| +} |
| + |
| +// Tests closing handle without args. |
| +TEST_F(MojoFacadeTest, CloseHandleWithoutArgs) { |
| + NSDictionary* close = @{ |
| + @"name" : @"core.close", |
| + @"args" : @{}, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(close)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests closing invalid handle. |
| +TEST_F(MojoFacadeTest, CloseInvalidHandle) { |
| + NSDictionary* close = @{ |
| + @"name" : @"core.close", |
| + @"args" : @{ |
| + @"handle" : @(-1), |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(close)); |
| + EXPECT_FALSE(result_as_string.empty()); |
| + int result = 0; |
| + EXPECT_TRUE(base::StringToInt(result_as_string, &result)); |
| + EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, static_cast<MojoResult>(result)); |
| +} |
| + |
| +// Tests creating a message pipe without args. |
| +TEST_F(MojoFacadeTest, CreateMessagePipeWithoutArgs) { |
| + NSDictionary* create = @{ |
| + @"name" : @"core.createMessagePipe", |
| + @"args" : @{}, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(create)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests creating a message pipe without options. |
| +TEST_F(MojoFacadeTest, CreateMessagePipeWithoutOptions) { |
| + // Create a message pipe. |
| + NSDictionary* create = @{ |
| + @"name" : @"core.createMessagePipe", |
| + @"args" : @{ |
| + @"optionsDict" : [NSNull null], |
| + }, |
| + }; |
| + std::string response_as_string = facade()->HandleMojoMessage(GetJson(create)); |
| + |
| + // Verify handles. |
| + EXPECT_FALSE(response_as_string.empty()); |
| + NSDictionary* response_as_dict = GetObject(response_as_string); |
| + EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]); |
| + id handle0 = response_as_dict[@"handle0"]; |
| + EXPECT_TRUE(handle0); |
| + id handle1 = response_as_dict[@"handle1"]; |
| + EXPECT_TRUE(handle1); |
| + |
| + // Close handle0. |
| + NSDictionary* close0 = @{ |
| + @"name" : @"core.close", |
| + @"args" : @{ |
| + @"handle" : handle0, |
| + }, |
| + }; |
| + std::string result0_as_string = facade()->HandleMojoMessage(GetJson(close0)); |
| + EXPECT_FALSE(result0_as_string.empty()); |
| + int result0 = 0; |
| + EXPECT_TRUE(base::StringToInt(result0_as_string, &result0)); |
| + EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result0)); |
| + |
| + // Close handle1. |
| + NSDictionary* close1 = @{ |
| + @"name" : @"core.close", |
| + @"args" : @{ |
| + @"handle" : handle1, |
| + }, |
| + }; |
| + std::string result1_as_string = facade()->HandleMojoMessage(GetJson(close1)); |
| + EXPECT_FALSE(result1_as_string.empty()); |
| + int result1 = 0; |
| + EXPECT_TRUE(base::StringToInt(result1_as_string, &result1)); |
| + EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result1)); |
| +} |
| + |
| +// Tests writing a message without handle arg. |
| +TEST_F(MojoFacadeTest, WriteMessageWithoutHandleArg) { |
| + NSDictionary* write = @{ |
| + @"name" : @"core.writeMessage", |
| + @"args" : @{ |
| + @"handles" : @[], |
| + @"buffer" : @{}, |
| + @"flags" : [NSNull null], |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests writing a message without handles arg. |
| +TEST_F(MojoFacadeTest, WriteMessageWithoutHandlesArg) { |
| + NSDictionary* write = @{ |
| + @"name" : @"core.writeMessage", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + @"buffer" : @{}, |
| + @"flags" : [NSNull null], |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests writing a message without buffer arg. |
| +TEST_F(MojoFacadeTest, WriteMessageWithoutBufferArg) { |
| + NSDictionary* write = @{ |
| + @"name" : @"core.writeMessage", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + @"handles" : @[], |
| + @"flags" : [NSNull null], |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests writing a message without flags arg. |
| +TEST_F(MojoFacadeTest, WriteMessageWithoutFlagsArg) { |
| + NSDictionary* write = @{ |
| + @"name" : @"core.writeMessage", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + @"handles" : @[], |
| + @"buffer" : @{}, |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests reading a message without handle arg. |
| +TEST_F(MojoFacadeTest, ReadMessageWithoutHandleArg) { |
| + NSDictionary* read = @{ |
| + @"name" : @"core.readMessage", |
| + @"args" : @{ |
| + @"flags" : [NSNull null], |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(read)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests reading a message without flags arg. |
| +TEST_F(MojoFacadeTest, ReadMessageWithoutFlagsArg) { |
| + NSDictionary* read = @{ |
| + @"name" : @"core.readMessage", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(read)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests watching without handle arg. |
| +TEST_F(MojoFacadeTest, WatchWithoutHandleArg) { |
| + NSDictionary* watch = @{ |
| + @"name" : @"support.watch", |
| + @"args" : @{ |
| + @"signals" : @0, |
| + @"callbackId" : @0, |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(watch)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests watching without signals arg. |
| +TEST_F(MojoFacadeTest, WatchWithoutSignalsArg) { |
| + NSDictionary* watch = @{ |
| + @"name" : @"support.watch", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + @"callbackId" : @0, |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(watch)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
| +// Tests watching without callbackId arg. |
| +TEST_F(MojoFacadeTest, WatchWithoutCallbackIdArg) { |
| + NSDictionary* watch = @{ |
| + @"name" : @"support.watch", |
| + @"args" : @{ |
| + @"handle" : @0, |
| + @"signals" : @0, |
| + }, |
| + }; |
| + std::string result_as_string = facade()->HandleMojoMessage(GetJson(watch)); |
| + EXPECT_TRUE(result_as_string.empty()); |
| +} |
| + |
|
Eugene But (OOO till 7-30)
2016/05/07 00:07:52
This is very basic unit test, but I do have an int
|
| +} // namespace web |