authkit 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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