user_plane 0.0.15
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/MIT-LICENSE +20 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/user_plane/application.js +13 -0
- data/app/assets/stylesheets/user_plane/application.css +15 -0
- data/app/concerns/null_object_persistable.rb +62 -0
- data/app/controllers/user/confirm_email_addresses_controller.rb +17 -0
- data/app/controllers/user/details_controller.rb +48 -0
- data/app/controllers/user/invites_controller.rb +69 -0
- data/app/controllers/user/reset_passwords_controller.rb +50 -0
- data/app/controllers/user/sign_ins_controller.rb +53 -0
- data/app/controllers/user/sign_ups_controller.rb +47 -0
- data/app/controllers/user_plane/application_controller.rb +5 -0
- data/app/helpers/user_plane/application_helper.rb +4 -0
- data/app/mailers/user_plane/application_mailer.rb +8 -0
- data/app/mailers/user_plane/invite_mailer.rb +14 -0
- data/app/mailers/user_plane/verification_mailer.rb +25 -0
- data/app/models/session_manager.rb +100 -0
- data/app/models/user.rb +5 -0
- data/app/models/user/account.rb +26 -0
- data/app/models/user/confirm_email_address.rb +55 -0
- data/app/models/user/guest.rb +18 -0
- data/app/models/user/identities.rb +5 -0
- data/app/models/user/identities/email.rb +98 -0
- data/app/models/user/identities/email_verification.rb +70 -0
- data/app/models/user/identities/facebook.rb +5 -0
- data/app/models/user/identities/github.rb +5 -0
- data/app/models/user/identities/id_token.rb +7 -0
- data/app/models/user/identities/o_auth.rb +67 -0
- data/app/models/user/identities/o_auth_endpoint.rb +28 -0
- data/app/models/user/identities/twitter.rb +5 -0
- data/app/models/user/identity.rb +26 -0
- data/app/models/user/reset_password.rb +59 -0
- data/app/models/user/send_password_reset.rb +25 -0
- data/app/models/user/send_sign_up_invite.rb +27 -0
- data/app/models/user/sign_in.rb +42 -0
- data/app/models/user/sign_up.rb +47 -0
- data/app/models/user/sign_up_invites.rb +5 -0
- data/app/models/user/sign_up_invites/invite.rb +46 -0
- data/app/models/user/sign_up_invites/stack.rb +22 -0
- data/app/models/user/sign_up_with_invite.rb +45 -0
- data/app/models/user/suspension.rb +7 -0
- data/app/models/user/update_details.rb +103 -0
- data/app/views/layouts/user_plane/application.html.erb +14 -0
- data/app/views/user/details/edit.html.erb +37 -0
- data/app/views/user/invites/edit.html.erb +34 -0
- data/app/views/user/invites/new.html.erb +21 -0
- data/app/views/user/reset_passwords/edit.html.erb +26 -0
- data/app/views/user/reset_passwords/new.html.erb +21 -0
- data/app/views/user/sign_ins/new.html.erb +25 -0
- data/app/views/user/sign_ups/new.html.erb +33 -0
- data/app/views/user_plane/invite_mailer/invite.html.erb +2 -0
- data/app/views/user_plane/invite_mailer/invite.text.erb +3 -0
- data/app/views/user_plane/verification_mailer/address_verification.html.erb +2 -0
- data/app/views/user_plane/verification_mailer/address_verification.text.erb +4 -0
- data/app/views/user_plane/verification_mailer/password_reset.html.erb +2 -0
- data/app/views/user_plane/verification_mailer/password_reset.text.erb +4 -0
- data/config/initializers/inflections.rb +3 -0
- data/config/locales/en.yml +63 -0
- data/config/locales/it.yml +62 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20121128143404_create_user_accounts.rb +11 -0
- data/db/migrate/20121226202553_create_user_identities_o_auths.rb +12 -0
- data/db/migrate/20121226203032_create_user_identities_emails.rb +13 -0
- data/db/migrate/20121227144617_create_user_identities_email_verifications.rb +15 -0
- data/db/migrate/20130113120152_create_user_identities_id_tokens.rb +12 -0
- data/db/migrate/20141025230304_create_user_sign_up_invites_stacks.rb +10 -0
- data/db/migrate/20141025230500_create_user_sign_up_invites_invites.rb +13 -0
- data/db/migrate/20141026230208_create_user_suspensions.rb +13 -0
- data/lib/generators/user_plane/view/details_generator.rb +22 -0
- data/lib/generators/user_plane/view/helpers.rb +68 -0
- data/lib/generators/user_plane/view/invites_generator.rb +23 -0
- data/lib/generators/user_plane/view/reset_passwords_generator.rb +22 -0
- data/lib/generators/user_plane/view/sign_ins_generator.rb +18 -0
- data/lib/generators/user_plane/view/sign_ups_generator.rb +22 -0
- data/lib/generators/user_plane/views_generator.rb +32 -0
- data/lib/tasks/user_plane_tasks.rake +4 -0
- data/lib/user_plane.rb +43 -0
- data/lib/user_plane/command.rb +24 -0
- data/lib/user_plane/engine.rb +27 -0
- data/lib/user_plane/fresh_validator.rb +9 -0
- data/lib/user_plane/omniauth.rb +50 -0
- data/lib/user_plane/redirect_to_sign_in.rb +22 -0
- data/lib/user_plane/route_concerns.rb +167 -0
- data/lib/user_plane/session_manager_concern.rb +9 -0
- data/lib/user_plane/signed_in_constraint.rb +11 -0
- data/lib/user_plane/token_segment.rb +52 -0
- data/lib/user_plane/version.rb +3 -0
- data/spec/controllers/user/confirm_email_addresses_controller_spec.rb +5 -0
- data/spec/controllers/user/details_controller_spec.rb +5 -0
- data/spec/controllers/user/invites_controller_spec.rb +19 -0
- data/spec/controllers/user/reset_passwords_controller_spec.rb +5 -0
- data/spec/controllers/user/sign_ins_controller_spec.rb +34 -0
- data/spec/controllers/user/sign_ups_controller_spec.rb +5 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/controllers/welcome_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +30 -0
- data/spec/dummy/app/views/welcome/index.html.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +49 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +78 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/user_plane.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +43 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/schema.rb +101 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +20185 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/-pOuxJZhYk_qXqMNKgm23KfvzyUW71NynNLlcNBOubE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/3AV9ywHBH56Leqey5LeznxK9vu4HD8fF3zSTk4MiDJA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/5fzR1G0D8ukHkPkLXsUu6rP6qV82aIdx3hugKkDy6nM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/9bKtJ2lkHPqtboGfbyknZ1OyH4xYO-aml7U3qhv-3kk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/HjDmE9SFP2wimdNHU8Nff9cm3vFZ5soO1iw7Jdlb6z8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/J9j6OdatarYW7VzVCVttmGphOhJKL0QXasdheyrgsTE.cache +2 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/KqrOQSlg0Th0N3XXx-h4p5BVJCfN0D8rRLoA9VxvXrc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/UCB1W65KwVU8ttOY8jnPRDp8HyyYYEjeTwwPD6R4qy8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/YmMSaaBmIcNZWPVF9jXcGBi-kwEzMuxzwPT_Zrcj1Bo.cache +2 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/g3wU8ajFWb5ZLPvujEt5l9DesbFCiAwqjx1WQgwTtHA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/i5pp88VHKoqlxQJdgmQd_lkgX1-4em_uHqNDjQ4nyHA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/jL74yXjxf8cb6Olkjbw1C28MH_HbZe221l8AI6WVeH0.cache +3 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/puh7X4rfS3eDN9oHTXoQdAgqxivonrwAAdYZ4UB3GIg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/qxPWFIWnE6gOCY-SsdBJe7Cgm5D3YUwaEne78Y7XdRg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/rM9s67WgzKMZ1bRhUdA0yhPZDlyRE5a1kmdt7cS6m4c.cache +3 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/v3.0/rVoG8EHlrCOgY4ZkzOj64f0jiTcbteQ_SYNzq9RqY0I.cache +0 -0
- data/spec/fabricators/user_account_fabricator.rb +11 -0
- data/spec/fabricators/user_guest_fabricator.rb +2 -0
- data/spec/fabricators/user_identities_email_fabricator.rb +8 -0
- data/spec/fabricators/user_identities_email_verification_fabricator.rb +5 -0
- data/spec/fabricators/user_identities_id_token_fabricator.rb +2 -0
- data/spec/fabricators/user_sign_up_fabricator.rb +51 -0
- data/spec/fabricators/user_sign_up_invites_invite_fabricator.rb +3 -0
- data/spec/fabricators/user_sign_up_invites_stack_fabricator.rb +4 -0
- data/spec/fabricators/user_suspension_fabricator.rb +4 -0
- data/spec/fabricators/user_update_detail_fabricator.rb +2 -0
- data/spec/features/user_plane/user_plane_invites_spec.rb +31 -0
- data/spec/features/user_plane/user_plane_reset_passwords_spec.rb +31 -0
- data/spec/features/user_plane/user_plane_sign_ins_spec.rb +44 -0
- data/spec/features/user_plane/user_plane_signed_in_only_spec.rb +31 -0
- data/spec/features/user_plane/user_plane_update_details_spec.rb +43 -0
- data/spec/fixtures/user_plane/invite_mailer/invite +3 -0
- data/spec/fixtures/user_plane/verification_mailer/address_verification +3 -0
- data/spec/fixtures/user_plane/verification_mailer/password_reset +3 -0
- data/spec/lib/generators/views_generator_spec.rb +16 -0
- data/spec/lib/route_concerns_spec.rb +54 -0
- data/spec/mailers/previews/user_plane/invite_mailer_preview.rb +11 -0
- data/spec/mailers/previews/user_plane/verification_mailer_preview.rb +16 -0
- data/spec/mailers/user_plane/invite_mailer_spec.rb +25 -0
- data/spec/mailers/user_plane/verification_mailer_spec.rb +52 -0
- data/spec/models/session_manager_spec.rb +28 -0
- data/spec/models/user/account_spec.rb +26 -0
- data/spec/models/user/confirm_email_address_spec.rb +101 -0
- data/spec/models/user/guest_spec.rb +5 -0
- data/spec/models/user/identities/email_spec.rb +5 -0
- data/spec/models/user/identities/email_verification_spec.rb +42 -0
- data/spec/models/user/identities/facebook_spec.rb +5 -0
- data/spec/models/user/identities/github_spec.rb +5 -0
- data/spec/models/user/identities/id_token_spec.rb +5 -0
- data/spec/models/user/identities/o_auth_spec.rb +12 -0
- data/spec/models/user/identities/twitter_spec.rb +5 -0
- data/spec/models/user/reset_password_spec.rb +141 -0
- data/spec/models/user/send_password_reset_spec.rb +44 -0
- data/spec/models/user/send_sign_up_invite_spec.rb +30 -0
- data/spec/models/user/sign_in_spec.rb +31 -0
- data/spec/models/user/sign_up_invites/invite_spec.rb +13 -0
- data/spec/models/user/sign_up_invites/stack_spec.rb +21 -0
- data/spec/models/user/sign_up_spec.rb +58 -0
- data/spec/models/user/sign_up_with_invite_spec.rb +83 -0
- data/spec/models/user/suspension_spec.rb +5 -0
- data/spec/models/user/update_details_spec.rb +98 -0
- data/spec/routing/invites_spec.rb +49 -0
- data/spec/routing/reset_passwords_spec.rb +31 -0
- data/spec/routing/sign_ins_spec.rb +36 -0
- data/spec/routing/update_details_spec.rb +30 -0
- data/spec/shared_contexts/feature_helpers.rb +12 -0
- data/spec/shared_contexts/routing.rb +8 -0
- data/spec/shared_contexts/user.rb +67 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/fabrication.rb +7 -0
- data/spec/support/omniauth.rb +4 -0
- metadata +770 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
|
4
|
+
RSpec.feature "SignedInOnly", type: :feature do
|
5
|
+
include_context 'user'
|
6
|
+
|
7
|
+
scenario 'trying to access a signed-in-only' do
|
8
|
+
visit '/signed_in_only'
|
9
|
+
expect(current_path).to eql(polymorphic_path([User::SignIn.new], action: :new))
|
10
|
+
|
11
|
+
fill_in 'Email', with: a_user.email.address
|
12
|
+
fill_in 'Password', with: a_user.email.password
|
13
|
+
click_button 'Sign In'
|
14
|
+
|
15
|
+
expect(current_path).to eql('/signed_in_only')
|
16
|
+
expect(page).to have_text 'You are successfully signed in.'
|
17
|
+
end
|
18
|
+
|
19
|
+
scenario 'trying to access a non-existing route when sigend in' do
|
20
|
+
visit '/non_existing'
|
21
|
+
expect(current_path).to eql(polymorphic_path([User::SignIn.new], action: :new))
|
22
|
+
|
23
|
+
fill_in 'Email', with: a_user.email.address
|
24
|
+
fill_in 'Password', with: a_user.email.password
|
25
|
+
click_button 'Sign In'
|
26
|
+
|
27
|
+
expect(current_path).to eql('/non_existing')
|
28
|
+
expect(page.status_code).to eq(404)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
require 'shared_contexts/feature_helpers'
|
4
|
+
|
5
|
+
RSpec.feature "UpdateDetails", type: :feature do
|
6
|
+
include_context 'user'
|
7
|
+
include_context 'feature_helpers'
|
8
|
+
|
9
|
+
scenario 'changing the email address' do
|
10
|
+
sign_in(a_user)
|
11
|
+
|
12
|
+
new_email = Faker::Internet.safe_email
|
13
|
+
|
14
|
+
visit polymorphic_path([User::UpdateDetails.new], action: :edit)
|
15
|
+
fill_in 'Email', with: new_email
|
16
|
+
click_button 'Update'
|
17
|
+
|
18
|
+
click_link 'Sign Out'
|
19
|
+
|
20
|
+
open_email(new_email)
|
21
|
+
current_email.click_link 'link'
|
22
|
+
|
23
|
+
|
24
|
+
visit polymorphic_path([User::SignIn.new], action: :new)
|
25
|
+
fill_in 'Email', with: new_email
|
26
|
+
fill_in 'Password', with: a_user.email.password
|
27
|
+
click_button 'Sign In'
|
28
|
+
|
29
|
+
expect(page).to have_text 'You are successfully signed in.'
|
30
|
+
# expect(current_path).to eql('/signed_in_only')
|
31
|
+
end
|
32
|
+
|
33
|
+
scenario 'changing the user name' do
|
34
|
+
sign_in(a_user)
|
35
|
+
|
36
|
+
visit polymorphic_path([User::UpdateDetails.new], action: :edit)
|
37
|
+
fill_in 'Name', with: 'marvin'
|
38
|
+
click_button 'Update'
|
39
|
+
|
40
|
+
expect(page).to have_selector('input[value="marvin"]')
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'generators/user_plane/views_generator'
|
3
|
+
|
4
|
+
describe UserPlane::Generators::ViewsGenerator, type: :generator do
|
5
|
+
destination Dir.mktmpdir
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
prepare_destination
|
9
|
+
run_generator
|
10
|
+
end
|
11
|
+
|
12
|
+
it "creates a test initializer" do
|
13
|
+
assert_file 'app/views/user/invites/new.html.erb', /form_for\(@send_sign_up_invite\)/
|
14
|
+
assert_file 'app/views/user/invites/edit.html.erb', /form_for\(@sign_up_with_invite\)/
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe UserPlane::RouteConcerns::AbstractConcern do
|
4
|
+
|
5
|
+
let (:mapper) {double()}
|
6
|
+
before {allow(mapper).to receive(:namespace).and_yield}
|
7
|
+
|
8
|
+
let :init_options do
|
9
|
+
{module: 'baz'}
|
10
|
+
end
|
11
|
+
|
12
|
+
subject :a_resource_concern do
|
13
|
+
class ConcreteConcern < described_class
|
14
|
+
def build
|
15
|
+
mapper.resource options(as: :foo)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ConcreteConcern.new(init_options)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'combines options' do
|
23
|
+
allow(mapper).to receive(:resource_scope?).and_return(true)
|
24
|
+
expect(mapper).to receive(:resource).with(hash_including(as: :foo))
|
25
|
+
a_resource_concern.call(mapper)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
context 'concern-specific options' do
|
30
|
+
subject :a_two_level_concern do
|
31
|
+
class ConcreteConcern < described_class
|
32
|
+
def build
|
33
|
+
foo_controller = concern_options.delete(:controller)
|
34
|
+
mapper.resource options
|
35
|
+
mapper.resource options(as: :foo, to: "#{foo_controller}#action")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
ConcreteConcern.new(init_options)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'combines options' do
|
43
|
+
allow(mapper).to receive(:resource_scope?).and_return(true)
|
44
|
+
|
45
|
+
allow(mapper).to receive(:resource)
|
46
|
+
expect(mapper).to receive(:resource).with(hash_including(as: :foo, to: 'foo#action'))
|
47
|
+
|
48
|
+
a_two_level_concern.call(mapper, controller: :foo)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'removes :on if the route is not a resoucrce scope'
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module UserPlane
|
2
|
+
# Preview all emails at http://localhost:3000/rails/mailers/user_plane/invite_mailer
|
3
|
+
class InviteMailerPreview < ActionMailer::Preview
|
4
|
+
|
5
|
+
# Preview this email at http://localhost:3000/rails/mailers/user_plane/invite_mailer/invite
|
6
|
+
def invite
|
7
|
+
InviteMailer.invite
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module UserPlane
|
2
|
+
# Preview all emails at http://localhost:3000/rails/mailers/user_plane/verification_mailer
|
3
|
+
class VerificationMailerPreview < ActionMailer::Preview
|
4
|
+
|
5
|
+
# Preview this email at http://localhost:3000/rails/mailers/user_plane/verification_mailer/address_verification
|
6
|
+
def address_verification
|
7
|
+
VerificationMailer.address_verification
|
8
|
+
end
|
9
|
+
|
10
|
+
# Preview this email at http://localhost:3000/rails/mailers/user_plane/verification_mailer/password_reset
|
11
|
+
def password_reset
|
12
|
+
VerificationMailer.password_reset
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
|
4
|
+
|
5
|
+
module UserPlane
|
6
|
+
describe InviteMailer, type: :mailer do
|
7
|
+
include_context 'user'
|
8
|
+
|
9
|
+
describe "invite" do
|
10
|
+
|
11
|
+
subject(:mail) { InviteMailer.invite a_sign_up_invite }
|
12
|
+
|
13
|
+
it "renders the headers" do
|
14
|
+
expect(mail.subject).to eq("Invite")
|
15
|
+
expect(mail.to).to eq([a_sign_up_invite.recipient])
|
16
|
+
expect(mail.from).to eq(["accounts@example.com"])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "links to the sign up page" do
|
20
|
+
expect(mail.body.encoded).to match("http://example.com/invites/#{a_sign_up_invite.code}/redeem")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
|
4
|
+
|
5
|
+
module UserPlane
|
6
|
+
describe VerificationMailer, type: :mailer do
|
7
|
+
include_context 'user'
|
8
|
+
|
9
|
+
describe "address_verification" do
|
10
|
+
|
11
|
+
let :address_verification do
|
12
|
+
a_user.email.unverified_address = Faker::Internet.safe_email
|
13
|
+
a_user.email.save!
|
14
|
+
User::ConfirmEmailAddress.new(verification: a_user.email.address_change_verification)
|
15
|
+
end
|
16
|
+
|
17
|
+
subject(:mail) { VerificationMailer.address_verification address_verification}
|
18
|
+
|
19
|
+
it "renders the headers" do
|
20
|
+
expect(mail.subject).to eq("Address verification")
|
21
|
+
expect(mail.to).to eq([address_verification.verification.recipient])
|
22
|
+
expect(mail.from).to eq(["accounts@example.com"])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "renders the body" do
|
26
|
+
confirm_link = "http://example.com/account/confirm_email/#{address_verification.code}"
|
27
|
+
expect(mail.body.encoded).to match(confirm_link)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "password_reset" do
|
32
|
+
|
33
|
+
let :reset_password do
|
34
|
+
User::ResetPassword.new(verification: a_user.email.reset_password!)
|
35
|
+
end
|
36
|
+
|
37
|
+
subject(:mail) { VerificationMailer.password_reset reset_password}
|
38
|
+
|
39
|
+
it "renders the headers" do
|
40
|
+
expect(mail.subject).to eq("Password reset")
|
41
|
+
expect(mail.to).to eq([reset_password.verification.recipient])
|
42
|
+
expect(mail.from).to eq(["accounts@example.com"])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "renders the body" do
|
46
|
+
reset_link = "http://example.com/account/reset_passwords/#{reset_password.code}/edit"
|
47
|
+
expect(mail.body.encoded).to match(reset_link)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SessionManager do
|
4
|
+
describe 'logging in' do
|
5
|
+
let(:account) { Fabricate(:user_with_email_identity) }
|
6
|
+
let(:session_manager) { SessionManager.new({}) }
|
7
|
+
|
8
|
+
it 'stores and retrieves a user account through an identity' do
|
9
|
+
session_manager.identity = account.identities.first
|
10
|
+
session_hash = session_manager.instance_variable_get '@session'
|
11
|
+
new_session = SessionManager.new(session_hash)
|
12
|
+
expect(new_session.identity).to eql(account.identities.first)
|
13
|
+
expect(new_session.account).to eql(account)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
it 'goes stale after a few minutes' do
|
18
|
+
session_hash = session_manager.instance_variable_get '@session'
|
19
|
+
new_session_manager = SessionManager.new(session_hash)
|
20
|
+
|
21
|
+
Timecop.travel(90.minutes.from_now) do
|
22
|
+
expect(new_session_manager.identity).to be_nil
|
23
|
+
expect(new_session_manager.account).to be_a(User::Guest)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
|
4
|
+
describe User::Account do
|
5
|
+
include_context 'user'
|
6
|
+
|
7
|
+
it 'must have an identity' do
|
8
|
+
new_user = described_class.new(name: Faker::Internet.user_name)
|
9
|
+
expect(new_user).not_to be_valid
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'has a uuid'
|
13
|
+
|
14
|
+
describe 'an existing user' do
|
15
|
+
|
16
|
+
it 'can forget an identity'
|
17
|
+
|
18
|
+
it 'can be disabled' do
|
19
|
+
login_token = a_user.email.serialize
|
20
|
+
|
21
|
+
a_user.suspensions.create(message: "Dodgy account")
|
22
|
+
|
23
|
+
expect { User::Identity.deserialize!(login_token) }.to raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared_contexts/user'
|
3
|
+
|
4
|
+
describe User::ConfirmEmailAddress do
|
5
|
+
include_context 'user'
|
6
|
+
let (:new_address) { Faker::Internet.safe_email }
|
7
|
+
let! (:old_address) { a_user.email.address }
|
8
|
+
|
9
|
+
context 'with a valid confirmation token' do
|
10
|
+
let (:address_change_verification_token) do
|
11
|
+
address_verification = a_user.email.verifications.address_change_verification.create(recipient: new_address)
|
12
|
+
address_verification.token
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
subject :confirm_email_address do
|
17
|
+
described_class.new(code: address_change_verification_token)
|
18
|
+
end
|
19
|
+
|
20
|
+
it {is_expected.to be_valid}
|
21
|
+
|
22
|
+
it 'confirms the first email address' do
|
23
|
+
expect(a_user.email).to be_verified
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'changes the email address' do
|
27
|
+
confirm_email_address.perform!
|
28
|
+
a_user.reload
|
29
|
+
expect(a_user.email.address).to eql(new_address)
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'once performed' do
|
33
|
+
before do
|
34
|
+
confirm_email_address.perform!
|
35
|
+
a_user.reload
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'spends the verification token' do
|
39
|
+
confirm_email_address.verification.reload
|
40
|
+
expect(confirm_email_address.verification).to be_spent
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'cannot be redeemed anymore' do
|
44
|
+
subject :verifying_again do
|
45
|
+
verifying_again = described_class.new(code: address_change_verification_token)
|
46
|
+
verifying_again.valid?
|
47
|
+
verifying_again
|
48
|
+
end
|
49
|
+
|
50
|
+
it {is_expected.not_to be_valid}
|
51
|
+
it {expect(verifying_again.errors.messages[:code].size).to eq(1)}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'without a valid verification token' do
|
57
|
+
subject :confirmation_with_bad_token do
|
58
|
+
email_address_confirmation = described_class.new(code: 'not a valid token')
|
59
|
+
email_address_confirmation.valid?
|
60
|
+
email_address_confirmation
|
61
|
+
end
|
62
|
+
|
63
|
+
it {is_expected.not_to be_valid}
|
64
|
+
it {expect(confirmation_with_bad_token.errors.messages[:code].size).to eq(1)}
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with an expired verification' do
|
68
|
+
let (:stale_verification_token) do
|
69
|
+
Timecop.travel (2.weeks + 1.day).ago do
|
70
|
+
address_verification = a_user.email.verifications.address_change_verification.create(recipient: new_address)
|
71
|
+
address_verification.token
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
subject :confirmation_with_stale_token do
|
76
|
+
email_address_confirmation = described_class.new(code: stale_verification_token)
|
77
|
+
email_address_confirmation.valid?
|
78
|
+
email_address_confirmation
|
79
|
+
end
|
80
|
+
|
81
|
+
it {is_expected.not_to be_valid}
|
82
|
+
it {expect(confirmation_with_stale_token.errors.messages[:code].size).to eq(1)}
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when the address being verified is taken' do
|
86
|
+
let (:address_change_verification_token) do
|
87
|
+
address_verification = a_user.email.verifications.address_change_verification.create(recipient: new_address)
|
88
|
+
address_verification.token
|
89
|
+
end
|
90
|
+
|
91
|
+
subject :confirm_email_address do
|
92
|
+
conflicting_signup = Fabricate(:user_sign_up, email: new_address)
|
93
|
+
conflicting_signup.perform!
|
94
|
+
|
95
|
+
described_class.new(code: address_change_verification_token)
|
96
|
+
end
|
97
|
+
|
98
|
+
it {is_expected.not_to be_valid}
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|