You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
5.5 KiB
162 lines
5.5 KiB
// Copyright 2020 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 "cast/protocol/castv2/validation.h"
|
|
|
|
#include <numeric>
|
|
#include <string>
|
|
|
|
#include "absl/strings/string_view.h"
|
|
#include "cast/protocol/castv2/receiver_examples/get_app_availability_data.h"
|
|
#include "cast/protocol/castv2/receiver_examples/get_app_availability_response_data.h"
|
|
#include "cast/protocol/castv2/receiver_examples/launch_data.h"
|
|
#include "cast/protocol/castv2/receiver_examples/stop_data.h"
|
|
#include "cast/protocol/castv2/receiver_schema_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/answer_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/capabilities_response_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/get_capabilities_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/get_status_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/offer_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/rpc_data.h"
|
|
#include "cast/protocol/castv2/streaming_examples/status_response_data.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "json/value.h"
|
|
#include "platform/base/error.h"
|
|
#include "util/json/json_serialization.h"
|
|
#include "util/osp_logging.h"
|
|
#include "util/std_util.h"
|
|
#include "util/stringprintf.h"
|
|
|
|
namespace openscreen {
|
|
namespace cast {
|
|
|
|
namespace {
|
|
|
|
constexpr char kEmptyJson[] = "{}";
|
|
|
|
// Schema format string, that allows for specifying definitions,
|
|
// properties, and required fields.
|
|
constexpr char kSchemaFormat[] = R"({
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"$id": "https://something/app_schema_data.h",
|
|
"definitions": {
|
|
%s
|
|
},
|
|
"type": "object",
|
|
"properties": {
|
|
%s
|
|
},
|
|
"required": [%s]
|
|
})";
|
|
|
|
// Fields used for an appId containing schema
|
|
constexpr char kAppIdDefinition[] = R"("app_id": {
|
|
"type": "string",
|
|
"enum": ["0F5096E8", "85CDB22F"]
|
|
})";
|
|
constexpr char kAppIdName[] = "\"appId\"";
|
|
constexpr char kAppIdProperty[] =
|
|
R"( "appId": {"$ref": "#/definitions/app_id"})";
|
|
|
|
// Teest documents containing an appId.
|
|
constexpr char kValidAppIdDocument[] = R"({ "appId": "0F5096E8" })";
|
|
constexpr char kInvalidAppIdDocument[] = R"({ "appId": "FooBar" })";
|
|
|
|
std::string BuildSchema(const char* definitions,
|
|
const char* properties,
|
|
const char* required) {
|
|
return StringPrintf(kSchemaFormat, definitions, properties, required);
|
|
}
|
|
|
|
bool TestValidate(absl::string_view document, absl::string_view schema) {
|
|
OSP_DVLOG << "Validating document: \"" << document << "\" against schema: \""
|
|
<< schema << "\"";
|
|
ErrorOr<Json::Value> document_root = json::Parse(document);
|
|
EXPECT_TRUE(document_root.is_value());
|
|
ErrorOr<Json::Value> schema_root = json::Parse(schema);
|
|
EXPECT_TRUE(schema_root.is_value());
|
|
|
|
std::vector<Error> errors =
|
|
Validate(document_root.value(), schema_root.value());
|
|
return errors.empty();
|
|
}
|
|
|
|
const std::string& GetEmptySchema() {
|
|
static const std::string kEmptySchema = BuildSchema("", "", "");
|
|
return kEmptySchema;
|
|
}
|
|
|
|
const std::string& GetAppSchema() {
|
|
static const std::string kAppIdSchema =
|
|
BuildSchema(kAppIdDefinition, kAppIdProperty, kAppIdName);
|
|
return kAppIdSchema;
|
|
}
|
|
|
|
class StreamingValidationTest : public testing::TestWithParam<const char*> {};
|
|
class ReceiverValidationTest : public testing::TestWithParam<const char*> {};
|
|
|
|
} // namespace
|
|
|
|
TEST(ValidationTest, EmptyPassesEmpty) {
|
|
EXPECT_TRUE(TestValidate(kEmptyJson, kEmptyJson));
|
|
}
|
|
|
|
TEST(ValidationTest, EmptyPassesBasicSchema) {
|
|
EXPECT_TRUE(TestValidate(kEmptyJson, GetEmptySchema()));
|
|
}
|
|
|
|
TEST(ValidationTest, EmptyFailsAppIdSchema) {
|
|
EXPECT_FALSE(TestValidate(kEmptyJson, GetAppSchema()));
|
|
}
|
|
|
|
TEST(ValidationTest, InvalidAppIdFailsAppIdSchema) {
|
|
EXPECT_FALSE(TestValidate(kInvalidAppIdDocument, GetAppSchema()));
|
|
}
|
|
|
|
TEST(ValidationTest, ValidAppIdPassesAppIdSchema) {
|
|
EXPECT_TRUE(TestValidate(kValidAppIdDocument, GetAppSchema()));
|
|
}
|
|
|
|
TEST(ValidationTest, InvalidAppIdPassesEmptySchema) {
|
|
EXPECT_TRUE(TestValidate(kInvalidAppIdDocument, GetEmptySchema()));
|
|
}
|
|
|
|
TEST(ValidationTest, ValidAppIdPassesEmptySchema) {
|
|
EXPECT_TRUE(TestValidate(kValidAppIdDocument, GetEmptySchema()));
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(StreamingValidations,
|
|
StreamingValidationTest,
|
|
testing::Values(kAnswer,
|
|
kCapabilitiesResponse,
|
|
kGetCapabilities,
|
|
kGetStatus,
|
|
kOffer,
|
|
kRpc,
|
|
kStatusResponse));
|
|
|
|
TEST_P(StreamingValidationTest, ExampleStreamingMessages) {
|
|
ErrorOr<Json::Value> message_root = json::Parse(GetParam());
|
|
EXPECT_TRUE(message_root.is_value());
|
|
EXPECT_TRUE(ValidateStreamingMessage(message_root.value()).empty());
|
|
}
|
|
|
|
void ExpectReceiverMessageValid(const char* message) {}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(ReceiverValidations,
|
|
ReceiverValidationTest,
|
|
testing::Values(kGetAppAvailability,
|
|
kGetAppAvailabilityResponse,
|
|
kLaunch,
|
|
kStop));
|
|
|
|
TEST_P(ReceiverValidationTest, ExampleReceiverMessages) {
|
|
ErrorOr<Json::Value> message_root = json::Parse(GetParam());
|
|
EXPECT_TRUE(message_root.is_value());
|
|
EXPECT_TRUE(ValidateReceiverMessage(message_root.value()).empty());
|
|
}
|
|
} // namespace cast
|
|
} // namespace openscreen
|