// 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 "content/browser/conversions/conversion_storage_delegate_impl.h"

#include <vector>

#include "base/optional.h"
#include "base/time/time.h"
#include "content/browser/conversions/conversion_report.h"
#include "content/browser/conversions/conversion_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

constexpr base::TimeDelta kDefaultExpiry = base::TimeDelta::FromDays(30);

ConversionReport GetReport(base::Time impression_time,
                           base::Time conversion_time,
                           base::TimeDelta expiry = kDefaultExpiry) {
  return ConversionReport(
      ImpressionBuilder(impression_time).SetExpiry(expiry).Build(),
      /*conversion_data=*/"123", conversion_time,
      /*conversion_id=*/base::nullopt);
}

}  // namespace

class ConversionStorageDelegateImplTest : public testing::Test {
 public:
  ConversionStorageDelegateImplTest() = default;
};

TEST_F(ConversionStorageDelegateImplTest, ImmediateConversion_FirstWindowUsed) {
  base::Time impression_time = base::Time::Now();
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, /*conversion_time=*/impression_time)};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(2),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       ConversionImmediatelyBeforeWindow_NextWindowUsed) {
  base::Time impression_time = base::Time::Now();
  base::Time conversion_time = impression_time + base::TimeDelta::FromDays(2) -
                               base::TimeDelta::FromMinutes(1);
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, conversion_time)};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(7),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       ConversionBeforeWindowDelay_WindowUsed) {
  base::Time impression_time = base::Time::Now();

  // The deadline for a window is 1 hour before the window. Use a time just
  // before the deadline.
  base::Time conversion_time = impression_time + base::TimeDelta::FromDays(2) -
                               base::TimeDelta::FromMinutes(61);
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, conversion_time)};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(2),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       ImpressionExpiryBeforeTwoDayWindow_TwoDayWindowUsed) {
  base::Time impression_time = base::Time::Now();
  base::Time conversion_time = impression_time + base::TimeDelta::FromHours(1);

  // Set the impression to expire before the two day window.
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, conversion_time,
                /*expiry=*/base::TimeDelta::FromHours(2))};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(2),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       ImpressionExpiryBeforeSevenDayWindow_ExpiryWindowUsed) {
  base::Time impression_time = base::Time::Now();
  base::Time conversion_time = impression_time + base::TimeDelta::FromDays(3);

  // Set the impression to expire before the two day window.
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, conversion_time,
                /*expiry=*/base::TimeDelta::FromDays(4))};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);

  // The expiry window is reported one hour after expiry time.
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(4) +
                base::TimeDelta::FromHours(1),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       ImpressionExpiryAfterSevenDayWindow_ExpiryWindowUsed) {
  base::Time impression_time = base::Time::Now();
  base::Time conversion_time = impression_time + base::TimeDelta::FromDays(7);

  // Set the impression to expire before the two day window.
  std::vector<ConversionReport> reports = {
      GetReport(impression_time, conversion_time,
                /*expiry=*/base::TimeDelta::FromDays(9))};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);

  // The expiry window is reported one hour after expiry time.
  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(9) +
                base::TimeDelta::FromHours(1),
            reports[0].report_time);
}

TEST_F(ConversionStorageDelegateImplTest,
       SingleReportForConversion_AttributionCreditAssigned) {
  base::Time now = base::Time::Now();
  std::vector<ConversionReport> reports = {
      GetReport(/*impression_time=*/now, /*conversion_time=*/now)};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(1u, reports.size());
  EXPECT_EQ(100, reports[0].attribution_credit);
}

TEST_F(ConversionStorageDelegateImplTest,
       TwoReportsForConversion_LastReceivesCredit) {
  base::Time now = base::Time::Now();
  std::vector<ConversionReport> reports = {
      GetReport(/*impression_time=*/now, /*conversion_time=*/now),
      GetReport(/*impression_time=*/now + base::TimeDelta::FromHours(100),
                /*conversion_time=*/now)};
  ConversionStorageDelegateImpl().ProcessNewConversionReports(&reports);
  EXPECT_EQ(2u, reports.size());
  EXPECT_EQ(0, reports[0].attribution_credit);
  EXPECT_EQ(100, reports[1].attribution_credit);

  // Ensure the reports were not rearranged.
  EXPECT_EQ(now + base::TimeDelta::FromHours(100),
            reports[1].impression.impression_time());
}

}  // namespace content
