0

people: Add phone numbers to contact request type

Bug: b:374624760
Change-Id: I6a6a21006ffaabe4fd30edcc2963aced8f7c3cc7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5942383
Reviewed-by: Ryan Sultanem <rsult@google.com>
Commit-Queue: Michael Cui <mlcui@google.com>
Cr-Commit-Position: refs/heads/main@{#1374455}
This commit is contained in:
mlcui
2024-10-28 02:46:26 +00:00
committed by Chromium LUCI CQ
parent cfbcc191c9
commit 0123d3f637
3 changed files with 152 additions and 0 deletions

@ -37,6 +37,19 @@ base::Value::Dict Name::ToDict() && {
return dict;
}
base::Value::Dict PhoneNumber::ToDict() && {
base::Value::Dict dict;
if (!value.empty()) {
dict.Set("value", std::move(value));
}
if (!type.empty()) {
dict.Set("type", std::move(type));
}
return dict;
}
Contact::Contact() = default;
Contact::Contact(const Contact&) = default;
Contact& Contact::operator=(const Contact&) = default;
@ -59,6 +72,12 @@ base::Value::Dict Contact::ToDict() && {
names.Append(std::move(name_dict));
dict.Set("names", std::move(names));
}
if (!phone_numbers.empty()) {
base::Value::List phones = base::ToValueList(
phone_numbers,
[](PhoneNumber& phone) { return std::move(phone).ToDict(); });
dict.Set("phoneNumbers", std::move(phones));
}
return dict;
}

@ -55,6 +55,39 @@ struct Name {
base::Value::Dict ToDict() &&;
};
// A person's phone number.
// The API may silently reject values if the `value` field is not set.
//
// https://developers.google.com/people/api/rest/v1/people#Person.EmailAddress
struct PhoneNumber {
// Predefined values for `type`.
static constexpr std::string_view kHomeType = "home";
static constexpr std::string_view kWorkType = "work";
static constexpr std::string_view kMobileType = "mobile";
static constexpr std::string_view kHomeFaxType = "homeFax";
static constexpr std::string_view kWorkFaxType = "workFax";
static constexpr std::string_view kOtherFaxType = "otherFax";
static constexpr std::string_view kPagerType = "pager";
static constexpr std::string_view kWorkMobileType = "workMobile";
static constexpr std::string_view kWorkPagerType = "workPager";
static constexpr std::string_view kMainType = "main";
static constexpr std::string_view kGoogleVoiceType = "googleVoice";
static constexpr std::string_view kOtherType = "other";
// The phone number.
std::string value;
// The type of the phone number. The type can be custom or one of the
// predefined values above.
std::string type;
// Converts this struct to a dict. Requires an rvalue reference, and leaves
// this struct in a valid but unspecified state.
//
// This should be called either with a moved struct, or an explicit copy of
// one.
base::Value::Dict ToDict() &&;
};
// A contact-based Person sent to mutation endpoints. Unlike the general
// `Person` struct, this struct ensures that any fields which should be a
// singleton for contact-based Persons - biographies, birthdays, genders, names
@ -77,6 +110,12 @@ struct Contact {
// This will be not be serialised if it is empty.
Name name;
// The person's phone numbers. For `people.connections.list` and
// `otherContacts.list` the number of phone numbers is limited to 100. If a
// Person has more phone numbers the entire set can be obtained by calling
// `people.getBatchGet`.
std::vector<PhoneNumber> phone_numbers;
Contact();
Contact(const Contact&);
Contact& operator=(const Contact&);

@ -91,6 +91,38 @@ TEST(PeopleApiRequestTypesTest, NameWithMultipleFieldsToDict) {
})json"));
}
TEST(PeopleApiRequestTypesTest, PhoneWithNoFieldsToDict) {
PhoneNumber phone;
base::Value::Dict dict = std::move(phone).ToDict();
EXPECT_THAT(dict, IsJson("{}"));
}
TEST(PeopleApiRequestTypesTest, PhoneWithOnlyValueToDict) {
PhoneNumber phone;
phone.value = "+61400000000";
base::Value::Dict dict = std::move(phone).ToDict();
EXPECT_THAT(dict, IsJson(R"json({
"value": "+61400000000",
})json"));
}
TEST(PeopleApiRequestTypesTest, PhoneWithMultipleFieldsToDict) {
PhoneNumber phone;
phone.value = "+61400000000";
phone.type = "mobile";
base::Value::Dict dict = std::move(phone).ToDict();
EXPECT_THAT(dict, IsJson(R"json({
"value": "+61400000000",
"type": "mobile",
})json"));
}
TEST(PeopleApiRequestTypesTest, ContactWithNoFieldsToDict) {
Contact contact;
@ -160,6 +192,50 @@ TEST(PeopleApiRequestTypesTest, ContactWithNameToDict) {
})json"));
}
TEST(PeopleApiRequestTypesTest, ContactWithOnePhoneToDict) {
Contact contact;
PhoneNumber phone;
phone.value = "+61400000000";
contact.phone_numbers.push_back(std::move(phone));
base::Value::Dict dict = std::move(contact).ToDict();
EXPECT_THAT(dict, IsJson(R"json({
"phoneNumbers": [
{
"value": "+61400000000",
},
],
})json"));
}
TEST(PeopleApiRequestTypesTest, ContactWithMultiplePhonesToDict) {
Contact contact;
PhoneNumber mobile_number;
mobile_number.value = "+61400000000";
mobile_number.type = "mobile";
contact.phone_numbers.push_back(std::move(mobile_number));
PhoneNumber home_number;
home_number.value = "+61390000000";
home_number.type = "home";
contact.phone_numbers.push_back(std::move(home_number));
base::Value::Dict dict = std::move(contact).ToDict();
EXPECT_THAT(dict, IsJson(R"json({
"phoneNumbers": [
{
"value": "+61400000000",
"type": "mobile",
},
{
"value": "+61390000000",
"type": "home",
},
],
})json"));
}
TEST(PeopleApiRequestTypesTest, ContactWithMultipleFieldsToDict) {
Contact contact;
EmailAddress home_email;
@ -174,6 +250,14 @@ TEST(PeopleApiRequestTypesTest, ContactWithMultipleFieldsToDict) {
name.family_name = "Francois";
name.given_name = "Andre";
contact.name = std::move(name);
PhoneNumber mobile_number;
mobile_number.value = "+61400000000";
mobile_number.type = "mobile";
contact.phone_numbers.push_back(std::move(mobile_number));
PhoneNumber home_number;
home_number.value = "+61390000000";
home_number.type = "home";
contact.phone_numbers.push_back(std::move(home_number));
base::Value::Dict dict = std::move(contact).ToDict();
@ -194,6 +278,16 @@ TEST(PeopleApiRequestTypesTest, ContactWithMultipleFieldsToDict) {
"givenName": "Andre",
},
],
"phoneNumbers": [
{
"value": "+61400000000",
"type": "mobile",
},
{
"value": "+61390000000",
"type": "home",
},
],
})json"));
}