wallet_items_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 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.
4
5#include "base/json/json_reader.h"
6#include "base/logging.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/strings/utf_string_conversions.h"
9#include "base/values.h"
10#include "components/autofill/content/browser/wallet/gaia_account.h"
11#include "components/autofill/content/browser/wallet/required_action.h"
12#include "components/autofill/content/browser/wallet/wallet_items.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "url/gurl.h"
15
16namespace {
17
18const char kMaskedInstrument[] =
19    "{"
20    "  \"descriptive_name\":\"descriptive_name\","
21    "  \"type\":\"VISA\","
22    "  \"supported_currency\":"
23    "  ["
24    "    \"currency\""
25    "  ],"
26    "  \"last_four_digits\":\"last_four_digits\","
27    "  \"expiration_month\":12,"
28    "  \"expiration_year\":2012,"
29    "  \"billing_address\":"
30    "  {"
31    "    \"name\":\"name\","
32    "    \"address1\":\"address1\","
33    "    \"address2\":\"address2\","
34    "    \"city\":\"city\","
35    "    \"state\":\"state\","
36    "    \"postal_code\":\"postal_code\","
37    "    \"phone_number\":\"phone_number\","
38    "    \"country_code\":\"US\","
39    "    \"type\":\"FULL\""
40    "  },"
41    "  \"status\":\"VALID\","
42    "  \"object_id\":\"object_id\""
43    "}";
44
45const char kMaskedInstrumentMissingStatus[] =
46    "{"
47    "  \"descriptive_name\":\"descriptive_name\","
48    "  \"type\":\"VISA\","
49    "  \"supported_currency\":"
50    "  ["
51    "    \"currency\""
52    "  ],"
53    "  \"last_four_digits\":\"last_four_digits\","
54    "  \"expiration_month\":12,"
55    "  \"expiration_year\":2012,"
56    "  \"billing_address\":"
57    "  {"
58    "    \"name\":\"name\","
59    "    \"address1\":\"address1\","
60    "    \"address2\":\"address2\","
61    "    \"city\":\"city\","
62    "    \"state\":\"state\","
63    "    \"postal_code\":\"postal_code\","
64    "    \"phone_number\":\"phone_number\","
65    "    \"country_code\":\"US\""
66    "  },"
67    "  \"object_id\":\"object_id\","
68    "  \"amex_disallowed\":true"
69    "}";
70
71const char kMaskedInstrumentMissingType[] =
72    "{"
73    "  \"descriptive_name\":\"descriptive_name\","
74    "  \"supported_currency\":"
75    "  ["
76    "    \"currency\""
77    "  ],"
78    "  \"last_four_digits\":\"last_four_digits\","
79    "  \"expiration_month\":12,"
80    "  \"expiration_year\":2012,"
81    "  \"billing_address\":"
82    "  {"
83    "    \"name\":\"name\","
84    "    \"address1\":\"address1\","
85    "    \"address2\":\"address2\","
86    "    \"city\":\"city\","
87    "    \"state\":\"state\","
88    "    \"postal_code\":\"postal_code\","
89    "    \"phone_number\":\"phone_number\","
90    "    \"country_code\":\"US\""
91    "  },"
92    "  \"status\":\"VALID\","
93    "  \"object_id\":\"object_id\""
94    "}";
95
96const char kMaskedInstrumentMissingLastFourDigits[] =
97    "{"
98    "  \"descriptive_name\":\"descriptive_name\","
99    "  \"type\":\"VISA\","
100    "  \"supported_currency\":"
101    "  ["
102    "    \"currency\""
103    "  ],"
104    "  \"expiration_month\":12,"
105    "  \"expiration_year\":2012,"
106    "  \"billing_address\":"
107    "  {"
108    "    \"name\":\"name\","
109    "    \"address1\":\"address1\","
110    "    \"address2\":\"address2\","
111    "    \"city\":\"city\","
112    "    \"state\":\"state\","
113    "    \"postal_code\":\"postal_code\","
114    "    \"phone_number\":\"phone_number\","
115    "    \"country_code\":\"US\""
116    "  },"
117    "  \"status\":\"VALID\","
118    "  \"object_id\":\"object_id\""
119    "}";
120
121const char kMaskedInstrumentMissingAddress[] =
122    "{"
123    "  \"descriptive_name\":\"descriptive_name\","
124    "  \"type\":\"VISA\","
125    "  \"supported_currency\":"
126    "  ["
127    "    \"currency\""
128    "  ],"
129    "  \"last_four_digits\":\"last_four_digits\","
130    "  \"expiration_month\":12,"
131    "  \"expiration_year\":2012,"
132    "  \"status\":\"VALID\","
133    "  \"object_id\":\"object_id\""
134    "}";
135
136const char kMaskedInstrumentMalformedAddress[] =
137    "{"
138    "  \"descriptive_name\":\"descriptive_name\","
139    "  \"type\":\"VISA\","
140    "  \"supported_currency\":"
141    "  ["
142    "    \"currency\""
143    "  ],"
144    "  \"last_four_digits\":\"last_four_digits\","
145    "  \"expiration_month\":12,"
146    "  \"expiration_year\":2012,"
147    "  \"billing_address\":"
148    "  {"
149    "    \"address1\":\"address1\","
150    "    \"address2\":\"address2\","
151    "    \"city\":\"city\","
152    "    \"state\":\"state\","
153    "    \"phone_number\":\"phone_number\","
154    "    \"country_code\":\"US\""
155    "  },"
156    "  \"status\":\"VALID\","
157    "  \"object_id\":\"object_id\""
158    "}";
159
160const char kMaskedInstrumentMissingObjectId[] =
161    "{"
162    "  \"descriptive_name\":\"descriptive_name\","
163    "  \"type\":\"VISA\","
164    "  \"supported_currency\":"
165    "  ["
166    "    \"currency\""
167    "  ],"
168    "  \"last_four_digits\":\"last_four_digits\","
169    "  \"expiration_month\":12,"
170    "  \"expiration_year\":2012,"
171    "  \"billing_address\":"
172    "  {"
173    "    \"name\":\"name\","
174    "    \"address1\":\"address1\","
175    "    \"address2\":\"address2\","
176    "    \"city\":\"city\","
177    "    \"state\":\"state\","
178    "    \"postal_code\":\"postal_code\","
179    "    \"phone_number\":\"phone_number\","
180    "    \"country_code\":\"US\""
181    "  },"
182    "  \"status\":\"VALID\""
183    "}";
184
185const char kLegalDocument[] =
186    "{"
187    "  \"legal_document_id\":\"doc_id\","
188    "  \"display_name\":\"display_name\""
189    "}";
190
191const char kLegalDocumentMissingDocumentId[] =
192    "{"
193    "  \"display_name\":\"display_name\""
194    "}";
195
196const char kLegalDocumentMissingDisplayName[] =
197    "{"
198    "  \"legal_document_id\":\"doc_id\""
199    "}";
200
201const char kWalletItemsWithRequiredActions[] =
202    "{"
203    "  \"required_action\":"
204    "  ["
205    "    \"  setup_wallet\","
206    "    \" CHOOse_ANother_INSTRUMENT_OR_ADDRESS\","
207    "    \"AcCePt_ToS  \","
208    "    \"  \\tGAIA_auth   \\n\\r\","
209    "    \"UPDATE_expiration_date\","
210    "    \"UPGRADE_min_ADDRESS   \","
211    "    \" pAsSiVe_GAIA_auth \","
212    "    \" REQUIRE_PHONE_NUMBER\\t \""
213    "  ]"
214    "}";
215
216const char kWalletItemsWithInvalidRequiredActions[] =
217    "{"
218    "  \"required_action\":"
219    "  ["
220    "    \"verify_CVV\","
221    "    \"invalid_FORM_FIELD\","
222    "    \" 忍者の正体 \""
223    "  ]"
224    "}";
225
226const char kWalletItemsMissingGoogleTransactionId[] =
227    "{"
228    "  \"required_action\":"
229    "  ["
230    "  ],"
231    "  \"instrument\":"
232    "  ["
233    "    {"
234    "      \"descriptive_name\":\"descriptive_name\","
235    "      \"type\":\"VISA\","
236    "      \"supported_currency\":"
237    "      ["
238    "        \"currency\""
239    "      ],"
240    "      \"last_four_digits\":\"last_four_digits\","
241    "      \"expiration_month\":12,"
242    "      \"expiration_year\":2012,"
243    "      \"billing_address\":"
244    "      {"
245    "        \"name\":\"name\","
246    "        \"address1\":\"address1\","
247    "        \"address2\":\"address2\","
248    "        \"city\":\"city\","
249    "        \"state\":\"state\","
250    "        \"postal_code\":\"postal_code\","
251    "        \"phone_number\":\"phone_number\","
252    "        \"country_code\":\"US\""
253    "      },"
254    "      \"status\":\"VALID\","
255    "      \"object_id\":\"object_id\""
256    "    }"
257    "  ],"
258    "  \"default_instrument_id\":\"default_instrument_id\","
259    "  \"address\":"
260    "  ["
261    "    {"
262    "      \"id\":\"id\","
263    "      \"phone_number\":\"phone_number\","
264    "      \"postal_address\":"
265    "      {"
266    "        \"recipient_name\":\"recipient_name\","
267    "        \"address_line\":"
268    "        ["
269    "          \"address_line_1\","
270    "          \"address_line_2\""
271    "        ],"
272    "        \"locality_name\":\"locality_name\","
273    "        \"administrative_area_name\":\"administrative_area_name\","
274    "        \"postal_code_number\":\"postal_code_number\","
275    "        \"country_name_code\":\"US\""
276    "      }"
277    "    }"
278    "  ],"
279    "  \"default_address_id\":\"default_address_id\","
280    "  \"amex_disallowed\":true,"
281    "  \"required_legal_document\":"
282    "  ["
283    "    {"
284    "      \"legal_document_id\":\"doc_id\","
285    "      \"display_name\":\"display_name\""
286    "    }"
287    "  ]"
288    "}";
289
290const char kWalletItems[] =
291    "{"
292    "  \"required_action\":"
293    "  ["
294    "  ],"
295    "  \"google_transaction_id\":\"google_transaction_id\","
296    "  \"instrument\":"
297    "  ["
298    "    {"
299    "      \"descriptive_name\":\"descriptive_name\","
300    "      \"type\":\"VISA\","
301    "      \"supported_currency\":"
302    "      ["
303    "        \"currency\""
304    "      ],"
305    "      \"last_four_digits\":\"last_four_digits\","
306    "      \"expiration_month\":12,"
307    "      \"expiration_year\":2012,"
308    "      \"billing_address\":"
309    "      {"
310    "        \"name\":\"name\","
311    "        \"address1\":\"address1\","
312    "        \"address2\":\"address2\","
313    "        \"city\":\"city\","
314    "        \"state\":\"state\","
315    "        \"postal_code\":\"postal_code\","
316    "        \"phone_number\":\"phone_number\","
317    "        \"country_code\":\"US\","
318    "        \"type\":\"FULL\""
319    "      },"
320    "      \"status\":\"VALID\","
321    "      \"object_id\":\"object_id\""
322    "    }"
323    "  ],"
324    "  \"default_instrument_id\":\"default_instrument_id\","
325    "  \"address\":"
326    "  ["
327    "    {"
328    "      \"id\":\"id\","
329    "      \"phone_number\":\"phone_number\","
330    "      \"postal_address\":"
331    "      {"
332    "        \"recipient_name\":\"recipient_name\","
333    "        \"address_line\":"
334    "        ["
335    "          \"address_line_1\","
336    "          \"address_line_2\""
337    "        ],"
338    "        \"locality_name\":\"locality_name\","
339    "        \"administrative_area_name\":\"administrative_area_name\","
340    "        \"postal_code_number\":\"postal_code_number\","
341    "        \"country_name_code\":\"US\""
342    "      }"
343    "    }"
344    "  ],"
345    "  \"default_address_id\":\"default_address_id\","
346    "  \"obfuscated_gaia_id\":\"ignore_this_value\","
347    "  \"amex_disallowed\":true,"
348    "  \"gaia_profile\":"
349    "  ["
350    "    {"
351    "      \"buyer_email\":\"user@chromium.org\","
352    "      \"gaia_index\":0,"
353    "      \"gaia_id\":\"123456789\","
354    "      \"buyer_name\":\"Joe Usecase\","
355    "      \"is_active\":true,"
356    "      \"avatar_url_27x27\":\"https://lh3.googleusercontent.com/27.jpg\","
357    "      \"avatar_url_54x54\":\"https://lh3.googleusercontent.com/54.jpg\","
358    "      \"avatar_url_48x48\":\"https://lh3.googleusercontent.com/48.jpg\","
359    "      \"avatar_url_96x96\":\"https://lh3.googleusercontent.com/96.jpg\""
360    "    },"
361    "    {"
362    "      \"buyer_email\":\"user2@chromium.org\","
363    "      \"gaia_index\":1,"
364    "      \"gaia_id\":\"obfuscated_gaia_id\","
365    "      \"buyer_name\":\"Jill Usecase\","
366    "      \"is_active\":false,"
367    "      \"avatar_url_27x27\":\"https://lh3.googleusercontent.com/27.jpg\","
368    "      \"avatar_url_54x54\":\"https://lh3.googleusercontent.com/54.jpg\","
369    "      \"avatar_url_48x48\":\"https://lh3.googleusercontent.com/48.jpg\","
370    "      \"avatar_url_96x96\":\"https://lh3.googleusercontent.com/96.jpg\""
371    "    }"
372    "  ]";
373
374const char kRequiredLegalDocument[] =
375    "  ,"
376    "  \"required_legal_document\":"
377    "  ["
378    "    {"
379    "      \"legal_document_id\":\"doc_id\","
380    "      \"display_name\":\"display_name\""
381    "    }"
382    "  ]";
383
384const char kCloseJson[] = "}";
385
386}  // anonymous namespace
387
388namespace autofill {
389namespace wallet {
390
391class WalletItemsTest : public testing::Test {
392 public:
393  WalletItemsTest() {}
394 protected:
395  void SetUpDictionary(const std::string& json) {
396    scoped_ptr<Value> value(base::JSONReader::Read(json));
397    ASSERT_TRUE(value.get());
398    ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY));
399    dict.reset(static_cast<DictionaryValue*>(value.release()));
400  }
401  scoped_ptr<DictionaryValue> dict;
402};
403
404TEST_F(WalletItemsTest, CreateMaskedInstrumentMissingStatus) {
405  SetUpDictionary(kMaskedInstrumentMissingStatus);
406  EXPECT_EQ(NULL,
407            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
408}
409
410TEST_F(WalletItemsTest, CreateMaskedInstrumentMissingType) {
411  SetUpDictionary(kMaskedInstrumentMissingType);
412  EXPECT_EQ(NULL,
413            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
414}
415
416TEST_F(WalletItemsTest, CreateMaskedInstrumentMissingLastFourDigits) {
417  SetUpDictionary(kMaskedInstrumentMissingLastFourDigits);
418  EXPECT_EQ(NULL,
419            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
420}
421
422TEST_F(WalletItemsTest, CreateMaskedInstrumentMissingAddress) {
423  SetUpDictionary(kMaskedInstrumentMissingAddress);
424  EXPECT_EQ(NULL,
425            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
426}
427
428TEST_F(WalletItemsTest, CreateMaskedInstrumentMalformedAddress) {
429  SetUpDictionary(kMaskedInstrumentMalformedAddress);
430  EXPECT_EQ(NULL,
431            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
432}
433
434TEST_F(WalletItemsTest, CreateMaskedInstrumentMissingObjectId) {
435  SetUpDictionary(kMaskedInstrumentMissingObjectId);
436  EXPECT_EQ(NULL,
437            WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict).get());
438}
439
440TEST_F(WalletItemsTest, CreateMaskedInstrument) {
441  SetUpDictionary(kMaskedInstrument);
442  scoped_ptr<Address> address(new Address("US",
443                                          ASCIIToUTF16("name"),
444                                          ASCIIToUTF16("address1"),
445                                          ASCIIToUTF16("address2"),
446                                          ASCIIToUTF16("city"),
447                                          ASCIIToUTF16("state"),
448                                          ASCIIToUTF16("postal_code"),
449                                          ASCIIToUTF16("phone_number"),
450                                          std::string()));
451  std::vector<base::string16> supported_currencies;
452  supported_currencies.push_back(ASCIIToUTF16("currency"));
453  WalletItems::MaskedInstrument masked_instrument(
454      ASCIIToUTF16("descriptive_name"),
455      WalletItems::MaskedInstrument::VISA,
456      supported_currencies,
457      ASCIIToUTF16("last_four_digits"),
458      12,
459      2012,
460      address.Pass(),
461      WalletItems::MaskedInstrument::VALID,
462      "object_id");
463  EXPECT_EQ(masked_instrument,
464            *WalletItems::MaskedInstrument::CreateMaskedInstrument(*dict));
465}
466
467TEST_F(WalletItemsTest, CreateLegalDocumentMissingDocId) {
468  SetUpDictionary(kLegalDocumentMissingDocumentId);
469  EXPECT_EQ(NULL, WalletItems::LegalDocument::CreateLegalDocument(*dict).get());
470}
471
472TEST_F(WalletItemsTest, CreateLegalDocumentMissingDisplayName) {
473  SetUpDictionary(kLegalDocumentMissingDisplayName);
474  EXPECT_EQ(NULL, WalletItems::LegalDocument::CreateLegalDocument(*dict).get());
475}
476
477TEST_F(WalletItemsTest, CreateLegalDocument) {
478  SetUpDictionary(kLegalDocument);
479  WalletItems::LegalDocument expected("doc_id", ASCIIToUTF16("display_name"));
480  EXPECT_EQ(expected,
481            *WalletItems::LegalDocument::CreateLegalDocument(*dict));
482}
483
484TEST_F(WalletItemsTest, LegalDocumentUrl) {
485  WalletItems::LegalDocument legal_doc("doc_id", ASCIIToUTF16("display_name"));
486  EXPECT_EQ("https://wallet.google.com/legaldocument?docId=doc_id",
487            legal_doc.url().spec());
488}
489
490TEST_F(WalletItemsTest, LegalDocumentEmptyId) {
491  WalletItems::LegalDocument legal_doc(GURL("http://example.com"),
492                                       ASCIIToUTF16("display_name"));
493  EXPECT_TRUE(legal_doc.id().empty());
494}
495
496TEST_F(WalletItemsTest, CreateWalletItemsWithRequiredActions) {
497  SetUpDictionary(kWalletItemsWithRequiredActions);
498
499  std::vector<RequiredAction> required_actions;
500  required_actions.push_back(SETUP_WALLET);
501  required_actions.push_back(CHOOSE_ANOTHER_INSTRUMENT_OR_ADDRESS);
502  required_actions.push_back(ACCEPT_TOS);
503  required_actions.push_back(GAIA_AUTH);
504  required_actions.push_back(UPDATE_EXPIRATION_DATE);
505  required_actions.push_back(UPGRADE_MIN_ADDRESS);
506  required_actions.push_back(PASSIVE_GAIA_AUTH);
507  required_actions.push_back(REQUIRE_PHONE_NUMBER);
508
509  WalletItems expected(required_actions,
510                       std::string(),
511                       std::string(),
512                       std::string(),
513                       AMEX_DISALLOWED);
514  EXPECT_EQ(expected, *WalletItems::CreateWalletItems(*dict));
515
516  ASSERT_FALSE(required_actions.empty());
517  required_actions.pop_back();
518  WalletItems different_required_actions(required_actions,
519                                         std::string(),
520                                         std::string(),
521                                         std::string(),
522                                         AMEX_DISALLOWED);
523  EXPECT_NE(expected, different_required_actions);
524}
525
526TEST_F(WalletItemsTest, CreateWalletItemsWithInvalidRequiredActions) {
527  SetUpDictionary(kWalletItemsWithInvalidRequiredActions);
528  EXPECT_EQ(NULL, WalletItems::CreateWalletItems(*dict).get());
529}
530
531TEST_F(WalletItemsTest, CreateWalletItemsMissingGoogleTransactionId) {
532  SetUpDictionary(kWalletItemsMissingGoogleTransactionId);
533  EXPECT_EQ(NULL, WalletItems::CreateWalletItems(*dict).get());
534}
535
536TEST_F(WalletItemsTest, CreateWalletItemsMissingAmexDisallowed) {
537  SetUpDictionary(std::string(kWalletItems) + std::string(kCloseJson));
538  EXPECT_TRUE(dict->Remove("amex_disallowed", NULL));
539  base::string16 amex_number = ASCIIToUTF16("378282246310005");
540  base::string16 message;
541  EXPECT_FALSE(WalletItems::CreateWalletItems(*dict)->SupportsCard(amex_number,
542                                                                   &message));
543  EXPECT_FALSE(message.empty());
544}
545
546TEST_F(WalletItemsTest, CreateWalletItems) {
547  SetUpDictionary(std::string(kWalletItems) + std::string(kCloseJson));
548  std::vector<RequiredAction> required_actions;
549  WalletItems expected(required_actions,
550                       "google_transaction_id",
551                       "default_instrument_id",
552                       "default_address_id",
553                       AMEX_DISALLOWED);
554
555  scoped_ptr<GaiaAccount> user1(GaiaAccount::CreateForTesting(
556      "user@chromium.org",
557      "123456789",
558      0,
559      true));
560  expected.AddAccount(user1.Pass());
561  scoped_ptr<GaiaAccount> user2(GaiaAccount::CreateForTesting(
562      "user2@chromium.org",
563      "obfuscated_gaia_id",
564      1,
565      false));
566  expected.AddAccount(user2.Pass());
567  EXPECT_EQ("123456789", expected.ObfuscatedGaiaId());
568
569  scoped_ptr<Address> billing_address(new Address("US",
570                                                  ASCIIToUTF16("name"),
571                                                  ASCIIToUTF16("address1"),
572                                                  ASCIIToUTF16("address2"),
573                                                  ASCIIToUTF16("city"),
574                                                  ASCIIToUTF16("state"),
575                                                  ASCIIToUTF16("postal_code"),
576                                                  ASCIIToUTF16("phone_number"),
577                                                  std::string()));
578  std::vector<base::string16> supported_currencies;
579  supported_currencies.push_back(ASCIIToUTF16("currency"));
580  scoped_ptr<WalletItems::MaskedInstrument> masked_instrument(
581      new WalletItems::MaskedInstrument(ASCIIToUTF16("descriptive_name"),
582                                        WalletItems::MaskedInstrument::VISA,
583                                        supported_currencies,
584                                        ASCIIToUTF16("last_four_digits"),
585                                        12,
586                                        2012,
587                                        billing_address.Pass(),
588                                        WalletItems::MaskedInstrument::VALID,
589                                        "object_id"));
590  expected.AddInstrument(masked_instrument.Pass());
591
592  scoped_ptr<Address> shipping_address(
593      new Address("US",
594                  ASCIIToUTF16("recipient_name"),
595                  ASCIIToUTF16("address_line_1"),
596                  ASCIIToUTF16("address_line_2"),
597                  ASCIIToUTF16("locality_name"),
598                  ASCIIToUTF16("administrative_area_name"),
599                  ASCIIToUTF16("postal_code_number"),
600                  ASCIIToUTF16("phone_number"),
601                  "id"));
602  expected.AddAddress(shipping_address.Pass());
603  EXPECT_EQ(expected, *WalletItems::CreateWalletItems(*dict));
604
605  // Now try with a legal document as well.
606  SetUpDictionary(std::string(kWalletItems) +
607                  std::string(kRequiredLegalDocument) +
608                  std::string(kCloseJson));
609  scoped_ptr<WalletItems::LegalDocument> legal_document(
610      new WalletItems::LegalDocument("doc_id",
611                                     ASCIIToUTF16("display_name")));
612  expected.AddLegalDocument(legal_document.Pass());
613  expected.AddLegalDocument(
614      WalletItems::LegalDocument::CreatePrivacyPolicyDocument());
615
616  EXPECT_EQ(expected, *WalletItems::CreateWalletItems(*dict));
617}
618
619}  // namespace wallet
620}  // namespace autofill
621