clearance 1.0.0.rc2 → 1.0.0.rc3

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 (50) hide show
  1. data/Gemfile.lock +2 -5
  2. data/NEWS.md +4 -1
  3. data/README.md +10 -10
  4. data/Rakefile +0 -1
  5. data/app/controllers/clearance/passwords_controller.rb +1 -10
  6. data/clearance.gemspec +0 -1
  7. data/features/add_migrations_to_project.feature +65 -0
  8. data/features/integration_with_rspec.feature +21 -0
  9. data/features/step_definitions/configuration_steps.rb +21 -0
  10. data/features/step_definitions/gem_file_steps.rb +7 -0
  11. data/features/support/env.rb +8 -18
  12. data/gemfiles/3.0.17.gemfile.lock +1 -4
  13. data/gemfiles/3.1.8.gemfile.lock +1 -4
  14. data/gemfiles/3.2.8.gemfile.lock +1 -4
  15. data/{features/support/clearance.rb → lib/clearance/testing/app/controllers/application_controller.rb} +0 -9
  16. data/lib/clearance/testing/application.rb +46 -0
  17. data/lib/clearance/testing/config/database.yml +11 -0
  18. data/lib/clearance/testing/config/routes.rb +3 -0
  19. data/lib/clearance/version.rb +1 -1
  20. data/lib/generators/clearance/install/install_generator.rb +103 -22
  21. data/lib/generators/clearance/install/templates/README +14 -7
  22. data/lib/generators/clearance/install/templates/db/migrate/add_clearance_to_users.rb +21 -0
  23. data/lib/generators/clearance/install/templates/db/migrate/create_users.rb +18 -0
  24. data/lib/generators/clearance/specs/USAGE +5 -0
  25. data/lib/generators/clearance/specs/specs_generator.rb +13 -0
  26. data/lib/generators/clearance/specs/templates/factories/clearance.rb +10 -0
  27. data/lib/generators/clearance/specs/templates/integration/clearance/user_signs_out_spec.rb +10 -0
  28. data/lib/generators/clearance/specs/templates/integration/clearance/visitor_resets_password_spec.rb +28 -0
  29. data/lib/generators/clearance/specs/templates/integration/clearance/visitor_signs_in_spec.rb +42 -0
  30. data/lib/generators/clearance/specs/templates/integration/clearance/visitor_signs_up_spec.rb +21 -0
  31. data/lib/generators/clearance/specs/templates/integration/clearance/visitor_updates_password_spec.rb +47 -0
  32. data/lib/generators/clearance/specs/templates/support/action_mailer.rb +3 -0
  33. data/lib/generators/clearance/specs/templates/support/clearance.rb +1 -0
  34. data/lib/generators/clearance/specs/templates/support/factory_girl.rb +5 -0
  35. data/lib/generators/clearance/specs/templates/support/integration.rb +4 -0
  36. data/lib/generators/clearance/specs/templates/support/integration/action_mailer_helpers.rb +19 -0
  37. data/lib/generators/clearance/specs/templates/support/integration/clearance_helpers.rb +49 -0
  38. data/lib/generators/clearance/views/USAGE +15 -0
  39. data/lib/generators/clearance/views/views_generator.rb +23 -2
  40. data/spec/controllers/passwords_controller_spec.rb +1 -2
  41. data/spec/spec_helper.rb +5 -3
  42. metadata +30 -35
  43. data/features/engine/visitor_resets_password.feature +0 -34
  44. data/features/engine/visitor_signs_in.feature +0 -33
  45. data/features/engine/visitor_signs_out.feature +0 -12
  46. data/features/engine/visitor_signs_up.feature +0 -17
  47. data/features/integration.feature +0 -50
  48. data/features/step_definitions/engine/clearance_steps.rb +0 -124
  49. data/lib/generators/clearance/features/features_generator.rb +0 -8
  50. data/lib/generators/clearance/install/templates/db/migrate/upgrade_clearance_to_diesel.rb +0 -37
@@ -1,3 +1,3 @@
1
1
  module Clearance
2
- VERSION = '1.0.0.rc2'
2
+ VERSION = '1.0.0.rc3'
3
3
  end
@@ -1,46 +1,127 @@
1
- require 'diesel/generators/install_base'
1
+ require 'rails/generators/base'
2
+ require 'rails/generators/active_record'
2
3
 
3
4
  module Clearance
4
5
  module Generators
5
- class InstallGenerator < Diesel::Generators::InstallBase
6
- def install
7
- template "clearance.rb", "config/initializers/clearance.rb"
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ source_root File.expand_path('../templates', __FILE__)
8
9
 
9
- inject_into_class "app/controllers/application_controller.rb", ApplicationController do
10
- " include Clearance::Authentication\n"
11
- end
10
+ def create_clearance_initializer
11
+ copy_file 'clearance.rb', 'config/initializers/clearance.rb'
12
+ end
12
13
 
13
- user_model = "app/models/user.rb"
14
- if File.exists?(user_model)
15
- inject_into_class user_model, User do
16
- "include Clearance::User"
17
- end
14
+ def inject_clearance_into_application_controller
15
+ inject_into(
16
+ ApplicationController,
17
+ 'app/controllers/application_controller.rb',
18
+ 'include Clearance::Authentication'
19
+ )
20
+ end
21
+
22
+ def create_or_inject_clearance_into_user_model
23
+ if File.exists? 'app/models/user.rb'
24
+ inject_into User, 'app/models/user.rb', 'include Clearance::User'
18
25
  else
19
- template "user.rb", user_model
26
+ copy_file 'user.rb', 'app/models/user.rb'
20
27
  end
28
+ end
21
29
 
22
- if File.exists?("spec")
23
- template "spec/factories.rb", "spec/factories/clearance.rb"
30
+ def create_clearance_migration
31
+ if users_table_exists?
32
+ create_add_columns_migration
24
33
  else
25
- template "spec/factories.rb", "test/factories/clearance.rb"
34
+ create_migration 'create_users.rb'
26
35
  end
36
+ end
27
37
 
28
- readme "README"
38
+ def display_readme_in_terminal
39
+ readme 'README'
29
40
  end
30
41
 
31
42
  private
32
43
 
33
- def migrations
34
- if users_table_exists?
35
- super.reject { |name| name.include?("create") } + ["db/migrate/upgrade_clearance_to_diesel.rb"]
36
- else
37
- super
44
+ def create_add_columns_migration
45
+ if migration_needed?
46
+ config = {
47
+ :new_columns => new_columns,
48
+ :new_indexes => new_indexes
49
+ }
50
+
51
+ create_migration('add_clearance_to_users.rb', config)
38
52
  end
39
53
  end
40
54
 
55
+ def create_migration(migration_name, config = {})
56
+ unless migration_exists?(migration_name)
57
+ migration_template(
58
+ "db/migrate/#{migration_name}",
59
+ "db/migrate/#{migration_name}",
60
+ config
61
+ )
62
+ end
63
+ end
64
+
65
+ def inject_into(class_name, file, text)
66
+ if file_does_not_contain?(file, text)
67
+ inject_into_class file, class_name, " #{text}\n"
68
+ end
69
+ end
70
+
71
+ def file_does_not_contain?(file, text)
72
+ File.readlines(file).grep(/#{text}/).none?
73
+ end
74
+
75
+ def migration_needed?
76
+ new_columns.any? || new_indexes.any?
77
+ end
78
+
79
+ def new_columns
80
+ @new_columns ||= {
81
+ :email => 't.string :email',
82
+ :encrypted_password => 't.string :encrypted_password, :limit => 128',
83
+ :confirmation_token => 't.string :confirmation_token, :limit => 128',
84
+ :remember_token => 't.string :remember_token, :limit => 128'
85
+ }.reject { |column| existing_users_columns.include?(column.to_s) }
86
+ end
87
+
88
+ def new_indexes
89
+ @new_indexes ||= {
90
+ :index_users_on_email => 'add_index :users, :email',
91
+ :index_users_on_remember_token => 'add_index :users, :remember_token'
92
+ }.reject { |index| existing_users_indexes.include?(index.to_s) }
93
+ end
94
+
95
+ def migration_exists?(name)
96
+ existing_migrations.include?(name)
97
+ end
98
+
99
+ def existing_migrations
100
+ @existing_migrations ||= Dir.glob("db/migrate/*.rb").map do |file|
101
+ migration_name_without_timestamp(file)
102
+ end
103
+ end
104
+
105
+ def migration_name_without_timestamp(file)
106
+ file.sub(%r{^.*(db/migrate/)(?:\d+_)?}, '')
107
+ end
108
+
41
109
  def users_table_exists?
42
110
  ActiveRecord::Base.connection.table_exists?(:users)
43
111
  end
112
+
113
+ def existing_users_columns
114
+ ActiveRecord::Base.connection.columns(:users).map(&:name)
115
+ end
116
+
117
+ def existing_users_indexes
118
+ ActiveRecord::Base.connection.indexes(:users).map(&:name)
119
+ end
120
+
121
+ # for generating a timestamp when using `create_migration`
122
+ def self.next_migration_number(dir)
123
+ ActiveRecord::Generators::Base.next_migration_number(dir)
124
+ end
44
125
  end
45
126
  end
46
127
  end
@@ -5,19 +5,26 @@ Next steps:
5
5
 
6
6
  1. Configure the mailer to create full URLs in emails:
7
7
 
8
- # config/environments/{development,test}.rb
9
- config.action_mailer.default_url_options = { :host => 'localhost:3000' }
8
+ # config/environments/{development,test}.rb
9
+ config.action_mailer.default_url_options = { :host => 'localhost:3000' }
10
10
 
11
- In production it should be your app's domain name.
11
+ In production it should be your app's domain name.
12
12
 
13
- 2. Display flashes. For example, in your application layout:
13
+ 2. Display user session and flashes. For example, in your application layout:
14
14
 
15
- <% flash.each do |key, value| -%>
15
+ <% if signed_in? %>
16
+ Signed in as: <%= current_user.email %>
17
+ <%= link_to 'Sign out', sign_out_path, :method => :delete %>
18
+ <% else %>
19
+ <%= link_to 'Sign in', sign_in_path %>
20
+ <% end %>
21
+
22
+ <% flash.each do |key, value| %>
16
23
  <div class="flash <%= key %>"><%= value %></div>
17
- <% end -%>
24
+ <% end %>
18
25
 
19
26
  3. Migrate:
20
27
 
21
- rake db:migrate
28
+ rake db:migrate
22
29
 
23
30
  *******************************************************************************
@@ -0,0 +1,21 @@
1
+ class AddClearanceToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :users do |t|
4
+ <% config[:new_columns].values.each do |column| -%>
5
+ <%= column %>
6
+ <% end -%>
7
+ end
8
+
9
+ <% config[:new_indexes].values.each do |index| -%>
10
+ <%= index %>
11
+ <% end -%>
12
+ end
13
+
14
+ def self.down
15
+ change_table :users do |t|
16
+ <% if config[:new_columns].any? -%>
17
+ t.remove <%= new_columns.keys.map { |column| ":#{column}" }.join(',') %>
18
+ <% end -%>
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.timestamps :null => false
5
+ t.string :email, :null => false
6
+ t.string :encrypted_password, :limit => 128, :null => false
7
+ t.string :confirmation_token, :limit => 128
8
+ t.string :remember_token, :limit => 128, :null => false
9
+ end
10
+
11
+ add_index :users, :email
12
+ add_index :users, :remember_token
13
+ end
14
+
15
+ def self.down
16
+ drop_table :users
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Generate RSpec integration tests
3
+
4
+ Examples:
5
+ rails generate clearance:specs
@@ -0,0 +1,13 @@
1
+ require 'rails/generators/base'
2
+
3
+ module Clearance
4
+ module Generators
5
+ class SpecsGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def create_specs
9
+ directory '.', 'spec'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ FactoryGirl.define do
2
+ sequence :email do |n|
3
+ "user#{n}@example.com"
4
+ end
5
+
6
+ factory :user do
7
+ email
8
+ password 'password'
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'User signs out' do
4
+ scenario 'signs out' do
5
+ user = signed_in_user
6
+ sign_out
7
+
8
+ user_should_be_signed_out
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor resets password' do
4
+ scenario 'with valid email' do
5
+ user = user_with_reset_password
6
+
7
+ page_should_display_change_password_message
8
+ reset_notification_should_be_sent_to user
9
+ end
10
+
11
+ scenario 'with non-user account' do
12
+ reset_password_for 'unknown.email@example.com'
13
+
14
+ page_should_display_change_password_message
15
+ mailer_should_have_no_deliveries
16
+ end
17
+
18
+ private
19
+
20
+ def reset_notification_should_be_sent_to(user)
21
+ user.confirmation_token.should_not be_blank
22
+ mailer_should_have_delivery user.email, 'password', user.confirmation_token
23
+ end
24
+
25
+ def page_should_display_change_password_message
26
+ page.should have_content('instructions for changing your password')
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor signs in' do
4
+ scenario 'with valid email and password' do
5
+ create_user 'user@example.com', 'password'
6
+ sign_in_with 'user@example.com', 'password'
7
+
8
+ user_should_be_signed_in
9
+ end
10
+
11
+ scenario 'with valid mixed-case email and password ' do
12
+ create_user 'user.name@example.com', 'password'
13
+ sign_in_with 'User.Name@example.com', 'password'
14
+
15
+ user_should_be_signed_in
16
+ end
17
+
18
+ scenario 'tries with invalid password' do
19
+ create_user 'user@example.com', 'password'
20
+ sign_in_with 'user@example.com', 'wrong_password'
21
+
22
+ page_should_display_sign_in_error
23
+ user_should_be_signed_out
24
+ end
25
+
26
+ scenario 'tries with invalid email' do
27
+ sign_in_with 'unknown.email@example.com', 'password'
28
+
29
+ page_should_display_sign_in_error
30
+ user_should_be_signed_out
31
+ end
32
+
33
+ private
34
+
35
+ def create_user(email, password)
36
+ create(:user, :email => email, :password => password)
37
+ end
38
+
39
+ def page_should_display_sign_in_error
40
+ page.should have_content('Bad email or password')
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor signs up' do
4
+ scenario 'with valid email and password' do
5
+ sign_up_with 'valid@example.com', 'password'
6
+
7
+ user_should_be_signed_in
8
+ end
9
+
10
+ scenario 'tries with invalid email' do
11
+ sign_up_with 'invalid_email', 'password'
12
+
13
+ user_should_be_signed_out
14
+ end
15
+
16
+ scenario 'tries with blank password' do
17
+ sign_up_with 'valid@example.com', ''
18
+
19
+ user_should_be_signed_out
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor updates password' do
4
+ scenario 'with valid password' do
5
+ user = user_with_reset_password
6
+ update_password user, 'newpassword'
7
+
8
+ user_should_be_signed_in
9
+ end
10
+
11
+ scenario 'signs in with new password' do
12
+ user = user_with_reset_password
13
+ update_password user, 'newpassword'
14
+ sign_out
15
+ sign_in_with user.email, 'newpassword'
16
+
17
+ user_should_be_signed_in
18
+ end
19
+
20
+ scenario 'tries with a blank password' do
21
+ user = user_with_reset_password
22
+ visit_password_reset_page_for user
23
+ change_password_to ''
24
+
25
+ page.should have_content("Password can't be blank")
26
+ user_should_be_signed_out
27
+ end
28
+
29
+ private
30
+
31
+ def update_password(user, password)
32
+ visit_password_reset_page_for user
33
+ change_password_to password
34
+ end
35
+
36
+ def visit_password_reset_page_for(user)
37
+ visit edit_user_password_path(
38
+ :user_id => user,
39
+ :token => user.confirmation_token
40
+ )
41
+ end
42
+
43
+ def change_password_to(password)
44
+ fill_in 'Choose password', :with => password
45
+ click_button 'Save this password'
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each) { ActionMailer::Base.deliveries.clear }
3
+ end
@@ -0,0 +1 @@
1
+ require 'clearance/testing'
@@ -0,0 +1,5 @@
1
+ require 'factory_girl_rails'
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryGirl::Syntax::Methods
5
+ end
@@ -0,0 +1,4 @@
1
+ RSpec.configure do |config|
2
+ config.include Integration::ClearanceHelpers
3
+ config.include Integration::ActionMailerHelpers
4
+ end
@@ -0,0 +1,19 @@
1
+ module Integration
2
+ module ActionMailerHelpers
3
+ def mailer_should_have_delivery(recipient, subject, body)
4
+ ActionMailer::Base.deliveries.should_not be_empty
5
+
6
+ message = ActionMailer::Base.deliveries.any? do |email|
7
+ email.to == [recipient] &&
8
+ email.subject =~ /#{subject}/i &&
9
+ email.body =~ /#{body}/
10
+ end
11
+
12
+ message.should be
13
+ end
14
+
15
+ def mailer_should_have_no_deliveries
16
+ ActionMailer::Base.deliveries.should be_empty
17
+ end
18
+ end
19
+ end