| // 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 "content/browser/btm/btm_utils.h" |
| |
| #include "base/time/time.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using ::testing::Eq; |
| using ::testing::Pair; |
| |
| namespace content { |
| |
| TEST(TimestampRangeTest, UpdateTimestampRangeEmpty) { |
| const base::Time time = base::Time::FromSecondsSinceUnixEpoch(1); |
| |
| TimestampRange range; |
| EXPECT_TRUE(UpdateTimestampRange(range, time)); |
| EXPECT_EQ(range.value(), std::make_pair(time, time)); |
| } |
| |
| TEST(TimestampRangeTest, UpdateTimestampRange_SetLast) { |
| const base::Time time1 = base::Time::FromSecondsSinceUnixEpoch(1); |
| const base::Time time2 = base::Time::FromSecondsSinceUnixEpoch(2); |
| const base::Time time3 = base::Time::FromSecondsSinceUnixEpoch(3); |
| |
| TimestampRange range = {{time1, time2}}; |
| EXPECT_TRUE(UpdateTimestampRange(range, time3)); |
| EXPECT_EQ(range.value(), std::make_pair(time1, time3)); |
| } |
| |
| TEST(TimestampRangeTest, UpdateTimestampRange_SetFirst) { |
| const base::Time time1 = base::Time::FromSecondsSinceUnixEpoch(1); |
| const base::Time time2 = base::Time::FromSecondsSinceUnixEpoch(2); |
| const base::Time time3 = base::Time::FromSecondsSinceUnixEpoch(3); |
| |
| TimestampRange range = {{time2, time3}}; |
| EXPECT_TRUE(UpdateTimestampRange(range, time1)); |
| EXPECT_EQ(range.value(), std::make_pair(time1, time3)); |
| } |
| |
| TEST(TimestampRangeTest, UpdateTimestampRange_Unmodified) { |
| const base::Time time1 = base::Time::FromSecondsSinceUnixEpoch(1); |
| const base::Time time2 = base::Time::FromSecondsSinceUnixEpoch(2); |
| const base::Time time3 = base::Time::FromSecondsSinceUnixEpoch(3); |
| |
| TimestampRange range = {{time1, time3}}; |
| EXPECT_FALSE(UpdateTimestampRange(range, time2)); |
| EXPECT_EQ(range.value(), std::make_pair(time1, time3)); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_BothEmpty) { |
| EXPECT_TRUE(IsNullOrWithin(/*inner=*/{}, /*outer=*/{})); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_NothingWithinEmptyOuter) { |
| TimestampRange inner = {{base::Time::FromSecondsSinceUnixEpoch(1), |
| base::Time::FromSecondsSinceUnixEpoch(1)}}; |
| TimestampRange outer = {}; |
| EXPECT_FALSE(IsNullOrWithin(inner, outer)); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_EmptyInnerWithin) { |
| TimestampRange inner = {}; |
| TimestampRange outer = {{base::Time::FromSecondsSinceUnixEpoch(1), |
| base::Time::FromSecondsSinceUnixEpoch(1)}}; |
| EXPECT_TRUE(IsNullOrWithin(inner, outer)); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_ChecksLowerBound) { |
| TimestampRange outer = {{base::Time::FromSecondsSinceUnixEpoch(2), |
| base::Time::FromSecondsSinceUnixEpoch(5)}}; |
| TimestampRange starts_on_time = {{base::Time::FromSecondsSinceUnixEpoch(3), |
| base::Time::FromSecondsSinceUnixEpoch(4)}}; |
| TimestampRange starts_too_early = { |
| {base::Time::FromSecondsSinceUnixEpoch(1), |
| base::Time::FromSecondsSinceUnixEpoch(4)}}; |
| |
| EXPECT_FALSE(IsNullOrWithin(starts_too_early, outer)); |
| EXPECT_TRUE(IsNullOrWithin(starts_on_time, outer)); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_ChecksUpperBound) { |
| TimestampRange outer = {{base::Time::FromSecondsSinceUnixEpoch(2), |
| base::Time::FromSecondsSinceUnixEpoch(5)}}; |
| TimestampRange ends_in_time = {{base::Time::FromSecondsSinceUnixEpoch(3), |
| base::Time::FromSecondsSinceUnixEpoch(4)}}; |
| TimestampRange ends_too_late = {{base::Time::FromSecondsSinceUnixEpoch(3), |
| base::Time::FromSecondsSinceUnixEpoch(10)}}; |
| |
| EXPECT_TRUE(IsNullOrWithin(ends_in_time, outer)); |
| EXPECT_FALSE(IsNullOrWithin(ends_too_late, outer)); |
| } |
| |
| TEST(TimestampRangeTest, IsNullOrWithin_AllowsEquals) { |
| TimestampRange range = {{base::Time::FromSecondsSinceUnixEpoch(1), |
| base::Time::FromSecondsSinceUnixEpoch(1)}}; |
| EXPECT_TRUE(IsNullOrWithin(range, range)); |
| } |
| |
| TEST(BucketizeBtmBounceDelayTest, BucketizeBtmBounceDelay) { |
| // any TimeDelta in (-inf, 1s) should return 0 |
| EXPECT_EQ(0, BucketizeBtmBounceDelay(base::Days(-1))); |
| EXPECT_EQ(0, BucketizeBtmBounceDelay(base::Milliseconds(0))); |
| EXPECT_EQ(0, BucketizeBtmBounceDelay(base::Milliseconds(999))); |
| // anything in [1s, 2s) should return 1 |
| EXPECT_EQ(1, BucketizeBtmBounceDelay(base::Milliseconds(1000))); |
| EXPECT_EQ(1, BucketizeBtmBounceDelay(base::Milliseconds(1999))); |
| // similarly for [2s, 3s) |
| EXPECT_EQ(2, BucketizeBtmBounceDelay(base::Milliseconds(2000))); |
| EXPECT_EQ(2, BucketizeBtmBounceDelay(base::Milliseconds(2999))); |
| // ... |
| EXPECT_EQ(9, BucketizeBtmBounceDelay(base::Milliseconds(9999))); |
| // anything in [10s, inf) should return 10 |
| EXPECT_EQ(10, BucketizeBtmBounceDelay(base::Milliseconds(10000))); |
| EXPECT_EQ(10, BucketizeBtmBounceDelay(base::Milliseconds(10001))); |
| EXPECT_EQ(10, BucketizeBtmBounceDelay(base::Days(1))); |
| } |
| |
| TEST(UpdateTimestampTest, AlwaysReplaceNullOpt) { |
| const base::Time new_value = base::Time::FromTimeT(42); |
| std::optional<base::Time> time; |
| |
| ASSERT_EQ(time, std::nullopt); |
| EXPECT_TRUE(UpdateTimestamp(time, new_value)); |
| EXPECT_THAT(time, testing::Optional(new_value)); |
| } |
| |
| TEST(UpdateTimestampTest, DontReplaceBeforeIntervalPasses) { |
| const base::Time old_value = base::Time::FromTimeT(42); |
| const base::Time new_value = |
| old_value + kBtmTimestampUpdateInterval - base::Milliseconds(1); |
| std::optional<base::Time> time = old_value; |
| |
| ASSERT_THAT(time, testing::Optional(old_value)); |
| EXPECT_FALSE(UpdateTimestamp(time, new_value)); |
| EXPECT_THAT(time, testing::Optional(old_value)); |
| } |
| |
| TEST(UpdateTimestampTest, ReplaceAfterIntervalPasses) { |
| const base::Time old_value = base::Time::FromTimeT(42); |
| const base::Time new_value = old_value + kBtmTimestampUpdateInterval; |
| std::optional<base::Time> time = old_value; |
| |
| ASSERT_THAT(time, testing::Optional(old_value)); |
| EXPECT_TRUE(UpdateTimestamp(time, new_value)); |
| EXPECT_THAT(time, testing::Optional(new_value)); |
| } |
| |
| TEST(HasCHIPS, TrueOnlyWhenHasAtLeastOnePartitionedCookie) { |
| auto unpartitioned_cookie = net::CanonicalCookie::CreateForTesting( |
| GURL("https://example.com"), "name=value;", base::Time::Now()); |
| auto partitioned_cookie = net::CanonicalCookie::CreateForTesting( |
| GURL("https://example.com"), "name=value; Partitioned; Path=/; Secure", |
| base::Time::Now(), std::nullopt, |
| net::CookiePartitionKey::FromURLForTesting(GURL("https://example.org"))); |
| |
| net::CookieAccessResultList cookie_access_result_list_without_partitioned{ |
| {*(unpartitioned_cookie.get())}}; |
| EXPECT_FALSE(HasCHIPS(cookie_access_result_list_without_partitioned)); |
| |
| net::CookieAccessResultList cookie_access_result_list_with_partitioned{ |
| {*unpartitioned_cookie.get()}, {*partitioned_cookie.get()}}; |
| EXPECT_TRUE(HasCHIPS(cookie_access_result_list_with_partitioned)); |
| } |
| |
| } // namespace content |