Commit 44711001 authored by Yue Zhang's avatar Yue Zhang Committed by Chromium LUCI CQ

[ChromeCart] Clear database when detected history deletion

Bug: 1157892
Change-Id: If79167aa5cb6af2a9e639a93596410f18d39a144
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2616974
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844302}
parent 695ff571
......@@ -3,12 +3,22 @@
// found in the LICENSE file.
#include "chrome/browser/cart/cart_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/search/ntp_features.h"
CartService::CartService(Profile* profile)
: profile_(profile), cart_db_(std::make_unique<CartDB>(profile_)) {}
: profile_(profile),
cart_db_(std::make_unique<CartDB>(profile_)),
history_service_(HistoryServiceFactory::GetForProfile(
profile_,
ServiceAccessType::EXPLICIT_ACCESS)) {
if (history_service_) {
history_service_->AddObserver(this);
}
}
CartService::~CartService() = default;
void CartService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
......@@ -39,3 +49,25 @@ void CartService::RestoreRemoved() {
bool CartService::IsRemoved() {
return profile_->GetPrefs()->GetBoolean(prefs::kCartModuleRemoved);
}
void CartService::OnOperationFinished(bool success) {
DCHECK(success) << "database operation failed.";
}
void CartService::Shutdown() {
if (history_service_) {
history_service_->RemoveObserver(this);
}
}
void CartService::OnURLsDeleted(history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) {
// TODO(crbug.com/1157892): Add more fine-grained deletion of cart data when
// history deletion happens.
cart_db_->DeleteAllCarts(base::BindOnce(&CartService::OnOperationFinished,
weak_ptr_factory_.GetWeakPtr()));
}
CartDB* CartService::GetDB() {
return cart_db_.get();
}
......@@ -4,17 +4,21 @@
#ifndef CHROME_BROWSER_CART_CART_SERVICE_H_
#define CHROME_BROWSER_CART_CART_SERVICE_H_
#include "base/callback_helpers.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/cart/cart_db.h"
#include "chrome/browser/cart/cart_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_registry_simple.h"
// Service to maintain and read/write data for chrome cart module.
// TODO(crbug.com/1157892) Make this BrowserContext-based and get rid of Profile
// usage so that we can modularize this.
class CartService : public KeyedService {
class CartService : public history::HistoryServiceObserver,
public KeyedService {
public:
CartService(const CartService&) = delete;
CartService& operator=(const CartService&) = delete;
......@@ -33,6 +37,13 @@ class CartService : public KeyedService {
void RestoreRemoved();
// Returns whether cart module has been permanently removed.
bool IsRemoved();
// Get the proto database owned by the service.
CartDB* GetDB();
// history::HistoryServiceObserver:
void OnURLsDeleted(history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) override;
// KeyedService:
void Shutdown() override;
private:
friend class CartServiceFactory;
......@@ -40,8 +51,12 @@ class CartService : public KeyedService {
// Use |CartServiceFactory::GetForProfile(...)| to get an instance of this
// service.
explicit CartService(Profile* profile);
// Callback when a database operation (e.g. insert or delete) is finished.
void OnOperationFinished(bool success);
Profile* profile_;
std::unique_ptr<CartDB> cart_db_;
history::HistoryService* history_service_;
base::WeakPtrFactory<CartService> weak_ptr_factory_{this};
};
......
......@@ -3,11 +3,31 @@
// found in the LICENSE file.
#include "chrome/browser/cart/cart_service.h"
#include "chrome/browser/cart/cart_db_content.pb.h"
#include "chrome/browser/cart/cart_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/persisted_state_db/profile_proto_db.h"
#include "chrome/browser/persisted_state_db/profile_proto_db_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
cart_db::ChromeCartContentProto BuildProto(const char* domain) {
cart_db::ChromeCartContentProto proto;
proto.set_key(domain);
proto.set_merchant_cart_url("www.foo.com");
return proto;
}
const char kMockMerchantA[] = "A_merchant";
const cart_db::ChromeCartContentProto kMockProtoA = BuildProto(kMockMerchantA);
const std::vector<ProfileProtoDB<cart_db::ChromeCartContentProto>::KeyAndValue>
kExpectedA = {{kMockMerchantA, kMockProtoA}};
const std::vector<ProfileProtoDB<cart_db::ChromeCartContentProto>::KeyAndValue>
kEmptyExpected = {};
} // namespace
class CartServiceTest : public testing::Test {
public:
CartServiceTest()
......@@ -17,6 +37,30 @@ class CartServiceTest : public testing::Test {
testing::Test::SetUp();
service_ = CartServiceFactory::GetForProfile(&profile_);
DCHECK(profile_.CreateHistoryService());
}
void OperationEvaluation(base::OnceClosure closure,
bool expected_success,
bool actual_success) {
EXPECT_EQ(expected_success, actual_success);
std::move(closure).Run();
}
void GetEvaluationPersistedStateDB(
base::OnceClosure closure,
std::vector<ProfileProtoDB<cart_db::ChromeCartContentProto>::KeyAndValue>
expected,
bool result,
std::vector<ProfileProtoDB<cart_db::ChromeCartContentProto>::KeyAndValue>
found) {
EXPECT_EQ(found.size(), expected.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(found[i].first, expected[i].first);
EXPECT_EQ(found[i].second.merchant_cart_url(),
expected[i].second.merchant_cart_url());
}
std::move(closure).Run();
}
void TearDown() override {}
......@@ -49,3 +93,34 @@ TEST_F(CartServiceTest, TestRemoveStatusChange) {
service_->RestoreRemoved();
ASSERT_FALSE(service_->IsRemoved());
}
// Verifies the database is cleared when detected history deletion.
TEST_F(CartServiceTest, TestOnHistoryDeletion) {
CartDB* cart_db_ = service_->GetDB();
base::RunLoop run_loop[3];
cart_db_->AddCart(
kMockMerchantA, kMockProtoA,
base::BindOnce(&CartServiceTest::OperationEvaluation,
base::Unretained(this), run_loop[0].QuitClosure(), true));
task_environment_.RunUntilIdle();
run_loop[0].Run();
cart_db_->LoadAllCarts(base::BindOnce(
&CartServiceTest::GetEvaluationPersistedStateDB, base::Unretained(this),
run_loop[1].QuitClosure(), kExpectedA));
task_environment_.RunUntilIdle();
run_loop[1].Run();
service_->OnURLsDeleted(
HistoryServiceFactory::GetForProfile(&profile_,
ServiceAccessType::EXPLICIT_ACCESS),
history::DeletionInfo(history::DeletionTimeRange::Invalid(), false,
history::URLRows(), std::set<GURL>(),
base::nullopt));
cart_db_->LoadAllCarts(base::BindOnce(
&CartServiceTest::GetEvaluationPersistedStateDB, base::Unretained(this),
run_loop[2].QuitClosure(), kEmptyExpected));
task_environment_.RunUntilIdle();
run_loop[2].Run();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment