| // 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 |