Add unit test for the Settings API Bubble.
[chromium-blink-merge.git] / chrome / browser / ui / autofill / autofill_dialog_i18n_input.cc
blobc079e3d9c5cb82b28f4f32eeede7e9bb599d704c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "components/autofill/core/browser/autofill_profile.h"
11 #include "components/autofill/core/browser/credit_card.h"
12 #include "components/autofill/core/browser/field_types.h"
13 #include "grit/component_strings.h"
14 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h"
15 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_field.h"
16 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h"
17 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h"
18 #include "ui/base/l10n/l10n_util.h"
20 namespace autofill {
21 namespace i18ninput {
23 namespace {
25 using base::UTF16ToUTF8;
26 using ::i18n::addressinput::AddressData;
27 using ::i18n::addressinput::AddressField;
28 using ::i18n::addressinput::AddressUiComponent;
30 DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) {
31 if (hint == AddressUiComponent::HINT_SHORT)
32 return DetailInput::SHORT;
33 DCHECK_EQ(hint, AddressUiComponent::HINT_LONG);
34 return DetailInput::LONG;
37 } // namespace
39 void BuildAddressInputs(common::AddressType address_type,
40 const std::string& country_code,
41 DetailInputs* inputs) {
42 // TODO(rouslan): Store the language code for the autofill profile.
43 // http://crbug.com/354955
44 std::vector<AddressUiComponent> components(
45 ::i18n::addressinput::BuildComponents(
46 country_code, g_browser_process->GetApplicationLocale(), NULL));
48 const bool billing = address_type == common::ADDRESS_TYPE_BILLING;
50 for (size_t i = 0; i < components.size(); ++i) {
51 const AddressUiComponent& component = components[i];
52 if (component.field == ::i18n::addressinput::ORGANIZATION) {
53 // TODO(dbeam): figure out when we actually need this.
54 continue;
57 ServerFieldType server_type = TypeForField(component.field, address_type);
58 DetailInput::Length length = LengthFromHint(component.length_hint);
59 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
60 DetailInput input = { length, server_type, placeholder };
61 inputs->push_back(input);
63 #if defined(OS_MACOSX) || defined(OS_ANDROID)
64 if (component.field == ::i18n::addressinput::STREET_ADDRESS &&
65 component.length_hint == AddressUiComponent::HINT_LONG) {
66 // TODO(dbeam): support more than 2 address lines. http://crbug.com/324889
67 ServerFieldType server_type =
68 billing ? ADDRESS_BILLING_LINE2 : ADDRESS_HOME_LINE2;
69 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
70 DetailInput input = { length, server_type, placeholder };
71 inputs->push_back(input);
73 #endif
76 ServerFieldType server_type =
77 billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
78 base::string16 placeholder_text =
79 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY);
80 DetailInput input = { DetailInput::LONG, server_type, placeholder_text };
81 inputs->push_back(input);
84 bool CardHasCompleteAndVerifiedData(const CreditCard& card) {
85 if (!card.IsVerified())
86 return false;
88 const ServerFieldType required_fields[] = {
89 CREDIT_CARD_NUMBER,
90 CREDIT_CARD_EXP_MONTH,
91 CREDIT_CARD_EXP_4_DIGIT_YEAR,
94 for (size_t i = 0; i < arraysize(required_fields); ++i) {
95 if (card.GetRawInfo(required_fields[i]).empty())
96 return false;
99 return true;
102 bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile) {
103 if (!profile.IsVerified())
104 return false;
106 base::string16 country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY);
107 if (country_code.empty())
108 return false;
110 std::vector<AddressField> required_fields =
111 ::i18n::addressinput::GetRequiredFields(base::UTF16ToUTF8(country_code));
113 for (size_t i = 0; i < required_fields.size(); ++i) {
114 ServerFieldType type =
115 TypeForField(required_fields[i], common::ADDRESS_TYPE_SHIPPING);
116 if (profile.GetRawInfo(type).empty())
117 return false;
120 const ServerFieldType more_required_fields[] = {
121 NAME_FULL,
122 PHONE_HOME_WHOLE_NUMBER
125 for (size_t i = 0; i < arraysize(more_required_fields); ++i) {
126 if (profile.GetRawInfo(more_required_fields[i]).empty())
127 return false;
130 return true;
133 ServerFieldType TypeForField(AddressField address_field,
134 common::AddressType address_type) {
135 bool billing = address_type == common::ADDRESS_TYPE_BILLING;
136 switch (address_field) {
137 case ::i18n::addressinput::COUNTRY:
138 return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
139 case ::i18n::addressinput::ADMIN_AREA:
140 return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE;
141 case ::i18n::addressinput::LOCALITY:
142 return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY;
143 case ::i18n::addressinput::DEPENDENT_LOCALITY:
144 return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY :
145 ADDRESS_HOME_DEPENDENT_LOCALITY;
146 case ::i18n::addressinput::POSTAL_CODE:
147 return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP;
148 case ::i18n::addressinput::SORTING_CODE:
149 return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE;
150 #if defined(OS_MACOSX) || defined(OS_ANDROID)
151 case ::i18n::addressinput::STREET_ADDRESS:
152 return billing ? ADDRESS_BILLING_LINE1 : ADDRESS_HOME_LINE1;
153 #else
154 case ::i18n::addressinput::STREET_ADDRESS:
155 return billing ? ADDRESS_BILLING_STREET_ADDRESS :
156 ADDRESS_HOME_STREET_ADDRESS;
157 #endif
158 case ::i18n::addressinput::RECIPIENT:
159 return billing ? NAME_BILLING_FULL : NAME_FULL;
160 case ::i18n::addressinput::ORGANIZATION:
161 return COMPANY_NAME;
163 NOTREACHED();
164 return UNKNOWN_TYPE;
167 bool FieldForType(ServerFieldType server_type,
168 ::i18n::addressinput::AddressField* field) {
169 switch (server_type) {
170 case ADDRESS_BILLING_COUNTRY:
171 case ADDRESS_HOME_COUNTRY:
172 if (field)
173 *field = ::i18n::addressinput::COUNTRY;
174 return true;
175 case ADDRESS_BILLING_STATE:
176 case ADDRESS_HOME_STATE:
177 if (field)
178 *field = ::i18n::addressinput::ADMIN_AREA;
179 return true;
180 case ADDRESS_BILLING_CITY:
181 case ADDRESS_HOME_CITY:
182 if (field)
183 *field = ::i18n::addressinput::LOCALITY;
184 return true;
185 case ADDRESS_BILLING_DEPENDENT_LOCALITY:
186 case ADDRESS_HOME_DEPENDENT_LOCALITY:
187 if (field)
188 *field = ::i18n::addressinput::DEPENDENT_LOCALITY;
189 return true;
190 case ADDRESS_BILLING_SORTING_CODE:
191 case ADDRESS_HOME_SORTING_CODE:
192 if (field)
193 *field = ::i18n::addressinput::SORTING_CODE;
194 return true;
195 case ADDRESS_BILLING_ZIP:
196 case ADDRESS_HOME_ZIP:
197 if (field)
198 *field = ::i18n::addressinput::POSTAL_CODE;
199 return true;
200 case ADDRESS_BILLING_STREET_ADDRESS:
201 case ADDRESS_BILLING_LINE1:
202 case ADDRESS_BILLING_LINE2:
203 case ADDRESS_HOME_STREET_ADDRESS:
204 case ADDRESS_HOME_LINE1:
205 case ADDRESS_HOME_LINE2:
206 if (field)
207 *field = ::i18n::addressinput::STREET_ADDRESS;
208 return true;
209 case COMPANY_NAME:
210 if (field)
211 *field = ::i18n::addressinput::ORGANIZATION;
212 return true;
213 case NAME_BILLING_FULL:
214 case NAME_FULL:
215 if (field)
216 *field = ::i18n::addressinput::RECIPIENT;
217 return true;
218 default:
219 return false;
223 void CreateAddressData(
224 const base::Callback<base::string16(const AutofillType&)>& get_info,
225 AddressData* address_data) {
226 address_data->recipient = UTF16ToUTF8(get_info.Run(AutofillType(NAME_FULL)));
227 address_data->country_code = UTF16ToUTF8(
228 get_info.Run(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_SHIPPING)));
229 DCHECK_EQ(2U, address_data->country_code.size());
230 address_data->administrative_area = UTF16ToUTF8(
231 get_info.Run(AutofillType(ADDRESS_HOME_STATE)));
232 address_data->locality = UTF16ToUTF8(
233 get_info.Run(AutofillType(ADDRESS_HOME_CITY)));
234 address_data->dependent_locality = UTF16ToUTF8(
235 get_info.Run(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY)));
236 address_data->sorting_code = UTF16ToUTF8(
237 get_info.Run(AutofillType(ADDRESS_HOME_SORTING_CODE)));
238 address_data->postal_code = UTF16ToUTF8(
239 get_info.Run(AutofillType(ADDRESS_HOME_ZIP)));
240 base::SplitString(
241 UTF16ToUTF8(get_info.Run(AutofillType(ADDRESS_HOME_STREET_ADDRESS))),
242 '\n',
243 &address_data->address_lines);
246 bool CountryIsFullySupported(const std::string& country_code) {
247 DCHECK_EQ(2U, country_code.size());
248 std::vector< ::i18n::addressinput::AddressUiComponent> components =
249 ::i18n::addressinput::BuildComponents(
250 country_code, g_browser_process->GetApplicationLocale(), NULL);
251 for (size_t i = 0; i < components.size(); ++i) {
252 if (components[i].field == ::i18n::addressinput::DEPENDENT_LOCALITY)
253 return false;
255 return true;
258 } // namespace i18ninput
259 } // namespace autofill