door_mat 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +32 -0
- data/app/assets/javascripts/door_mat/application.js +13 -0
- data/app/assets/stylesheets/door_mat/application.css +15 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/door_mat/activities_controller.rb +106 -0
- data/app/controllers/door_mat/application_controller.rb +14 -0
- data/app/controllers/door_mat/change_password_controller.rb +32 -0
- data/app/controllers/door_mat/forgot_passwords_controller.rb +57 -0
- data/app/controllers/door_mat/manage_email_controller.rb +61 -0
- data/app/controllers/door_mat/password_less_session_controller.rb +121 -0
- data/app/controllers/door_mat/reconfirm_password_controller.rb +27 -0
- data/app/controllers/door_mat/sessions_controller.rb +17 -0
- data/app/controllers/door_mat/sign_in_controller.rb +60 -0
- data/app/controllers/door_mat/sign_up_controller.rb +59 -0
- data/app/controllers/door_mat/static_controller.rb +5 -0
- data/app/mailers/door_mat/activity_mailer.rb +18 -0
- data/app/mailers/door_mat/password_less_session_mailer.rb +12 -0
- data/app/models/door_mat/access_token.rb +315 -0
- data/app/models/door_mat/activity.rb +14 -0
- data/app/models/door_mat/activity_confirm_email.rb +45 -0
- data/app/models/door_mat/activity_download_recovery_key.rb +30 -0
- data/app/models/door_mat/activity_reset_password.rb +47 -0
- data/app/models/door_mat/actor.rb +149 -0
- data/app/models/door_mat/change_password.rb +12 -0
- data/app/models/door_mat/email.rb +58 -0
- data/app/models/door_mat/forgot_password.rb +12 -0
- data/app/models/door_mat/membership.rb +42 -0
- data/app/models/door_mat/session.rb +315 -0
- data/app/models/door_mat/sign_in.rb +31 -0
- data/app/models/door_mat/sign_up.rb +17 -0
- data/app/views/door_mat/activity_mailer/confirm_email.html.erb +11 -0
- data/app/views/door_mat/activity_mailer/confirm_email.text.erb +7 -0
- data/app/views/door_mat/activity_mailer/reset_password.html.erb +11 -0
- data/app/views/door_mat/activity_mailer/reset_password.text.erb +7 -0
- data/app/views/door_mat/change_password/new.html.erb +22 -0
- data/app/views/door_mat/forgot_passwords/choose_new_password.html.erb +34 -0
- data/app/views/door_mat/forgot_passwords/new.html.erb +14 -0
- data/app/views/door_mat/helpers/_errors_if_any.html.erb +10 -0
- data/app/views/door_mat/manage_email/new.html.erb +14 -0
- data/app/views/door_mat/password_less_session/access_token.html.erb +16 -0
- data/app/views/door_mat/password_less_session/new.html.erb +34 -0
- data/app/views/door_mat/password_less_session_mailer/send_token.html.erb +11 -0
- data/app/views/door_mat/password_less_session_mailer/send_token.text.erb +7 -0
- data/app/views/door_mat/reconfirm_password/new.html.erb +12 -0
- data/app/views/door_mat/sign_in/new.html.erb +30 -0
- data/app/views/door_mat/sign_up/new.html.erb +24 -0
- data/app/views/door_mat/static/add_email_success.html.erb +5 -0
- data/app/views/door_mat/static/change_password_success.html.erb +2 -0
- data/app/views/door_mat/static/confirm_email_success.html.erb +2 -0
- data/app/views/door_mat/static/email_confirmation_required.html.erb +17 -0
- data/app/views/door_mat/static/forgot_password_verification_mail_sent.html.erb +2 -0
- data/app/views/door_mat/static/reconfirm_password_success.html.erb +4 -0
- data/app/views/door_mat/static/sign_in_success.html.erb +5 -0
- data/app/views/door_mat/static/sign_out_success.html.erb +5 -0
- data/app/views/door_mat/static/sign_up_success.html.erb +4 -0
- data/bin/rails +12 -0
- data/config/locales/en.yml +73 -0
- data/config/routes.rb +48 -0
- data/db/migrate/20140616234935_create_door_mat_actors.rb +23 -0
- data/db/migrate/20140617233357_create_door_mat_sessions.rb +17 -0
- data/db/migrate/20140630043202_create_door_mat_emails.rb +12 -0
- data/db/migrate/20140702045729_create_door_mat_activities.rb +14 -0
- data/db/migrate/20141115183045_create_door_mat_access_tokens.rb +17 -0
- data/db/migrate/20141121191824_create_door_mat_memberships.rb +14 -0
- data/db/migrate/20150910182126_rename_session_guid_column.rb +5 -0
- data/db/migrate/20150918210831_add_access_token_rating_column.rb +5 -0
- data/door_mat.gemspec +37 -0
- data/lib/door_mat.rb +20 -0
- data/lib/door_mat/attr_asymmetric_store.rb +82 -0
- data/lib/door_mat/attr_symmetric_store.rb +82 -0
- data/lib/door_mat/configuration.rb +193 -0
- data/lib/door_mat/controller.rb +117 -0
- data/lib/door_mat/crypto.rb +49 -0
- data/lib/door_mat/crypto/asymmetric_store.rb +77 -0
- data/lib/door_mat/crypto/fast_hash.rb +17 -0
- data/lib/door_mat/crypto/password_hash.rb +39 -0
- data/lib/door_mat/crypto/secure_compare.rb +23 -0
- data/lib/door_mat/crypto/symmetric_store.rb +68 -0
- data/lib/door_mat/engine.rb +23 -0
- data/lib/door_mat/process/actor_password_change.rb +65 -0
- data/lib/door_mat/process/actor_sign_in.rb +38 -0
- data/lib/door_mat/process/actor_sign_up.rb +39 -0
- data/lib/door_mat/process/create_new_anonymous_actor.rb +36 -0
- data/lib/door_mat/process/manage_email.rb +42 -0
- data/lib/door_mat/process/reset_password.rb +50 -0
- data/lib/door_mat/regex.rb +17 -0
- data/lib/door_mat/test_helper.rb +58 -0
- data/lib/door_mat/url_protocol.rb +9 -0
- data/lib/door_mat/version.rb +3 -0
- data/lib/tasks/door_mat_tasks.rake +31 -0
- data/spec/controllers/door_mat/activities_controller_spec.rb +70 -0
- data/spec/controllers/door_mat/forgot_passwords_controller_spec.rb +57 -0
- data/spec/controllers/door_mat/manage_email_spec.rb +181 -0
- data/spec/controllers/door_mat/password_less_session_controller_spec.rb +344 -0
- data/spec/controllers/door_mat/sign_in_controller_spec.rb +211 -0
- data/spec/controllers/door_mat/sign_up_controller_spec.rb +90 -0
- data/spec/factories/door_mat_access_tokens.rb +6 -0
- data/spec/factories/door_mat_activitiess.rb +6 -0
- data/spec/factories/door_mat_actors.rb +23 -0
- data/spec/factories/door_mat_emails.rb +14 -0
- data/spec/factories/door_mat_memberships.rb +6 -0
- data/spec/factories/door_mat_sessions.rb +24 -0
- data/spec/features/password_less_session_spec.rb +165 -0
- data/spec/features/remember_me_spec.rb +672 -0
- data/spec/features/session_spec.rb +336 -0
- data/spec/lib/attr_store_spec.rb +237 -0
- data/spec/lib/crypto_spec.rb +130 -0
- data/spec/lib/process_spec.rb +159 -0
- data/spec/models/door_mat/access_token_spec.rb +134 -0
- data/spec/models/door_mat/activity_spec.rb +38 -0
- data/spec/models/door_mat/actor_spec.rb +56 -0
- data/spec/models/door_mat/email_spec.rb +25 -0
- data/spec/models/door_mat/session_spec.rb +69 -0
- data/spec/spec_helper.rb +223 -0
- data/spec/support/timecop/timecop_helper.rb +52 -0
- data/spec/test_app/README.rdoc +28 -0
- data/spec/test_app/Rakefile +6 -0
- data/spec/test_app/app/assets/javascripts/application.js +13 -0
- data/spec/test_app/app/assets/stylesheets/application.css +15 -0
- data/spec/test_app/app/controllers/account_controller.rb +28 -0
- data/spec/test_app/app/controllers/application_controller.rb +10 -0
- data/spec/test_app/app/controllers/password_less_sample_controller.rb +56 -0
- data/spec/test_app/app/controllers/static_controller.rb +7 -0
- data/spec/test_app/app/helpers/account_helper.rb +2 -0
- data/spec/test_app/app/helpers/application_helper.rb +2 -0
- data/spec/test_app/app/models/game.rb +62 -0
- data/spec/test_app/app/models/shared_data.rb +4 -0
- data/spec/test_app/app/models/shared_key.rb +8 -0
- data/spec/test_app/app/models/user_detail.rb +7 -0
- data/spec/test_app/app/views/account/show.html.erb +133 -0
- data/spec/test_app/app/views/door_mat/static/sign_out_success.html.erb +7 -0
- data/spec/test_app/app/views/layouts/application.html.erb +20 -0
- data/spec/test_app/app/views/password_less_sample/draw_results.html.erb +6 -0
- data/spec/test_app/app/views/password_less_sample/final_result.html.erb +7 -0
- data/spec/test_app/app/views/password_less_sample/play_game.html.erb +5 -0
- data/spec/test_app/app/views/password_less_sample/show_loosing_door.html.erb +10 -0
- data/spec/test_app/app/views/static/index.html.erb +12 -0
- data/spec/test_app/app/views/static/only_confirmed_email_allowed.html.erb +10 -0
- data/spec/test_app/app/views/static/page_that_require_password_reconfirmation.html.erb +16 -0
- data/spec/test_app/app/views/static/session_protected_page.html.erb +32 -0
- data/spec/test_app/bin/bundle +3 -0
- data/spec/test_app/bin/rails +4 -0
- data/spec/test_app/bin/rake +4 -0
- data/spec/test_app/config.ru +4 -0
- data/spec/test_app/config/application.rb +29 -0
- data/spec/test_app/config/boot.rb +5 -0
- data/spec/test_app/config/database.yml +25 -0
- data/spec/test_app/config/environment.rb +19 -0
- data/spec/test_app/config/environments/development.rb +50 -0
- data/spec/test_app/config/environments/production.rb +83 -0
- data/spec/test_app/config/environments/test.rb +48 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/test_app/config/initializers/door_mat.rb +72 -0
- data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/test_app/config/initializers/inflections.rb +16 -0
- data/spec/test_app/config/initializers/mime_types.rb +4 -0
- data/spec/test_app/config/initializers/session_store.rb +3 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/locales/en.yml +23 -0
- data/spec/test_app/config/routes.rb +42 -0
- data/spec/test_app/config/secrets.yml +31 -0
- data/spec/test_app/db/migrate/20140717182813_create_user_details.rb +10 -0
- data/spec/test_app/db/migrate/20140908225256_create_shared_data.rb +10 -0
- data/spec/test_app/db/migrate/20140908225604_create_shared_keys.rb +11 -0
- data/spec/test_app/db/migrate/20141121190714_create_games.rb +10 -0
- data/spec/test_app/public/404.html +67 -0
- data/spec/test_app/public/422.html +67 -0
- data/spec/test_app/public/500.html +66 -0
- data/spec/test_app/public/favicon.ico +0 -0
- metadata +552 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module DoorMat
|
|
4
|
+
describe Actor do
|
|
5
|
+
let(:user1) { {email: 'user1@example.com', password: 'password_user1'} }
|
|
6
|
+
let(:user2) { {email: 'user2@example.com', password: 'password_user2'} }
|
|
7
|
+
|
|
8
|
+
describe '#can_add_email?' do
|
|
9
|
+
|
|
10
|
+
it 'can not add more emails than max_email_count_per_actor' do
|
|
11
|
+
actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
12
|
+
DoorMat::configuration.max_email_count_per_actor = 1
|
|
13
|
+
email = DoorMat::Email.for('user@example.com')
|
|
14
|
+
expect(actor1.can_add_email?(email)).to be false
|
|
15
|
+
expect(email.errors.count).to eq(1)
|
|
16
|
+
expect(email.errors.full_messages.join('')).to match(/maximum number of email per account was reached/)
|
|
17
|
+
DoorMat::configuration.max_email_count_per_actor = 2
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'can not add the same email twice' do
|
|
21
|
+
actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
22
|
+
DoorMat::configuration.max_email_count_per_actor = 2
|
|
23
|
+
email = DoorMat::Email.for(user1[:email])
|
|
24
|
+
|
|
25
|
+
expect(actor1.can_add_email?(email)).to be false
|
|
26
|
+
expect(email.errors.count).to eq(1)
|
|
27
|
+
expect(email.errors.full_messages.join('')).to match(/already associated/)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'can add a new email' do
|
|
31
|
+
actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
32
|
+
DoorMat::configuration.max_email_count_per_actor = 2
|
|
33
|
+
email = DoorMat::Email.for('user@example.com')
|
|
34
|
+
|
|
35
|
+
expect(actor1.can_add_email?(email)).to be true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "can share a secret with an other actor" do
|
|
40
|
+
message = "some message"
|
|
41
|
+
actor1, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
42
|
+
actor2, session2 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user2[:email], user2[:password])
|
|
43
|
+
|
|
44
|
+
share = actor1.share_with(actor2, message)
|
|
45
|
+
|
|
46
|
+
RequestStore.store[:current_session] = session1
|
|
47
|
+
messages = DoorMat::Crypto.decrypt_shared(share[:secrets], actor1.decrypt_shared_key(share[:key], session1))
|
|
48
|
+
expect(message).to eq(messages.first)
|
|
49
|
+
|
|
50
|
+
messages = DoorMat::Crypto.decrypt_shared(share[:secrets], actor2.decrypt_shared_key(share[:other_key], session2))
|
|
51
|
+
expect(message).to eq(messages.first)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module DoorMat
|
|
4
|
+
describe Email do
|
|
5
|
+
|
|
6
|
+
it 'creates a valid email from an email address' do
|
|
7
|
+
address = 'user@example.com'
|
|
8
|
+
|
|
9
|
+
email = DoorMat::Email.for(address)
|
|
10
|
+
expect(email).to be_valid
|
|
11
|
+
|
|
12
|
+
urlsafe_encoded_address = email.to_urlsafe_encoded
|
|
13
|
+
expect(DoorMat::Email.decode_urlsafe(urlsafe_encoded_address)).to eq(address)
|
|
14
|
+
expect(DoorMat::Email.address_hash(address)).to eq(DoorMat::Email.address_hash_from_encoded_address(urlsafe_encoded_address))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'returns an invalid url encoded address unchanged' do
|
|
18
|
+
address = 'user@example.com'
|
|
19
|
+
|
|
20
|
+
expect(DoorMat::Email.decode_urlsafe(address)).to eq(address)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module DoorMat
|
|
4
|
+
describe Session do
|
|
5
|
+
let(:user1) { {email: 'user1@example.com', password: 'password_user1'} }
|
|
6
|
+
let(:user2) { {email: 'user2@example.com', password: 'password_user2'} }
|
|
7
|
+
|
|
8
|
+
it "initialize a session with an actor and password" do
|
|
9
|
+
actor = DoorMat::TestHelper.create_signed_up_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
10
|
+
|
|
11
|
+
session = DoorMat::Session.new
|
|
12
|
+
session.ip = "request.remote_ip"
|
|
13
|
+
session.agent = "request.user_agent"
|
|
14
|
+
session.initialize_with(actor, user1[:password])
|
|
15
|
+
expect(session.valid?).to be true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "fail to initialize a session if an error is raised" do
|
|
19
|
+
actor = DoorMat::TestHelper.create_signed_up_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
20
|
+
|
|
21
|
+
allow(DoorMat::Crypto::PasswordHash).to receive(:pbkdf2_hash).and_raise(StandardError)
|
|
22
|
+
|
|
23
|
+
session = DoorMat::Session.new
|
|
24
|
+
session.ip = "request.remote_ip"
|
|
25
|
+
session.agent = "request.user_agent"
|
|
26
|
+
session.initialize_with(actor, 'wrong_password')
|
|
27
|
+
expect(session.valid?).to be false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'can add an authenticated sub session' do
|
|
31
|
+
_, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
32
|
+
_, session2 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user2[:email], user2[:password])
|
|
33
|
+
invalid_session = DoorMat::Session.new
|
|
34
|
+
|
|
35
|
+
RequestStore.store[:current_session] = session2
|
|
36
|
+
expect(session1.append_sub_session(session2)).to be false
|
|
37
|
+
|
|
38
|
+
RequestStore.store[:current_session] = session1
|
|
39
|
+
expect(session1.append_sub_session(invalid_session)).to be false
|
|
40
|
+
|
|
41
|
+
expect(session1.append_sub_session(session2)).to be true
|
|
42
|
+
|
|
43
|
+
expect(session1.append_sub_session(session2)).to be true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'can encrypt and decrypt messages' do
|
|
47
|
+
message = "some message"
|
|
48
|
+
_, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
49
|
+
|
|
50
|
+
ciphertext = session1.encrypt(message)
|
|
51
|
+
expect(session1.decrypt(ciphertext)).to eq message
|
|
52
|
+
|
|
53
|
+
allow(DoorMat::Crypto::SymmetricStore).to receive(:decrypt).and_raise(OpenSSL::Cipher::CipherError)
|
|
54
|
+
expect(session1.decrypt(ciphertext)).to be_nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'can encrypt and decrypt the recovery key' do
|
|
58
|
+
actor1, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
|
|
59
|
+
|
|
60
|
+
recovery_key = session1.package_recovery_key
|
|
61
|
+
expect(session1.recovery_key_restore(actor1, recovery_key)).to be true
|
|
62
|
+
|
|
63
|
+
allow(DoorMat::Crypto::SymmetricStore).to receive(:decrypt).and_raise(OpenSSL::Cipher::CipherError)
|
|
64
|
+
expect(session1.recovery_key_restore(actor1, recovery_key)).to be false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
|
3
|
+
require File.expand_path("../test_app/config/environment", __FILE__)
|
|
4
|
+
|
|
5
|
+
require 'email_spec'
|
|
6
|
+
require 'rspec/rails'
|
|
7
|
+
require 'database_cleaner'
|
|
8
|
+
require 'capybara/rspec'
|
|
9
|
+
require 'capybara/poltergeist'
|
|
10
|
+
require 'factory_girl_rails'
|
|
11
|
+
require 'door_mat'
|
|
12
|
+
require 'door_mat/test_helper'
|
|
13
|
+
require 'byebug'
|
|
14
|
+
require 'show_me_the_cookies'
|
|
15
|
+
require 'timecop'
|
|
16
|
+
|
|
17
|
+
Rails.backtrace_cleaner.remove_silencers!
|
|
18
|
+
|
|
19
|
+
# Requires supporting ruby files with custom matchers and macros, etc, in
|
|
20
|
+
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
|
21
|
+
# run as spec files by default. This means that files in spec/support that end
|
|
22
|
+
# in _spec.rb will both be required and run as specs, causing the specs to be
|
|
23
|
+
# run twice. It is recommended that you do not name files matching this glob to
|
|
24
|
+
# end with _spec.rb. You can configure this pattern with with the --pattern
|
|
25
|
+
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
|
26
|
+
# Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
|
|
27
|
+
ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
|
|
28
|
+
Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each {|f| require f }
|
|
29
|
+
|
|
30
|
+
# Checks for pending migrations before tests are run.
|
|
31
|
+
# If you are not using ActiveRecord, you can remove this line.
|
|
32
|
+
ActiveRecord::Migration.maintain_test_schema!
|
|
33
|
+
|
|
34
|
+
RSpec.configure do |config|
|
|
35
|
+
|
|
36
|
+
# ## Mock Framework
|
|
37
|
+
#
|
|
38
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
|
39
|
+
#
|
|
40
|
+
# config.mock_with :mocha
|
|
41
|
+
# config.mock_with :flexmock
|
|
42
|
+
# config.mock_with :rr
|
|
43
|
+
config.include FactoryGirl::Syntax::Methods # If you do not include FactoryGirl::Syntax::Methods in your test suite, then all factory_girl methods will need to be prefaced with FactoryGirl.
|
|
44
|
+
config.include ShowMeTheCookies
|
|
45
|
+
|
|
46
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
47
|
+
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
48
|
+
|
|
49
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
50
|
+
# examples within a transaction, remove the following line or assign false
|
|
51
|
+
# instead of true.
|
|
52
|
+
config.use_transactional_fixtures = false
|
|
53
|
+
|
|
54
|
+
# If true, the base class of anonymous controllers will be inferred
|
|
55
|
+
# automatically. This will be the default behavior in future versions of
|
|
56
|
+
# rspec-rails.
|
|
57
|
+
config.infer_base_class_for_anonymous_controllers = false
|
|
58
|
+
|
|
59
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
60
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
61
|
+
# the seed, which is printed after each run.
|
|
62
|
+
# --seed 1234
|
|
63
|
+
config.order = "random"
|
|
64
|
+
|
|
65
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
|
66
|
+
# based on their file location, for example enabling you to call `get` and
|
|
67
|
+
# `post` in specs under `spec/controllers`.
|
|
68
|
+
#
|
|
69
|
+
# You can disable this behaviour by removing the line below, and instead
|
|
70
|
+
# explictly tag your specs with their type, e.g.:
|
|
71
|
+
#
|
|
72
|
+
# describe UsersController, :type => :controller do
|
|
73
|
+
# # ...
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# The different available types are documented in the features, such as in
|
|
77
|
+
# https://relishapp.com/rspec/rspec-rails/v/3-0/docs
|
|
78
|
+
config.infer_spec_type_from_file_location!
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
config.expect_with :rspec do |expectations|
|
|
82
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
|
83
|
+
# and `failure_message` of custom matchers include text for helper methods
|
|
84
|
+
# defined using `chain`, e.g.:
|
|
85
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
|
86
|
+
# # => "be bigger than 2 and smaller than 4"
|
|
87
|
+
# ...rather than:
|
|
88
|
+
# # => "be bigger than 2"
|
|
89
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
config.before(:suite) do
|
|
95
|
+
DatabaseCleaner.clean_with(:truncation)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
config.before(:each) do
|
|
99
|
+
DatabaseCleaner.strategy = :truncation
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
config.before(:each, :js => true) do
|
|
103
|
+
DatabaseCleaner.strategy = :truncation
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
config.before(:each) do
|
|
107
|
+
DatabaseCleaner.start
|
|
108
|
+
ActionMailer::Base.deliveries.clear
|
|
109
|
+
Timecop.return
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
config.after(:each) do
|
|
113
|
+
DatabaseCleaner.clean
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
if ENV['IN_BROWSER']
|
|
118
|
+
# On demand: non-headless tests via Selenium/WebDriver
|
|
119
|
+
# To run the scenarios in browser (default: Firefox), use the following command line:
|
|
120
|
+
# IN_BROWSER=true bundle exec rspec
|
|
121
|
+
# or (to have a pause of 1 second between each step):
|
|
122
|
+
# IN_BROWSER=true PAUSE=1 bundle exec rspec
|
|
123
|
+
Capybara.default_driver = :selenium
|
|
124
|
+
# AfterStep do
|
|
125
|
+
# sleep (ENV['PAUSE'] || 0).to_i
|
|
126
|
+
# end
|
|
127
|
+
else
|
|
128
|
+
# DEFAULT: headless tests with poltergeist/PhantomJS
|
|
129
|
+
Capybara.register_driver :poltergeist do |app|
|
|
130
|
+
Capybara::Poltergeist::Driver.new(
|
|
131
|
+
app,
|
|
132
|
+
window_size: [1280, 1024],
|
|
133
|
+
timeout: 300,
|
|
134
|
+
phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=any'], # http://phantomjs.org/api/command-line.html ie ['--debug=no', '--load-images=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
|
|
135
|
+
debug: false
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
Capybara.default_driver = :poltergeist
|
|
139
|
+
Capybara.javascript_driver = :poltergeist
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
Capybara.default_wait_time = 5
|
|
143
|
+
|
|
144
|
+
Capybara.register_driver :rack_test do |app|
|
|
145
|
+
Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' })
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def set_hidden_input_value(css_matcher, value)
|
|
149
|
+
find(:css, css_matcher, :visible => false).set(value)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def fill_access_token_form(name, identifier, confirm_identifier=nil, is_public_computer=true, remember_me=false, return_path_with_access_token=true)
|
|
153
|
+
confirm_identifier ||= identifier
|
|
154
|
+
|
|
155
|
+
fill_in 'access_token_name', with: name
|
|
156
|
+
fill_in 'access_token_identifier', with: identifier
|
|
157
|
+
fill_in 'access_token_confirm_identifier', with: confirm_identifier
|
|
158
|
+
|
|
159
|
+
if is_public_computer
|
|
160
|
+
check('access_token_is_public')
|
|
161
|
+
else
|
|
162
|
+
uncheck('access_token_is_public')
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if remember_me
|
|
166
|
+
check('access_token_remember_me')
|
|
167
|
+
else
|
|
168
|
+
uncheck('access_token_remember_me')
|
|
169
|
+
end
|
|
170
|
+
click_button 'Request access token'
|
|
171
|
+
|
|
172
|
+
if return_path_with_access_token
|
|
173
|
+
expect(unread_emails_for(identifier).size).to eq(parse_email_count(1))
|
|
174
|
+
e = open_last_email_for(identifier)
|
|
175
|
+
return links_in_email(e).select {|url| /access_token/.match(url)}.first
|
|
176
|
+
else
|
|
177
|
+
return nil
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def fill_sign_in_form(email, password, is_public_computer=true, remember_me=false)
|
|
182
|
+
fill_in 'sign_in_email', with: email
|
|
183
|
+
fill_in 'sign_in_password', with: password
|
|
184
|
+
|
|
185
|
+
if is_public_computer
|
|
186
|
+
check('sign_in_is_public')
|
|
187
|
+
else
|
|
188
|
+
uncheck('sign_in_is_public')
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if remember_me
|
|
192
|
+
check('sign_in_remember_me')
|
|
193
|
+
else
|
|
194
|
+
uncheck('sign_in_remember_me')
|
|
195
|
+
end
|
|
196
|
+
click_button 'Sign In'
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def fill_sign_up_form(email, password, password_confirmation=nil)
|
|
200
|
+
password_confirmation ||= password
|
|
201
|
+
fill_in 'sign_up_email', with: email
|
|
202
|
+
fill_in 'sign_up_password', with: password
|
|
203
|
+
fill_in 'sign_up_password_confirmation', with: password_confirmation
|
|
204
|
+
click_button 'Sign Up'
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def reload_page
|
|
208
|
+
visit(current_path)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def reset_default_config
|
|
212
|
+
DoorMat.configuration.password_reconfirm_delay = 5
|
|
213
|
+
DoorMat.configuration.public_computer_access_session_timeout = 30
|
|
214
|
+
DoorMat.configuration.private_computer_access_session_timeout = 60
|
|
215
|
+
DoorMat.configuration.allow_remember_me_feature = false
|
|
216
|
+
DoorMat.configuration.remember_me_require_private_computer_confirmation = true
|
|
217
|
+
DoorMat.configuration.remember_me_max_day_count = 30
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def test_only_session_guid_anywhere_regex
|
|
222
|
+
/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
|
|
223
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Generic steps
|
|
4
|
+
|
|
5
|
+
def wait_two_minutes
|
|
6
|
+
t = 2.minutes.from_now
|
|
7
|
+
Timecop.travel(t)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def wait_two_days
|
|
11
|
+
t = 2.days.from_now
|
|
12
|
+
Timecop.travel(t)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# public computer timeout
|
|
17
|
+
|
|
18
|
+
def wait_longer_than_public_computer_session_timeout
|
|
19
|
+
t = (DoorMat.configuration.public_computer_access_session_timeout + 1).minutes.from_now
|
|
20
|
+
Timecop.travel(t)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def wait_less_than_public_computer_session_timeout
|
|
24
|
+
t = (DoorMat.configuration.public_computer_access_session_timeout - 1).minutes.from_now
|
|
25
|
+
Timecop.travel(t)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# private computer timeout
|
|
30
|
+
|
|
31
|
+
def wait_longer_than_private_computer_session_timeout
|
|
32
|
+
t = (DoorMat.configuration.private_computer_access_session_timeout + 1).minutes.from_now
|
|
33
|
+
Timecop.travel(t)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def wait_less_than_private_computer_session_timeout
|
|
37
|
+
t = (DoorMat.configuration.private_computer_access_session_timeout - 1).minutes.from_now
|
|
38
|
+
Timecop.travel(t)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# remember me timeout
|
|
43
|
+
|
|
44
|
+
def wait_longer_than_remember_me_timeout
|
|
45
|
+
t = (DoorMat.configuration.remember_me_max_day_count + 1).day.from_now
|
|
46
|
+
Timecop.travel(t)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def wait_less_than_remember_me_timeout
|
|
50
|
+
t = (DoorMat.configuration.remember_me_max_day_count - 1).day.from_now
|
|
51
|
+
Timecop.travel(t)
|
|
52
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
== README
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
|
4
|
+
application up and running.
|
|
5
|
+
|
|
6
|
+
Things you may want to cover:
|
|
7
|
+
|
|
8
|
+
* Ruby version
|
|
9
|
+
|
|
10
|
+
* System dependencies
|
|
11
|
+
|
|
12
|
+
* Configuration
|
|
13
|
+
|
|
14
|
+
* Database creation
|
|
15
|
+
|
|
16
|
+
* Database initialization
|
|
17
|
+
|
|
18
|
+
* How to run the test suite
|
|
19
|
+
|
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
|
21
|
+
|
|
22
|
+
* Deployment instructions
|
|
23
|
+
|
|
24
|
+
* ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
|
28
|
+
<tt>rake doc:app</tt>.
|