blob: f5a763295cdce891886feaee23a14839ba260f48 [file] [log] [blame]
// 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 "components/supervised_user/test_support/account_repository.h"
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_value_converter.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "components/supervised_user/core/browser/proto/kidsmanagement_messages.pb.h"
namespace supervised_user {
namespace {
test_accounts::Repository ParseFromTestResource(base::FilePath path) {
if (!path.IsAbsolute()) {
base::FilePath root_path;
base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &root_path);
path = base::MakeAbsoluteFilePath(root_path.Append(path));
}
int error_code = 0;
std::string error_str;
JSONFileValueDeserializer deserializer(path);
std::unique_ptr<base::Value> json =
deserializer.Deserialize(&error_code, &error_str);
CHECK(error_code == 0 && json)
<< "Error reading json file at " << path << ". Error code: " << error_code
<< " " << error_str;
test_accounts::Repository repository;
base::JSONValueConverter<test_accounts::Repository> converter;
CHECK(converter.Convert(*json, &repository))
<< "Error converting the repository to data structure";
return repository;
}
} // namespace
std::optional<test_accounts::Family>
TestAccountRepository::GetRandomFamilyByFeature(
test_accounts::Feature feature) {
std::vector<test_accounts::Family> matching_families;
for (const auto& family : repository_.families) {
if (family->feature == feature) {
matching_families.push_back(*family);
}
}
if (matching_families.empty()) {
return std::nullopt;
}
return matching_families[base::RandInt(0, matching_families.size() - 1)];
}
std::optional<test_accounts::FamilyMember> GetFirstFamilyMemberByRole(
const test_accounts::Family& family,
kidsmanagement::FamilyRole role) {
for (const auto& member : family.members) {
if (member->role == role) {
return *member;
}
}
return std::nullopt;
}
TestAccountRepository::TestAccountRepository(const base::FilePath& path)
: repository_(ParseFromTestResource(path)) {}
TestAccountRepository::~TestAccountRepository() = default;
namespace test_accounts {
std::optional<Feature> ParseFeature(std::string_view feature_name) {
static std::map<std::string_view, Feature> features{
{"REGULAR", Feature::REGULAR},
{"DMA_ELIGIBLE_WITH_CONSENT", Feature::DMA_ELIGIBLE_WITH_CONSENT},
{"DMA_ELIGIBLE_WITHOUT_CONSENT", Feature::DMA_ELIGIBLE_WITHOUT_CONSENT},
{"DMA_INELIGIBLE", Feature::DMA_INELIGIBLE},
};
if (features.count(feature_name) == 0) {
return std::nullopt;
}
return features.at(feature_name);
}
void Repository::RegisterJSONConverter(
base::JSONValueConverter<Repository>* converter) {
converter->RegisterRepeatedMessage<Family>("families", &Repository::families);
}
void Family::RegisterJSONConverter(
base::JSONValueConverter<Family>* converter) {
converter->RegisterRepeatedMessage<FamilyMember>("members", &Family::members);
converter->RegisterCustomField<Feature>("feature", &Family::feature,
&Family::ParseFeature);
}
bool Family::ParseFeature(std::string_view value, Feature* feature) {
std::optional<Feature> parsed =
::supervised_user::test_accounts::ParseFeature(value);
if (!parsed.has_value()) {
return false;
}
*feature = *parsed;
return true;
}
void FamilyMember::RegisterJSONConverter(
base::JSONValueConverter<FamilyMember>* converter) {
converter->RegisterStringField("name", &FamilyMember::name);
converter->RegisterCustomField<kidsmanagement::FamilyRole>(
"role", &FamilyMember::role, &FamilyMember::ParseRole);
converter->RegisterStringField("username", &FamilyMember::username);
converter->RegisterStringField("password", &FamilyMember::password);
}
// LINT.IfChange(family_role_parser)
bool FamilyMember::ParseRole(std::string_view value,
kidsmanagement::FamilyRole* role) {
static std::map<std::string_view, kidsmanagement::FamilyRole> roles{
{"UNKNOWN_FAMILY_ROLE", kidsmanagement::FamilyRole::UNKNOWN_FAMILY_ROLE},
{"HEAD_OF_HOUSEHOLD", kidsmanagement::FamilyRole::HEAD_OF_HOUSEHOLD},
{"PARENT", kidsmanagement::FamilyRole::PARENT},
{"MEMBER", kidsmanagement::FamilyRole::MEMBER},
{"CHILD", kidsmanagement::FamilyRole::CHILD},
{"UNCONFIRMED_MEMBER", kidsmanagement::FamilyRole::UNCONFIRMED_MEMBER},
};
if (roles.count(value) == 0) {
return false;
}
*role = roles.at(value);
return true;
}
// LINT.ThenChange(//components/supervised_user/core/browser/proto/families_common.proto::family_role)
FamilyMember::FamilyMember() = default;
FamilyMember::FamilyMember(const FamilyMember&) = default;
FamilyMember& FamilyMember::operator=(const FamilyMember&) = default;
FamilyMember::~FamilyMember() = default;
Family::Family() = default;
Family::Family(const Family& other) {
*this = other;
}
Family& Family::operator=(const Family& other) {
if (this != &other) {
members.clear();
for (const auto& member : other.members) {
members.push_back(std::make_unique<FamilyMember>(*member));
}
feature = other.feature;
}
return *this;
}
Family::~Family() = default;
Repository::Repository() = default;
Repository::Repository(const Repository& other) {
*this = other;
}
Repository& Repository::operator=(const Repository& other) {
if (this != &other) {
families.clear();
for (const auto& family : other.families) {
families.push_back(std::make_unique<Family>(*family));
}
}
return *this;
}
Repository::~Repository() = default;
} // namespace test_accounts
} // namespace supervised_user