From b6d14dc19dd350a807826e3e097738a36613e083 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 8 Apr 2014 11:49:14 +0200 Subject: moving users: app and test files --- test/integration/browser/account_test.rb | 147 +++++++++++++++++++++++++++++++ test/integration/browser/session_test.rb | 27 ++++++ 2 files changed, 174 insertions(+) create mode 100644 test/integration/browser/account_test.rb create mode 100644 test/integration/browser/session_test.rb (limited to 'test/integration/browser') diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb new file mode 100644 index 0000000..a5677ad --- /dev/null +++ b/test/integration/browser/account_test.rb @@ -0,0 +1,147 @@ +require 'test_helper' + +class AccountTest < BrowserIntegrationTest + + teardown do + Identity.destroy_all_disabled + end + + test "normal account workflow" do + username, password = submit_signup + assert page.has_content?("Welcome #{username}") + click_on 'Logout' + assert page.has_content?("Log In") + assert_equal '/', current_path + assert user = User.find_by_login(username) + user.account.destroy + end + + test "successful login" do + username, password = submit_signup + click_on 'Logout' + attempt_login(username, password) + assert page.has_content?("Welcome #{username}") + within('.sidenav li.active') do + assert page.has_content?("Overview") + end + User.find_by_login(username).account.destroy + end + + test "failed login" do + visit '/' + attempt_login("username", "wrong password") + assert_invalid_login(page) + end + + test "account destruction" do + username, password = submit_signup + click_on I18n.t('account_settings') + click_on I18n.t('destroy_my_account') + assert page.has_content?(I18n.t('account_destroyed')) + attempt_login(username, password) + assert_invalid_login(page) + end + + test "handle blocked after account destruction" do + username, password = submit_signup + click_on I18n.t('account_settings') + click_on I18n.t('destroy_my_account') + submit_signup(username) + assert page.has_content?('has already been taken') + end + + test "default user actions" do + username, password = submit_signup + click_on "Account Settings" + assert page.has_content? I18n.t('destroy_my_account') + assert page.has_no_css? '#update_login_and_password' + assert page.has_no_css? '#update_pgp_key' + end + + test "default admin actions" do + username, password = submit_signup + with_config admins: [username] do + click_on "Account Settings" + assert page.has_content? I18n.t('destroy_my_account') + assert page.has_no_css? '#update_login_and_password' + assert page.has_css? '#update_pgp_key' + end + end + + test "change password" do + with_config user_actions: ['change_password'] do + username, password = submit_signup + click_on "Account Settings" + within('#update_login_and_password') do + fill_in 'Password', with: "other password" + fill_in 'Password confirmation', with: "other password" + click_on 'Save' + end + click_on 'Logout' + attempt_login(username, "other password") + assert page.has_content?("Welcome #{username}") + User.find_by_login(username).account.destroy + end + end + + test "change pgp key" do + with_config user_actions: ['change_pgp_key'] do + pgp_key = FactoryGirl.build :pgp_key + username, password = submit_signup + click_on "Account Settings" + within('#update_pgp_key') do + fill_in 'Public key', with: pgp_key + click_on 'Save' + end + page.assert_selector 'input[value="Saving..."]' + # at some point we're done: + page.assert_no_selector 'input[value="Saving..."]' + assert page.has_field? 'Public key', with: pgp_key.to_s + user = User.find_by_login(username) + assert_equal pgp_key, user.public_key + user.account.destroy + end + end + + + # trying to seed an invalid A for srp login + test "detects attempt to circumvent SRP" do + user = FactoryGirl.create :user + visit '/login' + fill_in 'Username', with: user.login + fill_in 'Password', with: "password" + inject_malicious_js + click_on 'Log In' + assert page.has_content?("Invalid random key") + assert page.has_no_content?("Welcome") + user.destroy + end + + test "reports internal server errors" do + V1::UsersController.any_instance.stubs(:create).raises + submit_signup + assert page.has_content?("server failed") + end + + def attempt_login(username, password) + click_on 'Log In' + fill_in 'Username', with: username + fill_in 'Password', with: password + click_on 'Log In' + end + + def assert_invalid_login(page) + assert page.has_selector? 'input.btn-primary.disabled' + assert page.has_content? I18n.t(:invalid_user_pass) + assert page.has_no_selector? 'input.btn-primary.disabled' + end + + def inject_malicious_js + page.execute_script <<-EOJS + var calc = new srp.Calculate(); + calc.A = function(_a) {return "00";}; + calc.S = calc.A; + srp.session = new srp.Session(null, calc); + EOJS + end +end diff --git a/test/integration/browser/session_test.rb b/test/integration/browser/session_test.rb new file mode 100644 index 0000000..3a41b3a --- /dev/null +++ b/test/integration/browser/session_test.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class SessionTest < BrowserIntegrationTest + + setup do + @username, password = submit_signup + end + + teardown do + user = User.find_by_login(@username) + id = user.identity + id.destroy + user.destroy + end + + test "valid session" do + assert page.has_content?("Welcome #{@username}") + end + + test "expired session" do + assert page.has_content?("Welcome #{@username}") + pretend_now_is(Time.now + 40.minutes) do + visit '/' + assert page.has_no_content?("Welcome #{@username}") + end + end +end -- cgit v1.2.3 From f23ca91c01ce14d75c221ccddb7d8b1b7e2c0cef Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 24 Apr 2014 13:17:06 +0200 Subject: make test independent of button tag input or button can be used --- test/integration/browser/account_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/integration/browser') diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb index a5677ad..6d5f7f9 100644 --- a/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_test.rb @@ -131,9 +131,9 @@ class AccountTest < BrowserIntegrationTest end def assert_invalid_login(page) - assert page.has_selector? 'input.btn-primary.disabled' + assert page.has_selector? '.btn-primary.disabled' assert page.has_content? I18n.t(:invalid_user_pass) - assert page.has_no_selector? 'input.btn-primary.disabled' + assert page.has_no_selector? '.btn-primary.disabled' end def inject_malicious_js -- cgit v1.2.3 From a2909d781a790e47acbdbb8b4560177100ad9942 Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 25 Apr 2014 16:51:03 +0200 Subject: basic password validation without client side gem The client_side_validations gem is not maintained anymore and the validations were not working lately. So instead of trying to fix it I started working on independent validations for the password as it can't be validated on the server due to SRP. So far these validations are very primitive. They require 8 characters length and a matching confirmation. --- .../browser/password_validation_test.rb | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 test/integration/browser/password_validation_test.rb (limited to 'test/integration/browser') diff --git a/test/integration/browser/password_validation_test.rb b/test/integration/browser/password_validation_test.rb new file mode 100644 index 0000000..45eb0bf --- /dev/null +++ b/test/integration/browser/password_validation_test.rb @@ -0,0 +1,31 @@ +require 'test_helper' + +class PasswordValidationTest < BrowserIntegrationTest + + test "password confirmation is validated" do + username ||= "test_#{SecureRandom.urlsafe_base64}".downcase + password ||= SecureRandom.base64 + visit '/users/new' + fill_in 'Username', with: username + fill_in 'Password', with: password + fill_in 'Password confirmation', with: password + "-typo" + click_on 'Sign Up' + assert page.has_content? "does not match." + assert_equal '/users/new', current_path + assert page.has_selector? ".error #srp_password_confirmation" + end + + test "password needs to be at least 8 chars long" do + username ||= "test_#{SecureRandom.urlsafe_base64}".downcase + password ||= SecureRandom.base64[0,7] + visit '/users/new' + fill_in 'Username', with: username + fill_in 'Password', with: password + fill_in 'Password confirmation', with: password + click_on 'Sign Up' + assert page.has_content? "needs to be at least 8 characters long" + assert_equal '/users/new', current_path + assert page.has_selector? ".error #srp_password" + end +end + -- cgit v1.2.3 From 3952a7dfcd13993bd51ac7dc07cb3a01b4658e25 Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 30 Apr 2014 16:35:39 +0200 Subject: hide srp forms when no js is available Hiding them using two mechanisms in case one fails: .hidden class - bootstrap hides them then style='display:none' - so they are hidden even if css load fails --- test/integration/browser/account_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'test/integration/browser') diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb index 6d5f7f9..4e11520 100644 --- a/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_test.rb @@ -123,6 +123,20 @@ class AccountTest < BrowserIntegrationTest assert page.has_content?("server failed") end + test "does not render signup form without js" do + Capybara.current_driver = :rack_test # no js + visit '/signup' + assert page.has_no_content?("Username") + assert page.has_no_content?("Password") + end + + test "does not render login form without js" do + Capybara.current_driver = :rack_test # no js + visit '/login' + assert page.has_no_content?("Username") + assert page.has_no_content?("Password") + end + def attempt_login(username, password) click_on 'Log In' fill_in 'Username', with: username -- cgit v1.2.3 From 86eb9062f1e81302647bf18ce0f5fd981202b68a Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 13 May 2014 09:51:36 +0200 Subject: allow for usernames with dots preparing for #5664 with some test improvements i ran into this issue This commit includes a fix and the test improvements. In particular it adds BrowserIntegrationTest#login - so there is no need to go through the signup procedure everytime you want a user to be logged in. --- test/integration/browser/account_test.rb | 27 +++++++++++++++------------ test/integration/browser/session_test.rb | 20 +++++--------------- 2 files changed, 20 insertions(+), 27 deletions(-) (limited to 'test/integration/browser') diff --git a/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb index 4e11520..491a9e1 100644 --- a/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_test.rb @@ -6,7 +6,7 @@ class AccountTest < BrowserIntegrationTest Identity.destroy_all_disabled end - test "normal account workflow" do + test "signup successfully" do username, password = submit_signup assert page.has_content?("Welcome #{username}") click_on 'Logout' @@ -16,6 +16,12 @@ class AccountTest < BrowserIntegrationTest user.account.destroy end + test "signup with username ending in dot json" do + username = Faker::Internet.user_name + '.json' + submit_signup username + assert page.has_content?("Welcome #{username}") + end + test "successful login" do username, password = submit_signup click_on 'Logout' @@ -51,7 +57,7 @@ class AccountTest < BrowserIntegrationTest end test "default user actions" do - username, password = submit_signup + login click_on "Account Settings" assert page.has_content? I18n.t('destroy_my_account') assert page.has_no_css? '#update_login_and_password' @@ -59,8 +65,8 @@ class AccountTest < BrowserIntegrationTest end test "default admin actions" do - username, password = submit_signup - with_config admins: [username] do + login + with_config admins: [@user.login] do click_on "Account Settings" assert page.has_content? I18n.t('destroy_my_account') assert page.has_no_css? '#update_login_and_password' @@ -70,7 +76,7 @@ class AccountTest < BrowserIntegrationTest test "change password" do with_config user_actions: ['change_password'] do - username, password = submit_signup + login click_on "Account Settings" within('#update_login_and_password') do fill_in 'Password', with: "other password" @@ -78,16 +84,15 @@ class AccountTest < BrowserIntegrationTest click_on 'Save' end click_on 'Logout' - attempt_login(username, "other password") - assert page.has_content?("Welcome #{username}") - User.find_by_login(username).account.destroy + attempt_login(@user.login, "other password") + assert page.has_content?("Welcome #{@user.login}") end end test "change pgp key" do with_config user_actions: ['change_pgp_key'] do pgp_key = FactoryGirl.build :pgp_key - username, password = submit_signup + login click_on "Account Settings" within('#update_pgp_key') do fill_in 'Public key', with: pgp_key @@ -97,9 +102,7 @@ class AccountTest < BrowserIntegrationTest # at some point we're done: page.assert_no_selector 'input[value="Saving..."]' assert page.has_field? 'Public key', with: pgp_key.to_s - user = User.find_by_login(username) - assert_equal pgp_key, user.public_key - user.account.destroy + assert_equal pgp_key, @user.reload.public_key end end diff --git a/test/integration/browser/session_test.rb b/test/integration/browser/session_test.rb index 3a41b3a..fb20847 100644 --- a/test/integration/browser/session_test.rb +++ b/test/integration/browser/session_test.rb @@ -2,26 +2,16 @@ require 'test_helper' class SessionTest < BrowserIntegrationTest - setup do - @username, password = submit_signup - end - - teardown do - user = User.find_by_login(@username) - id = user.identity - id.destroy - user.destroy - end - test "valid session" do - assert page.has_content?("Welcome #{@username}") + login + assert page.has_content?("Logout") end test "expired session" do - assert page.has_content?("Welcome #{@username}") - pretend_now_is(Time.now + 40.minutes) do + login + pretend_now_is(Time.now + 80.minutes) do visit '/' - assert page.has_no_content?("Welcome #{@username}") + assert page.has_content?("Log In") end end end -- cgit v1.2.3