blob: 82f83830c98ca0697093132258834c9f76ed4770 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/content/public/interfaces/test_autofill_types.mojom.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
const std::vector<const char*> kOptions = {"Option1", "Option2", "Option3",
"Option4"};
namespace {
void CreateTestFieldDataPredictions(const std::string& signature,
FormFieldDataPredictions* field_predict) {
test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
kOptions, 4, &field_predict->field);
field_predict->signature = signature;
field_predict->heuristic_type = "TestSignature";
field_predict->server_type = "TestServerType";
field_predict->overall_type = "TestOverallType";
field_predict->parseable_name = "TestParseableName";
}
void CreateTestPasswordFormFillData(PasswordFormFillData* fill_data) {
fill_data->name = base::ASCIIToUTF16("TestName");
fill_data->origin = GURL("https://foo.com/");
fill_data->action = GURL("https://foo.com/login");
test::CreateTestSelectField("TestUsernameFieldLabel", "TestUsernameFieldName",
"TestUsernameFieldValue", kOptions, kOptions, 4,
&fill_data->username_field);
test::CreateTestSelectField("TestPasswordFieldLabel", "TestPasswordFieldName",
"TestPasswordFieldValue", kOptions, kOptions, 4,
&fill_data->password_field);
fill_data->preferred_realm = "https://foo.com/";
base::string16 name;
PasswordAndRealm pr;
name = base::ASCIIToUTF16("Tom");
pr.password = base::ASCIIToUTF16("Tom_Password");
pr.realm = "https://foo.com/";
fill_data->additional_logins[name] = pr;
name = base::ASCIIToUTF16("Jerry");
pr.password = base::ASCIIToUTF16("Jerry_Password");
pr.realm = "https://bar.com/";
fill_data->additional_logins[name] = pr;
UsernamesCollectionKey key;
key.username = base::ASCIIToUTF16("Tom");
key.password = base::ASCIIToUTF16("Tom_Password");
key.realm = "https://foo.com/";
std::vector<base::string16>& possible_names =
fill_data->other_possible_usernames[key];
possible_names.push_back(base::ASCIIToUTF16("Tom_1"));
possible_names.push_back(base::ASCIIToUTF16("Tom_2"));
key.username = base::ASCIIToUTF16("Jerry");
key.password = base::ASCIIToUTF16("Jerry_Password");
key.realm = "https://bar.com/";
possible_names = fill_data->other_possible_usernames[key];
possible_names.push_back(base::ASCIIToUTF16("Jerry_1"));
possible_names.push_back(base::ASCIIToUTF16("Jerry_2"));
fill_data->wait_for_username = true;
fill_data->is_possible_change_password_form = false;
}
void CreateTestPasswordForm(PasswordForm* form) {
form->scheme = PasswordForm::Scheme::SCHEME_HTML;
form->signon_realm = "https://foo.com/";
form->origin = GURL("https://foo.com/");
form->action = GURL("https://foo.com/login");
form->affiliated_web_realm = "https://foo.com/";
form->submit_element = base::ASCIIToUTF16("test_submit");
form->username_element = base::ASCIIToUTF16("username");
form->username_marked_by_site = true;
form->username_value = base::ASCIIToUTF16("test@gmail.com");
form->other_possible_usernames.push_back(base::ASCIIToUTF16("Jerry_1"));
form->other_possible_usernames.push_back(base::ASCIIToUTF16("Jerry_2"));
form->password_element = base::ASCIIToUTF16("password");
form->password_value = base::ASCIIToUTF16("test");
form->password_value_is_default = true;
form->new_password_element = base::ASCIIToUTF16("new_password");
form->new_password_value = base::ASCIIToUTF16("new_password_value");
form->new_password_value_is_default = false;
form->new_password_marked_by_site = false;
form->preferred = false;
form->date_created = base::Time::Now();
form->date_synced = base::Time::Now();
form->blacklisted_by_user = false;
form->type = PasswordForm::Type::TYPE_GENERATED;
form->times_used = 999;
test::CreateTestAddressFormData(&form->form_data);
form->generation_upload_status =
PasswordForm::GenerationUploadStatus::POSITIVE_SIGNAL_SENT;
form->display_name = base::ASCIIToUTF16("test display name");
form->icon_url = GURL("https://foo.com/icon.png");
form->federation_origin =
url::Origin::UnsafelyCreateOriginWithoutNormalization(
"http", "www.google.com", 80);
form->skip_zero_click = false;
form->layout = PasswordForm::Layout::LAYOUT_LOGIN_AND_SIGNUP;
form->was_parsed_using_autofill_predictions = false;
form->is_public_suffix_match = true;
form->is_affiliation_based_match = true;
form->does_look_like_signup_form = true;
}
void CreateTestFormsPredictionsMap(FormsPredictionsMap* predictions) {
FormsPredictionsMap& result_map = *predictions;
// 1st element.
FormData form_data;
test::CreateTestAddressFormData(&form_data);
ASSERT_TRUE(form_data.fields.size() >= 4);
result_map[form_data][form_data.fields[0]] =
PasswordFormFieldPredictionType::PREDICTION_USERNAME;
result_map[form_data][form_data.fields[1]] =
PasswordFormFieldPredictionType::PREDICTION_CURRENT_PASSWORD;
result_map[form_data][form_data.fields[2]] =
PasswordFormFieldPredictionType::PREDICTION_NEW_PASSWORD;
result_map[form_data][form_data.fields[3]] =
PasswordFormFieldPredictionType::PREDICTION_NOT_PASSWORD;
// 2nd element.
form_data.fields.clear();
result_map[form_data] =
std::map<FormFieldData, PasswordFormFieldPredictionType>();
// 3rd element.
FormFieldData field_data;
test::CreateTestSelectField("TestLabel1", "TestName1", "TestValue1", kOptions,
kOptions, 4, &field_data);
form_data.fields.push_back(field_data);
test::CreateTestSelectField("TestLabel2", "TestName2", "TestValue2", kOptions,
kOptions, 4, &field_data);
form_data.fields.push_back(field_data);
result_map[form_data][form_data.fields[0]] =
PasswordFormFieldPredictionType::PREDICTION_NEW_PASSWORD;
result_map[form_data][form_data.fields[1]] =
PasswordFormFieldPredictionType::PREDICTION_CURRENT_PASSWORD;
}
void CheckEqualPasswordFormFillData(const PasswordFormFillData& expected,
const PasswordFormFillData& actual) {
EXPECT_EQ(expected.name, actual.name);
EXPECT_EQ(expected.origin, actual.origin);
EXPECT_EQ(expected.action, actual.action);
EXPECT_EQ(expected.username_field, actual.username_field);
EXPECT_EQ(expected.password_field, actual.password_field);
EXPECT_EQ(expected.preferred_realm, actual.preferred_realm);
{
EXPECT_EQ(expected.additional_logins.size(),
actual.additional_logins.size());
auto iter1 = expected.additional_logins.begin();
auto end1 = expected.additional_logins.end();
auto iter2 = actual.additional_logins.begin();
auto end2 = actual.additional_logins.end();
for (; iter1 != end1 && iter2 != end2; ++iter1, ++iter2) {
EXPECT_EQ(iter1->first, iter2->first);
EXPECT_EQ(iter1->second.password, iter2->second.password);
EXPECT_EQ(iter1->second.realm, iter2->second.realm);
}
ASSERT_EQ(iter1, end1);
ASSERT_EQ(iter2, end2);
}
{
EXPECT_EQ(expected.other_possible_usernames.size(),
actual.other_possible_usernames.size());
auto iter1 = expected.other_possible_usernames.begin();
auto end1 = expected.other_possible_usernames.end();
auto iter2 = actual.other_possible_usernames.begin();
auto end2 = actual.other_possible_usernames.end();
for (; iter1 != end1 && iter2 != end2; ++iter1, ++iter2) {
EXPECT_EQ(iter1->first.username, iter2->first.username);
EXPECT_EQ(iter1->first.password, iter2->first.password);
EXPECT_EQ(iter1->first.realm, iter2->first.realm);
EXPECT_EQ(iter1->second, iter2->second);
}
ASSERT_EQ(iter1, end1);
ASSERT_EQ(iter2, end2);
}
EXPECT_EQ(expected.wait_for_username, actual.wait_for_username);
EXPECT_EQ(expected.is_possible_change_password_form,
actual.is_possible_change_password_form);
}
void CheckEqualPasswordFormGenerationData(
const PasswordFormGenerationData& expected,
const PasswordFormGenerationData& actual) {
EXPECT_EQ(expected.name, actual.name);
EXPECT_EQ(expected.action, actual.action);
EXPECT_EQ(expected.generation_field, actual.generation_field);
}
} // namespace
class AutofillTypeTraitsTestImpl : public testing::Test,
public mojom::TypeTraitsTest {
public:
AutofillTypeTraitsTestImpl() {}
mojom::TypeTraitsTestPtr GetTypeTraitsTestProxy() {
return bindings_.CreateInterfacePtrAndBind(this);
}
// mojom::TypeTraitsTest:
void PassFormData(const FormData& s,
const PassFormDataCallback& callback) override {
callback.Run(s);
}
void PassFormFieldData(const FormFieldData& s,
const PassFormFieldDataCallback& callback) override {
callback.Run(s);
}
void PassFormDataPredictions(
const FormDataPredictions& s,
const PassFormDataPredictionsCallback& callback) override {
callback.Run(s);
}
void PassFormFieldDataPredictions(
const FormFieldDataPredictions& s,
const PassFormFieldDataPredictionsCallback& callback) override {
callback.Run(s);
}
void PassPasswordFormFillData(
const PasswordFormFillData& s,
const PassPasswordFormFillDataCallback& callback) override {
callback.Run(s);
}
void PassPasswordFormGenerationData(
const PasswordFormGenerationData& s,
const PassPasswordFormGenerationDataCallback& callback) override {
callback.Run(s);
}
void PassPasswordForm(const PasswordForm& s,
const PassPasswordFormCallback& callback) override {
callback.Run(s);
}
void PassFormsPredictionsMap(
const FormsPredictionsMap& s,
const PassFormsPredictionsMapCallback& callback) override {
callback.Run(s);
}
private:
base::MessageLoop loop_;
mojo::BindingSet<TypeTraitsTest> bindings_;
};
void ExpectFormFieldData(const FormFieldData& expected,
const base::Closure& closure,
const FormFieldData& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
void ExpectFormData(const FormData& expected,
const base::Closure& closure,
const FormData& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
void ExpectFormFieldDataPredictions(const FormFieldDataPredictions& expected,
const base::Closure& closure,
const FormFieldDataPredictions& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
void ExpectFormDataPredictions(const FormDataPredictions& expected,
const base::Closure& closure,
const FormDataPredictions& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
void ExpectPasswordFormFillData(const PasswordFormFillData& expected,
const base::Closure& closure,
const PasswordFormFillData& passed) {
CheckEqualPasswordFormFillData(expected, passed);
closure.Run();
}
void ExpectPasswordFormGenerationData(
const PasswordFormGenerationData& expected,
const base::Closure& closure,
const PasswordFormGenerationData& passed) {
CheckEqualPasswordFormGenerationData(expected, passed);
closure.Run();
}
void ExpectPasswordForm(const PasswordForm& expected,
const base::Closure& closure,
const PasswordForm& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
void ExpectFormsPredictionsMap(const FormsPredictionsMap& expected,
const base::Closure& closure,
const FormsPredictionsMap& passed) {
EXPECT_EQ(expected, passed);
closure.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldData) {
FormFieldData input;
test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
kOptions, 4, &input);
// Set other attributes to check if they are passed correctly.
input.autocomplete_attribute = "on";
input.placeholder = base::ASCIIToUTF16("placeholder");
input.css_classes = base::ASCIIToUTF16("class1");
input.max_length = 12345;
input.is_autofilled = true;
input.check_status = FormFieldData::CHECKED;
input.should_autocomplete = true;
input.role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
input.text_direction = base::i18n::RIGHT_TO_LEFT;
input.properties_mask = FieldPropertiesFlags::HAD_FOCUS;
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassFormFieldData(
input, base::Bind(&ExpectFormFieldData, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassFormData) {
FormData input;
test::CreateTestAddressFormData(&input);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassFormData(
input, base::Bind(&ExpectFormData, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldDataPredictions) {
FormFieldDataPredictions input;
CreateTestFieldDataPredictions("TestSignature", &input);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassFormFieldDataPredictions(
input,
base::Bind(&ExpectFormFieldDataPredictions, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassFormDataPredictions) {
FormDataPredictions input;
test::CreateTestAddressFormData(&input.data);
input.signature = "TestSignature";
FormFieldDataPredictions field_predict;
CreateTestFieldDataPredictions("Tom", &field_predict);
input.fields.push_back(field_predict);
CreateTestFieldDataPredictions("Jerry", &field_predict);
input.fields.push_back(field_predict);
CreateTestFieldDataPredictions("NoOne", &field_predict);
input.fields.push_back(field_predict);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassFormDataPredictions(
input,
base::Bind(&ExpectFormDataPredictions, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassPasswordFormFillData) {
PasswordFormFillData input;
CreateTestPasswordFormFillData(&input);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassPasswordFormFillData(input, base::Bind(&ExpectPasswordFormFillData,
input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassPasswordFormGenerationData) {
FormData form;
test::CreateTestAddressFormData(&form);
PasswordFormGenerationData input{form.name, form.action, form.fields[0]};
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassPasswordFormGenerationData(
input,
base::Bind(&ExpectPasswordFormGenerationData, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassPasswordForm) {
PasswordForm input;
CreateTestPasswordForm(&input);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassPasswordForm(
input, base::Bind(&ExpectPasswordForm, input, loop.QuitClosure()));
loop.Run();
}
TEST_F(AutofillTypeTraitsTestImpl, PassFormsPredictionsMap) {
FormsPredictionsMap input;
CreateTestFormsPredictionsMap(&input);
base::RunLoop loop;
mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
proxy->PassFormsPredictionsMap(
input, base::Bind(&ExpectFormsPredictionsMap, input, loop.QuitClosure()));
loop.Run();
}
} // namespace autofill