chromium/chrome/browser/ash/child_accounts/on_device_controls/blocked_app_store_unittest.cc

// Copyright 2024 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/child_accounts/on_device_controls/blocked_app_store.h"

#include <memory>
#include <optional>
#include <string>

#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/ash/child_accounts/on_device_controls/blocked_app_types.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash::on_device_controls {

// Tests blocked app registry.
class BlockedAppStoreTest : public testing::Test {
 public:
  BlockedAppStoreTest() = default;
  BlockedAppStoreTest(const BlockedAppStoreTest&) = delete;
  BlockedAppStoreTest& operator=(const BlockedAppStoreTest&) = delete;

  ~BlockedAppStoreTest() override = default;

 protected:
  BlockedAppStore* store() { return store_.get(); }

  // testing::Test:
  void SetUp() override;

 private:
  content::BrowserTaskEnvironment task_environment_;
  TestingProfile profile_;

  std::unique_ptr<BlockedAppStore> store_;
};

void BlockedAppStoreTest::SetUp() {
  testing::Test::SetUp();

  store_ = std::make_unique<BlockedAppStore>(profile_.GetPrefs());
}

// Tests reading from the empty preference.
TEST_F(BlockedAppStoreTest, TestGetFromEmptyPref) {
  BlockedAppMap apps = store()->GetFromPref();

  EXPECT_EQ(0UL, apps.size());
}

// Tests writing and reading one blocked app.
TEST_F(BlockedAppStoreTest, TestBlockedApp) {
  BlockedAppMap apps_in;

  const std::string app_id = "abc";
  const base::Time timestamp = base::Time::Now();
  apps_in[app_id] = BlockedAppDetails(timestamp);

  store()->SaveToPref(apps_in);

  const BlockedAppMap apps_out = store()->GetFromPref();
  EXPECT_EQ(1UL, apps_out.size());
  ASSERT_TRUE(base::Contains(apps_out, app_id));
  EXPECT_EQ(timestamp, apps_out.at(app_id).block_timestamp());
  EXPECT_EQ(std::nullopt, apps_out.at(app_id).uninstall_timestamp());
}

// Tests writing and reading one uninstalled app.
TEST_F(BlockedAppStoreTest, TestUninstalledApp) {
  BlockedAppMap apps_in;

  const std::string app_id = "abc";
  const base::Time block_timestamp = base::Time::Now();
  const base::Time uninstall_timestamp = base::Time::Now() + base::Minutes(5);
  apps_in[app_id] = BlockedAppDetails(block_timestamp, uninstall_timestamp);

  store()->SaveToPref(apps_in);

  const BlockedAppMap apps_out = store()->GetFromPref();
  EXPECT_EQ(1UL, apps_out.size());
  ASSERT_TRUE(base::Contains(apps_out, app_id));
  EXPECT_EQ(block_timestamp, apps_out.at(app_id).block_timestamp());
  EXPECT_EQ(uninstall_timestamp, *apps_out.at(app_id).uninstall_timestamp());
}

// Tests writing and reading multiple apps.
TEST_F(BlockedAppStoreTest, TestMultipleApps) {
  const std::string base_app_id = "abc";
  const base::Time initial_time = base::Time::Now();
  const base::TimeDelta uninstall_delta = base::Hours(5);
  const base::TimeDelta block_delta = base::Minutes(13);
  const size_t apps_count = 10;

  BlockedAppMap apps_in;
  base::Time timestamp = initial_time;
  // Adds apps with the different block and uninstall timestamps.
  for (size_t i = 0; i < apps_count; ++i) {
    const std::string app_id =
        base::StrCat({base_app_id, base::NumberToString(i)});
    apps_in[app_id] = BlockedAppDetails(timestamp, timestamp + uninstall_delta);
    timestamp += block_delta;
  }

  store()->SaveToPref(apps_in);

  const BlockedAppMap apps_out = store()->GetFromPref();
  EXPECT_EQ(apps_count, apps_out.size());

  for (size_t i = 0; i < apps_count; ++i) {
    const std::string app_id =
        base::StrCat({base_app_id, base::NumberToString(i)});
    ASSERT_TRUE(base::Contains(apps_out, app_id));

    const BlockedAppDetails& details = apps_out.at(app_id);

    const base::Time expected_block_time = initial_time + i * block_delta;
    EXPECT_EQ(expected_block_time, details.block_timestamp());

    const base::Time expected_uninstall_time =
        expected_block_time + uninstall_delta;
    EXPECT_EQ(expected_uninstall_time, *details.uninstall_timestamp());
  }
}

}  // namespace ash::on_device_controls