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.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +88 -0
  6. data/Rakefile +32 -0
  7. data/app/assets/javascripts/door_mat/application.js +13 -0
  8. data/app/assets/stylesheets/door_mat/application.css +15 -0
  9. data/app/assets/stylesheets/scaffold.css +56 -0
  10. data/app/controllers/door_mat/activities_controller.rb +106 -0
  11. data/app/controllers/door_mat/application_controller.rb +14 -0
  12. data/app/controllers/door_mat/change_password_controller.rb +32 -0
  13. data/app/controllers/door_mat/forgot_passwords_controller.rb +57 -0
  14. data/app/controllers/door_mat/manage_email_controller.rb +61 -0
  15. data/app/controllers/door_mat/password_less_session_controller.rb +121 -0
  16. data/app/controllers/door_mat/reconfirm_password_controller.rb +27 -0
  17. data/app/controllers/door_mat/sessions_controller.rb +17 -0
  18. data/app/controllers/door_mat/sign_in_controller.rb +60 -0
  19. data/app/controllers/door_mat/sign_up_controller.rb +59 -0
  20. data/app/controllers/door_mat/static_controller.rb +5 -0
  21. data/app/mailers/door_mat/activity_mailer.rb +18 -0
  22. data/app/mailers/door_mat/password_less_session_mailer.rb +12 -0
  23. data/app/models/door_mat/access_token.rb +315 -0
  24. data/app/models/door_mat/activity.rb +14 -0
  25. data/app/models/door_mat/activity_confirm_email.rb +45 -0
  26. data/app/models/door_mat/activity_download_recovery_key.rb +30 -0
  27. data/app/models/door_mat/activity_reset_password.rb +47 -0
  28. data/app/models/door_mat/actor.rb +149 -0
  29. data/app/models/door_mat/change_password.rb +12 -0
  30. data/app/models/door_mat/email.rb +58 -0
  31. data/app/models/door_mat/forgot_password.rb +12 -0
  32. data/app/models/door_mat/membership.rb +42 -0
  33. data/app/models/door_mat/session.rb +315 -0
  34. data/app/models/door_mat/sign_in.rb +31 -0
  35. data/app/models/door_mat/sign_up.rb +17 -0
  36. data/app/views/door_mat/activity_mailer/confirm_email.html.erb +11 -0
  37. data/app/views/door_mat/activity_mailer/confirm_email.text.erb +7 -0
  38. data/app/views/door_mat/activity_mailer/reset_password.html.erb +11 -0
  39. data/app/views/door_mat/activity_mailer/reset_password.text.erb +7 -0
  40. data/app/views/door_mat/change_password/new.html.erb +22 -0
  41. data/app/views/door_mat/forgot_passwords/choose_new_password.html.erb +34 -0
  42. data/app/views/door_mat/forgot_passwords/new.html.erb +14 -0
  43. data/app/views/door_mat/helpers/_errors_if_any.html.erb +10 -0
  44. data/app/views/door_mat/manage_email/new.html.erb +14 -0
  45. data/app/views/door_mat/password_less_session/access_token.html.erb +16 -0
  46. data/app/views/door_mat/password_less_session/new.html.erb +34 -0
  47. data/app/views/door_mat/password_less_session_mailer/send_token.html.erb +11 -0
  48. data/app/views/door_mat/password_less_session_mailer/send_token.text.erb +7 -0
  49. data/app/views/door_mat/reconfirm_password/new.html.erb +12 -0
  50. data/app/views/door_mat/sign_in/new.html.erb +30 -0
  51. data/app/views/door_mat/sign_up/new.html.erb +24 -0
  52. data/app/views/door_mat/static/add_email_success.html.erb +5 -0
  53. data/app/views/door_mat/static/change_password_success.html.erb +2 -0
  54. data/app/views/door_mat/static/confirm_email_success.html.erb +2 -0
  55. data/app/views/door_mat/static/email_confirmation_required.html.erb +17 -0
  56. data/app/views/door_mat/static/forgot_password_verification_mail_sent.html.erb +2 -0
  57. data/app/views/door_mat/static/reconfirm_password_success.html.erb +4 -0
  58. data/app/views/door_mat/static/sign_in_success.html.erb +5 -0
  59. data/app/views/door_mat/static/sign_out_success.html.erb +5 -0
  60. data/app/views/door_mat/static/sign_up_success.html.erb +4 -0
  61. data/bin/rails +12 -0
  62. data/config/locales/en.yml +73 -0
  63. data/config/routes.rb +48 -0
  64. data/db/migrate/20140616234935_create_door_mat_actors.rb +23 -0
  65. data/db/migrate/20140617233357_create_door_mat_sessions.rb +17 -0
  66. data/db/migrate/20140630043202_create_door_mat_emails.rb +12 -0
  67. data/db/migrate/20140702045729_create_door_mat_activities.rb +14 -0
  68. data/db/migrate/20141115183045_create_door_mat_access_tokens.rb +17 -0
  69. data/db/migrate/20141121191824_create_door_mat_memberships.rb +14 -0
  70. data/db/migrate/20150910182126_rename_session_guid_column.rb +5 -0
  71. data/db/migrate/20150918210831_add_access_token_rating_column.rb +5 -0
  72. data/door_mat.gemspec +37 -0
  73. data/lib/door_mat.rb +20 -0
  74. data/lib/door_mat/attr_asymmetric_store.rb +82 -0
  75. data/lib/door_mat/attr_symmetric_store.rb +82 -0
  76. data/lib/door_mat/configuration.rb +193 -0
  77. data/lib/door_mat/controller.rb +117 -0
  78. data/lib/door_mat/crypto.rb +49 -0
  79. data/lib/door_mat/crypto/asymmetric_store.rb +77 -0
  80. data/lib/door_mat/crypto/fast_hash.rb +17 -0
  81. data/lib/door_mat/crypto/password_hash.rb +39 -0
  82. data/lib/door_mat/crypto/secure_compare.rb +23 -0
  83. data/lib/door_mat/crypto/symmetric_store.rb +68 -0
  84. data/lib/door_mat/engine.rb +23 -0
  85. data/lib/door_mat/process/actor_password_change.rb +65 -0
  86. data/lib/door_mat/process/actor_sign_in.rb +38 -0
  87. data/lib/door_mat/process/actor_sign_up.rb +39 -0
  88. data/lib/door_mat/process/create_new_anonymous_actor.rb +36 -0
  89. data/lib/door_mat/process/manage_email.rb +42 -0
  90. data/lib/door_mat/process/reset_password.rb +50 -0
  91. data/lib/door_mat/regex.rb +17 -0
  92. data/lib/door_mat/test_helper.rb +58 -0
  93. data/lib/door_mat/url_protocol.rb +9 -0
  94. data/lib/door_mat/version.rb +3 -0
  95. data/lib/tasks/door_mat_tasks.rake +31 -0
  96. data/spec/controllers/door_mat/activities_controller_spec.rb +70 -0
  97. data/spec/controllers/door_mat/forgot_passwords_controller_spec.rb +57 -0
  98. data/spec/controllers/door_mat/manage_email_spec.rb +181 -0
  99. data/spec/controllers/door_mat/password_less_session_controller_spec.rb +344 -0
  100. data/spec/controllers/door_mat/sign_in_controller_spec.rb +211 -0
  101. data/spec/controllers/door_mat/sign_up_controller_spec.rb +90 -0
  102. data/spec/factories/door_mat_access_tokens.rb +6 -0
  103. data/spec/factories/door_mat_activitiess.rb +6 -0
  104. data/spec/factories/door_mat_actors.rb +23 -0
  105. data/spec/factories/door_mat_emails.rb +14 -0
  106. data/spec/factories/door_mat_memberships.rb +6 -0
  107. data/spec/factories/door_mat_sessions.rb +24 -0
  108. data/spec/features/password_less_session_spec.rb +165 -0
  109. data/spec/features/remember_me_spec.rb +672 -0
  110. data/spec/features/session_spec.rb +336 -0
  111. data/spec/lib/attr_store_spec.rb +237 -0
  112. data/spec/lib/crypto_spec.rb +130 -0
  113. data/spec/lib/process_spec.rb +159 -0
  114. data/spec/models/door_mat/access_token_spec.rb +134 -0
  115. data/spec/models/door_mat/activity_spec.rb +38 -0
  116. data/spec/models/door_mat/actor_spec.rb +56 -0
  117. data/spec/models/door_mat/email_spec.rb +25 -0
  118. data/spec/models/door_mat/session_spec.rb +69 -0
  119. data/spec/spec_helper.rb +223 -0
  120. data/spec/support/timecop/timecop_helper.rb +52 -0
  121. data/spec/test_app/README.rdoc +28 -0
  122. data/spec/test_app/Rakefile +6 -0
  123. data/spec/test_app/app/assets/javascripts/application.js +13 -0
  124. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  125. data/spec/test_app/app/controllers/account_controller.rb +28 -0
  126. data/spec/test_app/app/controllers/application_controller.rb +10 -0
  127. data/spec/test_app/app/controllers/password_less_sample_controller.rb +56 -0
  128. data/spec/test_app/app/controllers/static_controller.rb +7 -0
  129. data/spec/test_app/app/helpers/account_helper.rb +2 -0
  130. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  131. data/spec/test_app/app/models/game.rb +62 -0
  132. data/spec/test_app/app/models/shared_data.rb +4 -0
  133. data/spec/test_app/app/models/shared_key.rb +8 -0
  134. data/spec/test_app/app/models/user_detail.rb +7 -0
  135. data/spec/test_app/app/views/account/show.html.erb +133 -0
  136. data/spec/test_app/app/views/door_mat/static/sign_out_success.html.erb +7 -0
  137. data/spec/test_app/app/views/layouts/application.html.erb +20 -0
  138. data/spec/test_app/app/views/password_less_sample/draw_results.html.erb +6 -0
  139. data/spec/test_app/app/views/password_less_sample/final_result.html.erb +7 -0
  140. data/spec/test_app/app/views/password_less_sample/play_game.html.erb +5 -0
  141. data/spec/test_app/app/views/password_less_sample/show_loosing_door.html.erb +10 -0
  142. data/spec/test_app/app/views/static/index.html.erb +12 -0
  143. data/spec/test_app/app/views/static/only_confirmed_email_allowed.html.erb +10 -0
  144. data/spec/test_app/app/views/static/page_that_require_password_reconfirmation.html.erb +16 -0
  145. data/spec/test_app/app/views/static/session_protected_page.html.erb +32 -0
  146. data/spec/test_app/bin/bundle +3 -0
  147. data/spec/test_app/bin/rails +4 -0
  148. data/spec/test_app/bin/rake +4 -0
  149. data/spec/test_app/config.ru +4 -0
  150. data/spec/test_app/config/application.rb +29 -0
  151. data/spec/test_app/config/boot.rb +5 -0
  152. data/spec/test_app/config/database.yml +25 -0
  153. data/spec/test_app/config/environment.rb +19 -0
  154. data/spec/test_app/config/environments/development.rb +50 -0
  155. data/spec/test_app/config/environments/production.rb +83 -0
  156. data/spec/test_app/config/environments/test.rb +48 -0
  157. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  158. data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
  159. data/spec/test_app/config/initializers/door_mat.rb +72 -0
  160. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  161. data/spec/test_app/config/initializers/inflections.rb +16 -0
  162. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  163. data/spec/test_app/config/initializers/session_store.rb +3 -0
  164. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  165. data/spec/test_app/config/locales/en.yml +23 -0
  166. data/spec/test_app/config/routes.rb +42 -0
  167. data/spec/test_app/config/secrets.yml +31 -0
  168. data/spec/test_app/db/migrate/20140717182813_create_user_details.rb +10 -0
  169. data/spec/test_app/db/migrate/20140908225256_create_shared_data.rb +10 -0
  170. data/spec/test_app/db/migrate/20140908225604_create_shared_keys.rb +11 -0
  171. data/spec/test_app/db/migrate/20141121190714_create_games.rb +10 -0
  172. data/spec/test_app/public/404.html +67 -0
  173. data/spec/test_app/public/422.html +67 -0
  174. data/spec/test_app/public/500.html +66 -0
  175. data/spec/test_app/public/favicon.ico +0 -0
  176. 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
+
@@ -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>.