blob: 4bafa9eeddcc3c645e74c3f818c79b13ff73932e [file] [log] [blame]
// Copyright 2017 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 "components/browsing_data/core/counters/browsing_data_counter.h"
#include <memory>
#include <vector>
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace browsing_data {
namespace {
static const char* kTestingDatatypePref = "counter.testing.datatype";
void IgnoreResult(std::unique_ptr<BrowsingDataCounter::Result> result) {
}
class MockBrowsingDataCounter : public BrowsingDataCounter {
public:
MockBrowsingDataCounter() {}
~MockBrowsingDataCounter() override {}
// There are two overloaded ReportResult methods. We need to disambiguate
// between them to be able to bind one of them in base::Bind().
using ReportResultType =
void(MockBrowsingDataCounter::*)(BrowsingDataCounter::ResultInt);
// BrowsingDataCounter implementation:
const char* GetPrefName() const override {
return kTestingDatatypePref;
}
void Count() override {
if (delay_ms_ < 0)
return;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(static_cast<ReportResultType>(
&MockBrowsingDataCounter::ReportResult),
base::Unretained(this),
static_cast<BrowsingDataCounter::ResultInt>(0)),
base::TimeDelta::FromMilliseconds(delay_ms_));
}
void OnInitialized() override {}
void DoReportResult(std::unique_ptr<BrowsingDataCounter::Result> result)
override {
BrowsingDataCounter::DoReportResult(std::move(result));
run_loop_->Quit();
}
// Blocks the UI thread until the counter has finished.
void WaitForResult() {
run_loop_.reset(new base::RunLoop());
run_loop_->Run();
}
void set_counting_delay(int delay_ms) { delay_ms_ = delay_ms; }
private:
std::unique_ptr<base::RunLoop> run_loop_;
int delay_ms_ = 0;
};
} // namespace
class BrowsingDataCounterTest : public testing::Test {
public:
void SetUp() override {
testing::Test::SetUp();
pref_service_.reset(new TestingPrefServiceSimple());
pref_service_->registry()->RegisterBooleanPref(kTestingDatatypePref, true);
pref_service_->registry()->RegisterIntegerPref(prefs::kDeleteTimePeriod, 0);
counter_.reset(new MockBrowsingDataCounter());
counter_->Init(pref_service_.get(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&IgnoreResult));
}
void TearDown() override {
counter_.reset();
pref_service_.reset();
testing::Test::TearDown();
}
MockBrowsingDataCounter* counter() { return counter_.get(); }
private:
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
std::unique_ptr<MockBrowsingDataCounter> counter_;
base::test::ScopedTaskEnvironment task_environment_;
};
TEST_F(BrowsingDataCounterTest, NoResponse) {
counter()->set_counting_delay(-1 /* never */);
counter()->Restart();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(1u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
}
TEST_F(BrowsingDataCounterTest, ImmediateResponse) {
counter()->set_counting_delay(0 /* ms */);
counter()->Restart();
counter()->WaitForResult();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(2u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
DCHECK_EQ(BrowsingDataCounter::State::IDLE, state_transitions[1]);
}
TEST_F(BrowsingDataCounterTest, ResponseWhileCalculatingIsShown) {
counter()->set_counting_delay(500 /* ms */);
counter()->Restart();
counter()->WaitForResult();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(4u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
DCHECK_EQ(BrowsingDataCounter::State::SHOW_CALCULATING, state_transitions[1]);
DCHECK_EQ(BrowsingDataCounter::State::REPORT_STAGED_RESULT,
state_transitions[2]);
DCHECK_EQ(BrowsingDataCounter::State::IDLE, state_transitions[3]);
}
TEST_F(BrowsingDataCounterTest, LateResponse) {
counter()->set_counting_delay(2000 /* ms */);
counter()->Restart();
counter()->WaitForResult();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(4u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
DCHECK_EQ(BrowsingDataCounter::State::SHOW_CALCULATING, state_transitions[1]);
DCHECK_EQ(BrowsingDataCounter::State::READY_TO_REPORT_RESULT,
state_transitions[2]);
DCHECK_EQ(BrowsingDataCounter::State::IDLE, state_transitions[3]);
}
TEST_F(BrowsingDataCounterTest, MultipleRuns) {
counter()->set_counting_delay(0 /* ms */);
counter()->Restart();
counter()->WaitForResult();
counter()->set_counting_delay(500 /* ms */);
counter()->Restart();
counter()->WaitForResult();
counter()->set_counting_delay(1500 /* ms */);
counter()->Restart();
counter()->WaitForResult();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(4u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
DCHECK_EQ(BrowsingDataCounter::State::SHOW_CALCULATING, state_transitions[1]);
DCHECK_EQ(BrowsingDataCounter::State::READY_TO_REPORT_RESULT,
state_transitions[2]);
DCHECK_EQ(BrowsingDataCounter::State::IDLE, state_transitions[3]);
}
TEST_F(BrowsingDataCounterTest, RestartingDoesntBreak) {
counter()->set_counting_delay(10 /* ms */);
counter()->Restart();
counter()->Restart();
counter()->Restart();
counter()->WaitForResult();
const std::vector<BrowsingDataCounter::State>& state_transitions =
counter()->GetStateTransitionsForTesting();
DCHECK_EQ(2u, state_transitions.size());
DCHECK_EQ(BrowsingDataCounter::State::RESTARTED, state_transitions[0]);
DCHECK_EQ(BrowsingDataCounter::State::IDLE, state_transitions[1]);
}
} // namespace browsing_data