blob: 3c4d9e02732bd7b4eb608f81795f04dd03ad7cd8 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/attribution_reporting/parsing_utils.h"
#include <stdint.h>
#include <limits>
#include <string>
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "components/attribution_reporting/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace attribution_reporting {
namespace {
TEST(AttributionReportingParsingUtilsTest, StringToAggregationKeyPiece) {
const struct {
const char* string;
absl::optional<absl::uint128> expected;
} kTestCases[] = {
{"123", absl::nullopt},
{"0x123", 291},
{"0X123", 291},
{"0xG", absl::nullopt},
};
for (const auto& test_case : kTestCases) {
EXPECT_EQ(StringToAggregationKeyPiece(test_case.string),
test_case.expected);
}
}
TEST(AttributionReportingParsingUtilsTest, AggregationKeyIdHasValidLength) {
EXPECT_TRUE(AggregationKeyIdHasValidLength(
std::string(kMaxBytesPerAggregationKeyId, 'a')));
EXPECT_FALSE(AggregationKeyIdHasValidLength(
std::string(kMaxBytesPerAggregationKeyId + 1, 'a')));
}
TEST(AttributionReportingParsingUtilsTest, ParseUint64) {
const struct {
const char* description;
const char* json;
absl::optional<uint64_t> expected;
} kTestCases[] = {
{
"missing_key",
R"json({})json",
absl::nullopt,
},
{
"not_string",
R"json({"key":123})json",
absl::nullopt,
},
{
"negative",
R"json({"key":"-1"})json",
absl::nullopt,
},
{
"zero",
R"json({"key":"0"})json",
0,
},
{
"max",
R"json({"key":"18446744073709551615"})json",
std::numeric_limits<uint64_t>::max(),
},
{
"out_of_range",
R"json({"key":"18446744073709551616"})json",
absl::nullopt,
},
};
for (const auto& test_case : kTestCases) {
base::Value value = base::test::ParseJson(test_case.json);
EXPECT_EQ(ParseUint64(value.GetDict(), "key"), test_case.expected)
<< test_case.description;
}
}
TEST(AttributionReportingParsingUtilsTest, ParseInt64) {
const struct {
const char* description;
const char* json;
absl::optional<int64_t> expected;
} kTestCases[] = {
{
"missing_key",
R"json({})json",
absl::nullopt,
},
{
"not_string",
R"json({"key":123})json",
absl::nullopt,
},
{
"zero",
R"json({"key":"0"})json",
0,
},
{
"min",
R"json({"key":"-9223372036854775808"})json",
std::numeric_limits<int64_t>::min(),
},
{
"max",
R"json({"key":"9223372036854775807"})json",
std::numeric_limits<int64_t>::max(),
},
{
"out_of_range",
R"json({"key":"9223372036854775808"})json",
absl::nullopt,
},
};
for (const auto& test_case : kTestCases) {
base::Value value = base::test::ParseJson(test_case.json);
EXPECT_EQ(ParseInt64(value.GetDict(), "key"), test_case.expected)
<< test_case.description;
}
}
TEST(AttributionReportingParsingUtilsTest, HexEncodeAggregationKey) {
const struct {
absl::uint128 input;
const char* expected;
} kTestCases[] = {
{0, "0x0"},
{absl::MakeUint128(/*high=*/0,
/*low=*/std::numeric_limits<uint64_t>::max()),
"0xffffffffffffffff"},
{absl::MakeUint128(/*high=*/1,
/*low=*/std::numeric_limits<uint64_t>::max()),
"0x1ffffffffffffffff"},
{std::numeric_limits<absl::uint128>::max(),
"0xffffffffffffffffffffffffffffffff"},
};
for (const auto& test_case : kTestCases) {
EXPECT_EQ(HexEncodeAggregationKey(test_case.input), test_case.expected)
<< test_case.input;
}
}
} // namespace
} // namespace attribution_reporting