mori 0.0.1

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 (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