authkit 0.4.0 → 0.5.0

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -3
  3. data/Rakefile +3 -2
  4. data/lib/authkit/version.rb +1 -1
  5. data/lib/generators/authkit/install_generator.rb +181 -35
  6. data/lib/generators/authkit/templates/app/controllers/application_controller.rb +6 -0
  7. data/lib/generators/authkit/templates/app/controllers/auths_controller.rb +144 -0
  8. data/lib/generators/authkit/templates/app/controllers/email_confirmation_controller.rb +1 -1
  9. data/lib/generators/authkit/templates/app/controllers/password_reset_controller.rb +7 -1
  10. data/lib/generators/authkit/templates/app/controllers/sessions_controller.rb +11 -2
  11. data/lib/generators/authkit/templates/app/controllers/signup_controller.rb +4 -2
  12. data/lib/generators/authkit/templates/app/controllers/upload_controller.rb +78 -0
  13. data/lib/generators/authkit/templates/app/controllers/users_controller.rb +2 -2
  14. data/lib/generators/authkit/templates/app/forms/signup.rb +57 -7
  15. data/lib/generators/authkit/templates/app/helpers/auths_helper.rb +26 -0
  16. data/lib/generators/authkit/templates/app/helpers/upload_helper.rb +118 -0
  17. data/lib/generators/authkit/templates/app/models/auth.rb +81 -0
  18. data/lib/generators/authkit/templates/app/models/avatar.rb +45 -0
  19. data/lib/generators/authkit/templates/app/models/user.rb +53 -26
  20. data/lib/generators/authkit/templates/app/views/auths/connect.html.erb +34 -0
  21. data/lib/generators/authkit/templates/app/views/password_change/show.html.erb +9 -9
  22. data/lib/generators/authkit/templates/app/views/password_reset/show.html.erb +6 -6
  23. data/lib/generators/authkit/templates/app/views/sessions/new.html.erb +25 -7
  24. data/lib/generators/authkit/templates/app/views/signup/new.html.erb +44 -32
  25. data/lib/generators/authkit/templates/app/views/users/complete.html.erb +39 -0
  26. data/lib/generators/authkit/templates/app/views/users/edit.html.erb +31 -31
  27. data/lib/generators/authkit/templates/app/workers/avatar_import_worker.rb +12 -0
  28. data/lib/generators/authkit/templates/config/initializers/filter_parameter_logging.rb +2 -2
  29. data/lib/generators/authkit/templates/config/initializers/omniauth.rb +59 -0
  30. data/lib/generators/authkit/templates/config/initializers/paperclip.rb +68 -0
  31. data/lib/generators/authkit/templates/db/migrate/add_authkit_fields_to_users.rb +8 -6
  32. data/lib/generators/authkit/templates/db/migrate/create_auths.rb +24 -0
  33. data/lib/generators/authkit/templates/db/migrate/create_avatars.rb +27 -0
  34. data/lib/generators/authkit/templates/lib/full_name_splitter.rb +111 -0
  35. data/lib/generators/authkit/templates/lib/username_format_validator.rb +11 -0
  36. data/lib/generators/authkit/templates/spec/controllers/application_controller_spec.rb +31 -38
  37. data/lib/generators/authkit/templates/spec/controllers/auths_controller_spec.rb +72 -0
  38. data/lib/generators/authkit/templates/spec/controllers/email_confirmation_controller_spec.rb +25 -27
  39. data/lib/generators/authkit/templates/spec/controllers/password_change_controller_spec.rb +30 -30
  40. data/lib/generators/authkit/templates/spec/controllers/password_reset_controller_spec.rb +20 -20
  41. data/lib/generators/authkit/templates/spec/controllers/sessions_controller_spec.rb +33 -33
  42. data/lib/generators/authkit/templates/spec/controllers/signup_controller_spec.rb +19 -19
  43. data/lib/generators/authkit/templates/spec/controllers/users_controller_spec.rb +21 -21
  44. data/lib/generators/authkit/templates/spec/factories/user.rb +3 -3
  45. data/lib/generators/authkit/templates/spec/forms/signup_spec.rb +32 -31
  46. data/lib/generators/authkit/templates/spec/models/auth_spec.rb +18 -0
  47. data/lib/generators/authkit/templates/spec/models/user_spec.rb +72 -78
  48. data/spec/rails_helper.rb +50 -0
  49. data/spec/spec_helper.rb +70 -13
  50. metadata +35 -17
  51. data/lib/generators/authkit/templates/spec/spec_helper.rb +0 -4
@@ -0,0 +1,12 @@
1
+ class AvatarImportWorker
2
+ include Sidekiq::Worker
3
+
4
+ sidekiq_options queue: "default"
5
+ sidekiq_options retry: false
6
+
7
+ def perform(avatar_id)
8
+ avatar = Avatar.find(avatar_id)
9
+ avatar.import!
10
+ end
11
+ end
12
+
@@ -14,8 +14,8 @@ Rails.application.config.filter_parameters += [
14
14
  :first_name,
15
15
  :last_name,
16
16
  :phone_number,
17
- :username,
18
- :email,
17
+ <% if username? %>:username,
18
+ <% end %>:email,
19
19
  :confirmation_email,
20
20
  :current_sign_in_ip,
21
21
  :last_sign_in_ip
@@ -0,0 +1,59 @@
1
+ OmniAuth.config.logger = Rails.logger
2
+
3
+ Rails.application.config.middleware.use OmniAuth::Builder do
4
+ <% if provider?(:facebook) %>
5
+ # https://github.com/mkdynamic/omniauth-facebook
6
+ provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], {
7
+ setup: lambda{ |env|
8
+ default_scope = 'email'
9
+ env['omniauth.strategy'].options[:scope] = env['rack.session']['facebook_oauth_scope'] || default_scope
10
+ },
11
+ display: 'popup',
12
+ image_size: 'square', # 50x50
13
+ reauthenticate: true
14
+ }
15
+ <% end %>
16
+
17
+ <% if provider?(:google) %>
18
+ # https://github.com/zquestz/omniauth-google-oauth2
19
+ provider :google_oauth2, ENV['GOOGLE_API_CLIENT_ID'], ENV['GOOGLE_API_CLIENT_SECRET'], {
20
+ setup: lambda{ |env|
21
+ default_scope = 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
22
+ env['omniauth.strategy'].options[:scope] = env['rack.session']['google_oauth_scope'] || default_scope
23
+ },
24
+ access_type: 'offline',
25
+ prompt: 'consent', # To get an offline access token you must specify 'consent'
26
+ image_aspect_ratio: 'square',
27
+ scope: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
28
+ redirect_uri:"#{ENV['DOMAIN']}/auth/google_oauth2/callback"
29
+ }
30
+ <% end %>
31
+
32
+ <% if provider?(:soundcloud) %>
33
+ # https://github.com/soundcloud/omniauth-soundcloud
34
+ provider "soundcloud", ENV['SOUNDCLOUD_CLIENT_ID'], ENV['SOUNDCLOUD_SECRET']
35
+ <% end %>
36
+
37
+ <% if provider?(:tumblr) %>
38
+ # https://github.com/jamiew/omniauth-tumblr
39
+ provider :tumblr, ENV['TUMBLR_KEY'], ENV['TUMBLR_SECRET']
40
+ <% end %>
41
+
42
+ <% if provider?(:twitter) %>
43
+ # https://github.com/arunagw/omniauth-twitter
44
+ provider :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'], {
45
+ image_size: 'bigger', # 73x73
46
+ authorize_params: {
47
+ force_login: true
48
+ }
49
+ }
50
+ <% end %>
51
+
52
+ <% if provider?(:shopify) %>
53
+ # https://github.com/Shopify/omniauth-shopify-oauth2
54
+ provider :shopify, ENV['SHOPIFY_API_KEY'], ENV['SHOPIFY_SHARED_SECRET'],
55
+ :scope => 'read_products,read_orders,write_content,read_customers,write_themes,write_script_tags',
56
+ :setup => lambda { |env| params = Rack::Utils.parse_query(env['QUERY_STRING'])
57
+ env['omniauth.strategy'].options[:client_options][:site] = "https://#{params['shop']}" }
58
+ <% end %>
59
+ end
@@ -0,0 +1,68 @@
1
+ # By default attachments are stored on S3. The path of the file is unique
2
+ # (based on the hash which is calculated at the time of upload). We expect
3
+ # that hash to be predictable so we set the :default_url (which usually
4
+ # points to a missing.png) to a calculated interpolation called
5
+ # :s3_default_url. When uploading directly we expect the signed params
6
+ # to include the ${filename} key for Amazon uploads. This prevents
7
+ # a variety of JavaScript filename vulnerabilities (though doesn't
8
+ # entirely prevent bad filenames). Given that, we actually prefer to
9
+ # use the uploaded filename in the resulting path (without escaping).
10
+ Paperclip::Attachment.default_options.merge!(
11
+ storage: :s3,
12
+ default_url: ':s3_default_url',
13
+ url: ':s3_domain_url',
14
+ path: '/system/:class/:style/:hash/:filename',
15
+ hash_data: ':class/:attachment/:id/:style/:uploaded_at',
16
+ hash_secret: ENV['aws_hash_secret'],
17
+ s3_permissions: :private,
18
+ s3_protocol: 'https',
19
+ s3_credentials: {
20
+ bucket: ENV['aws_bucket'],
21
+ access_key_id: ENV['aws_access_key_id'],
22
+ secret_access_key: ENV['aws_secret_access_key']
23
+ },
24
+ restricted_characters: nil,
25
+ escape_url: false
26
+ )
27
+
28
+ # By default, the :hash interpolation includes the :updated_at interpolation.
29
+ # This way, every time the model changes the hash is also changed and the
30
+ # content is expired. This can break if the same file is uploaded at the
31
+ # same second with different contents, but in such a case there are a number
32
+ # of other coordinated pieces (transactions, background jobs, etc) that
33
+ # might break and it could be expected.
34
+ #
35
+ # When importing, however, the updated_at key changes when the attachment_import_url is
36
+ # actually imported into the attachment, which changes the hash. This makes
37
+ # it impossible to predict what the ultimate URL will be because you cannot
38
+ # know what the future updated_at will be. Instead, if you record the time
39
+ # that the attachment_import_url was set and use that to calculate the hash the
40
+ # hash won't change when the contents of attachment_import_url are actually imported.
41
+ Paperclip.interpolates :uploaded_at do |attachment, style_name|
42
+ return attachment.instance.attachment_uploaded_at.to_i.to_s
43
+ end
44
+
45
+ # When importing, the attachment_import_url is set, but not the attachment information.
46
+ # In order to poll for the completed processed styles (like thumb) we need
47
+ # to know what the ultimate url will be. This interpolation is used as the
48
+ # default_url and, if the attachment_import_url is set can assume the eventual path.
49
+ Paperclip.interpolates :s3_default_url do |attachment, style_name|
50
+ return nil if attachment.instance.blank? || attachment.instance.attachment_import_url.blank?
51
+ uri = URI.parse(attachment.instance.attachment_import_url) rescue nil
52
+ return nil unless uri
53
+ # Currently, Paperclip doesn't pass the style to the default, it always uses 'original'
54
+ style_name = "thumb"
55
+ classname = plural_cache.underscore_and_pluralize(attachment.instance.class.to_s)
56
+ original_filename = File.basename(URI.decode(uri.path))
57
+ basename = original_filename.gsub(/#{Regexp.escape(File.extname(original_filename))}$/, "")
58
+ extension = ((style = attachment.styles[style_name.to_s.to_sym]) && style[:format]) || File.extname(original_filename).gsub(/^\.+/, "")
59
+ filename = [basename, extension].reject(&:blank?).join(".")
60
+ hash = attachment.hash_key(style_name)
61
+ path = "system/#{classname}/#{style_name}/#{hash}/#{filename}"
62
+ if attachment.s3_permissions(style_name) == "public-read"
63
+ UploadHelper.aws_bucket_url + "/" + path
64
+ else
65
+ # We still get an authenticated url for the path, it is just based on the destination rather than the current
66
+ UploadHelper.aws_url_for(path)
67
+ end
68
+ end
@@ -6,8 +6,8 @@ class AddAuthkitFieldsToUsers < ActiveRecord::Migration
6
6
  def self.up
7
7
  add_column :users, :email, :string, :default => "", :null => false
8
8
  add_column :users, :password_digest, :string, :default => "", :null => false
9
- add_column :users, :username, :string, :limit => 64
10
-
9
+ <% if username? %>add_column :users, :username, :string, :limit => 64
10
+ <% end %>
11
11
  add_column :users, :time_zone, :string, :default => "Eastern Time (US & Canada)"
12
12
  add_column :users, :first_name, :string
13
13
  add_column :users, :last_name, :string
@@ -50,10 +50,12 @@ class AddAuthkitFieldsToUsers < ActiveRecord::Migration
50
50
  add_column :users, :unlock_token, :string
51
51
  add_column :users, :unlock_token_created_at, :datetime
52
52
 
53
+ add_column :users, :suspended_at, :datetime
54
+
53
55
  # Make sure the validations are enforced
54
56
  add_index :users, :email, :unique => true
55
- add_index :users, :username, :unique => true
56
- add_index :users, :reset_password_token, :unique => true
57
+ <% if username? %>add_index :users, :username, :unique => true
58
+ <% end %>add_index :users, :reset_password_token, :unique => true
57
59
  add_index :users, :remember_token, :unique => true
58
60
  add_index :users, :confirmation_token, :unique => true
59
61
  add_index :users, :unlock_token, :unique => true
@@ -63,8 +65,8 @@ class AddAuthkitFieldsToUsers < ActiveRecord::Migration
63
65
  def self.down
64
66
  drop_column :users, :email
65
67
  drop_column :users, :password_digest
66
- drop_column :users, :username
67
-
68
+ <% if username? %>drop_column :users, :username
69
+ <% end %>
68
70
  drop_column :users, :time_zone
69
71
  drop_column :users, :first_name
70
72
  drop_column :users, :last_name
@@ -0,0 +1,24 @@
1
+ # Generated by Authkit.
2
+ #
3
+ # Create an auths table for managing OAuth authentication.
4
+ class CreateAuths < ActiveRecord::Migration
5
+ def self.up
6
+ create_table :auths do |t|
7
+ t.integer :user_id
8
+ t.string :provider
9
+ t.string :uid
10
+ t.string :email
11
+ t.boolean :verified_email
12
+ t.string :token
13
+ t.datetime :token_expires_at
14
+ t.string :refresh_token
15
+ t.string :secret_token
16
+ t.text :env
17
+ t.timestamps
18
+ end
19
+ end
20
+
21
+ def self.down
22
+ drop_table :auths
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # Generated by Authkit.
2
+ #
3
+ # Create an avatars table for managing user profile images
4
+ #
5
+ class CreateAvatars < ActiveRecord::Migration
6
+ def self.up
7
+ create_table :avatars do |t|
8
+ t.integer :user_id
9
+ t.integer :top, default: 0
10
+ t.integer :left, default: 0
11
+ t.integer :width, default: 0
12
+ t.integer :height, default: 0
13
+ t.text :remote_url
14
+ t.string :attachment_file_name
15
+ t.string :attachment_content_type
16
+ t.integer :attachment_file_size
17
+ t.datetime :attachment_updated_at
18
+ t.boolean :attachment_importing, default: false
19
+ t.datetime :attachment_uploaded_at
20
+ t.timestamps
21
+ end
22
+ end
23
+
24
+ def self.down
25
+ drop_table :avatars
26
+ end
27
+ end
@@ -0,0 +1,111 @@
1
+ class FullNameSplitter
2
+
3
+ PREFIXES = %w(de da la du del dei vda. dello della degli delle van von der den heer ten ter vande vanden vander voor ver aan mc mac ben ibn bint al).freeze
4
+ HONORIFICS = %w(mr mrs miss ms dr capt ofc rev prof sir cr hon).freeze
5
+
6
+ def initialize(full_name, honorific=false)
7
+ full_name ||= ''
8
+ @full_name = full_name.to_s.strip.gsub(/\s+/, ' ')
9
+ @honorific = [] if honorific
10
+ @first_name = []
11
+ @last_name = []
12
+ split!
13
+ end
14
+
15
+ def split!
16
+ # Reset these
17
+ @first_name = []
18
+ @last_name = []
19
+ @honorific = [] if honorific?
20
+
21
+ # deals with comma, eg. Smith, John => John Smith
22
+ tokens = @full_name.split(',')
23
+ if tokens.size == 2
24
+ @full_name = (tokens[1] + ' ' + tokens[0]).lstrip
25
+ end
26
+
27
+ @units = @full_name.split(/\s+/)
28
+ while @unit = @units.shift do
29
+ if honorific?
30
+ @honorific << @unit
31
+ elsif prefix? or with_apostrophe? or (first_name? and last_unit? and not initial?) or (has_honorific? and last_unit? and not first_name?)
32
+ @last_name << @unit and break
33
+ else
34
+ @first_name << @unit
35
+ end
36
+ end
37
+ @last_name += @units
38
+
39
+ adjust_exceptions!
40
+ end
41
+
42
+
43
+ def split_with_honorific(name)
44
+ split(name, true)
45
+ end
46
+
47
+ def split(name, honorific=false)
48
+ end
49
+
50
+ def honorific
51
+ @honorific.nil? || @honorific.empty? ? nil : @honorific[0].gsub(/[^\w]/, '')
52
+ end
53
+
54
+ def first_name
55
+ @first_name.empty? ? nil : @first_name.join(' ')
56
+ end
57
+
58
+ def last_name
59
+ @last_name.empty? ? nil : @last_name.join(' ')
60
+ end
61
+
62
+ private
63
+
64
+ def honorific?
65
+ !@honorific.nil? && HONORIFICS.include?(@unit.downcase.gsub(/[^\w]/, '')) && @honorific.empty? && @first_name.empty? && @last_name.empty?
66
+ end
67
+
68
+ def has_honorific?
69
+ not @honorific.nil? and not @honorific.empty?
70
+ end
71
+
72
+ def prefix?
73
+ PREFIXES.include?(@unit.downcase)
74
+ end
75
+
76
+ # M or W.
77
+ def initial?
78
+ @unit =~ /^\w\.?$/
79
+ end
80
+
81
+ # O'Connor, d'Artagnan match
82
+ # Noda' doesn't match
83
+ def with_apostrophe?
84
+ @unit =~ /\w{1}'\w+/
85
+ end
86
+
87
+ def last_unit?
88
+ @units.empty?
89
+ end
90
+
91
+ def first_name?
92
+ not @first_name.empty?
93
+ end
94
+
95
+ def adjust_exceptions!
96
+ return if @first_name.size <= 1
97
+
98
+ # Adjusting exceptions like
99
+ # "Ludwig Mies van der Rohe" => ["Ludwig", "Mies van der Rohe" ]
100
+ # "Juan Martín de la Cruz Gómez" => ["Juan Martín", "de la Cruz Gómez" ]
101
+ # "Javier Reyes de la Barrera" => ["Javier", "Reyes de la Barrera" ]
102
+ # Rosa María Pérez Martínez Vda. de la Cruz
103
+ # => ["Rosa María", "Pérez Martínez Vda. de la Cruz"]
104
+ if last_name =~ /^(van der|(vda\. )?de la \w+$)/i
105
+ loop do
106
+ @last_name.unshift @first_name.pop
107
+ break if @first_name.size <= 2
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,11 @@
1
+ class UsernameFormatValidator < ActiveModel::EachValidator
2
+ def validate_each(object, attribute, value)
3
+ unless UsernameFormatValidator::is_valid_username(value)
4
+ object.errors[attribute] << (options[:message] || "is not a valid username")
5
+ end
6
+ end
7
+
8
+ def self.is_valid_username(value)
9
+ value =~ /\A[0-9A-Za-z\-\_]+\z/
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'rails_helper'
2
2
 
3
3
  describe ApplicationController do
4
4
  let(:user) { create(:user) }
@@ -28,31 +28,27 @@ describe ApplicationController do
28
28
  describe "current_user" do
29
29
  it "returns nil if there is no current user" do
30
30
  get :new
31
- controller.send(:current_user).should be_nil
31
+ expect(controller.send(:current_user)).to be_nil
32
32
  end
33
33
 
34
34
  it "does not perform multiple finds" do
35
- where = double
36
- where.stub(:first).and_return(nil)
37
- User.should_receive(:where).and_return(where)
35
+ where = double(first: nil)
36
+ expect(User).to receive(:where).and_return(where)
38
37
  get :new, {}, unknown_session
39
- controller.send(:current_user).should be_nil
38
+ expect(controller.send(:current_user)).to be_nil
40
39
  end
41
40
 
42
41
  it "finds the current user in the session" do
43
42
  get :new, {}, logged_in_session
44
- controller.send(:current_user).should == user
43
+ expect(controller.send(:current_user)).to eq(user)
45
44
  end
46
45
 
47
46
  it "finds the current user from the remember cookie" do
48
47
  user.save
49
48
  user.set_remember_token
50
- # Need to sign the cookie
51
- request.env["action_dispatch.secret_token"] = "SECRET"
52
- verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze])
53
- request.cookies[:remember] = verifier.generate(user.remember_token)
49
+ cookies.signed[:remember] = user.remember_token
54
50
  get :index
55
- controller.send(:current_user).should == user
51
+ expect(controller.send(:current_user)).to eq(user)
56
52
  end
57
53
 
58
54
  it "doesn't find the current user from the remember cookie if it is expired" do
@@ -61,23 +57,20 @@ describe ApplicationController do
61
57
  user.remember_token_created_at = 1.year.ago
62
58
  user.save
63
59
 
64
- # Need to sign the cookie
65
- request.env["action_dispatch.secret_token"] = "SECRET"
66
- verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze])
67
- request.cookies[:remember] = verifier.generate(user.remember_token)
60
+ cookies.signed[:remember] = user.remember_token
68
61
  get :index
69
- controller.send(:current_user).should be_nil
62
+ expect(controller.send(:current_user)).to be_nil
70
63
  end
71
64
 
72
65
  it "sets the time zone" do
73
- User.any_instance.should_receive(:time_zone).and_return("Pacific Time (US & Canada)")
66
+ expect_any_instance_of(User).to receive(:time_zone).and_return("Pacific Time (US & Canada)")
74
67
  get :index, {}, logged_in_session
75
- Time.zone.name.should == "Pacific Time (US & Canada)"
68
+ expect(Time.zone.name).to eq("Pacific Time (US & Canada)")
76
69
  end
77
70
 
78
71
  it "has a logged in helper method" do
79
72
  get :new, {}, logged_in_session
80
- controller.should be_logged_in
73
+ expect(controller.send(:logged_in?)).to eq(true)
81
74
  end
82
75
  end
83
76
 
@@ -85,42 +78,42 @@ describe ApplicationController do
85
78
  it "does not allow tracking if there is a do not track header" do
86
79
  request.headers["DNT"] = "1"
87
80
  get :new
88
- controller.send(:allow_tracking?).should == false
81
+ expect(controller.send(:allow_tracking?)).to eq(false)
89
82
  end
90
83
 
91
84
  it "allows tracking if there is no do not track header" do
92
85
  get :new
93
- controller.send(:allow_tracking?).should == true
86
+ expect(controller.send(:allow_tracking?)).to eq(true)
94
87
  end
95
88
  end
96
89
 
97
90
  describe "when requiring a user" do
98
91
  it "allows access if there is a user" do
99
92
  get :index, {}, logged_in_session
100
- response.should be_success
93
+ expect(response).to be_success
101
94
  end
102
95
 
103
96
  it "stores the return path" do
104
97
  get :index, {}
105
- session[:return_url].should == "/anonymous"
98
+ expect(session[:return_url]).to eq("/anonymous")
106
99
  end
107
100
 
108
101
  describe "when responding to html" do
109
102
  it "sets the flash message" do
110
103
  get :index, {}
111
- flash.should_not be_empty
104
+ expect(flash).to_not be_empty
112
105
  end
113
106
 
114
107
  it "redirecs the user to login" do
115
108
  get :index, {}
116
- response.should be_redirect
109
+ expect(response).to be_redirect
117
110
  end
118
111
  end
119
112
 
120
113
  describe "when responding to json" do
121
114
  it "returns a forbidden status" do
122
115
  get :index, {format: :json}
123
- response.code.should == "403"
116
+ expect(response.code).to eq("403")
124
117
  end
125
118
  end
126
119
  end
@@ -128,27 +121,27 @@ describe ApplicationController do
128
121
  describe "login" do
129
122
  it "tracks the login" do
130
123
  get :new
131
- user.should_receive(:track_sign_in)
124
+ expect(user).to receive(:track_sign_in)
132
125
  controller.send(:login, user)
133
126
  end
134
127
 
135
128
  it "remembers the user using a token and cookie" do
136
129
  get :new
137
- controller.should_receive(:set_remember_cookie)
138
- user.should_receive(:set_remember_token)
130
+ expect(controller).to receive(:set_remember_cookie)
131
+ expect(user).to receive(:set_remember_token)
139
132
  controller.send(:login, user, true)
140
133
  end
141
134
 
142
135
  it "does not remember the user using a token and cookie when not requested" do
143
136
  get :new
144
- controller.should_not_receive(:set_remember_cookie)
145
- user.should_not_receive(:set_remember_token)
137
+ expect(controller).to_not receive(:set_remember_cookie)
138
+ expect(user).to_not receive(:set_remember_token)
146
139
  controller.send(:login, user, false)
147
140
  end
148
141
 
149
142
  it "resets the session" do
150
143
  get :new
151
- controller.should_receive(:reset_session)
144
+ expect(controller).to receive(:reset_session)
152
145
  controller.send(:login, user)
153
146
  end
154
147
  end
@@ -156,19 +149,19 @@ describe ApplicationController do
156
149
  describe "logout" do
157
150
  it "resets the session" do
158
151
  get :index, {}, logged_in_session
159
- controller.should_receive(:reset_session)
152
+ expect(controller).to receive(:reset_session)
160
153
  controller.send(:logout)
161
154
  end
162
155
 
163
156
  it "logs the user out" do
164
157
  get :index, {}, logged_in_session
165
158
  controller.send(:logout)
166
- controller.send(:current_user).should be_nil
159
+ expect(controller.send(:current_user)).to be_nil
167
160
  end
168
161
 
169
162
  it "clears the remember token" do
170
163
  get :index, {}, logged_in_session
171
- User.any_instance.should_receive(:clear_remember_token).and_return(:true)
164
+ expect_any_instance_of(User).to receive(:clear_remember_token).and_return(:true)
172
165
  controller.send(:logout)
173
166
  end
174
167
  end
@@ -177,12 +170,12 @@ describe ApplicationController do
177
170
  request.env["action_dispatch.secret_token"] = "SECRET"
178
171
  get :new
179
172
  controller.send(:login, user)
180
- cookies.permanent.signed[:remember].should == user.remember_token
173
+ expect(cookies.permanent.signed[:remember]).to eq(user.remember_token)
181
174
  end
182
175
 
183
176
  it "redirects to a stored session location if present" do
184
177
  get :new, {}, {return_url: "/return"}
185
- controller.should_receive(:redirect_to).with("/return").and_return(true)
178
+ expect(controller).to receive(:redirect_to).with("/return").and_return(true)
186
179
  controller.send(:redirect_back_or_default)
187
180
  end
188
181
  end