Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: ios/chrome/browser/passwords/password_controller_js_unittest.mm

Issue 2152593002: Upstream password manager unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix GYP Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/passwords/password_controller_js_unittest.mm
diff --git a/ios/chrome/browser/passwords/password_controller_js_unittest.mm b/ios/chrome/browser/passwords/password_controller_js_unittest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..966edc5e91ce98cea16d70331dc494bf17fc2592
--- /dev/null
+++ b/ios/chrome/browser/passwords/password_controller_js_unittest.mm
@@ -0,0 +1,300 @@
+// Copyright 2013 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.
+
+#import <Foundation/Foundation.h>
+
+#import "ios/chrome/browser/passwords/js_password_manager.h"
+#import "ios/web/public/test/web_js_test.h"
+#import "ios/web/public/test/web_test_with_web_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+
+// Unit tests for ios/chrome/browser/web/resources/password_controller.js
+namespace {
+
+// Text fixture to test password controller.
+class PasswordControllerJsTest
+ : public web::WebJsTest<web::WebTestWithWebState> {
+ public:
+ PasswordControllerJsTest()
+ : web::WebJsTest<web::WebTestWithWebState>(@[ @"password_controller" ]) {}
+};
+
+// IDs used in the Username and Password <input> elements.
+NSString* const kEmailInputID = @"Email";
+NSString* const kPasswordInputID = @"Passwd";
+
+// Returns an autoreleased string of an HTML form that is similar to the
+// Google Accounts sign in form. |email| may be nil if the form does not
+// need to be pre-filled with the username. Use |isReadOnly| flag to indicate
+// if the email field should be read-only.
+NSString* GAIASignInForm(NSString* formAction,
+ NSString* email,
+ BOOL isReadOnly) {
+ return [NSString
+ stringWithFormat:
+ @"<html><body>"
+ "<form novalidate method=\"post\" action=\"%@\" "
+ "id=\"gaia_loginform\">"
+ " <input name=\"GALX\" type=\"hidden\" value=\"abcdefghij\">"
+ " <input name=\"service\" type=\"hidden\" value=\"mail\">"
+ " <input id=\"%@\" name=\"Email\" type=\"email\" value=\"%@\" %@>"
+ " <input id=\"%@\" name=\"Passwd\" type=\"password\" "
+ " placeholder=\"Password\">"
+ "</form></body></html>",
+ formAction, kEmailInputID, email ? email : @"",
+ isReadOnly ? @"readonly" : @"", kPasswordInputID];
+}
+
+// Returns an autoreleased string of JSON for a parsed form.
+NSString* GAIASignInFormData(NSString* formAction) {
+ return [NSString stringWithFormat:@"{"
+ " \"action\":\"%@\","
+ " \"origin\":\"%@\","
+ " \"fields\":["
+ " {\"name\":\"%@\", \"value\":\"\"},"
+ " {\"name\":\"%@\",\"value\":\"\"}"
+ " ]"
+ "}",
+ formAction, formAction, kEmailInputID,
+ kPasswordInputID];
+}
+
+// Loads a page with a password form containing a username value already.
+// Checks that an attempt to fill in credentials with the same username
+// succeeds.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithPrefilledUsername_SucceedsWhenUsernameMatches) {
+ NSString* const formAction = @"https://accounts.google.com/ServiceLoginAuth";
+ NSString* const username = @"john.doe@gmail.com";
+ NSString* const password = @"super!secret";
+ LoadHtmlAndInject(GAIASignInForm(formAction, username, YES));
+ EXPECT_NSEQ(@"true", EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')",
+ GAIASignInFormData(formAction), username, password,
+ formAction));
+ // Verifies that the sign-in form has been filled with username/password.
+ EvaluateJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value",
+ @[ kEmailInputID, kPasswordInputID ],
+ @[ username, password ]);
+}
+
+// Loads a page with a password form containing a username value already.
+// Checks that an attempt to fill in credentials with a different username
+// fails, as long as the field is read-only.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithPrefilledUsername_FailsWhenUsernameMismatched) {
+ NSString* const formAction = @"https://accounts.google.com/ServiceLoginAuth";
+ NSString* const username1 = @"john.doe@gmail.com";
+ NSString* const username2 = @"jean.dubois@gmail.com";
+ NSString* const password = @"super!secret";
+ LoadHtmlAndInject(GAIASignInForm(formAction, username1, YES));
+ EXPECT_NSEQ(@"false", EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')",
+ GAIASignInFormData(formAction), username2, password,
+ formAction));
+ // Verifies that the sign-in form has not been filled.
+ EvaluateJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value",
+ @[ kEmailInputID, kPasswordInputID ],
+ @[ username1, @"" ]);
+}
+
+// Loads a page with a password form containing a username value already.
+// Checks that an attempt to fill in credentials with a different username
+// succeeds, as long as the field is writeable.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithPrefilledUsername_SucceedsByOverridingUsername) {
+ NSString* const formAction = @"https://accounts.google.com/ServiceLoginAuth";
+ NSString* const username1 = @"john.doe@gmail.com";
+ NSString* const username2 = @"jane.doe@gmail.com";
+ NSString* const password = @"super!secret";
+ LoadHtmlAndInject(GAIASignInForm(formAction, username1, NO));
+ EXPECT_NSEQ(@"true", EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')",
+ GAIASignInFormData(formAction), username2, password,
+ formAction));
+ // Verifies that the sign-in form has been filled with the new username
+ // and password.
+ EvaluateJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value",
+ @[ kEmailInputID, kPasswordInputID ],
+ @[ username2, password ]);
+}
+
+// Check that when instructed to fill a form named "bar", a form named "foo"
+// is not filled with generated password.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithGeneratedPassword_FailsWhenFormNotFound) {
+ LoadHtmlAndInject(@"<html>"
+ " <body>"
+ " <form name=\"foo\">"
+ " <input type=\"password\" name=\"ps\">"
+ " </form>"
+ " </body"
+ "</html>");
+ NSString* const formName = @"bar";
+ NSString* const password = @"abc";
+ EXPECT_NSEQ(@"false",
+ EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordFormWithGeneratedPassword('%@', '%@')",
+ formName, password));
+}
+
+// Check that filling a form without password fields fails.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithGeneratedPassword_FailsWhenNoFieldsFilled) {
+ LoadHtmlAndInject(@"<html>"
+ " <body>"
+ " <form name=\"foo\">"
+ " <input type=\"text\" name=\"user\">"
+ " <input type=\"submit\" name=\"go\">"
+ " </form>"
+ " </body"
+ "</html>");
+ NSString* const formName = @"foo";
+ NSString* const password = @"abc";
+ EXPECT_NSEQ(@"false",
+ EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordFormWithGeneratedPassword('%@', '%@')",
+ formName, password));
+}
+
+// Check that a matching and complete password form is successfully filled
+// with the generated password.
+TEST_F(PasswordControllerJsTest,
+ FillPasswordFormWithGeneratedPassword_SucceedsWhenFieldsFilled) {
+ LoadHtmlAndInject(@"<html>"
+ " <body>"
+ " <form name=\"foo\">"
+ " <input type=\"text\" id=\"user\" name=\"user\">"
+ " <input type=\"password\" id=\"ps1\" name=\"ps1\">"
+ " <input type=\"password\" id=\"ps2\" name=\"ps2\">"
+ " <input type=\"submit\" name=\"go\">"
+ " </form>"
+ " </body"
+ "</html>");
+ NSString* const formName = @"foo";
+ NSString* const password = @"abc";
+ EXPECT_NSEQ(@"true",
+ EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.fillPasswordFormWithGeneratedPassword('%@', '%@')",
+ formName, password));
+ EXPECT_NSEQ(@"true",
+ EvaluateJavaScriptWithFormat(
+ @"document.getElementById('ps1').value == '%@'", password));
+ EXPECT_NSEQ(@"true",
+ EvaluateJavaScriptWithFormat(
+ @"document.getElementById('ps2').value == '%@'", password));
+ EXPECT_NSEQ(@"false",
+ EvaluateJavaScriptWithFormat(
+ @"document.getElementById('user').value == '%@'", password));
+}
+
+// Check that one password form is identified and serialized correctly.
+TEST_F(PasswordControllerJsTest,
+ FindAndPreparePasswordFormsSingleFrameSingleForm) {
+ LoadHtmlAndInject(
+ @"<html><body>"
+ "<form action='/generic_submit' method='post' name='login_form'>"
+ " Name: <input type='text' name='name'>"
+ " Password: <input type='password' name='password'>"
+ " <input type='submit' value='Submit'>"
+ "</form>"
+ "</body></html>");
+
+ const std::string base_url = BaseUrl();
+ NSString* result = [NSString
+ stringWithFormat:
+ @"[{\"action\":\"/generic_submit\","
+ "\"method\":\"post\","
+ "\"name\":\"login_form\","
+ "\"origin\":\"%s\","
+ "\"fields\":[{\"element\":\"name\",\"type\":\"text\"},"
+ "{\"element\":\"password\",\"type\":\"password\"},"
+ "{\"element\":\"\",\"type\":\"submit\"}],"
+ "\"usernameElement\":\"name\","
+ "\"usernameValue\":\"\","
+ "\"passwords\":[{\"element\":\"password\",\"value\":\"\"}]}]",
+ base_url.c_str()];
+ EXPECT_NSEQ(result,
+ EvaluateJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()"));
+};
+
+// Check that multiple password forms are identified and serialized correctly.
+TEST_F(PasswordControllerJsTest,
+ FindAndPreparePasswordFormsSingleFrameMultipleForms) {
+ LoadHtmlAndInject(
+ @"<html><body>"
+ "<form action='/generic_submit' method='post' id='login_form1'>"
+ " Name: <input type='text' name='name'>"
+ " Password: <input type='password' name='password'>"
+ " <input type='submit' value='Submit'>"
+ "</form>"
+ "<form action='/generic_s2' method='post' name='login_form2'>"
+ " Name: <input type='text' name='name2'>"
+ " Password: <input type='password' name='password2'>"
+ " <input type='submit' value='Submit'>"
+ "</form>"
+ "</body></html>");
+
+ const std::string base_url = BaseUrl();
+ NSString* result = [NSString
+ stringWithFormat:
+ @"[{\"action\":\"/generic_submit\","
+ "\"method\":\"post\","
+ "\"name\":\"login_form1\","
+ "\"origin\":\"%s\","
+ "\"fields\":[{\"element\":\"name\",\"type\":\"text\"},"
+ "{\"element\":\"password\",\"type\":\"password\"},"
+ "{\"element\":\"\",\"type\":\"submit\"}],"
+ "\"usernameElement\":\"name\","
+ "\"usernameValue\":\"\","
+ "\"passwords\":[{\"element\":\"password\",\"value\":\"\"}]},"
+ "{\"action\":\"/generic_s2\","
+ "\"method\":\"post\","
+ "\"name\":\"login_form2\","
+ "\"origin\":\"%s\","
+ "\"fields\":[{\"element\":\"name2\",\"type\":\"text\"},"
+ "{\"element\":\"password2\",\"type\":\"password\"},"
+ "{\"element\":\"\",\"type\":\"submit\"}],"
+ "\"usernameElement\":\"name2\","
+ "\"usernameValue\":\"\","
+ "\"passwords\":[{\"element\":\"password2\",\"value\":\"\"}]}]",
+ base_url.c_str(), base_url.c_str()];
+ EXPECT_NSEQ(result,
+ EvaluateJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()"));
+};
+
+// Test serializing of password forms.
+TEST_F(PasswordControllerJsTest, GetPasswordFormData) {
+ LoadHtmlAndInject(
+ @"<html><body>"
+ "<form name='np' id='np1' action='/generic_submit' method='post'>"
+ " Name: <input type='text' name='name'>"
+ " Password: <input type='password' name='password'>"
+ " <input type='submit' value='Submit'>"
+ "</form>"
+ "</body></html>");
+
+ const std::string base_url = BaseUrl();
+ NSString* parameter = @"window.document.getElementsByTagName('form')[0]";
+ NSString* result = [NSString
+ stringWithFormat:
+ @"{\"action\":\"/generic_submit\","
+ "\"method\":\"post\","
+ "\"name\":\"np\","
+ "\"origin\":\"%s\","
+ "\"fields\":[{\"element\":\"name\",\"type\":\"text\"},"
+ "{\"element\":\"password\",\"type\":\"password\"},"
+ "{\"element\":\"\",\"type\":\"submit\"}],"
+ "\"usernameElement\":\"name\","
+ "\"usernameValue\":\"\","
+ "\"passwords\":[{\"element\":\"password\",\"value\":\"\"}]}",
+ base_url.c_str()];
+ EXPECT_NSEQ(
+ result,
+ EvaluateJavaScriptWithFormat(
+ @"__gCrWeb.stringify(__gCrWeb.getPasswordFormData(%@))", parameter));
+};
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698