// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/desks_storage/core/local_desk_data_manager.h"
#include <stddef.h>
#include <string>
#include <string_view>
#include "ash/public/cpp/desk_template.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/account_id/account_id.h"
#include "components/app_constants/constants.h"
#include "components/desks_storage/core/desk_storage_metrics_util.h"
#include "components/desks_storage/core/desk_template_conversion.h"
#include "components/desks_storage/core/desk_template_util.h"
#include "components/desks_storage/core/desk_test_util.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace desks_storage {
namespace {
using TestUuidId = base::StrongAlias<class TestUuidIdTag, int>;
// Search `entry_list` for `entry_query` as a uuid and returns true if
// found, false if not.
bool FindUuidInUuidList(
const base::Uuid& uuid,
const std::vector<raw_ptr<const ash::DeskTemplate, VectorExperimental>>&
entry_list) {
for (const ash::DeskTemplate* entry : entry_list) {
if (entry->uuid() == uuid)
return true;
}
return false;
}
base::FilePath GetInvalidFilePath() {
return base::FilePath(FILE_PATH_LITERAL("?"));
}
base::Uuid GetTestUuid(TestUuidId uuid_id) {
return base::Uuid::ParseCaseInsensitive(
base::StringPrintf("1c186d5a-502e-49ce-9ee1-%012d", uuid_id.value()));
}
std::string GetTestFileNameString(TestUuidId uuid_id) {
return base::StringPrintf("%s.template",
GetTestUuid(uuid_id).AsLowercaseString().c_str());
}
std::string GetTestSaveDeskFileNameString(TestUuidId uuid_id) {
return base::StringPrintf("%s.saveddesk",
GetTestUuid(uuid_id).AsLowercaseString().c_str());
}
std::string GetTestTemplateJSONData() {
return "{\"version\":1,\"uuid\":\"" +
GetTestUuid(TestUuidId(1)).AsLowercaseString() +
"\",\"name\":\""
"Saved Desk Template 1"
"\",\"created_time_usec\":\"1633535632\",\"updated_time_usec\": "
"\"1633535632\",\"desk\":{\"apps\":[{\"window_"
"bound\":{\"left\":0,\"top\":1,\"height\":121,\"width\":120},\"window_"
"state\":\"NORMAL\",\"z_index\":1,\"app_type\":\"BROWSER\",\"tabs\":[{"
"\"url\":\"https://"
"example.com\",\"title\":\"Example\"},{\"url\":\"https://"
"example.com/"
"2\",\"title\":\"Example2\"}],\"active_tab_index\":1,\"window_id\":0,"
"\"display_id\":\"100\",\"pre_minimized_window_state\":\"NORMAL\"}]}}";
}
std::string GetPolicyWithOneTemplate() {
return "[{\"version\":1,\"uuid\":\"" +
GetTestUuid(TestUuidId(9)).AsLowercaseString() +
"\",\"name\":\""
"Admin Template 1"
"\",\"created_time_usec\":\"1633535632\",\"updated_time_usec\": "
"\"1633535632\",\"desk\":{\"apps\":[{\"window_"
"bound\":{\"left\":0,\"top\":1,\"height\":121,\"width\":120},\"window_"
"state\":\"NORMAL\",\"z_index\":1,\"app_type\":\"BROWSER\",\"tabs\":[{"
"\"url\":\"https://"
"example.com\",\"title\":\"Example\"},{\"url\":\"https://"
"example.com/"
"2\",\"title\":\"Example2\"}],\"active_tab_index\":1,\"window_id\":0,"
"\"display_id\":\"100\",\"pre_minimized_window_state\":\"NORMAL\"}]}}"
"]";
}
std::string GetUnParseableTemplate() {
return "????????/asdfg;.lkawhuerfflizHxcbklnmzd;kldfgjha;owwem";
}
// Verifies that the status passed into it is kOk
void VerifyEntryAddedCorrectly(DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kOk);
}
// Verifies that the status passed into it is kOk
void VerifyEntryDeletedCorrectly(DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}
// Verifies that the status passed into it is kFailure
void VerifyEntryAddedFailure(DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kFailure);
}
// Verifies that the status passed into it is kInvalidArgument
void VerifyEntryAddedErrorInvalidArgument(
DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kInvalidArgument);
}
void VerifyEntryAddedErrorHitMaximumLimit(
DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kHitMaximumLimit);
}
void WriteJunkData(const base::FilePath& temp_dir) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
EXPECT_TRUE(
base::WriteFile(temp_dir.Append(GetTestFileNameString(TestUuidId(1))),
"This is not valid template data."));
}
void WriteIncorrectlyNamedData(const base::FilePath& temp_dir) {
base::FilePath saved_desk_path = temp_dir.Append("saveddesk");
base::CreateDirectory(saved_desk_path);
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
EXPECT_TRUE(base::WriteFile(
saved_desk_path.Append(GetTestSaveDeskFileNameString(TestUuidId(2))),
GetTestTemplateJSONData()));
}
// Make test template with ID containing the index. Defaults to desk template
// type if a type is not specified.
std::unique_ptr<ash::DeskTemplate> MakeTestDeskTemplate(
int index,
ash::DeskTemplateType type) {
std::unique_ptr<ash::DeskTemplate> desk_template =
std::make_unique<ash::DeskTemplate>(
base::Uuid::ParseCaseInsensitive(base::StringPrintf(
"1c186d5a-502e-49ce-9ee1-00000000000%d", index)),
ash::DeskTemplateSource::kUser, base::StringPrintf("desk_%d", index),
base::Time::Now(), type);
desk_template->set_desk_restore_data(
std::make_unique<app_restore::RestoreData>());
return desk_template;
}
// Make test template with default restore data.
std::unique_ptr<ash::DeskTemplate> MakeTestDeskTemplate(
const base::Uuid& uuid,
ash::DeskTemplateSource source,
const std::string& name,
const base::Time created_time) {
auto entry = std::make_unique<ash::DeskTemplate>(
uuid, source, name, created_time, ash::DeskTemplateType::kTemplate);
entry->set_desk_restore_data(std::make_unique<app_restore::RestoreData>());
return entry;
}
// Make test save and recall desk with default restore data.
std::unique_ptr<ash::DeskTemplate> MakeTestSaveAndRecallDesk(
const base::Uuid& uuid,
const std::string& name,
const base::Time created_time) {
auto entry = std::make_unique<ash::DeskTemplate>(
uuid, ash::DeskTemplateSource::kUser, name, created_time,
ash::DeskTemplateType::kSaveAndRecall);
entry->set_desk_restore_data(std::make_unique<app_restore::RestoreData>());
return entry;
}
// Creates a template with the same UUID as the test policy template but with
// a different policy.
std::unique_ptr<ash::DeskTemplate> MakePolicyTemplateWithEmptyPolicy() {
std::unique_ptr<ash::DeskTemplate> desk_template =
std::make_unique<ash::DeskTemplate>(
base::Uuid::ParseCaseInsensitive(
"27ea906b-a7d3-40b1-8c36-76d332d7f184"),
ash::DeskTemplateSource::kUser, base::StringPrintf("desk_01"),
base::Time::Now(), ash::DeskTemplateType::kTemplate, false,
base::Value());
desk_template->set_desk_restore_data(
std::make_unique<app_restore::RestoreData>());
return desk_template;
}
} // namespace
// TODO(crbug:1320940): Clean up tests to move on from std::string.
class LocalDeskDataManagerTest : public testing::Test {
public:
LocalDeskDataManagerTest()
: sample_desk_template_one_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(1)),
ash::DeskTemplateSource::kUser,
std::string("desk_01"),
base::Time())),
sample_desk_template_one_duplicate_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(5)),
ash::DeskTemplateSource::kUser,
std::string("desk_01"),
base::Time::Now())),
sample_desk_template_one_duplicate_two_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(6)),
ash::DeskTemplateSource::kUser,
std::string("desk_01"),
base::Time::Now())),
duplicate_pattern_matching_named_desk_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(7)),
ash::DeskTemplateSource::kUser,
std::string("(1) desk_template"),
base::Time::Now())),
duplicate_pattern_matching_named_desk_two_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(8)),
ash::DeskTemplateSource::kUser,
std::string("(1) desk_template"),
base::Time::Now())),
duplicate_pattern_matching_named_desk_three_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(9)),
ash::DeskTemplateSource::kUser,
std::string("(1) desk_template"),
base::Time::Now())),
sample_desk_template_two_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(2)),
ash::DeskTemplateSource::kUser,
std::string("desk_02"),
base::Time::Now())),
sample_desk_template_three_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(3)),
ash::DeskTemplateSource::kUser,
std::string("desk_03"),
base::Time::Now())),
sample_save_and_recall_desk_one_(
MakeTestSaveAndRecallDesk(GetTestUuid(TestUuidId(10)),
"save_and_recall_desk_01",
base::Time())),
sample_save_and_recall_desk_two_(
MakeTestSaveAndRecallDesk(GetTestUuid(TestUuidId(11)),
"save_and_recall_desk_02",
base::Time::Now())),
sample_save_and_recall_desk_three_(
MakeTestSaveAndRecallDesk(GetTestUuid(TestUuidId(12)),
"save_and_recall_desk_03",
base::Time::Now())),
modified_sample_desk_template_one_(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(1)),
ash::DeskTemplateSource::kUser,
std::string("desk_01_mod"),
base::Time())),
task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
cache_(std::make_unique<apps::AppRegistryCache>()),
account_id_(AccountId::FromUserEmail("[email protected]")),
data_manager_(std::unique_ptr<LocalDeskDataManager>()) {}
LocalDeskDataManagerTest(const LocalDeskDataManagerTest&) = delete;
LocalDeskDataManagerTest& operator=(const LocalDeskDataManagerTest&) = delete;
~LocalDeskDataManagerTest() override = default;
void SetUp() override {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
data_manager_ = std::make_unique<LocalDeskDataManager>(temp_dir_.GetPath(),
account_id_);
desk_test_util::PopulateAppRegistryCache(account_id_, cache_.get());
task_environment_.RunUntilIdle();
testing::Test::SetUp();
}
void AddTwoTemplates() {
base::RunLoop loop1;
data_manager_->AddOrUpdateEntry(
std::move(sample_desk_template_one_),
base::BindLambdaForTesting(
[&](DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(DeskModel::AddOrUpdateEntryStatus::kOk, status);
loop1.Quit();
}));
loop1.Run();
base::RunLoop loop2;
data_manager_->AddOrUpdateEntry(
std::move(sample_desk_template_two_),
base::BindLambdaForTesting(
[&](DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(DeskModel::AddOrUpdateEntryStatus::kOk, status);
loop2.Quit();
}));
loop2.Run();
}
void AddTwoSaveAndRecallDeskTemplates() {
base::RunLoop loop1;
data_manager_->AddOrUpdateEntry(
std::move(sample_save_and_recall_desk_one_),
base::BindLambdaForTesting(
[&](DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(DeskModel::AddOrUpdateEntryStatus::kOk, status);
loop1.Quit();
}));
loop1.Run();
base::RunLoop loop2;
data_manager_->AddOrUpdateEntry(
std::move(sample_save_and_recall_desk_two_),
base::BindLambdaForTesting(
[&](DeskModel::AddOrUpdateEntryStatus status,
std::unique_ptr<ash::DeskTemplate> new_entry) {
EXPECT_EQ(DeskModel::AddOrUpdateEntryStatus::kOk, status);
loop2.Quit();
}));
loop2.Run();
}
void VerifyAllEntries(size_t expected_size, const std::string& trace_string) {
SCOPED_TRACE(trace_string);
task_environment_.RunUntilIdle();
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.status, DeskModel::GetAllEntriesStatus::kOk);
EXPECT_EQ(result.entries.size(), expected_size);
}
void VerifyUpdateEntryDuplicate() {
EXPECT_EQ(data_manager_->last_update_status_,
LocalDeskDataManager::UpdateEntryStatus::kDuplicate);
}
void VerifyUpdateEntryOk() {
EXPECT_EQ(data_manager_->last_update_status_,
LocalDeskDataManager::UpdateEntryStatus::kOk);
}
void VerifyUpdateEntryOutdatePolicy() {
EXPECT_EQ(data_manager_->last_update_status_,
LocalDeskDataManager::UpdateEntryStatus::kOutdatedPolicy);
}
void VerifyUpdateEntryNotFound() {
EXPECT_EQ(data_manager_->last_update_status_,
LocalDeskDataManager::UpdateEntryStatus::kNotFound);
}
base::ScopedTempDir temp_dir_;
std::unique_ptr<ash::DeskTemplate> sample_desk_template_one_;
std::unique_ptr<ash::DeskTemplate> sample_desk_template_one_duplicate_;
std::unique_ptr<ash::DeskTemplate> sample_desk_template_one_duplicate_two_;
std::unique_ptr<ash::DeskTemplate> duplicate_pattern_matching_named_desk_;
std::unique_ptr<ash::DeskTemplate> duplicate_pattern_matching_named_desk_two_;
std::unique_ptr<ash::DeskTemplate>
duplicate_pattern_matching_named_desk_three_;
std::unique_ptr<ash::DeskTemplate> sample_desk_template_two_;
std::unique_ptr<ash::DeskTemplate> sample_desk_template_three_;
std::unique_ptr<ash::DeskTemplate> sample_save_and_recall_desk_one_;
std::unique_ptr<ash::DeskTemplate> sample_save_and_recall_desk_two_;
std::unique_ptr<ash::DeskTemplate> sample_save_and_recall_desk_three_;
std::unique_ptr<ash::DeskTemplate> modified_sample_desk_template_one_;
base::test::TaskEnvironment task_environment_;
std::unique_ptr<apps::AppRegistryCache> cache_;
AccountId account_id_;
std::unique_ptr<LocalDeskDataManager> data_manager_;
};
// TODO(crbug/1320949): Pass a callback to VerifyEntryAdded.
TEST_F(LocalDeskDataManagerTest, CanAddEntry) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, ReturnsErrorWhenAddingTooManyEntry) {
for (size_t index = 0u; index < data_manager_->GetMaxDeskTemplateEntryCount();
++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(data_manager_->GetMaxDeskTemplateEntryCount() + 1,
ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedErrorHitMaximumLimit));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest,
ReturnsErrorWhenAddingTooManySaveAndRecallDeskEntry) {
for (size_t index = 0u;
index < data_manager_->GetMaxSaveAndRecallDeskEntryCount(); ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(
data_manager_->GetMaxSaveAndRecallDeskEntryCount() + 1,
ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedErrorHitMaximumLimit));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, CanGetAllEntries) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.status, DeskModel::GetAllEntriesStatus::kOk);
EXPECT_EQ(result.entries.size(), 3ul);
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(1)), result.entries));
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(2)), result.entries));
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(3)), result.entries));
// Sanity check for the search function.
EXPECT_FALSE(FindUuidInUuidList(GetTestUuid(TestUuidId(4)), result.entries));
}
TEST_F(LocalDeskDataManagerTest, CanGetAllUuids) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
std::set<base::Uuid> entry_uuids = data_manager_->GetAllEntryUuids();
entry_uuids.erase(GetTestUuid(TestUuidId(1)));
entry_uuids.erase(GetTestUuid(TestUuidId(2)));
entry_uuids.erase(GetTestUuid(TestUuidId(3)));
// We should have exactly the correct set of IDs returned from the model.
EXPECT_TRUE(entry_uuids.empty());
}
TEST_F(LocalDeskDataManagerTest, GetAllEntriesIncludesPolicyValues) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->SetPolicyDeskTemplates(GetPolicyWithOneTemplate());
task_environment_.RunUntilIdle();
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.status, DeskModel::GetAllEntriesStatus::kOk);
EXPECT_EQ(result.entries.size(), 4ul);
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(1)), result.entries));
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(2)), result.entries));
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(3)), result.entries));
EXPECT_TRUE(FindUuidInUuidList(GetTestUuid(TestUuidId(9)), result.entries));
// One of these templates should be from policy.
EXPECT_EQ(base::ranges::count_if(result.entries,
[](const ash::DeskTemplate* entry) {
return entry->source() ==
ash::DeskTemplateSource::kPolicy;
}),
1l);
// Sanity check for the search function.
EXPECT_FALSE(FindUuidInUuidList(GetTestUuid(TestUuidId(4)), result.entries));
data_manager_->SetPolicyDeskTemplates("");
}
TEST_F(LocalDeskDataManagerTest, CanDetectDuplicateEntryNames) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(
std::move(sample_desk_template_one_duplicate_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(
std::move(sample_desk_template_one_duplicate_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
EXPECT_TRUE(data_manager_->FindOtherEntryWithName(
base::UTF8ToUTF16(std::string("desk_01")),
ash::DeskTemplateType::kTemplate, GetTestUuid(TestUuidId(1))));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, CanDetectNoDuplicateEntryNames) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
EXPECT_FALSE(data_manager_->FindOtherEntryWithName(
base::UTF8ToUTF16(std::string("desk_01")),
ash::DeskTemplateType::kTemplate, GetTestUuid(TestUuidId(1))));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, CanGetEntryByUuid) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
EXPECT_EQ(GetTestUuid(TestUuidId(1)), result.entry->uuid());
EXPECT_EQ(base::UTF8ToUTF16(std::string("desk_01")),
result.entry->template_name());
EXPECT_EQ(base::Time(), result.entry->created_time());
}
TEST_F(LocalDeskDataManagerTest, GetEntryByUuidShouldReturnAdminTemplate) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
// Set admin template with UUID: GetTestUuid(TestUuidId(9)).
data_manager_->SetPolicyDeskTemplates(GetPolicyWithOneTemplate());
task_environment_.RunUntilIdle();
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(9)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
EXPECT_EQ(GetTestUuid(TestUuidId(9)), result.entry->uuid());
EXPECT_EQ(ash::DeskTemplateSource::kPolicy, result.entry->source());
EXPECT_EQ(base::UTF8ToUTF16(std::string("Admin Template 1")),
result.entry->template_name());
}
TEST_F(LocalDeskDataManagerTest,
GetEntryByUuidReturnsNotFoundIfEntryDoesNotExist) {
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kNotFound, result.status);
}
TEST_F(LocalDeskDataManagerTest, DeskTemplateIsIgnoredIfItHasBadData) {
auto task_runner = task_environment_.GetMainThreadTaskRunner();
task_runner->PostTask(FROM_HERE,
base::BindOnce(&WriteJunkData, temp_dir_.GetPath()));
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kNotFound, result.status);
}
TEST_F(LocalDeskDataManagerTest,
GetEntryByUuidReturnsFailureIfDeskManagerHasInvalidPath) {
data_manager_ =
std::make_unique<LocalDeskDataManager>(GetInvalidFilePath(), account_id_);
task_environment_.RunUntilIdle();
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kFailure, result.status);
}
TEST_F(LocalDeskDataManagerTest,
CanRenameSavedDeskTemplateIfFilenameDoesNotMatchUUID) {
// Initialize new local temp directory
base::ScopedTempDir local_temp_dir;
EXPECT_TRUE(local_temp_dir.CreateUniqueTempDir());
// Pre-write file into directory for correcting
task_environment_.GetMainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&WriteIncorrectlyNamedData, local_temp_dir.GetPath()));
task_environment_.RunUntilIdle();
EXPECT_TRUE(base::PathExists(
local_temp_dir.GetPath()
.Append("saveddesk")
.Append(GetTestSaveDeskFileNameString(TestUuidId(2)))));
EXPECT_FALSE(base::PathExists(
local_temp_dir.GetPath()
.Append("saveddesk")
.Append(GetTestSaveDeskFileNameString(TestUuidId(1)))));
// Initialize temp data manager
auto temp_data_manager_ = std::make_unique<LocalDeskDataManager>(
local_temp_dir.GetPath(), account_id_);
task_environment_.RunUntilIdle();
// Retrieve entry from test directory
auto result = temp_data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
EXPECT_EQ(result.entry->uuid(), GetTestUuid(TestUuidId(1)));
EXPECT_EQ(temp_data_manager_->GetEntryCount(), 1u);
EXPECT_TRUE(base::PathExists(
local_temp_dir.GetPath()
.Append("saveddesk")
.Append(GetTestSaveDeskFileNameString(TestUuidId(1)))));
EXPECT_FALSE(base::PathExists(
local_temp_dir.GetPath()
.Append("saveddesk")
.Append(GetTestSaveDeskFileNameString(TestUuidId(2)))));
}
TEST_F(LocalDeskDataManagerTest, CanUpdateEntry) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(modified_sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(1)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
EXPECT_EQ(GetTestUuid(TestUuidId(1)), result.entry->uuid());
EXPECT_EQ(base::UTF8ToUTF16(std::string("desk_01_mod")),
result.entry->template_name());
EXPECT_EQ(base::Time(), result.entry->created_time());
}
TEST_F(LocalDeskDataManagerTest, CanDeleteEntry) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->DeleteEntry(
GetTestUuid(TestUuidId(1)),
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
VerifyAllEntries(0ul, "Delete one entry");
}
TEST_F(LocalDeskDataManagerTest, CanDeleteAllEntries) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->DeleteAllEntries(
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
VerifyAllEntries(0ul, "Delete all entries");
}
TEST_F(LocalDeskDataManagerTest,
GetEntryCountShouldIncludeBothUserAndAdminTemplates) {
// Add two user templates.
AddTwoTemplates();
// Set one admin template.
data_manager_->SetPolicyDeskTemplates(GetPolicyWithOneTemplate());
// There should be 3 templates: 2 user templates + 1 admin template.
EXPECT_EQ(3ul, data_manager_->GetEntryCount());
}
TEST_F(LocalDeskDataManagerTest,
GetMaxEntryCountShouldIncreaseWithAdminTemplates) {
// Add two user templates.
AddTwoTemplates();
size_t max_entry_count = data_manager_->GetMaxDeskTemplateEntryCount() +
data_manager_->GetMaxSaveAndRecallDeskEntryCount();
EXPECT_EQ(12ul, max_entry_count);
// Set one admin template.
data_manager_->SetPolicyDeskTemplates(GetPolicyWithOneTemplate());
size_t max_entry_count_with_admin_template =
data_manager_->GetMaxDeskTemplateEntryCount() +
data_manager_->GetMaxSaveAndRecallDeskEntryCount();
// The max entry count should increase by 1 since we have set an admin
// template.
EXPECT_EQ(13ul, max_entry_count_with_admin_template);
}
TEST_F(LocalDeskDataManagerTest, AddDeskTemplatesAndSaveAndRecallDeskEntries) {
// Add two user templates.
AddTwoTemplates();
// Add two SaveAndRecall desks.
AddTwoSaveAndRecallDeskTemplates();
EXPECT_EQ(data_manager_->GetEntryCount(), 4ul);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 2ul);
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 2ul);
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.status, DeskModel::GetAllEntriesStatus::kOk);
VerifyAllEntries(4ul,
"Add two desks templates and two saved and recall desks");
}
TEST_F(LocalDeskDataManagerTest, AddSaveAndRecallDeskEntry) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(1u, ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedCorrectly));
VerifyAllEntries(1ul, "Added one save and recall desk");
// Verify that it's not SaveAndRecall entry in the desk template cache.
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.status, DeskModel::GetAllEntriesStatus::kOk);
EXPECT_EQ(result.entries.size(), 1ul);
EXPECT_EQ(result.entries[0]->type(), ash::DeskTemplateType::kSaveAndRecall);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 0ul);
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 1ul);
}
TEST_F(LocalDeskDataManagerTest, CanGetSaveAndRecallDeskEntryByUuid) {
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
auto result = data_manager_->GetEntryByUUID(GetTestUuid(TestUuidId(10)));
EXPECT_EQ(DeskModel::GetEntryByUuidStatus::kOk, result.status);
EXPECT_EQ(GetTestUuid(TestUuidId(10)), result.entry->uuid());
EXPECT_EQ(u"save_and_recall_desk_01", result.entry->template_name());
EXPECT_EQ(base::Time(), result.entry->created_time());
}
TEST_F(LocalDeskDataManagerTest, CanDeleteSaveAndRecallDeskEntry) {
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
VerifyAllEntries(1ul, "Added one save and recall desk");
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 1ul);
data_manager_->DeleteEntry(
GetTestUuid(TestUuidId(10)),
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
VerifyAllEntries(0ul, "Deleted one save and recall desk");
}
TEST_F(LocalDeskDataManagerTest, CanAddMaxEntriesForBothTypes) {
for (size_t index = 0u;
index < data_manager_->GetMaxSaveAndRecallDeskEntryCount(); ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
for (size_t index = 0u; index < data_manager_->GetMaxDeskTemplateEntryCount();
++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
VerifyAllEntries(
12ul, "Added max number of save and recall desks and desk templates");
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 6ul);
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 6ul);
}
TEST_F(LocalDeskDataManagerTest, CanDeleteAllEntriesOfBothTypes) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_two_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_three_),
base::BindOnce(&VerifyEntryAddedCorrectly));
VerifyAllEntries(6ul,
"Added a mix of save and recall desks and desk templates");
data_manager_->DeleteAllEntries(
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
VerifyAllEntries(0ul, "Deleted all entries");
EXPECT_EQ(0ul, data_manager_->GetEntryCount());
}
TEST_F(LocalDeskDataManagerTest,
CanAddMaxEntriesDeskTemplatesAndStillAddEntryForSaveAndRecallDesks) {
for (size_t index = 0u; index < data_manager_->GetMaxDeskTemplateEntryCount();
++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(1ul, ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedCorrectly));
VerifyAllEntries(7ul,
"Added one save and recall desk after capping "
"desk template entries");
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 6ul);
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 1ul);
}
TEST_F(LocalDeskDataManagerTest,
CanAddMaxEntriesForSaveAndRecallDeskAndStillAddEntryForDeskTemplate) {
for (size_t index = 0u;
index < data_manager_->GetMaxSaveAndRecallDeskEntryCount(); ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kSaveAndRecall),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(1ul, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
VerifyAllEntries(7ul,
"Added one desk template after capping "
"save and recall desk entries");
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 1ul);
EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 6ul);
}
TEST_F(LocalDeskDataManagerTest, RollbackUpdateTemplatesOnFileWriteFailure) {
// Add two user templates.
for (size_t index = 0u; index < 2u; ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
EXPECT_EQ(data_manager_->GetEntryCount(), 2ul);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 2ul);
task_environment_.RunUntilIdle();
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER);
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(1ul, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedFailure));
VerifyAllEntries(2ul,
"Updated one desk template failed to write to file system");
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER |
base::FILE_PERMISSION_WRITE_BY_USER |
base::FILE_PERMISSION_EXECUTE_BY_USER);
}
TEST_F(LocalDeskDataManagerTest, RollbackAddTemplatesOnFileWriteFailure) {
// Add two user templates.
for (size_t index = 0u; index < 2u; ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
EXPECT_EQ(data_manager_->GetEntryCount(), 2ul);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 2ul);
task_environment_.RunUntilIdle();
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER);
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(3ul, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedFailure));
task_environment_.RunUntilIdle();
VerifyAllEntries(2ul, "Add one desk template failed to write to file system");
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER |
base::FILE_PERMISSION_WRITE_BY_USER |
base::FILE_PERMISSION_EXECUTE_BY_USER);
}
TEST_F(LocalDeskDataManagerTest, RollbackDeleteTemplatesOnFileDeleteFailure) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
EXPECT_EQ(data_manager_->GetEntryCount(), 1ul);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 1ul);
task_environment_.RunUntilIdle();
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER);
data_manager_->DeleteEntry(
GetTestUuid(TestUuidId(1)),
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kFailure);
}));
task_environment_.RunUntilIdle();
VerifyAllEntries(1ul, "Delete desk template failed to delete on file system");
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER |
base::FILE_PERMISSION_WRITE_BY_USER |
base::FILE_PERMISSION_EXECUTE_BY_USER);
}
TEST_F(LocalDeskDataManagerTest,
RollbackDeleteAllTemplatesOnFileDeleteFailure) {
// Add four user templates.
for (size_t index = 0u; index < 4u; ++index) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
}
EXPECT_EQ(data_manager_->GetEntryCount(), 4ul);
EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 4ul);
task_environment_.RunUntilIdle();
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER);
data_manager_->DeleteAllEntries(
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kFailure);
}));
task_environment_.RunUntilIdle();
VerifyAllEntries(4ul,
"Delete all desk template failed to delete on file system");
base::SetPosixFilePermissions(temp_dir_.GetPath(),
base::FILE_PERMISSION_READ_BY_USER |
base::FILE_PERMISSION_WRITE_BY_USER |
base::FILE_PERMISSION_EXECUTE_BY_USER);
}
// Note: To fully utilize this test build and run it in a tsan build.
// Instructions to do so can be found at:
// //docs/website/site/developers/testing/threadsanitizer-tsan-v2/index.md
// Otherwise the tsan tryjob should catch this test failing in CQ.
TEST_F(LocalDeskDataManagerTest, StressTestModifyingEntriesForThreadSafety) {
constexpr uint32_t kThreadSafeIterations = 1000;
for (uint32_t iteration = 0; iteration < kThreadSafeIterations; ++iteration) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(iteration % 10, ash::DeskTemplateType::kTemplate),
base::BindOnce(&VerifyEntryAddedCorrectly));
if (iteration % data_manager_->GetDeskTemplateEntryCount() == 0) {
data_manager_->DeleteAllEntries(
base::BindOnce(&VerifyEntryDeletedCorrectly));
}
}
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, DeleteSameEntryAgain) {
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->DeleteEntry(
GetTestUuid(TestUuidId(1)),
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
data_manager_->DeleteEntry(
GetTestUuid(TestUuidId(1)),
base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) {
EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk);
}));
VerifyAllEntries(0ul, "Delete one entry");
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, CanHandleFileErrorGracefully) {
base::ScopedTempDir local_temp_dir;
EXPECT_TRUE(local_temp_dir.CreateUniqueTempDir());
// Write out file that should not be parseable.
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
base::FilePath path_to_dir = local_temp_dir.GetPath().Append("saveddesk");
base::CreateDirectory(path_to_dir);
EXPECT_TRUE(base::WriteFile(path_to_dir.Append("bad_format.saveddesk"),
GetUnParseableTemplate()));
auto local_data_manager = std::make_unique<LocalDeskDataManager>(
local_temp_dir.GetPath(), account_id_);
task_environment_.RunUntilIdle();
EXPECT_EQ(local_data_manager->GetEntryCount(), static_cast<size_t>(0));
}
TEST_F(LocalDeskDataManagerTest, CanRecordFileSizeMetrics) {
base::HistogramTester histogram_tester;
data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
data_manager_->AddOrUpdateEntry(std::move(sample_save_and_recall_desk_one_),
base::BindOnce(&VerifyEntryAddedCorrectly));
task_environment_.RunUntilIdle();
histogram_tester.ExpectTotalCount(kTemplateSizeHistogramName, 1u);
histogram_tester.ExpectTotalCount(kSaveAndRecallTemplateSizeHistogramName,
1u);
}
TEST_F(LocalDeskDataManagerTest, AddUnknownDeskTypeShouldFail) {
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(1u, ash::DeskTemplateType::kUnknown),
base::BindOnce(&VerifyEntryAddedErrorInvalidArgument));
task_environment_.RunUntilIdle();
}
TEST_F(LocalDeskDataManagerTest, UpdtesAdminTemplatesCorrectly) {
// populate with single template.
data_manager_->AddOrUpdateEntry(
MakeTestDeskTemplate(GetTestUuid(TestUuidId(5)),
ash::DeskTemplateSource::kUser,
std::string("desk_01"), base::Time::Now()),
base::BindOnce(&VerifyEntryAddedCorrectly));
// Update with modified template.
data_manager_->UpdateEntry(MakeTestDeskTemplate(
GetTestUuid(TestUuidId(5)), ash::DeskTemplateSource::kUser,
std::string("desk_02"), base::Time::Now()));
task_environment_.RunUntilIdle();
VerifyAllEntries(1ul, "Updated template");
auto result = data_manager_->GetAllEntries();
EXPECT_EQ(result.entries.at(0)->template_name(), u"desk_02");
VerifyUpdateEntryOk();
}
TEST_F(LocalDeskDataManagerTest, IngoresUpdateForNonExistantTemplate) {
// Update with modified template.
data_manager_->UpdateEntry(MakeTestDeskTemplate(
GetTestUuid(TestUuidId(5)), ash::DeskTemplateSource::kUser,
std::string("desk_02"), base::Time::Now()));
task_environment_.RunUntilIdle();
VerifyAllEntries(0ul, "Updated template");
VerifyUpdateEntryNotFound();
}
TEST_F(LocalDeskDataManagerTest, DoesNotUpdateWhenRestoreContentIsTheSame) {
auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(
std::string_view(desk_test_util::kAdminTemplatePolicyWithOneTemplate));
EXPECT_TRUE(parsed_json.has_value());
EXPECT_TRUE(parsed_json->is_list());
// "retrieve policy" and add it to the model. We do this to easily get a
// fully enough defined template.
std::vector<std::unique_ptr<ash::DeskTemplate>> parsed_policy =
desk_template_conversion::ParseAdminTemplatesFromPolicyValue(
parsed_json.value());
data_manager_->AddOrUpdateEntry(parsed_policy.at(0)->Clone(),
base::BindOnce(&VerifyEntryAddedCorrectly));
// If we update the template it should return kDuplicate.
data_manager_->UpdateEntry(parsed_policy.at(0)->Clone());
VerifyUpdateEntryDuplicate();
}
TEST_F(LocalDeskDataManagerTest, DoesNotOverwriteOnDifferentPolicy) {
auto parsed_json = base::JSONReader::ReadAndReturnValueWithError(
std::string_view(desk_test_util::kAdminTemplatePolicyWithOneTemplate));
EXPECT_TRUE(parsed_json.has_value());
EXPECT_TRUE(parsed_json->is_list());
// "retrieve policy" and add it to the model. We do this to easily get a
// fully enough defined template.
std::vector<std::unique_ptr<ash::DeskTemplate>> parsed_policy =
desk_template_conversion::ParseAdminTemplatesFromPolicyValue(
parsed_json.value());
data_manager_->AddOrUpdateEntry(parsed_policy.at(0)->Clone(),
base::BindOnce(&VerifyEntryAddedCorrectly));
// If we update the template it should return kOutdatedPolicy because the
// policy definitions differ. During runtime this happens if we attempt to
// update a template that has had a new policy pushed to it.
data_manager_->UpdateEntry(MakePolicyTemplateWithEmptyPolicy());
VerifyUpdateEntryOutdatePolicy();
}
} // namespace desks_storage