blob: f7299fda0798f58ff89cc6340d9ab46e20cc4ef5 [file] [log] [blame]
// Copyright 2017 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.
#include "chromeos/components/tether/message_wrapper.h"
#include <sstream>
#include "base/base64url.h"
#include "base/logging.h"
#include "base/macros.h"
#include "chromeos/components/tether/proto/tether.pb.h"
#include "chromeos/components/tether/proto_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace tether {
namespace {
TetherAvailabilityResponse CreateTetherAvailabilityResponse() {
TetherAvailabilityResponse response;
response.set_response_code(
TetherAvailabilityResponse_ResponseCode::
TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE);
response.mutable_device_status()->CopyFrom(
CreateDeviceStatusWithFakeFields());
return response;
}
void VerifyProtoConversion(const google::protobuf::MessageLite* proto,
const MessageWrapper& wrapper,
const MessageType& expected_message_type) {
std::string raw_message = wrapper.ToRawMessage();
EXPECT_TRUE(raw_message.length() > 0);
std::unique_ptr<MessageWrapper> wrapper_from_raw_message =
MessageWrapper::FromRawMessage(raw_message);
EXPECT_TRUE(wrapper_from_raw_message);
EXPECT_EQ(expected_message_type, wrapper_from_raw_message->GetMessageType());
EXPECT_EQ(proto->SerializeAsString(),
wrapper_from_raw_message->GetProto()->SerializeAsString());
}
} // namespace
class MessageWrapperTest : public testing::Test {
protected:
MessageWrapperTest() = default;
private:
DISALLOW_COPY_AND_ASSIGN(MessageWrapperTest);
};
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_ConnectTetheringRequest) {
ConnectTetheringRequest request;
MessageWrapper wrapper(request);
VerifyProtoConversion(&request, wrapper,
MessageType::CONNECT_TETHERING_REQUEST);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_ConnectTetheringResponse) {
ConnectTetheringResponse response;
response.set_ssid("Instant Tethering 123456");
response.set_password("password");
response.set_response_code(ConnectTetheringResponse_ResponseCode::
ConnectTetheringResponse_ResponseCode_SUCCESS);
response.mutable_device_status()->CopyFrom(
CreateDeviceStatusWithFakeFields());
MessageWrapper wrapper(response);
VerifyProtoConversion(&response, wrapper,
MessageType::CONNECT_TETHERING_RESPONSE);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_DisconnectTetheringRequest) {
DisconnectTetheringRequest request;
MessageWrapper wrapper(request);
VerifyProtoConversion(&request, wrapper,
MessageType::DISCONNECT_TETHERING_REQUEST);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_KeepAliveTickle) {
KeepAliveTickle tickle;
MessageWrapper wrapper(tickle);
VerifyProtoConversion(&tickle, wrapper, MessageType::KEEP_ALIVE_TICKLE);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_KeepAliveTickleResponse) {
KeepAliveTickleResponse response;
MessageWrapper wrapper(response);
VerifyProtoConversion(&response, wrapper,
MessageType::KEEP_ALIVE_TICKLE_RESPONSE);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_TetherAvailabilityRequest) {
TetherAvailabilityRequest request;
MessageWrapper wrapper(request);
VerifyProtoConversion(&request, wrapper,
MessageType::TETHER_AVAILABILITY_REQUEST);
}
TEST_F(MessageWrapperTest, TestToAndFromRawMessage_TetherAvailabilityResponse) {
TetherAvailabilityResponse response = CreateTetherAvailabilityResponse();
MessageWrapper wrapper(response);
VerifyProtoConversion(&response, wrapper,
MessageType::TETHER_AVAILABILITY_RESPONSE);
}
TEST_F(MessageWrapperTest, TestHandleInvalidJson) {
EXPECT_FALSE(MessageWrapper::FromRawMessage("not JSON"));
}
TEST_F(MessageWrapperTest, TestHandleJsonWithoutType) {
ConnectTetheringRequest request;
std::string encoded_message;
base::Base64UrlEncode(request.SerializeAsString(),
base::Base64UrlEncodePolicy::INCLUDE_PADDING,
&encoded_message);
std::stringstream ss;
ss << "{\"data\": \"" << encoded_message << "\"}";
EXPECT_FALSE(MessageWrapper::FromRawMessage(ss.str()));
}
TEST_F(MessageWrapperTest, TestHandleJsonWithoutData) {
EXPECT_FALSE(MessageWrapper::FromRawMessage("{\"type\":1}"));
}
TEST_F(MessageWrapperTest, TestHandleJsonWithoutTypeOrData) {
EXPECT_FALSE(MessageWrapper::FromRawMessage("{}"));
}
TEST_F(MessageWrapperTest, TestHandleDataNotEncodedWithBase64) {
TetherAvailabilityResponse response = CreateTetherAvailabilityResponse();
std::stringstream ss;
ss << "{\"type\":" << static_cast<int>(MessageType::CONNECT_TETHERING_REQUEST)
<< ",\"data\":\""
<< response.SerializeAsString() // Do not convert to base-64.
<< "\"}";
EXPECT_FALSE(MessageWrapper::FromRawMessage(ss.str()));
}
TEST_F(MessageWrapperTest, TestFromRawMessage_StringLiteral) {
// Type 2 is TETHER_AVAILABILITY_RESPONSE, and the data supplied is
// CreateTetherAvailabilityResponse() encoded in base-64.
std::string raw_message =
"{\"type\":2,\"data\":\"CAESHQhLEglHb29nbGUgRmkYBCIMCAESCFdpZmlTc2lk\"}";
std::unique_ptr<MessageWrapper> wrapper =
MessageWrapper::FromRawMessage(raw_message);
EXPECT_TRUE(wrapper);
EXPECT_EQ(MessageType::TETHER_AVAILABILITY_RESPONSE,
wrapper->GetMessageType());
EXPECT_EQ(CreateTetherAvailabilityResponse().SerializeAsString(),
wrapper->GetProto()->SerializeAsString());
}
TEST_F(MessageWrapperTest, TestFromRawMessage_ExtraJsonKeyValuePair) {
TetherAvailabilityResponse response = CreateTetherAvailabilityResponse();
std::string response_string_base64;
base::Base64UrlEncode(response.SerializeAsString(),
base::Base64UrlEncodePolicy::INCLUDE_PADDING,
&response_string_base64);
std::stringstream ss;
ss << "{\"type\":"
<< static_cast<int>(MessageType::TETHER_AVAILABILITY_RESPONSE)
<< ",\"data\":\"" << response_string_base64 << "\""
<< ",\"extraKey\":\"extraValue\"}";
std::unique_ptr<MessageWrapper> wrapper =
MessageWrapper::FromRawMessage(ss.str());
EXPECT_TRUE(wrapper);
EXPECT_EQ(MessageType::TETHER_AVAILABILITY_RESPONSE,
wrapper->GetMessageType());
EXPECT_EQ(response.SerializeAsString(),
wrapper->GetProto()->SerializeAsString());
}
} // namespace tether
} // namespace cryptauth