From 53808b073f539ba2b442738b6abf97228488e311 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 8 Apr 2014 09:12:37 +0200 Subject: moving all of core into toplevel, tests fail. --- test/support/browser_integration_test.rb | 81 ++++++++++++++++++++++++++++++++ test/support/rack_test.rb | 37 +++++++++++++++ test/support/with_config_helper.rb | 16 +++++++ 3 files changed, 134 insertions(+) create mode 100644 test/support/browser_integration_test.rb create mode 100644 test/support/rack_test.rb create mode 100644 test/support/with_config_helper.rb (limited to 'test/support') diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb new file mode 100644 index 0000000..2885c3a --- /dev/null +++ b/test/support/browser_integration_test.rb @@ -0,0 +1,81 @@ +# +# BrowserIntegrationTest +# +# Use this class for capybara based integration tests for the ui. +# + +class BrowserIntegrationTest < ActionDispatch::IntegrationTest + + CONFIG_RU = (Rails.root + 'config.ru').to_s + OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first + + require 'capybara/poltergeist' + + Capybara.register_driver :rack_test do |app| + Capybara::RackTest::Driver.new(app) + end + + Capybara.register_driver :poltergeist do |app| + Capybara::Poltergeist::Driver.new(app) + end + + # this is integration testing. So let's make the whole + # rack stack available... + Capybara.app = OUTER_APP + Capybara.run_server = true + Capybara.app_host = 'http://lvh.me:3003' + Capybara.server_port = 3003 + Capybara.javascript_driver = :poltergeist + Capybara.default_wait_time = 5 + + + # Make the Capybara DSL available + include Capybara::DSL + + setup do + Capybara.current_driver = Capybara.javascript_driver + page.driver.add_headers 'ACCEPT-LANGUAGE' => 'en-EN' + end + + teardown do + Capybara.reset_sessions! # Forget the (simulated) browser state + Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver + end + + def submit_signup(username = nil, password = nil) + 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 + click_on 'Sign Up' + return username, password + end + + add_teardown_hook do |testcase| + unless testcase.passed? + testcase.save_state + end + end + + def save_state + page.save_screenshot screenshot_path + File.open(logfile_path, 'w') do |test_log| + test_log.puts self.class.name + test_log.puts "=========================" + test_log.puts __name__ + test_log.puts Time.now + test_log.puts current_path + test_log.puts page.status_code + test_log.puts page.response_headers + test_log.puts "page.html" + test_log.puts "------------------------" + test_log.puts page.html + test_log.puts "server log" + test_log.puts "------------------------" + test_log.puts `tail log/test.log -n 200` + end + end + +end diff --git a/test/support/rack_test.rb b/test/support/rack_test.rb new file mode 100644 index 0000000..2d8e5c4 --- /dev/null +++ b/test/support/rack_test.rb @@ -0,0 +1,37 @@ +class RackTest < ActiveSupport::TestCase + include Rack::Test::Methods + include Warden::Test::Helpers + include LeapWebCore::AssertResponses + + CONFIG_RU = (Rails.root + 'config.ru').to_s + OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first + + def app + OUTER_APP + end + + def assert_access_denied + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + end + + # inspired by rails 4 + # -> actionpack/lib/action_dispatch/testing/assertions/response.rb + def assert_response(type, message = nil) + # RackTest does not know @response + response_code = last_response.status + message ||= "Expected response to be a <#{type}>, but was <#{response_code}>" + + if Symbol === type + if [:success, :missing, :redirect, :error].include?(type) + assert last_response.send("#{type}?"), message + else + code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type] + assert_equal code, response_code, message + end + else + assert_equal type, response_code, message + end + end + +end diff --git a/test/support/with_config_helper.rb b/test/support/with_config_helper.rb new file mode 100644 index 0000000..65eb7bc --- /dev/null +++ b/test/support/with_config_helper.rb @@ -0,0 +1,16 @@ +module WithConfigHelper + extend ActiveSupport::Concern + + def with_config(options) + old_config = APP_CONFIG.dup + APP_CONFIG.merge! options + yield + ensure + APP_CONFIG.replace old_config + end + +end + +class ActiveSupport::TestCase + include WithConfigHelper +end -- cgit v1.2.3 From 045237ff88ffd5f1fe23d9621b043a9e604e54fa Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 8 Apr 2014 09:58:41 +0200 Subject: fix requiring core extensions - most tests pass some message tests are failing for me right now. --- test/support/assert_responses.rb | 46 ++++++++++++++++++++++++++++++++++++++++ test/support/rack_test.rb | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/support/assert_responses.rb (limited to 'test/support') diff --git a/test/support/assert_responses.rb b/test/support/assert_responses.rb new file mode 100644 index 0000000..b01166f --- /dev/null +++ b/test/support/assert_responses.rb @@ -0,0 +1,46 @@ +module AssertResponses + + # response that works with different TestCases: + # ActionController::TestCase has @response + # ActionDispatch::IntegrationTest has @response + # Rack::Test::Methods defines last_response + def get_response + @response || last_response + end + + def assert_attachement_filename(name) + assert_equal %Q(attachment; filename="#{name}"), + get_response.headers["Content-Disposition"] + end + + def json_response + response = JSON.parse(get_response.body) + response.respond_to?(:with_indifferent_access) ? + response.with_indifferent_access : + response + end + + def assert_json_response(object) + assert_equal 'application/json', + get_response.content_type.to_s.split(';').first + if object.is_a? Hash + object.stringify_keys! if object.respond_to? :stringify_keys! + assert_equal object, json_response + else + assert_equal object.to_json, get_response.body + end + end + + def assert_json_error(object) + object.stringify_keys! if object.respond_to? :stringify_keys! + assert_json_response :errors => object + end +end + +class ::ActionController::TestCase + include AssertResponses +end + +class ::ActionDispatch::IntegrationTest + include AssertResponses +end diff --git a/test/support/rack_test.rb b/test/support/rack_test.rb index 2d8e5c4..35d191b 100644 --- a/test/support/rack_test.rb +++ b/test/support/rack_test.rb @@ -1,7 +1,7 @@ class RackTest < ActiveSupport::TestCase include Rack::Test::Methods include Warden::Test::Helpers - include LeapWebCore::AssertResponses + include AssertResponses CONFIG_RU = (Rails.root + 'config.ru').to_s OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first -- cgit v1.2.3 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/support/auth_test_helper.rb | 65 ++++++++++++++++++++++++++++++++++++++ test/support/stub_record_helper.rb | 53 +++++++++++++++++++++++++++++++ test/support/time_test_helper.rb | 30 ++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 test/support/auth_test_helper.rb create mode 100644 test/support/stub_record_helper.rb create mode 100644 test/support/time_test_helper.rb (limited to 'test/support') diff --git a/test/support/auth_test_helper.rb b/test/support/auth_test_helper.rb new file mode 100644 index 0000000..57f9f9b --- /dev/null +++ b/test/support/auth_test_helper.rb @@ -0,0 +1,65 @@ +module AuthTestHelper + extend ActiveSupport::Concern + + # Controller will fetch current user from warden. + # Make it pick up our current_user + included do + setup do + request.env['warden'] ||= stub :user => nil + end + end + + def login(user_or_method_hash = {}) + if user_or_method_hash.respond_to?(:reverse_merge) + user_or_method_hash.reverse_merge! :is_admin? => false + end + @current_user = stub_record(:user, user_or_method_hash) + request.env['warden'] = stub :user => @current_user + request.env['HTTP_AUTHORIZATION'] = header_for_token_auth + return @current_user + end + + def assert_access_denied(denied = true, logged_in = true) + if denied + if @response.content_type == 'application/json' + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + else + if logged_in + assert_equal({:alert => I18n.t(:not_authorized)}, flash.to_hash) + assert_redirected_to home_url + else + assert_equal({:alert => I18n.t(:not_authorized_login)}, flash.to_hash) + assert_redirected_to login_url + end + end + else + assert flash[:alert].blank? + end + end + + def expect_logout + expect_warden_logout + @token.expects(:destroy) if @token + end + + protected + + def header_for_token_auth + @token = find_record(:token, :authenticate => @current_user) + ActionController::HttpAuthentication::Token.encode_credentials @token.id + end + + def expect_warden_logout + raw = mock('raw session') do + expects(:inspect) + end + request.env['warden'].expects(:raw_session).returns(raw) + request.env['warden'].expects(:logout) + end + +end + +class ActionController::TestCase + include AuthTestHelper +end diff --git a/test/support/stub_record_helper.rb b/test/support/stub_record_helper.rb new file mode 100644 index 0000000..25138a0 --- /dev/null +++ b/test/support/stub_record_helper.rb @@ -0,0 +1,53 @@ +module StubRecordHelper + + # + # We will stub find when called on the records class and + # return the record given. + # + # If no record is given but a hash or nil will create a stub based on + # that instead and returns the stub. + # + def find_record(factory, record_or_attribs_hash = {}) + record = stub_record factory, record_or_attribs_hash, true + klass = record.class + # find is just an alias for get with CouchRest Model + klass.stubs(:get).with(record.to_param.to_s).returns(record) + klass.stubs(:find).with(record.to_param.to_s).returns(record) + return record + end + + # Create a stub that has the usual functions of a database record. + # It won't fail on rendering a form for example. + # + # If the second parameter is a record we return the record itself. + # This way you can build functions that either take a record or a + # method hash to stub from. See find_record for an example. + def stub_record(factory, record_or_method_hash = {}, persisted=false) + if record_or_method_hash && !record_or_method_hash.is_a?(Hash) + return record_or_method_hash + end + FactoryGirl.build_stubbed(factory).tap do |record| + if persisted or record.persisted? + record_or_method_hash.reverse_merge! :created_at => Time.now, + :updated_at => Time.now, :id => Random.rand(100000).to_s + end + record.stubs(record_or_method_hash) if record_or_method_hash.present? + end + end + + # returns deep stringified attributes so they can be compared to + # what the controller receives as params + def record_attributes_for(factory, attribs_hash = nil) + FactoryGirl.attributes_for(factory, attribs_hash).tap do |attribs| + attribs.keys.each do |key| + val = attribs.delete(key) + attribs[key.to_s] = val.is_a?(Hash) ? val.stringify_keys! : val + end + end + end + +end + +class ActionController::TestCase + include StubRecordHelper +end diff --git a/test/support/time_test_helper.rb b/test/support/time_test_helper.rb new file mode 100644 index 0000000..f673f12 --- /dev/null +++ b/test/support/time_test_helper.rb @@ -0,0 +1,30 @@ +# Extend the Time class so that we can offset the time that 'now' +# returns. This should allow us to effectively time warp for functional +# tests that require limits per hour, what not. +class Time #:nodoc: + class < Date: Fri, 11 Apr 2014 10:35:41 +0200 Subject: move include AssertResponses into test itself it may not have been required before the RackTest support class. --- test/support/rack_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test/support') diff --git a/test/support/rack_test.rb b/test/support/rack_test.rb index 35d191b..806339a 100644 --- a/test/support/rack_test.rb +++ b/test/support/rack_test.rb @@ -1,7 +1,8 @@ +require_relative 'assert_responses' + class RackTest < ActiveSupport::TestCase include Rack::Test::Methods include Warden::Test::Helpers - include AssertResponses CONFIG_RU = (Rails.root + 'config.ru').to_s OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first -- 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/support/browser_integration_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test/support') diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb index 2885c3a..9cae8cb 100644 --- a/test/support/browser_integration_test.rb +++ b/test/support/browser_integration_test.rb @@ -60,7 +60,6 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest end def save_state - page.save_screenshot screenshot_path File.open(logfile_path, 'w') do |test_log| test_log.puts self.class.name test_log.puts "=========================" @@ -76,6 +75,9 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest test_log.puts "------------------------" test_log.puts `tail log/test.log -n 200` end + page.save_screenshot screenshot_path + # some drivers do not support screenshots + rescue Capybara::NotSupportedByDriverError end end -- 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/support/browser_integration_test.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/support') diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb index 9cae8cb..836eb63 100644 --- a/test/support/browser_integration_test.rb +++ b/test/support/browser_integration_test.rb @@ -53,6 +53,22 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest return username, password end + # currently this only works for tests with poltergeist. + def login(user = nil) + user ||= @user ||= FactoryGirl.create(:user) + token = Token.create user_id: user.id + page.driver.add_header "Authorization", + 'Token token="' + token.to_s + '"' + visit '/' + end + + teardown do + if @user && @user.reload + Identity.destroy_all_for @user + @user.destroy + end + end + add_teardown_hook do |testcase| unless testcase.passed? testcase.save_state -- cgit v1.2.3 From 0261e82686ec4fcfc8b633664fadb1dd6d9c8070 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 13 May 2014 10:52:55 +0200 Subject: keep empty email field if user removed prefill We should respect the users choice. We can still get their email from the user id if we really need to. --- test/support/browser_integration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/support') diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb index 836eb63..dbd56a9 100644 --- a/test/support/browser_integration_test.rb +++ b/test/support/browser_integration_test.rb @@ -55,7 +55,7 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest # currently this only works for tests with poltergeist. def login(user = nil) - user ||= @user ||= FactoryGirl.create(:user) + @user ||= user ||= FactoryGirl.create(:user) token = Token.create user_id: user.id page.driver.add_header "Authorization", 'Token token="' + token.to_s + '"' -- cgit v1.2.3 From 84ce597ad0516b92d6633c1f81c03517b5d74004 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 13 May 2014 11:01:10 +0200 Subject: minor: use %Q for interpolated string with " --- test/support/browser_integration_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/support') diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb index dbd56a9..1c872ff 100644 --- a/test/support/browser_integration_test.rb +++ b/test/support/browser_integration_test.rb @@ -57,8 +57,7 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest def login(user = nil) @user ||= user ||= FactoryGirl.create(:user) token = Token.create user_id: user.id - page.driver.add_header "Authorization", - 'Token token="' + token.to_s + '"' + page.driver.add_header "Authorization", %Q(Token token="#{token}") visit '/' end -- cgit v1.2.3