mori 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +6 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/javascripts/mori/application.js +13 -0
  6. data/app/assets/stylesheets/mori/application.css +13 -0
  7. data/app/controllers/mori/registrations_controller.rb +23 -0
  8. data/app/controllers/mori/sessions_controller.rb +17 -0
  9. data/app/controllers/mori_controller.rb +8 -0
  10. data/app/helpers/mori_helper.rb +5 -0
  11. data/app/mailers/mori/mailer.rb +17 -0
  12. data/app/models/mori/user.rb +85 -0
  13. data/app/views/layouts/mori/application.html.erb +14 -0
  14. data/app/views/mori/mailer/confirm_email.html.erb +1 -0
  15. data/app/views/mori/mailer/invite_user.html.erb +1 -0
  16. data/app/views/mori/mailer/password_reset_notification.html.erb +1 -0
  17. data/app/views/mori/registrations/new.slim +9 -0
  18. data/app/views/mori/sessions/new.slim +8 -0
  19. data/config/database.travis.yml +27 -0
  20. data/config/initializers/warden.rb +27 -0
  21. data/config/locales/mori.en.yml +17 -0
  22. data/config/mori.en.yml +0 -0
  23. data/config/routes.rb +9 -0
  24. data/db/migrate/20140126052000_enable_hstore.rb +9 -0
  25. data/db/migrate/20140128055658_create_mori_users.rb +33 -0
  26. data/lib/mori.rb +12 -0
  27. data/lib/mori/configuration.rb +36 -0
  28. data/lib/mori/engine.rb +19 -0
  29. data/lib/mori/string.rb +20 -0
  30. data/lib/mori/token.rb +16 -0
  31. data/lib/mori/version.rb +3 -0
  32. data/lib/tasks/mori_tasks.rake +4 -0
  33. data/spec/dummy/README.rdoc +28 -0
  34. data/spec/dummy/Rakefile +6 -0
  35. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  36. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  37. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  38. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  39. data/spec/dummy/app/views/application/index.slim +2 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  41. data/spec/dummy/bin/bundle +3 -0
  42. data/spec/dummy/bin/rails +4 -0
  43. data/spec/dummy/bin/rake +4 -0
  44. data/spec/dummy/config.ru +4 -0
  45. data/spec/dummy/config/application.rb +31 -0
  46. data/spec/dummy/config/boot.rb +5 -0
  47. data/spec/dummy/config/database.yml +29 -0
  48. data/spec/dummy/config/environment.rb +5 -0
  49. data/spec/dummy/config/environments/development.rb +29 -0
  50. data/spec/dummy/config/environments/production.rb +80 -0
  51. data/spec/dummy/config/environments/test.rb +48 -0
  52. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  53. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  54. data/spec/dummy/config/initializers/inflections.rb +16 -0
  55. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  56. data/spec/dummy/config/initializers/mori.rb +3 -0
  57. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  58. data/spec/dummy/config/initializers/session_store.rb +3 -0
  59. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  60. data/spec/dummy/config/locales/en.yml +23 -0
  61. data/spec/dummy/config/routes.rb +4 -0
  62. data/spec/dummy/db/migrate/20140128055553_enable_hstore.mori.rb +10 -0
  63. data/spec/dummy/db/migrate/20140209071716_create_users.mori_engine.rb +34 -0
  64. data/spec/dummy/db/schema.rb +39 -0
  65. data/spec/dummy/log/development.log +25025 -0
  66. data/spec/dummy/log/test.log +79149 -0
  67. data/spec/dummy/log/user.log +43 -0
  68. data/spec/dummy/public/404.html +58 -0
  69. data/spec/dummy/public/422.html +58 -0
  70. data/spec/dummy/public/500.html +57 -0
  71. data/spec/dummy/public/favicon.ico +0 -0
  72. data/spec/dummy/tmp/cache/assets/development/sprockets/07db4022ed50ebf1535599a3e2344037 +0 -0
  73. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  74. data/spec/dummy/tmp/cache/assets/development/sprockets/19f899de0e04ccfd931a7a11e36aca13 +0 -0
  75. data/spec/dummy/tmp/cache/assets/development/sprockets/1b98ef3337306536c2890a74951d225c +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/56b349da612a4be9d5e6733778ce17e4 +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/5b3ef4ce70e1da7b1afd392754613726 +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/a6374c002de146da5c25b8cfd375ce6c +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  84. data/spec/dummy/tmp/cache/assets/test/sprockets/07db4022ed50ebf1535599a3e2344037 +0 -0
  85. data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  86. data/spec/dummy/tmp/cache/assets/test/sprockets/19f899de0e04ccfd931a7a11e36aca13 +0 -0
  87. data/spec/dummy/tmp/cache/assets/test/sprockets/1b98ef3337306536c2890a74951d225c +0 -0
  88. data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  89. data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  90. data/spec/dummy/tmp/cache/assets/test/sprockets/56b349da612a4be9d5e6733778ce17e4 +0 -0
  91. data/spec/dummy/tmp/cache/assets/test/sprockets/5b3ef4ce70e1da7b1afd392754613726 +0 -0
  92. data/spec/dummy/tmp/cache/assets/test/sprockets/a6374c002de146da5c25b8cfd375ce6c +0 -0
  93. data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  94. data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  95. data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  96. data/spec/dummy/tmp/pids/server.pid +1 -0
  97. data/spec/factories/mori_users.rb +16 -0
  98. data/spec/features/registrations_spec.rb +23 -0
  99. data/spec/features/sessions_spec.rb +31 -0
  100. data/spec/helpers/mori_helper_spec.rb +15 -0
  101. data/spec/mailer_matcher.rb +33 -0
  102. data/spec/mailers/mori/mailer_spec.rb +7 -0
  103. data/spec/models/mori/user_spec.rb +195 -0
  104. data/spec/spec_helper.rb +38 -0
  105. data/spec/views/mori/registrations/create.html.erb_spec.rb +5 -0
  106. data/spec/views/mori/registrations/new.html.erb_spec.rb +5 -0
  107. data/spec/views/mori/sessions/create.html.erb_spec.rb +5 -0
  108. data/spec/views/mori/sessions/destroy.html.erb_spec.rb +5 -0
  109. data/spec/views/mori/sessions/new.html.erb_spec.rb +5 -0
  110. metadata +298 -0
@@ -0,0 +1,43 @@
1
+  (2.7ms) CREATE TABLE "schema_migrations" ("version" character varying(255) NOT NULL) 
2
+  (1.6ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
3
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
4
+ Migrating to EnableHstore (20140128055553)
5
+  (0.1ms) BEGIN
6
+  (29.8ms) CREATE EXTENSION hstore
7
+ SQL (0.7ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140128055553"]]
8
+  (1.3ms) COMMIT
9
+ Migrating to CreateMoriUsers (20140204044714)
10
+  (0.2ms) BEGIN
11
+  (5.0ms) CREATE TABLE "mori_users" ("id" serial primary key, "email" character varying(255), "password" text, "invitation_token" character varying(255), "invitation_sent" timestamp, "password_reset_token" character varying(255), "password_reset_sent" timestamp, "confirmed" boolean, "confirmation_token" character varying(255), "confirmation_sent" timestamp, "group_id" integer, "data" hstore DEFAULT '', "created_at" timestamp, "updated_at" timestamp) 
12
+  (1.1ms) CREATE INDEX "index_mori_users_on_email" ON "mori_users" ("email")
13
+  (0.9ms) CREATE INDEX "index_mori_users_on_group_id" ON "mori_users" ("group_id")
14
+ SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140204044714"]]
15
+  (0.5ms) COMMIT
16
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
17
+ ActiveRecord::SchemaMigration Load (7.8ms) SELECT "schema_migrations".* FROM "schema_migrations"
18
+ Migrating to CreateUsers (20140209071716)
19
+  (0.3ms) BEGIN
20
+  (9.1ms) CREATE TABLE "users" ("id" serial primary key, "email" character varying(255), "password" text, "invitation_token" character varying(255), "invitation_sent" timestamp, "password_reset_token" character varying(255), "password_reset_sent" timestamp, "confirmed" boolean, "confirmation_token" character varying(255), "confirmation_sent" timestamp, "group_id" integer, "data" hstore DEFAULT '', "created_at" timestamp, "updated_at" timestamp) 
21
+  (1.3ms) CREATE INDEX "index_users_on_email" ON "users" ("email")
22
+  (1.0ms) CREATE INDEX "index_users_on_group_id" ON "users" ("group_id")
23
+ SQL (0.5ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140209071716"]]
24
+  (0.8ms) COMMIT
25
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
26
+ ActiveRecord::SchemaMigration Load (0.7ms) SELECT "schema_migrations".* FROM "schema_migrations"
27
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
28
+  (2.9ms) CREATE TABLE "schema_migrations" ("version" character varying(255) NOT NULL) 
29
+  (1.7ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
30
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
31
+ Migrating to EnableHstore (20140128055553)
32
+  (0.1ms) BEGIN
33
+  (26.6ms) CREATE EXTENSION hstore
34
+ SQL (0.9ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140128055553"]]
35
+  (1.5ms) COMMIT
36
+ Migrating to CreateUsers (20140209071716)
37
+  (0.3ms) BEGIN
38
+  (5.9ms) CREATE TABLE "users" ("id" serial primary key, "email" character varying(255), "password" text, "invitation_token" character varying(255), "invitation_sent" timestamp, "password_reset_token" character varying(255), "password_reset_sent" timestamp, "confirmed" boolean, "confirmation_token" character varying(255), "confirmation_sent" timestamp, "group_id" integer, "data" hstore DEFAULT '', "created_at" timestamp, "updated_at" timestamp) 
39
+  (1.2ms) CREATE INDEX "index_users_on_email" ON "users" ("email")
40
+  (0.8ms) CREATE INDEX "index_users_on_group_id" ON "users" ("group_id")
41
+ SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140209071716"]]
42
+  (0.4ms) COMMIT
43
+ ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
@@ -0,0 +1,58 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style>
6
+ body {
7
+ background-color: #EFEFEF;
8
+ color: #2E2F30;
9
+ text-align: center;
10
+ font-family: arial, sans-serif;
11
+ }
12
+
13
+ div.dialog {
14
+ width: 25em;
15
+ margin: 4em auto 0 auto;
16
+ border: 1px solid #CCC;
17
+ border-right-color: #999;
18
+ border-left-color: #999;
19
+ border-bottom-color: #BBB;
20
+ border-top: #B00100 solid 4px;
21
+ border-top-left-radius: 9px;
22
+ border-top-right-radius: 9px;
23
+ background-color: white;
24
+ padding: 7px 4em 0 4em;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 100%;
29
+ color: #730E15;
30
+ line-height: 1.5em;
31
+ }
32
+
33
+ body > p {
34
+ width: 33em;
35
+ margin: 0 auto 1em;
36
+ padding: 1em 0;
37
+ background-color: #F7F7F7;
38
+ border: 1px solid #CCC;
39
+ border-right-color: #999;
40
+ border-bottom-color: #999;
41
+ border-bottom-left-radius: 4px;
42
+ border-bottom-right-radius: 4px;
43
+ border-top-color: #DADADA;
44
+ color: #666;
45
+ box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
46
+ }
47
+ </style>
48
+ </head>
49
+
50
+ <body>
51
+ <!-- This file lives in public/404.html -->
52
+ <div class="dialog">
53
+ <h1>The page you were looking for doesn't exist.</h1>
54
+ <p>You may have mistyped the address or the page may have moved.</p>
55
+ </div>
56
+ <p>If you are the application owner check the logs for more information.</p>
57
+ </body>
58
+ </html>
@@ -0,0 +1,58 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style>
6
+ body {
7
+ background-color: #EFEFEF;
8
+ color: #2E2F30;
9
+ text-align: center;
10
+ font-family: arial, sans-serif;
11
+ }
12
+
13
+ div.dialog {
14
+ width: 25em;
15
+ margin: 4em auto 0 auto;
16
+ border: 1px solid #CCC;
17
+ border-right-color: #999;
18
+ border-left-color: #999;
19
+ border-bottom-color: #BBB;
20
+ border-top: #B00100 solid 4px;
21
+ border-top-left-radius: 9px;
22
+ border-top-right-radius: 9px;
23
+ background-color: white;
24
+ padding: 7px 4em 0 4em;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 100%;
29
+ color: #730E15;
30
+ line-height: 1.5em;
31
+ }
32
+
33
+ body > p {
34
+ width: 33em;
35
+ margin: 0 auto 1em;
36
+ padding: 1em 0;
37
+ background-color: #F7F7F7;
38
+ border: 1px solid #CCC;
39
+ border-right-color: #999;
40
+ border-bottom-color: #999;
41
+ border-bottom-left-radius: 4px;
42
+ border-bottom-right-radius: 4px;
43
+ border-top-color: #DADADA;
44
+ color: #666;
45
+ box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
46
+ }
47
+ </style>
48
+ </head>
49
+
50
+ <body>
51
+ <!-- This file lives in public/422.html -->
52
+ <div class="dialog">
53
+ <h1>The change you wanted was rejected.</h1>
54
+ <p>Maybe you tried to change something you didn't have access to.</p>
55
+ </div>
56
+ <p>If you are the application owner check the logs for more information.</p>
57
+ </body>
58
+ </html>
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style>
6
+ body {
7
+ background-color: #EFEFEF;
8
+ color: #2E2F30;
9
+ text-align: center;
10
+ font-family: arial, sans-serif;
11
+ }
12
+
13
+ div.dialog {
14
+ width: 25em;
15
+ margin: 4em auto 0 auto;
16
+ border: 1px solid #CCC;
17
+ border-right-color: #999;
18
+ border-left-color: #999;
19
+ border-bottom-color: #BBB;
20
+ border-top: #B00100 solid 4px;
21
+ border-top-left-radius: 9px;
22
+ border-top-right-radius: 9px;
23
+ background-color: white;
24
+ padding: 7px 4em 0 4em;
25
+ }
26
+
27
+ h1 {
28
+ font-size: 100%;
29
+ color: #730E15;
30
+ line-height: 1.5em;
31
+ }
32
+
33
+ body > p {
34
+ width: 33em;
35
+ margin: 0 auto 1em;
36
+ padding: 1em 0;
37
+ background-color: #F7F7F7;
38
+ border: 1px solid #CCC;
39
+ border-right-color: #999;
40
+ border-bottom-color: #999;
41
+ border-bottom-left-radius: 4px;
42
+ border-bottom-right-radius: 4px;
43
+ border-top-color: #DADADA;
44
+ color: #666;
45
+ box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
46
+ }
47
+ </style>
48
+ </head>
49
+
50
+ <body>
51
+ <!-- This file lives in public/500.html -->
52
+ <div class="dialog">
53
+ <h1>We're sorry, but something went wrong.</h1>
54
+ </div>
55
+ <p>If you are the application owner check the logs for more information.</p>
56
+ </body>
57
+ </html>
File without changes
@@ -0,0 +1 @@
1
+ 48749
@@ -0,0 +1,16 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :mori_minimal_user, :class => 'Mori::User' do
5
+ email "email@example.com"
6
+ password "123456789sdf"
7
+ end
8
+ factory :mori_invited_user, :class => 'Mori::User' do
9
+ email "email@example.com"
10
+ invitation_token "sdflkjadfsd24rec2"
11
+ end
12
+ factory :mori_random_user, :class => 'Mori::User' do
13
+ email Faker::Internet.email
14
+ password "password"
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "The registration process", :type => :feature do
4
+ it "should be able to register" do
5
+ visit '/sign_up'
6
+ within('#new_mori_user') do
7
+ fill_in 'Email', :with => Faker::Internet.email
8
+ fill_in 'Password', :with => "imapassword123"
9
+ end
10
+ click_button 'Create User'
11
+ current_path.should eq Mori.configuration.after_signup_url
12
+ end
13
+ it "should redirect them if already signed up" do
14
+ visit '/sign_up'
15
+ within '#new_mori_user' do
16
+ fill_in 'Email', :with => Faker::Internet.email
17
+ fill_in 'Password', :with => 'password123'
18
+ end
19
+ click_button 'Create User'
20
+ visit '/sign_up'
21
+ current_path.should eq Mori.configuration.after_signup_url
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Sessions controller", :type => :feature do
4
+ let(:password){"password123"}
5
+ before(:each) do
6
+ @user = create(:mori_random_user, :password => "password123")
7
+ end
8
+ def log_in
9
+ visit '/login'
10
+ within '#new_session' do
11
+ fill_in "Email", :with => @user.email
12
+ fill_in "Password", :with => password
13
+ end
14
+ page.find('#submit_button').click
15
+ end
16
+ it "should be able to log in" do
17
+ log_in
18
+ current_path.should eq Mori.configuration.after_login_url
19
+ end
20
+ it "should redirect to the after login url if already logged in" do
21
+ log_in
22
+ visit '/login'
23
+ current_path.should eq Mori.configuration.after_login_url
24
+ end
25
+ it "should be able to log out" do
26
+ log_in
27
+ click_link 'Log Out'
28
+ visit '/login'
29
+ current_path.should eq '/login'
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ # Specs in this file have access to a helper object that includes
4
+ # the MoriHelper. For example:
5
+ #
6
+ # describe MoriHelper do
7
+ # describe "string concat" do
8
+ # it "concats two strings with spaces" do
9
+ # expect(helper.concat_strings("this","that")).to eq("this that")
10
+ # end
11
+ # end
12
+ # end
13
+ describe MoriHelper do
14
+ pending "add some examples to (or delete) #{__FILE__}"
15
+ end
@@ -0,0 +1,33 @@
1
+ # Usage
2
+ # order = create(:order)
3
+ #
4
+ # expect {
5
+ # order.pay!
6
+ # }.to deliver_email(OrderMailer, :paid, order.id)
7
+ #
8
+ #
9
+
10
+
11
+ RSpec::Matchers.define :deliver_email do |mailer, action, *args|
12
+ match do |block|
13
+ stubbed_mailer = double('mailer', deliver: true)
14
+ mailer.stub(action => stubbed_mailer)
15
+
16
+ block.call
17
+
18
+ expect(mailer).to have_received(action).with(*args)
19
+ expect(stubbed_mailer).to have_received(:deliver)
20
+ end
21
+
22
+ failure_message_for_should do |actual|
23
+ "expected that block would deliver #{mailer}##{:action}"
24
+ end
25
+
26
+ failure_message_for_should_not do |actual|
27
+ "expected that block would not deliver #{mailer}##{:action}"
28
+ end
29
+
30
+ description do
31
+ "deliver #{mailer}##{:action}"
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ module Mori
4
+ describe Mailer do
5
+ pending "add some examples to (or delete) #{__FILE__}"
6
+ end
7
+ end
@@ -0,0 +1,195 @@
1
+ require 'spec_helper'
2
+
3
+ module Mori
4
+ describe User do
5
+
6
+ let(:password){"imapassword"}
7
+ let(:password2){"imtheotherpassword"}
8
+ let(:email){"theemail@theexample.com"}
9
+
10
+ #########################################
11
+ # User Validation
12
+ #########################################
13
+
14
+ describe "is Valid: it" do
15
+ it {should validate_presence_of(:email)}
16
+ it {should validate_uniqueness_of(:email)}
17
+ it {should validate_presence_of(:password)}
18
+ it { should allow_value('foo@example.co.uk').for(:email) }
19
+ it { should allow_value('foo@example.com').for(:email) }
20
+ it { should allow_value('foo+bar@example.com').for(:email) }
21
+ it { should_not allow_value('foo@').for(:email) }
22
+ it { should_not allow_value('foo@example..com').for(:email) }
23
+ it { should_not allow_value('foo@.example.com').for(:email) }
24
+ it { should_not allow_value('foo').for(:email) }
25
+ it { should_not allow_value('example.com').for(:email) }
26
+ it { should_not allow_value('foo;@example.com').for(:email) }
27
+
28
+ it "should require basic information" do
29
+ build(:mori_minimal_user).valid?.should be true
30
+ build(:mori_invited_user).valid?.should be true
31
+ end
32
+ end
33
+
34
+ #########################################
35
+ # Post Creation/Save methods
36
+ #########################################
37
+ describe "after creation it" do
38
+ it "should encrypt the password" do
39
+ user = build(:mori_minimal_user)
40
+ password_before = user.password
41
+ user.save
42
+ user.password.should eq password_before
43
+ user.password.to_s.should_not eq password_before
44
+ end
45
+ it "should normalize the email on save" do
46
+ user = build(:mori_minimal_user, email: "E MAIL@exa MpLE.com")
47
+ user.save
48
+ user.email.should eq "email@example.com"
49
+ user.email.should_not eq "E MAIL@exa MpLE.com"
50
+ end
51
+ end
52
+
53
+ #########################################
54
+ # Helper methods for the User model
55
+ #########################################
56
+ it "#find_by_normalized_email" do
57
+ create(:mori_minimal_user)
58
+ User.find_by_normalized_email('e maIl@eXam ple.com').email.should eq 'email@example.com'
59
+ end
60
+
61
+ #########################################
62
+ # Inviting a User to the System
63
+ #########################################
64
+ describe "Inviting a User" do
65
+ before :each do
66
+ User.invite(email)
67
+ @user = User.find_by_email(email)
68
+ end
69
+ it "should be invitable" do
70
+ @user.should_not be nil
71
+ @user.invitation_sent.should eq Date.today
72
+ end
73
+ describe "accepting the invitation" do
74
+ before :each do
75
+ User.invite(email)
76
+ @user = User.find_by_email(email)
77
+ end
78
+ it "should set their password" do
79
+ user = @user.accept_invitation(@user.invitation_token,password)
80
+ user.password.to_s.should_not eq password
81
+ user.password.should eq password
82
+ end
83
+ it "should not be able to use a stale token" do
84
+ Timecop.freeze(Date.today + 3.weeks) do
85
+ expect{@user.accept_invitation(@user.invitation_token,password)}.to raise_error
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ #########################################
92
+ # Resetting the password
93
+ #########################################
94
+ describe "Resetting their password" do
95
+ before(:each) do
96
+ @user = create(:mori_minimal_user)
97
+ User.forgot_password(@user.email)
98
+ @user = User.find_by_email('email@example.com')
99
+ end
100
+ it "should be able to reset password" do
101
+ @user.password_reset_token.should_not be nil
102
+ @user.password_reset_sent.should eq Date.today
103
+ end
104
+ it "should require a valid reset token" do
105
+ expect {@user.reset_password('token123',password)}.to raise_error
106
+ token = @user.password_reset_token
107
+ @user.reset_password(token, password).password.should eq password
108
+ end
109
+ it "should not be able to use an old token" do
110
+ token = @user.password_reset_token
111
+ ::Timecop.freeze(Date.today + 3.weeks) do
112
+ expect {@user.reset_password(token, password)}.to raise_error
113
+ end
114
+ end
115
+ end
116
+
117
+ #########################################
118
+ # Actions a User can Take
119
+ #########################################
120
+
121
+ describe "changing their password" do
122
+ before :each do
123
+ @user = create(:mori_minimal_user)
124
+ end
125
+ it "should be able to change their password" do
126
+ User.change_password(@user.email,"123456789sdf",password2)
127
+ ::BCrypt::Password.new(User.find_by_email(@user.email).password).should eq password2
128
+ end
129
+ it "should raise an error if the incorrect password is provided" do
130
+ expect{ User.change_password(@user.email,password2,password)}.to raise_error
131
+ end
132
+ end
133
+
134
+ #########################################
135
+ # Confirming Their Email
136
+ #########################################
137
+
138
+ describe "confirming their email" do
139
+ before :each do
140
+ @user = create(:mori_minimal_user)
141
+ end
142
+ it "should require a valid token" do
143
+ expect{User.confirm_email(@user.email, "tokentoken123")}.to raise_error
144
+ end
145
+ it "should require the token to be recent" do
146
+ token = @user.confirmation_token
147
+ ::Timecop.freeze(Date.today + 3.weeks) do
148
+ expect {User.confirm_email(@user.email, token)}.to raise_error
149
+ end
150
+ end
151
+ it "should set confirmed to true" do
152
+ user = User.confirm_email(@user.email, @user.confirmation_token)
153
+ user.confirmed.should eq true
154
+ end
155
+ end
156
+ #########################################
157
+ # Emails sent from the model
158
+ #########################################
159
+
160
+ describe "should recieve an email for" do
161
+ it "getting invited" do
162
+ Mailer.stub(:invite_user)
163
+ Mailer.should_receive(:invite_user)
164
+ User.invite(email)
165
+ end
166
+ it "resetting their password" do
167
+ user = create(:mori_minimal_user)
168
+ Mailer.stub(:password_reset_notification)
169
+ Mailer.should_receive(:password_reset_notification)
170
+ User.forgot_password(user.email)
171
+ end
172
+ it "confirming their email" do
173
+ Mailer.stub(:confirm_email)
174
+ Mailer.should_receive(:confirm_email)
175
+ user = create(:mori_minimal_user)
176
+ end
177
+ end
178
+
179
+ #########################################
180
+ # Authentication
181
+ #########################################
182
+
183
+ describe "logging in" do
184
+ before :each do
185
+ @user = create(:mori_minimal_user, :password => password)
186
+ end
187
+ it "should be able to authenticate with their credentials" do
188
+ @user.authenticate(password).should be true
189
+ end
190
+ it "should raise an error if password is incorrect" do
191
+ expect{@user.authenticate(password2) }.to raise_error
192
+ end
193
+ end
194
+ end
195
+ end