| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "components/autofill/ios/browser/autofill_util.h" |
| |
| #import <variant> |
| |
| #import "base/memory/scoped_refptr.h" |
| #import "base/strings/string_util.h" |
| #import "base/strings/utf_string_conversions.h" |
| #import "base/values.h" |
| #import "components/autofill/core/common/field_data_manager.h" |
| #import "components/autofill/core/common/form_data.h" |
| #import "components/autofill/core/common/form_field_data.h" |
| #import "components/autofill/core/common/unique_ids.h" |
| #import "testing/platform_test.h" |
| |
| using AutofillUtilTest = PlatformTest; |
| |
| using autofill::ExtractIDs; |
| using autofill::ExtractFillingResults; |
| using autofill::FieldRendererId; |
| using base::ASCIIToUTF16; |
| |
| TEST_F(AutofillUtilTest, ExtractIDs) { |
| NSString* valid_ids = @"[\"1\",\"2\"]"; |
| std::set<FieldRendererId> expected_result = {FieldRendererId(1), |
| FieldRendererId(2)}; |
| std::optional<std::set<FieldRendererId>> extracted_ids = |
| ExtractIDs<FieldRendererId>(valid_ids); |
| EXPECT_TRUE(extracted_ids); |
| EXPECT_EQ(expected_result, *extracted_ids); |
| |
| NSString* empty_ids = @"[]"; |
| extracted_ids = ExtractIDs<FieldRendererId>(empty_ids); |
| EXPECT_TRUE(extracted_ids); |
| EXPECT_TRUE(extracted_ids.value().empty()); |
| |
| NSString* invalid_ids1 = @"[\"1\"\"2\"]"; |
| EXPECT_FALSE(ExtractIDs<FieldRendererId>(invalid_ids1)); |
| NSString* invalid_ids2 = @"[1,2]"; |
| EXPECT_FALSE(ExtractIDs<FieldRendererId>(invalid_ids2)); |
| NSString* too_big_id = @"[\"111222333444\"]"; |
| EXPECT_FALSE(ExtractIDs<FieldRendererId>(too_big_id)); |
| } |
| |
| TEST_F(AutofillUtilTest, ExtractFillingResults) { |
| std::map<uint32_t, std::u16string> extracted_results; |
| NSString* valid_results = @"{\"1\":\"username\",\"2\":\"adress\"}"; |
| std::map<uint32_t, std::u16string> expected_result = {{1, u"username"}, |
| {2, u"adress"}}; |
| EXPECT_TRUE(ExtractFillingResults(valid_results, &extracted_results)); |
| EXPECT_EQ(expected_result, extracted_results); |
| |
| extracted_results.clear(); |
| NSString* empty_results = @"{}"; |
| EXPECT_TRUE(ExtractFillingResults(empty_results, &extracted_results)); |
| EXPECT_TRUE(extracted_results.empty()); |
| |
| NSString* invalid_results1 = @"{\"1\":\"username\"\"2\":\"adress\"}"; |
| EXPECT_FALSE(ExtractFillingResults(invalid_results1, &extracted_results)); |
| NSString* invalid_results2 = @"{\"1\":\"username\"\"2\":100}"; |
| EXPECT_FALSE(ExtractFillingResults(invalid_results2, &extracted_results)); |
| } |
| |
| // Test that the properties mask is extracted from the form field data. |
| TEST_F(AutofillUtilTest, ExtractFormFieldData_PropertiesMask) { |
| base::Value::Dict field; |
| // Set mandatory field attributes. |
| field.Set("name", base::Value("email")); |
| field.Set("form_control_type", base::Value("text")); |
| |
| // Set field attribute to get mask. |
| field.Set("renderer_id", base::Value("1")); |
| |
| const scoped_refptr<autofill::FieldDataManager> field_data_manager = |
| base::MakeRefCounted<autofill::FieldDataManager>(); |
| // Set test field property as user typed. |
| field_data_manager->UpdateFieldDataMap( |
| autofill::FieldRendererId(1), u"my@mail", |
| autofill::FieldPropertiesFlags::kUserTyped); |
| |
| autofill::FormFieldData field_data; |
| autofill::ExtractFormFieldData(field, *field_data_manager, &field_data); |
| |
| EXPECT_EQ(u"my@mail", field_data.user_input()); |
| EXPECT_EQ(autofill::FieldPropertiesFlags::kUserTyped, |
| field_data.properties_mask()); |
| } |
| |
| // Tests various aspects of converting hex IDs equivalent to those generated by |
| // JavaScript into UnguessableTokens. |
| TEST_F(AutofillUtilTest, DeserializeTokens) { |
| // Should work with a 32-character (128-bit) hex string. Also test that |
| // hex conversion is robust to upper/lower case. |
| auto token = autofill::DeserializeJavaScriptFrameId( |
| "0123456789abcdef0123456789ABCDEF"); |
| ASSERT_TRUE(token.has_value()); |
| EXPECT_EQ("0123456789abcdef0123456789abcdef", |
| base::ToLowerASCII(token->ToString())); |
| |
| // Should fail if the string has the wrong length |
| token = autofill::DeserializeJavaScriptFrameId(std::string(4, '1')); |
| EXPECT_FALSE(token.has_value()); |
| token = autofill::DeserializeJavaScriptFrameId(std::string(34, 'f')); |
| EXPECT_FALSE(token.has_value()); |
| |
| // Should fail if the string isn't hex |
| token = autofill::DeserializeJavaScriptFrameId(std::string(32, '?')); |
| EXPECT_FALSE(token.has_value()); |
| } |
| |
| // Test that the properties mask is extracted from the form field data. |
| TEST_F(AutofillUtilTest, ExtractRemoteFrameToken) { |
| base::Value::Dict remote_frame_token_dict; |
| remote_frame_token_dict.Set("token", |
| base::Value("beefbeefbeefbeefcafecafecafecafe")); |
| remote_frame_token_dict.Set("predecessor", base::Value(64)); |
| |
| autofill::FrameTokenWithPredecessor token_with_predecessor; |
| |
| ASSERT_TRUE(ExtractRemoteFrameToken(remote_frame_token_dict, |
| &token_with_predecessor)); |
| EXPECT_EQ(base::ToLowerASCII(std::get<autofill::RemoteFrameToken>( |
| token_with_predecessor.token) |
| .ToString()), |
| "beefbeefbeefbeefcafecafecafecafe"); |
| EXPECT_EQ(token_with_predecessor.predecessor, 64); |
| |
| base::Value::Dict malformed1; |
| malformed1.Set("garbage", base::Value("garbage")); |
| EXPECT_FALSE(ExtractRemoteFrameToken(malformed1, &token_with_predecessor)); |
| |
| base::Value::Dict malformed2; |
| malformed2.Set("token", base::Value("garbage")); |
| EXPECT_FALSE(ExtractRemoteFrameToken(malformed2, &token_with_predecessor)); |
| |
| base::Value::Dict malformed3; |
| malformed3.Set("token", base::Value("beefbeefbeefbeefcafecafecafecafe")); |
| malformed3.Set("predecessor", base::Value("garbage")); |
| EXPECT_FALSE(ExtractRemoteFrameToken(malformed3, &token_with_predecessor)); |
| } |