blob: 7dce38f74c7d18c6864af655b37c57739aac2d08 [file]
// Copyright 2026 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/skills/internal/skills_sync_bridge.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/test/task_environment.h"
#include "base/uuid.h"
#include "components/skills/public/skill.h"
#include "components/skills/public/skills_service.h"
#include "components/sync/model/in_memory_metadata_change_list.h"
#include "components/sync/protocol/entity_data.h"
#include "components/sync/protocol/skill_specifics.pb.h"
#include "components/sync/test/data_type_store_test_util.h"
#include "components/sync/test/mock_data_type_local_change_processor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace skills {
namespace {
constexpr char kDefaultPrompt[] = "test prompt";
sync_pb::SkillSpecifics CreateSkillSpecifics(std::string prompt) {
sync_pb::SkillSpecifics specifics;
specifics.set_guid(base::Uuid::GenerateRandomV4().AsLowercaseString());
specifics.mutable_simple_skill()->set_prompt(std::move(prompt));
return specifics;
}
syncer::EntityData CreateSkillEntityData(
std::string prompt = std::string(kDefaultPrompt)) {
syncer::EntityData entity_data;
*entity_data.specifics.mutable_skill() =
CreateSkillSpecifics(std::move(prompt));
return entity_data;
}
class MockSkillsService : public SkillsService {
public:
MOCK_METHOD(const Skill*,
AddSkill,
(const std::string&, const std::string&, const std::string&));
MOCK_METHOD(void, LoadInitialSkills, (std::vector<std::unique_ptr<Skill>>));
MOCK_METHOD(const Skill*, GetSkillById, (const std::string_view&), (const));
MOCK_METHOD(const std::vector<std::unique_ptr<Skill>>&,
GetSkills,
(),
(const));
MOCK_METHOD(void, AddObserver, (Observer*));
MOCK_METHOD(void, RemoveObserver, (Observer*));
MOCK_METHOD(base::WeakPtr<syncer::DataTypeControllerDelegate>,
GetControllerDelegate,
());
};
class SkillsSyncBridgeTest : public testing::Test {
public:
SkillsSyncBridgeTest()
: store_(syncer::DataTypeStoreTestUtil::CreateInMemoryStoreForTest()) {
ResetBridgeAndWaitForInitialization();
}
void ResetBridgeAndWaitForInitialization() {
bridge_.reset();
base::RunLoop run_loop;
EXPECT_CALL(processor_, ModelReadyToSync)
.WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
bridge_ = std::make_unique<SkillsSyncBridge>(
processor_.CreateForwardingProcessor(),
syncer::DataTypeStoreTestUtil::FactoryForForwardingStore(store_.get()),
skills_service_);
run_loop.Run();
}
syncer::DataTypeStore& store() { return *store_; }
SkillsSyncBridge& bridge() { return *bridge_; }
private:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<syncer::DataTypeStore> store_;
testing::NiceMock<syncer::MockDataTypeLocalChangeProcessor> processor_;
testing::NiceMock<MockSkillsService> skills_service_;
std::unique_ptr<SkillsSyncBridge> bridge_;
};
TEST_F(SkillsSyncBridgeTest, GetClientTag) {
const syncer::EntityData kEntityData = CreateSkillEntityData();
ASSERT_FALSE(kEntityData.specifics.skill().guid().empty());
EXPECT_EQ(kEntityData.specifics.skill().guid(),
bridge().GetClientTag(kEntityData));
}
TEST_F(SkillsSyncBridgeTest, GetStorageKey) {
const syncer::EntityData kEntityData = CreateSkillEntityData();
ASSERT_FALSE(kEntityData.specifics.skill().guid().empty());
EXPECT_EQ(kEntityData.specifics.skill().guid(),
bridge().GetClientTag(kEntityData));
}
TEST_F(SkillsSyncBridgeTest, IsEntityDataValid) {
const syncer::EntityData kValidEntityData = CreateSkillEntityData();
EXPECT_TRUE(bridge().IsEntityDataValid(kValidEntityData));
}
TEST_F(SkillsSyncBridgeTest, IsEntityDataValid_EmptyGuid) {
syncer::EntityData entity_data = CreateSkillEntityData();
ASSERT_TRUE(bridge().IsEntityDataValid(entity_data));
entity_data.specifics.mutable_skill()->set_guid("");
EXPECT_FALSE(bridge().IsEntityDataValid(entity_data));
}
TEST_F(SkillsSyncBridgeTest, IsEntityDataValid_MissingSimpleSkill) {
syncer::EntityData entity_data = CreateSkillEntityData();
ASSERT_TRUE(bridge().IsEntityDataValid(entity_data));
entity_data.specifics.mutable_skill()->clear_simple_skill();
EXPECT_FALSE(bridge().IsEntityDataValid(entity_data));
}
} // namespace
} // namespace skills