chromium/chrome/browser/ash/printing/history/print_job_history_cleaner_unittest.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/printing/history/print_job_history_cleaner.h"

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/printing/history/print_job_history_service.h"
#include "chrome/browser/ash/printing/history/print_job_info.pb.h"
#include "chrome/browser/ash/printing/history/test_print_job_database.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {

namespace {

using printing::proto::PrintJobInfo;

constexpr char kId1[] = "id1";
constexpr char kId2[] = "id2";

PrintJobInfo ConstructPrintJobInfo(const std::string& id,
                                   const base::Time& completion_time) {
  PrintJobInfo print_job_info;
  print_job_info.set_id(id);
  print_job_info.set_completion_time(
      static_cast<int64_t>(completion_time.InMillisecondsFSinceUnixEpoch()));
  return print_job_info;
}

}  // namespace

class PrintJobHistoryCleanerTest : public ::testing::Test {
 public:
  PrintJobHistoryCleanerTest() = default;

  void SetUp() override {
    test_prefs_.SetInitializationCompleted();

    print_job_database_ = std::make_unique<TestPrintJobDatabase>();
    print_job_history_cleaner_ = std::make_unique<PrintJobHistoryCleaner>(
        print_job_database_.get(), &test_prefs_);

    print_job_history_cleaner_->SetClockForTesting(
        task_environment_.GetMockClock());

    PrintJobHistoryService::RegisterProfilePrefs(test_prefs_.registry());
  }

  void TearDown() override {}

 protected:
  void SavePrintJob(const PrintJobInfo& print_job_info) {
    base::RunLoop run_loop;
    print_job_database_->SavePrintJob(
        print_job_info,
        base::BindOnce(&PrintJobHistoryCleanerTest::OnPrintJobSaved,
                       base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
  }

  void OnPrintJobSaved(base::RepeatingClosure run_loop_closure, bool success) {
    EXPECT_TRUE(success);
    run_loop_closure.Run();
  }

  std::vector<PrintJobInfo> GetPrintJobs() {
    base::RunLoop run_loop;
    print_job_database_->GetPrintJobs(
        base::BindOnce(&PrintJobHistoryCleanerTest::OnPrintJobsRetrieved,
                       base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
    return entries_;
  }

  void OnPrintJobsRetrieved(base::RepeatingClosure run_loop_closure,
                            bool success,
                            std::vector<PrintJobInfo> entries) {
    EXPECT_TRUE(success);
    entries_ = std::move(entries);
    run_loop_closure.Run();
  }

  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  TestingPrefServiceSimple test_prefs_;
  std::unique_ptr<PrintJobDatabase> print_job_database_;
  std::unique_ptr<PrintJobHistoryCleaner> print_job_history_cleaner_;

 private:
  std::vector<PrintJobInfo> entries_;
};

TEST_F(PrintJobHistoryCleanerTest, CleanExpiredPrintJobs) {
  // Set expiration period to 1 day.
  test_prefs_.SetInteger(prefs::kPrintJobHistoryExpirationPeriod, 1);
  print_job_database_->Initialize(base::DoNothing());

  task_environment_.FastForwardBy(base::Days(300));
  PrintJobInfo print_job_info1 =
      ConstructPrintJobInfo(kId1, task_environment_.GetMockClock()->Now());
  SavePrintJob(print_job_info1);

  task_environment_.FastForwardBy(base::Days(1));
  PrintJobInfo print_job_info2 =
      ConstructPrintJobInfo(kId2, task_environment_.GetMockClock()->Now());
  SavePrintJob(print_job_info2);

  task_environment_.FastForwardBy(base::Hours(12));
  base::RunLoop run_loop1;
  print_job_history_cleaner_->CleanUp(run_loop1.QuitClosure());
  run_loop1.Run();

  std::vector<PrintJobInfo> entries = GetPrintJobs();
  // CleanUp() call should clear the first entry which is expected to expire.
  ASSERT_EQ(1u, entries.size());
  EXPECT_EQ(kId2, entries[0].id());

  task_environment_.FastForwardBy(base::Days(1));
  base::RunLoop run_loop2;
  print_job_history_cleaner_->CleanUp(run_loop2.QuitClosure());
  run_loop2.Run();
  entries = GetPrintJobs();
  // The second entry is expected to be removed after cleaner ran again.
  EXPECT_TRUE(entries.empty());
}

TEST_F(PrintJobHistoryCleanerTest, CleanExpiredPrintJobsAfterPrefChanged) {
  // Set expiration period to 1 day.
  test_prefs_.SetInteger(prefs::kPrintJobHistoryExpirationPeriod, 3);
  print_job_database_->Initialize(base::DoNothing());

  task_environment_.FastForwardBy(base::Days(300));
  PrintJobInfo print_job_info =
      ConstructPrintJobInfo(kId1, task_environment_.GetMockClock()->Now());
  SavePrintJob(print_job_info);

  task_environment_.FastForwardBy(base::Hours(36));
  base::RunLoop run_loop1;
  print_job_history_cleaner_->CleanUp(run_loop1.QuitClosure());
  run_loop1.Run();

  std::vector<PrintJobInfo> entries = GetPrintJobs();
  // CleanUp() shouldn't clear anything.
  ASSERT_EQ(1u, entries.size());
  EXPECT_EQ(kId1, entries[0].id());

  test_prefs_.SetInteger(prefs::kPrintJobHistoryExpirationPeriod, 1);
  base::RunLoop run_loop2;
  print_job_history_cleaner_->CleanUp(run_loop2.QuitClosure());
  run_loop2.Run();
  entries = GetPrintJobs();
  // The entry is expected to be removed after pref has changed.
  EXPECT_TRUE(entries.empty());
}

TEST_F(PrintJobHistoryCleanerTest, StorePrintJobHistoryIndefinite) {
  // Set expiration period policy to store history indefinitely.
  test_prefs_.SetInteger(prefs::kPrintJobHistoryExpirationPeriod, -1);
  print_job_database_->Initialize(base::DoNothing());

  task_environment_.FastForwardBy(base::Days(300));
  PrintJobInfo print_job_info1 =
      ConstructPrintJobInfo(kId1, task_environment_.GetMockClock()->Now());
  SavePrintJob(print_job_info1);

  task_environment_.FastForwardBy(base::Days(300));

  base::RunLoop run_loop;
  print_job_history_cleaner_->CleanUp(run_loop.QuitClosure());
  run_loop.Run();

  std::vector<PrintJobInfo> entries = GetPrintJobs();
  // CleanUp() call shouldn't clear anything as according to pref we store
  // history indefinitely.
  ASSERT_EQ(1u, entries.size());
  EXPECT_EQ(kId1, entries[0].id());
}

}  // namespace ash