| // Copyright 2018 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 "chrome/browser/android/explore_sites/import_catalog_task.h" |
| |
| #include <memory> |
| |
| #include "base/logging.h" |
| #include "base/test/bind_test_util.h" |
| #include "base/test/mock_callback.h" |
| #include "chrome/browser/android/explore_sites/catalog.pb.h" |
| #include "chrome/browser/android/explore_sites/explore_sites_schema.h" |
| #include "components/offline_pages/task/task.h" |
| #include "components/offline_pages/task/task_test_base.h" |
| #include "sql/database.h" |
| #include "sql/meta_table.h" |
| #include "sql/statement.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using offline_pages::TaskTestBase; |
| |
| namespace explore_sites { |
| |
| constexpr int64_t timestamp = 12345L; |
| const char kGoogleUrl[] = "https://www.google.com"; |
| const char kGoogleTitle[] = "Google Search"; |
| const char kGmailUrl[] = "https://mail.google.com/mail"; |
| const char kGmailTitle[] = "GMail"; |
| const char kGoogleCategoryTitle[] = "Goooogle"; |
| const char kIcon[] = |
| "data:image/gif;" |
| "base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; |
| |
| class ExploreSitesImportCatalogTaskTest : public TaskTestBase { |
| public: |
| ExploreSitesImportCatalogTaskTest() = default; |
| ~ExploreSitesImportCatalogTaskTest() override = default; |
| |
| void SetUp() override { |
| store_ = std::make_unique<ExploreSitesStore>(task_runner()); |
| } |
| |
| ExploreSitesStore* store() { return store_.get(); } |
| |
| void ExecuteSync(base::RepeatingCallback<bool(sql::Database*)> query) { |
| store()->Execute(base::OnceCallback<bool(sql::Database*)>(query), |
| base::BindOnce([](bool result) { ASSERT_TRUE(result); }), |
| false); |
| RunUntilIdle(); |
| } |
| |
| private: |
| std::unique_ptr<ExploreSitesStore> store_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ExploreSitesImportCatalogTaskTest); |
| }; |
| |
| TEST_F(ExploreSitesImportCatalogTaskTest, StoreFailure) { |
| store()->SetInitializationStatusForTest(InitializationStatus::FAILURE); |
| ImportCatalogTask task(store(), timestamp, std::make_unique<Catalog>()); |
| RunTask(&task); |
| |
| // A null catalog should be completed but return with an error. |
| EXPECT_TRUE(task.complete()); |
| EXPECT_FALSE(task.result()); |
| } |
| |
| TEST_F(ExploreSitesImportCatalogTaskTest, EmptyTask) { |
| ImportCatalogTask task(store(), timestamp, std::unique_ptr<Catalog>()); |
| RunTask(&task); |
| |
| // A null catalog should be completed but return with an error. |
| EXPECT_TRUE(task.complete()); |
| EXPECT_FALSE(task.result()); |
| } |
| |
| // This tests the behavior of the catalog task when there is already a catalog |
| // with the current timestamp in the database. This tests both the case where it |
| // is the "current" catalog, and where it is the "downloading" catalog. |
| TEST_F(ExploreSitesImportCatalogTaskTest, CatalogAlreadyInUse) { |
| // Successfully import a catalog with "timestamp". |
| ImportCatalogTask task(store(), timestamp, std::make_unique<Catalog>()); |
| RunTask(&task); |
| ASSERT_TRUE(task.result()); |
| |
| // Importing the same catalog again should cause a successful import, |
| // since the catalog was not "current". |
| ImportCatalogTask task2(store(), timestamp, std::make_unique<Catalog>()); |
| RunTask(&task2); |
| EXPECT_TRUE(task2.result()); |
| |
| // Now make the catalog "current". |
| ExecuteSync(base::BindLambdaForTesting([&](sql::Database* db) { |
| sql::MetaTable meta_table; |
| ExploreSitesSchema::InitMetaTable(db, &meta_table); |
| meta_table.SetValue("current_catalog", timestamp); |
| meta_table.DeleteKey("downloading_catalog"); |
| return true; |
| })); |
| |
| // Now it should fail to import another copy of the same catalog. |
| ImportCatalogTask task3(store(), timestamp, std::make_unique<Catalog>()); |
| RunTask(&task3); |
| EXPECT_TRUE(task3.complete()); |
| EXPECT_FALSE(task3.result()); |
| } |
| |
| TEST_F(ExploreSitesImportCatalogTaskTest, BasicCatalog) { |
| auto catalog = std::make_unique<Catalog>(); |
| auto* categories = catalog->mutable_categories(); |
| Category* first = categories->Add(); |
| first->set_type(Category_CategoryType_GOOGLE); |
| first->set_localized_title(kGoogleCategoryTitle); |
| first->set_icon(kIcon); |
| |
| auto* sites = first->mutable_sites(); |
| Site* google = sites->Add(); |
| google->set_title(kGoogleTitle); |
| google->set_site_url(kGoogleUrl); |
| google->set_icon(kIcon); |
| Site* gmail = sites->Add(); |
| gmail->set_title(kGmailTitle); |
| gmail->set_site_url(kGmailUrl); |
| gmail->set_icon(kIcon); |
| |
| ImportCatalogTask task(store(), timestamp, std::move(catalog)); |
| RunTask(&task); |
| |
| EXPECT_TRUE(task.complete()); |
| EXPECT_TRUE(task.result()); |
| |
| ExecuteSync(base::BindLambdaForTesting([&](sql::Database* db) { |
| sql::Statement cat_count_s( |
| db->GetUniqueStatement("SELECT COUNT(*) FROM categories")); |
| cat_count_s.Step(); |
| EXPECT_EQ(1, cat_count_s.ColumnInt(0)); |
| |
| sql::Statement cat_data_s(db->GetUniqueStatement( |
| "SELECT version, type, label, image, category_id FROM categories")); |
| cat_data_s.Step(); |
| EXPECT_EQ(timestamp, cat_data_s.ColumnInt64(0)); |
| EXPECT_EQ(static_cast<int>(Category_CategoryType_GOOGLE), |
| cat_data_s.ColumnInt(1)); |
| EXPECT_EQ(kGoogleCategoryTitle, cat_data_s.ColumnString(2)); |
| EXPECT_EQ(kIcon, cat_data_s.ColumnString(3)); |
| |
| // Extract category id for joining with sites. |
| int category_id = cat_data_s.ColumnInt(4); |
| |
| sql::Statement site_count_s( |
| db->GetUniqueStatement("SELECT COUNT(*) FROM sites")); |
| site_count_s.Step(); |
| EXPECT_EQ(2, site_count_s.ColumnInt(0)); |
| |
| sql::Statement site_data_s(db->GetUniqueStatement( |
| "SELECT url, category_id, title, favicon FROM sites")); |
| site_data_s.Step(); |
| EXPECT_EQ(kGoogleUrl, site_data_s.ColumnString(0)); |
| EXPECT_EQ(category_id, site_data_s.ColumnInt(1)); |
| EXPECT_EQ(kGoogleTitle, site_data_s.ColumnString(2)); |
| EXPECT_EQ(kIcon, site_data_s.ColumnString(3)); |
| |
| site_data_s.Step(); |
| EXPECT_EQ(kGmailUrl, site_data_s.ColumnString(0)); |
| EXPECT_EQ(category_id, site_data_s.ColumnInt(1)); |
| EXPECT_EQ(kGmailTitle, site_data_s.ColumnString(2)); |
| EXPECT_EQ(kIcon, site_data_s.ColumnString(3)); |
| return true; |
| })); |
| } |
| |
| } // namespace explore_sites |