clearance 1.6.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of clearance might be problematic. Click here for more details.

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +6 -8
  4. data/Gemfile +2 -2
  5. data/Gemfile.lock +20 -19
  6. data/NEWS.md +3 -0
  7. data/Rakefile +13 -14
  8. data/app/mailers/clearance_mailer.rb +9 -4
  9. data/app/views/clearance_mailer/change_password.html.erb +3 -3
  10. data/app/views/layouts/application.html.erb +1 -1
  11. data/app/views/passwords/edit.html.erb +2 -2
  12. data/app/views/passwords/new.html.erb +2 -2
  13. data/app/views/sessions/_form.html.erb +2 -2
  14. data/app/views/sessions/new.html.erb +1 -1
  15. data/app/views/users/_form.html.erb +1 -1
  16. data/app/views/users/new.html.erb +1 -1
  17. data/bin/setup +1 -2
  18. data/config/locales/clearance.en.yml +4 -4
  19. data/features/step_definitions/configuration_steps.rb +2 -2
  20. data/features/support/env.rb +15 -23
  21. data/gemfiles/rails3.2.gemfile +20 -0
  22. data/gemfiles/rails4.0.gemfile +20 -0
  23. data/gemfiles/rails4.1.gemfile +20 -0
  24. data/gemfiles/rails4.2.gemfile +20 -0
  25. data/lib/clearance/configuration.rb +1 -1
  26. data/lib/clearance/session.rb +5 -1
  27. data/lib/clearance/testing/deny_access_matcher.rb +1 -3
  28. data/lib/clearance/version.rb +1 -1
  29. data/lib/generators/clearance/install/install_generator.rb +5 -15
  30. data/spec/clearance/session_spec.rb +1 -1
  31. data/{lib/clearance/testing → spec/dummy}/app/controllers/application_controller.rb +0 -0
  32. data/spec/dummy/application.rb +47 -0
  33. data/{lib/clearance/testing → spec/dummy}/config/database.yml +0 -0
  34. data/{lib/clearance/testing → spec/dummy}/config/routes.rb +0 -0
  35. data/spec/generators/clearance/install/install_generator_spec.rb +118 -0
  36. data/spec/generators/clearance/routes/routes_generator_spec.rb +17 -0
  37. data/spec/generators/clearance/specs/specs_generator_spec.rb +26 -0
  38. data/spec/generators/clearance/views/views_generator_spec.rb +35 -0
  39. data/spec/mailers/clearance_mailer_spec.rb +48 -19
  40. data/spec/models/bcrypt_migration_from_sha1_spec.rb +81 -51
  41. data/spec/models/password_strategies_spec.rb +2 -0
  42. data/spec/spec_helper.rb +12 -18
  43. data/spec/support/app_templates/app/controllers/application_controller.rb +2 -0
  44. data/spec/support/app_templates/app/models/user.rb +5 -0
  45. data/spec/support/app_templates/config/routes.rb +3 -0
  46. data/spec/support/cookies.rb +1 -1
  47. data/spec/support/generator_spec_helpers.rb +40 -0
  48. metadata +31 -13
  49. data/.rspec +0 -2
  50. data/features/add_migrations_to_project.feature +0 -36
  51. data/features/copy_routes_to_host_application.feature +0 -9
  52. data/lib/clearance/testing/application.rb +0 -49
  53. data/lib/clearance/testing/assertion_error.rb +0 -6
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 1.0"
6
+ gem "ammeter"
7
+ gem "aruba", "~> 0.5"
8
+ gem "bundler", "~> 1.3"
9
+ gem "capybara", "~> 2.2.0"
10
+ gem "cucumber-rails", "~> 1.3", :require => false
11
+ gem "database_cleaner", "~> 1.0"
12
+ gem "factory_girl_rails", "~> 4.2"
13
+ gem "rspec-rails", "~> 3.1"
14
+ gem "shoulda-matchers", "~> 2.4"
15
+ gem "sqlite3", "~> 1.3"
16
+ gem "timecop", "~> 0.6"
17
+ gem "pry", :require => false
18
+ gem "rails", "~> 4.2.0"
19
+
20
+ gemspec :path => "../"
@@ -27,7 +27,7 @@ module Clearance
27
27
  end
28
28
 
29
29
  def user_model
30
- @user_model || ::User
30
+ @user_model ||= ::User
31
31
  end
32
32
 
33
33
  def allow_sign_up?
@@ -6,10 +6,14 @@ module Clearance
6
6
 
7
7
  def initialize(env)
8
8
  @env = env
9
+ @current_user = nil
10
+ @cookies = nil
9
11
  end
10
12
 
11
13
  def add_cookie_to_headers(headers)
12
- Rack::Utils.set_cookie_header!(headers, REMEMBER_TOKEN_COOKIE, cookie_value)
14
+ if cookie_value[:value].present?
15
+ Rack::Utils.set_cookie_header!(headers, REMEMBER_TOKEN_COOKIE, cookie_value)
16
+ end
13
17
  end
14
18
 
15
19
  def current_user
@@ -1,5 +1,3 @@
1
- require 'clearance/testing/assertion_error'
2
-
3
1
  module Clearance
4
2
  module Testing
5
3
  module Matchers
@@ -66,7 +64,7 @@ module Clearance
66
64
  @failure_message_when_negated <<
67
65
  "Didn't expect to redirect to #{@url}."
68
66
  true
69
- rescue Clearance::Testing::AssertionError
67
+ rescue MiniTest::Assertion
70
68
  @failure_message << "Expected to redirect to #{@url} but did not."
71
69
  false
72
70
  end
@@ -1,3 +1,3 @@
1
1
  module Clearance
2
- VERSION = "1.6.0"
2
+ VERSION = "1.6.1"
3
3
  end
@@ -12,17 +12,17 @@ module Clearance
12
12
  end
13
13
 
14
14
  def inject_clearance_into_application_controller
15
- inject_into(
15
+ inject_into_class(
16
+ "app/controllers/application_controller.rb",
16
17
  ApplicationController,
17
- 'app/controllers/application_controller.rb',
18
- 'include Clearance::Controller'
18
+ " include Clearance::Controller\n"
19
19
  )
20
20
  end
21
21
 
22
22
  def create_or_inject_clearance_into_user_model
23
- if File.exists? 'app/models/user.rb'
23
+ if File.exist? "app/models/user.rb"
24
24
  inject_into_file(
25
- 'app/models/user.rb',
25
+ "app/models/user.rb",
26
26
  "include Clearance::User\n\n",
27
27
  after: "class User < ActiveRecord::Base\n"
28
28
  )
@@ -66,16 +66,6 @@ module Clearance
66
66
  end
67
67
  end
68
68
 
69
- def inject_into(class_name, file, text)
70
- if file_does_not_contain?(file, text)
71
- inject_into_class file, class_name, " #{text}\n"
72
- end
73
- end
74
-
75
- def file_does_not_contain?(file, text)
76
- File.readlines(file).grep(/#{text}/).none?
77
- end
78
-
79
69
  def migration_needed?
80
70
  new_columns.any? || new_indexes.any?
81
71
  end
@@ -320,7 +320,7 @@ describe Clearance::Session do
320
320
  headers = {}
321
321
  session = Clearance::Session.new(env_without_remember_token)
322
322
  session.add_cookie_to_headers headers
323
- expect(headers).not_to set_cookie('remember_token')
323
+ expect(headers["Set-Cookie"]).to be nil
324
324
  end
325
325
 
326
326
  it 'signs out a user' do
@@ -0,0 +1,47 @@
1
+ require "rails/all"
2
+
3
+ module Dummy
4
+ APP_ROOT = File.expand_path("..", __FILE__).freeze
5
+
6
+ def self.rails4?
7
+ Rails::VERSION::MAJOR >= 4
8
+ end
9
+
10
+ I18n.enforce_available_locales = true
11
+
12
+ class Application < Rails::Application
13
+ config.action_controller.allow_forgery_protection = false
14
+ config.action_controller.perform_caching = false
15
+ config.action_dispatch.show_exceptions = false
16
+ config.action_mailer.default_url_options = { host: "dummy.example.com" }
17
+ config.action_mailer.delivery_method = :test
18
+ config.active_support.deprecation = :stderr
19
+ config.active_support.test_order = :random
20
+ config.assets.enabled = true
21
+ config.cache_classes = true
22
+ config.consider_all_requests_local = true
23
+ config.eager_load = false
24
+ config.encoding = "utf-8"
25
+ config.paths["app/controllers"] << "#{APP_ROOT}/app/controllers"
26
+ config.paths["app/views"] << "#{APP_ROOT}/app/views"
27
+ config.paths["config/database"] = "#{APP_ROOT}/config/database.yml"
28
+ config.paths["log"] = "tmp/log/development.log"
29
+ config.secret_token = "SECRET_TOKEN_IS_MIN_30_CHARS_LONG"
30
+
31
+ if Dummy.rails4?
32
+ config.paths.add "config/routes.rb", with: "#{APP_ROOT}/config/routes.rb"
33
+ config.secret_key_base = "SECRET_KEY_BASE"
34
+ else
35
+ config.paths.add "config/routes", with: "#{APP_ROOT}/config/routes.rb"
36
+ end
37
+
38
+ def require_environment!
39
+ initialize!
40
+ end
41
+
42
+ def initialize!(&block)
43
+ FileUtils.mkdir_p(Rails.root.join("db").to_s)
44
+ super unless @initialized
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+ require "generators/clearance/install/install_generator"
3
+
4
+ describe Clearance::Generators::InstallGenerator, :generator do
5
+ describe "initializer" do
6
+ it "is copied to the application" do
7
+ provide_existing_application_controller
8
+
9
+ run_generator
10
+ initializer = file("config/initializers/clearance.rb")
11
+
12
+ expect(initializer).to exist
13
+ expect(initializer).to have_correct_syntax
14
+ expect(initializer).to contain("Clearance.configure do |config|")
15
+ end
16
+ end
17
+
18
+ describe "application controller" do
19
+ it "includes Clearance::Controller" do
20
+ provide_existing_application_controller
21
+
22
+ run_generator
23
+ application_controller = file("app/controllers/application_controller.rb")
24
+
25
+ expect(application_controller).to have_correct_syntax
26
+ expect(application_controller).to contain("include Clearance::Controller")
27
+ end
28
+ end
29
+
30
+ describe "user_model" do
31
+ context "no existing user class" do
32
+ it "creates a user class including Clearance::User" do
33
+ provide_existing_application_controller
34
+
35
+ run_generator
36
+ user_class = file("app/models/user.rb")
37
+
38
+ expect(user_class).to exist
39
+ expect(user_class).to have_correct_syntax
40
+ expect(user_class).to contain("include Clearance::User")
41
+ end
42
+ end
43
+
44
+ context "user class already exists" do
45
+ it "includes Clearance::User" do
46
+ provide_existing_application_controller
47
+ provide_existing_user_class
48
+
49
+ run_generator
50
+ user_class = file("app/models/user.rb")
51
+
52
+ expect(user_class).to exist
53
+ expect(user_class).to have_correct_syntax
54
+ expect(user_class).to contain("include Clearance::User")
55
+ expect(user_class).to have_method("previously_existed?")
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "user migration" do
61
+ context "users table does not exist" do
62
+ it "creates a migration to create the users table" do
63
+ provide_existing_application_controller
64
+ allow(ActiveRecord::Base.connection).to receive(:table_exists?).
65
+ with(:users).
66
+ and_return(false)
67
+
68
+ run_generator
69
+ migration = migration_file("db/migrate/create_users.rb")
70
+
71
+ expect(migration).to exist
72
+ expect(migration).to have_correct_syntax
73
+ expect(migration).to contain("create_table :users")
74
+ end
75
+ end
76
+
77
+ context "existing users table with all clearance columns and indexes" do
78
+ it "does not create a migration" do
79
+ provide_existing_application_controller
80
+
81
+ run_generator
82
+ create_migration = migration_file("db/migrate/create_users.rb")
83
+ add_migration = migration_file("db/migrate/add_clearance_to_users.rb")
84
+
85
+ expect(create_migration).not_to exist
86
+ expect(add_migration).not_to exist
87
+ end
88
+ end
89
+
90
+ context "existing users table missing some columns and indexes" do
91
+ it "create a migration to add missing columns and indexes" do
92
+ provide_existing_application_controller
93
+ Struct.new("Named", :name)
94
+ existing_columns = [Struct::Named.new("remember_token")]
95
+ existing_indexes = [Struct::Named.new("index_users_on_remember_token")]
96
+
97
+ allow(ActiveRecord::Base.connection).to receive(:columns).
98
+ with(:users).
99
+ and_return(existing_columns)
100
+
101
+ allow(ActiveRecord::Base.connection).to receive(:indexes).
102
+ with(:users).
103
+ and_return(existing_indexes)
104
+
105
+ run_generator
106
+ migration = migration_file("db/migrate/add_clearance_to_users.rb")
107
+
108
+ expect(migration).to exist
109
+ expect(migration).to have_correct_syntax
110
+ expect(migration).to contain("change_table :users")
111
+ expect(migration).to contain("t.string :email")
112
+ expect(migration).to contain("add_index :users, :email")
113
+ expect(migration).not_to contain("t.string :remember_token")
114
+ expect(migration).not_to contain("add_index :users, :remember_token")
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+ require "generators/clearance/routes/routes_generator"
3
+
4
+ describe Clearance::Generators::RoutesGenerator, :generator do
5
+ it "adds clearance routes to host application routes" do
6
+ provide_existing_routes_file
7
+
8
+ routes = file("config/routes.rb")
9
+
10
+ run_generator
11
+
12
+ expect(routes).to have_correct_syntax
13
+ expect(routes).to contain(
14
+ "get '/sign_in' => 'clearance/sessions#new', as: 'sign_in'"
15
+ )
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+ require "generators/clearance/specs/specs_generator"
3
+
4
+ describe Clearance::Generators::SpecsGenerator, :generator do
5
+ it "copies specs to host app" do
6
+ run_generator
7
+
8
+ specs = %w(
9
+ factories/clearance
10
+ features/clearance/user_signs_out_spec
11
+ features/clearance/visitor_resets_password_spec
12
+ features/clearance/visitor_signs_in_spec
13
+ features/clearance/visitor_signs_up_spec
14
+ features/clearance/visitor_updates_password_spec
15
+ support/clearance
16
+ support/features/clearance_helpers
17
+ )
18
+
19
+ spec_files = specs.map { |spec| file("spec/#{spec}.rb") }
20
+
21
+ spec_files.each do |spec_file|
22
+ expect(spec_file).to exist
23
+ expect(spec_file).to have_correct_syntax
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+ require "generators/clearance/views/views_generator"
3
+
4
+ describe Clearance::Generators::ViewsGenerator, :generator do
5
+ it "copies clearance views to the host application" do
6
+ run_generator
7
+
8
+ views = %w(
9
+ clearance_mailer/change_password
10
+ layouts/application
11
+ passwords/create
12
+ passwords/edit
13
+ passwords/new
14
+ sessions/_form
15
+ sessions/new
16
+ users/_form
17
+ users/new
18
+ )
19
+
20
+ view_files = views.map { |view| file("app/views/#{view}.html.erb") }
21
+
22
+ view_files.each do |each|
23
+ expect(each).to exist
24
+ expect(each).to have_correct_syntax
25
+ end
26
+ end
27
+
28
+ it "copies clearance locales to the host application" do
29
+ run_generator
30
+
31
+ locale = file("config/locales/clearance.en.yml")
32
+
33
+ expect(locale).to exist
34
+ end
35
+ end
@@ -1,35 +1,64 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe ClearanceMailer do
4
- before do
5
- @user = create(:user)
6
- @user.forgot_password!
7
- @email = ClearanceMailer.change_password(@user)
8
- end
4
+ it "is from DO_NOT_REPLY" do
5
+ user = create(:user)
6
+ user.forgot_password!
7
+
8
+ email = ClearanceMailer.change_password(user)
9
9
 
10
- it 'is from DO_NOT_REPLY' do
11
- expect(Clearance.configuration.mailer_sender).to match(/#{@email.from[0]}/i)
10
+ expect(Clearance.configuration.mailer_sender).to eq(email.from[0])
12
11
  end
13
12
 
14
- it 'is sent to user' do
15
- expect(@email.to.first).to match(/#{@user.email}/i)
13
+ it "is sent to user" do
14
+ user = create(:user)
15
+ user.forgot_password!
16
+
17
+ email = ClearanceMailer.change_password(user)
18
+
19
+ expect(email.to.first).to eq(user.email)
16
20
  end
17
21
 
18
- it 'contains a link to edit the password' do
22
+ it "contains a link to edit the password" do
23
+ user = create(:user)
24
+ user.forgot_password!
19
25
  host = ActionMailer::Base.default_url_options[:host]
20
- regexp = %r{http://#{host}/users/#{@user.id}/password/edit\?token=#{@user.confirmation_token}}
21
- expect(@email.body.to_s).to match(regexp)
26
+ link = "http://#{host}/users/#{user.id}/password/edit" \
27
+ "?token=#{user.confirmation_token}"
28
+
29
+ email = ClearanceMailer.change_password(user)
30
+
31
+ expect(email.body.to_s).to include(link)
22
32
  end
23
33
 
24
- it 'sets its subject' do
25
- expect(@email.subject).to match(/Change your password/)
34
+ it "sets its subject" do
35
+ user = create(:user)
36
+ user.forgot_password!
37
+
38
+ email = ClearanceMailer.change_password(user)
39
+
40
+ expect(email.subject).to include("Change your password")
26
41
  end
27
42
 
28
- it 'contains opening text in the body' do
29
- expect(@email.body).to match(/a link to change your password/)
43
+ it "contains opening text in the body" do
44
+ user = create(:user)
45
+ user.forgot_password!
46
+
47
+ email = ClearanceMailer.change_password(user)
48
+
49
+ expect(email.body).to include(
50
+ I18n.t("clearance_mailer.change_password.opening")
51
+ )
30
52
  end
31
53
 
32
- it 'contains closing text in the body' do
33
- expect(@email.body).to match(/Your password has not been changed/)
54
+ it "contains closing text in the body" do
55
+ user = create(:user)
56
+ user.forgot_password!
57
+
58
+ email = ClearanceMailer.change_password(user)
59
+
60
+ expect(email.body.raw_source).to include(
61
+ I18n.t("clearance_mailer.change_password.closing")
62
+ )
34
63
  end
35
64
  end