blob: 59abc66c8333139c918f142220f0a2157736d156 [file] [log] [blame]
// Copyright 2015 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/password_manager/core/browser/statistics_table.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/utf_string_conversions.h"
#include "sql/database.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace password_manager {
namespace {
const char kTestDomain[] = "http://google.com";
const char kTestDomain2[] = "http://example.com";
const char kTestDomain3[] = "https://example.org";
const char kTestDomain4[] = "http://localhost";
const char kUsername1[] = "user1";
const char kUsername2[] = "user2";
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Pointee;
using ::testing::UnorderedElementsAre;
class StatisticsTableTest : public testing::Test {
protected:
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
ReloadDatabase();
test_data_.origin_domain = GURL(kTestDomain);
test_data_.username_value = base::ASCIIToUTF16(kUsername1);
test_data_.dismissal_count = 10;
test_data_.update_time = base::Time::FromTimeT(1);
}
void ReloadDatabase() {
base::FilePath file = temp_dir_.GetPath().AppendASCII("TestDatabase");
db_.reset(new StatisticsTable);
connection_.reset(new sql::Database);
connection_->set_exclusive_locking();
ASSERT_TRUE(connection_->Open(file));
db_->Init(connection_.get());
ASSERT_TRUE(db_->CreateTableIfNecessary());
}
InteractionsStats& test_data() { return test_data_; }
StatisticsTable* db() { return db_.get(); }
private:
base::ScopedTempDir temp_dir_;
std::unique_ptr<sql::Database> connection_;
std::unique_ptr<StatisticsTable> db_;
InteractionsStats test_data_;
};
TEST_F(StatisticsTableTest, Sanity) {
EXPECT_TRUE(db()->AddRow(test_data()));
EXPECT_THAT(db()->GetAllRows(), ElementsAre(test_data()));
EXPECT_THAT(db()->GetRows(test_data().origin_domain),
ElementsAre(test_data()));
EXPECT_TRUE(db()->RemoveRow(test_data().origin_domain));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(test_data().origin_domain), IsEmpty());
}
TEST_F(StatisticsTableTest, Reload) {
EXPECT_TRUE(db()->AddRow(test_data()));
ReloadDatabase();
EXPECT_THAT(db()->GetAllRows(), ElementsAre(test_data()));
EXPECT_THAT(db()->GetRows(test_data().origin_domain),
ElementsAre(test_data()));
}
TEST_F(StatisticsTableTest, DoubleOperation) {
EXPECT_TRUE(db()->AddRow(test_data()));
test_data().dismissal_count++;
EXPECT_TRUE(db()->AddRow(test_data()));
EXPECT_THAT(db()->GetAllRows(), ElementsAre(test_data()));
EXPECT_THAT(db()->GetRows(test_data().origin_domain),
ElementsAre(test_data()));
EXPECT_TRUE(db()->RemoveRow(test_data().origin_domain));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(test_data().origin_domain), IsEmpty());
EXPECT_TRUE(db()->RemoveRow(test_data().origin_domain));
}
TEST_F(StatisticsTableTest, DifferentUsernames) {
InteractionsStats stats1 = test_data();
InteractionsStats stats2 = test_data();
stats2.username_value = base::ASCIIToUTF16(kUsername2);
EXPECT_TRUE(db()->AddRow(stats1));
EXPECT_TRUE(db()->AddRow(stats2));
EXPECT_THAT(db()->GetAllRows(), UnorderedElementsAre(stats1, stats2));
EXPECT_THAT(db()->GetRows(test_data().origin_domain),
UnorderedElementsAre(stats1, stats2));
EXPECT_TRUE(db()->RemoveRow(test_data().origin_domain));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(test_data().origin_domain), IsEmpty());
}
TEST_F(StatisticsTableTest, RemoveStatsByOriginAndTime) {
InteractionsStats stats1 = test_data();
stats1.update_time = base::Time::FromTimeT(1);
InteractionsStats stats2 = test_data();
stats2.update_time = base::Time::FromTimeT(2);
stats2.origin_domain = GURL(kTestDomain2);
InteractionsStats stats3 = test_data();
stats3.update_time = base::Time::FromTimeT(2);
stats3.origin_domain = GURL(kTestDomain3);
InteractionsStats stats4 = test_data();
stats4.update_time = base::Time::FromTimeT(2);
stats4.origin_domain = GURL(kTestDomain4);
EXPECT_TRUE(db()->AddRow(stats1));
EXPECT_TRUE(db()->AddRow(stats2));
EXPECT_TRUE(db()->AddRow(stats3));
EXPECT_TRUE(db()->AddRow(stats4));
EXPECT_THAT(db()->GetAllRows(),
UnorderedElementsAre(stats1, stats2, stats3, stats4));
EXPECT_THAT(db()->GetRows(stats1.origin_domain), ElementsAre(stats1));
EXPECT_THAT(db()->GetRows(stats2.origin_domain), ElementsAre(stats2));
EXPECT_THAT(db()->GetRows(stats3.origin_domain), ElementsAre(stats3));
EXPECT_THAT(db()->GetRows(stats4.origin_domain), ElementsAre(stats4));
// Remove the entry with the timestamp 1 with no origin filter.
EXPECT_TRUE(
db()->RemoveStatsByOriginAndTime(base::Callback<bool(const GURL&)>(),
base::Time(), base::Time::FromTimeT(2)));
EXPECT_THAT(db()->GetAllRows(), UnorderedElementsAre(stats2, stats3, stats4));
EXPECT_THAT(db()->GetRows(stats1.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats2.origin_domain), ElementsAre(stats2));
EXPECT_THAT(db()->GetRows(stats3.origin_domain), ElementsAre(stats3));
EXPECT_THAT(db()->GetRows(stats4.origin_domain), ElementsAre(stats4));
// Remove the entries with the timestamp 2 that are NOT matching
// |kTestDomain3|.
EXPECT_TRUE(db()->RemoveStatsByOriginAndTime(
base::Bind(static_cast<bool (*)(const GURL&, const GURL&)>(operator!=),
stats3.origin_domain),
base::Time::FromTimeT(2), base::Time()));
EXPECT_THAT(db()->GetAllRows(), ElementsAre(stats3));
EXPECT_THAT(db()->GetRows(stats1.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats2.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats3.origin_domain), ElementsAre(stats3));
EXPECT_THAT(db()->GetRows(stats4.origin_domain), IsEmpty());
// Remove the entries with the timestamp 2 with no origin filter.
// This should delete the remaining entry.
EXPECT_TRUE(
db()->RemoveStatsByOriginAndTime(base::Callback<bool(const GURL&)>(),
base::Time::FromTimeT(2), base::Time()));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(stats1.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats2.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats3.origin_domain), IsEmpty());
EXPECT_THAT(db()->GetRows(stats4.origin_domain), IsEmpty());
}
TEST_F(StatisticsTableTest, BadURL) {
test_data().origin_domain = GURL("trash");
EXPECT_FALSE(db()->AddRow(test_data()));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(test_data().origin_domain), IsEmpty());
EXPECT_FALSE(db()->RemoveRow(test_data().origin_domain));
}
TEST_F(StatisticsTableTest, EmptyURL) {
test_data().origin_domain = GURL();
EXPECT_FALSE(db()->AddRow(test_data()));
EXPECT_THAT(db()->GetAllRows(), IsEmpty());
EXPECT_THAT(db()->GetRows(test_data().origin_domain), IsEmpty());
EXPECT_FALSE(db()->RemoveRow(test_data().origin_domain));
}
} // namespace
} // namespace password_manager