restful_authentication 1.1.6

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 (64) hide show
  1. data/CHANGELOG +68 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +232 -0
  4. data/Rakefile +54 -0
  5. data/TODO +15 -0
  6. data/generators/authenticated/USAGE +1 -0
  7. data/generators/authenticated/authenticated_generator.rb +493 -0
  8. data/generators/authenticated/lib/insert_routes.rb +69 -0
  9. data/generators/authenticated/templates/_model_partial.html.erb +8 -0
  10. data/generators/authenticated/templates/activation.erb +3 -0
  11. data/generators/authenticated/templates/authenticated_system.rb +189 -0
  12. data/generators/authenticated/templates/authenticated_test_helper.rb +12 -0
  13. data/generators/authenticated/templates/controller.rb +43 -0
  14. data/generators/authenticated/templates/features/accounts.feature +67 -0
  15. data/generators/authenticated/templates/features/sessions.feature +77 -0
  16. data/generators/authenticated/templates/features/step_definitions/ra_env.rb +7 -0
  17. data/generators/authenticated/templates/features/step_definitions/user_steps.rb +31 -0
  18. data/generators/authenticated/templates/helper.rb +2 -0
  19. data/generators/authenticated/templates/login.html.erb +14 -0
  20. data/generators/authenticated/templates/machinist_spec.rb +5 -0
  21. data/generators/authenticated/templates/machinist_test.rb +5 -0
  22. data/generators/authenticated/templates/mailer.rb +25 -0
  23. data/generators/authenticated/templates/migration.rb +24 -0
  24. data/generators/authenticated/templates/model.rb +83 -0
  25. data/generators/authenticated/templates/model_controller.rb +96 -0
  26. data/generators/authenticated/templates/model_helper.rb +93 -0
  27. data/generators/authenticated/templates/model_helper_spec.rb +157 -0
  28. data/generators/authenticated/templates/observer.rb +11 -0
  29. data/generators/authenticated/templates/signup.html.erb +19 -0
  30. data/generators/authenticated/templates/signup_notification.erb +8 -0
  31. data/generators/authenticated/templates/site_keys.rb +38 -0
  32. data/generators/authenticated/templates/spec/blueprints/user.rb +13 -0
  33. data/generators/authenticated/templates/spec/controllers/access_control_spec.rb +89 -0
  34. data/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +107 -0
  35. data/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +138 -0
  36. data/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +197 -0
  37. data/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
  38. data/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
  39. data/generators/authenticated/templates/spec/models/user_spec.rb +298 -0
  40. data/generators/authenticated/templates/tasks/auth.rake +33 -0
  41. data/generators/authenticated/templates/test/functional_test.rb +84 -0
  42. data/generators/authenticated/templates/test/mailer_test.rb +31 -0
  43. data/generators/authenticated/templates/test/model_functional_test.rb +91 -0
  44. data/generators/authenticated/templates/test/unit_test.rb +177 -0
  45. data/lib/authentication.rb +40 -0
  46. data/lib/authentication/by_cookie_token.rb +82 -0
  47. data/lib/authentication/by_password.rb +64 -0
  48. data/lib/authorization.rb +14 -0
  49. data/lib/authorization/aasm_roles.rb +64 -0
  50. data/lib/authorization/stateful_roles.rb +64 -0
  51. data/lib/restful_authentication.rb +6 -0
  52. data/lib/trustification.rb +14 -0
  53. data/lib/trustification/email_validation.rb +20 -0
  54. data/notes/AccessControl.txt +2 -0
  55. data/notes/Authentication.txt +5 -0
  56. data/notes/Authorization.txt +154 -0
  57. data/notes/RailsPlugins.txt +78 -0
  58. data/notes/SecurityFramework.graffle +0 -0
  59. data/notes/SecurityFramework.png +0 -0
  60. data/notes/SecurityPatterns.txt +163 -0
  61. data/notes/Tradeoffs.txt +126 -0
  62. data/notes/Trustification.txt +49 -0
  63. data/restful_authentication.gemspec +32 -0
  64. metadata +128 -0
@@ -0,0 +1,7 @@
1
+ begin
2
+ ApplicationController.send(:public, :logged_in?, :current_<%= file_name %>, :authorized?)
3
+ rescue NameError => e
4
+ puts "An exception occurred: #{e}"
5
+ puts 'Did you forget to move "include AuthenticatedSystem" from sessions_controller.rb to application_controller.rb?'
6
+ exit!
7
+ end
@@ -0,0 +1,31 @@
1
+ Given /^I am not logged in$/ do
2
+ visit '/logout'
3
+ end
4
+
5
+ Given /^I am logged in$/ do
6
+ <%= file_name %> = <%= class_name %>.make
7
+ visit '/login'
8
+ fill_in 'login', :with => <%= file_name %>.login
9
+ fill_in 'password', :with => <%= file_name %>.password
10
+ click_button 'Log in'
11
+ end
12
+
13
+ Then /^I should not be logged in$/ do
14
+ controller.current_<%= file_name %>.should be_nil
15
+ end
16
+
17
+ Then /^I should be logged in$/ do
18
+ controller.current_<%= file_name %>.should_not be_nil
19
+ end
20
+
21
+ Given /^someone with the login "([^\"]*)" already exists$/ do |login|
22
+ <%= class_name %>.make(:login => login)
23
+ end
24
+
25
+ Then /^I should have a remember token$/ do
26
+ controller.current_<%= file_name %>.remember_token.should_not be_nil
27
+ end
28
+
29
+ Then /^I should not have a remember token$/ do
30
+ controller.current_<%= file_name %>.remember_token.should be_nil
31
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,14 @@
1
+ <h1>Log In</h1>
2
+
3
+ <%% form_tag <%= controller_routing_name %>_path do -%>
4
+ <p><%%= label_tag 'login' %><br />
5
+ <%%= text_field_tag 'login', @login %></p>
6
+
7
+ <p><%%= label_tag 'password' %><br/>
8
+ <%%= password_field_tag 'password', nil %></p>
9
+
10
+ <p><%%= label_tag 'remember_me', 'Remember me' %>
11
+ <%%= check_box_tag 'remember_me', '1', @remember_me %></p>
12
+
13
+ <p><%%= submit_tag 'Log in' %></p>
14
+ <%% end -%>
@@ -0,0 +1,5 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Dir["#{RAILS_ROOT}/spec/blueprints/*.rb"].each { |f| require f }
@@ -0,0 +1,5 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Dir["#{RAILS_ROOT}/test/blueprints/*.rb"].each { |f| require f }
@@ -0,0 +1,25 @@
1
+ class <%= class_name %>Mailer < ActionMailer::Base
2
+ def signup_notification(<%= file_name %>)
3
+ setup_email(<%= file_name %>)
4
+ @subject += 'Please activate your new account'
5
+ <% if options[:include_activation] %>
6
+ @body[:url] = "http://YOURSITE/activate/#{<%= file_name %>.activation_code}"
7
+ <% else %>
8
+ @body[:url] = "http://YOURSITE/login/" <% end %>
9
+ end
10
+
11
+ def activation(<%= file_name %>)
12
+ setup_email(<%= file_name %>)
13
+ @subject += 'Your account has been activated!'
14
+ @body[:url] = "http://YOURSITE/"
15
+ end
16
+
17
+ protected
18
+ def setup_email(<%= file_name %>)
19
+ @recipients = "#{<%= file_name %>.email}"
20
+ @from = "ADMINEMAIL"
21
+ @subject = "[YOURSITE] "
22
+ @sent_on = Time.now
23
+ @body[:<%= file_name %>] = <%= file_name %>
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %>, :force => true do |t|
4
+ t.string :login, :crypted_password, :salt, :remember_token, :limit => 40
5
+ t.datetime :remember_token_expires_at
6
+ t.string :name, :limit => 100, :default => '', :null => true
7
+ t.string :email, :limit => 100
8
+ <% if options[:include_activation] -%>
9
+ t.string :activation_code, :limit => 40
10
+ t.datetime :activated_at
11
+ <% end -%>
12
+ <% if options[:stateful] -%>
13
+ t.string :state, :null => :no, :default => 'passive'
14
+ t.datetime :deleted_at
15
+ <% end -%>
16
+ t.timestamps
17
+ end
18
+ add_index :<%= table_name %>, :login, :unique => true
19
+ end
20
+
21
+ def self.down
22
+ drop_table :<%= table_name %>
23
+ end
24
+ end
@@ -0,0 +1,83 @@
1
+ require 'digest/sha1'
2
+
3
+ class <%= class_name %> < ActiveRecord::Base
4
+ include Authentication
5
+ include Authentication::ByPassword
6
+ include Authentication::ByCookieToken
7
+ <% if options[:aasm] -%>
8
+ include Authorization::AasmRoles
9
+ <% elsif options[:stateful] -%>
10
+ include Authorization::StatefulRoles<% end %>
11
+ validates_presence_of :login
12
+ validates_length_of :login, :within => 3..40
13
+ validates_uniqueness_of :login
14
+ validates_format_of :login, :with => Authentication.login_regex, :message => Authentication.bad_login_message
15
+
16
+ validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true
17
+ validates_length_of :name, :maximum => 100
18
+
19
+ validates_presence_of :email
20
+ validates_length_of :email, :within => 6..100 #r@a.wk
21
+ validates_uniqueness_of :email
22
+ validates_format_of :email, :with => Authentication.email_regex, :message => Authentication.bad_email_message
23
+
24
+ <% if options[:include_activation] && !options[:stateful] %>before_create :make_activation_code <% end %>
25
+
26
+ # HACK HACK HACK -- how to do attr_accessible from here?
27
+ # prevents a user from submitting a crafted form that bypasses activation
28
+ # anything else you want your user to change should be added here.
29
+ attr_accessible :login, :email, :name, :password, :password_confirmation
30
+
31
+ <% if options[:include_activation] && !options[:stateful] %>
32
+ # Activates the user in the database.
33
+ def activate!
34
+ @activated = true
35
+ self.activated_at = Time.now.utc
36
+ self.activation_code = nil
37
+ save(false)
38
+ end
39
+
40
+ # Returns true if the user has just been activated.
41
+ def recently_activated?
42
+ @activated
43
+ end
44
+
45
+ def active?
46
+ # the existence of an activation code means they have not activated yet
47
+ activation_code.nil?
48
+ end<% end %>
49
+
50
+ # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
51
+ #
52
+ # uff. this is really an authorization, not authentication routine.
53
+ # We really need a Dispatch Chain here or something.
54
+ # This will also let us return a human error message.
55
+ #
56
+ def self.authenticate(login, password)
57
+ return nil if login.blank? || password.blank?
58
+ u = <% if options[:stateful] %>find_in_state :first, :active, :conditions => {:login => login.downcase}<%
59
+ elsif options[:include_activation] %>find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]<%
60
+ else %>find_by_login(login.downcase)<% end %> # need to get the salt
61
+ u && u.authenticated?(password) ? u : nil
62
+ end
63
+
64
+ def login=(value)
65
+ write_attribute :login, (value ? value.downcase : nil)
66
+ end
67
+
68
+ def email=(value)
69
+ write_attribute :email, (value ? value.downcase : nil)
70
+ end
71
+
72
+ protected
73
+
74
+ <% if options[:include_activation] -%>
75
+ def make_activation_code
76
+ <% if options[:stateful] -%>
77
+ self.deleted_at = nil
78
+ <% end -%>
79
+ self.activation_code = self.class.make_token
80
+ end
81
+ <% end %>
82
+
83
+ end
@@ -0,0 +1,96 @@
1
+ class <%= model_controller_class_name %>Controller < ApplicationController
2
+ # Be sure to include AuthenticationSystem in Application Controller instead
3
+ include AuthenticatedSystem
4
+ <% if options[:stateful] %>
5
+ # Protect these actions behind an admin login
6
+ # before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge]
7
+ before_filter :find_<%= file_name %>, :only => [:suspend, :unsuspend, :destroy, :purge]
8
+ <% end %>
9
+
10
+ # render new.html.erb
11
+ def new
12
+ @<%= file_name %> = <%= class_name %>.new
13
+ end
14
+
15
+ def create
16
+ logout_keeping_session!
17
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
18
+ <% if options[:stateful] -%>
19
+ @<%= file_name %>.register! if @<%= file_name %> && @<%= file_name %>.valid?
20
+ success = @<%= file_name %> && @<%= file_name %>.valid?
21
+ <% else -%>
22
+ success = @<%= file_name %> && @<%= file_name %>.save
23
+ <% end -%>
24
+ if success && @<%= file_name %>.errors.empty?
25
+ <% if !options[:include_activation] -%>
26
+ # Protects against session fixation attacks, causes request forgery
27
+ # protection if visitor resubmits an earlier form using back
28
+ # button. Uncomment if you understand the tradeoffs.
29
+ # reset session
30
+ self.current_<%= file_name %> = @<%= file_name %> # !! now logged in
31
+ <% end -%>redirect_back_or_default('/')
32
+ <% if options[:include_activation] -%>
33
+ flash[:notice] = "Thanks for signing up! We're sending you an email with your activation code."
34
+ <% else -%>
35
+ flash[:notice] = "Thanks for signing up!"
36
+ <% end -%>
37
+ else
38
+ <% if options[:include_activation] -%>
39
+ flash[:error] = "We couldn't set up that account, sorry. Please try again, or contact an admin (link is above)."
40
+ <% else -%>
41
+ flash[:error] = "We couldn't create your account, sorry."
42
+ <% end -%>
43
+ render :action => 'new'
44
+ end
45
+ end
46
+
47
+ <% if options[:include_activation] -%>
48
+ def activate
49
+ logout_keeping_session!
50
+ <%= file_name %> = <%= class_name %>.find_by_activation_code(params[:activation_code]) unless params[:activation_code].blank?
51
+ case
52
+ when (!params[:activation_code].blank?) && <%= file_name %> && !<%= file_name %>.active?
53
+ <%= file_name %>.activate!
54
+ flash[:notice] = "Signup complete! Please sign in to continue."
55
+ redirect_to '/login'
56
+ when params[:activation_code].blank?
57
+ flash[:error] = "The activation code was missing. Please follow the URL from your email."
58
+ redirect_back_or_default('/')
59
+ else
60
+ flash[:error] = "We couldn't find a <%= file_name %> with that activation code -- check your email? Or maybe you've already activated -- try signing in."
61
+ redirect_back_or_default('/')
62
+ end
63
+ end
64
+ <% end -%>
65
+
66
+ <% if options[:stateful] -%>
67
+ def suspend
68
+ @<%= file_name %>.suspend!
69
+ redirect_to <%= model_controller_routing_name %>_path
70
+ end
71
+
72
+ def unsuspend
73
+ @<%= file_name %>.unsuspend!
74
+ redirect_to <%= model_controller_routing_name %>_path
75
+ end
76
+
77
+ def destroy
78
+ @<%= file_name %>.delete!
79
+ redirect_to <%= model_controller_routing_name %>_path
80
+ end
81
+
82
+ def purge
83
+ @<%= file_name %>.destroy
84
+ redirect_to <%= model_controller_routing_name %>_path
85
+ end
86
+
87
+ # There's no page here to update or destroy a <%= file_name %>. If you add those, be
88
+ # smart -- make sure you check that the visitor is authorized to do so, that they
89
+ # supply their old password along with a new one to update it, etc.
90
+
91
+ protected
92
+ def find_<%= file_name %>
93
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
94
+ end
95
+ <% end -%>
96
+ end
@@ -0,0 +1,93 @@
1
+ module <%= model_controller_class_name %>Helper
2
+
3
+ #
4
+ # Use this to wrap view elements that the user can't access.
5
+ # !! Note: this is an *interface*, not *security* feature !!
6
+ # You need to do all access control at the controller level.
7
+ #
8
+ # Example:
9
+ # <%%= if_authorized?(:index, User) do link_to('List all users', users_path) end %> |
10
+ # <%%= if_authorized?(:edit, @user) do link_to('Edit this user', edit_user_path) end %> |
11
+ # <%%= if_authorized?(:destroy, @user) do link_to 'Destroy', @user, :confirm => 'Are you sure?', :method => :delete end %>
12
+ #
13
+ #
14
+ def if_authorized?(action, resource, &block)
15
+ if authorized?(action, resource)
16
+ yield action, resource
17
+ end
18
+ end
19
+
20
+ #
21
+ # Link to user's page ('<%= table_name %>/1')
22
+ #
23
+ # By default, their login is used as link text and link title (tooltip)
24
+ #
25
+ # Takes options
26
+ # * :content_text => 'Content text in place of <%= file_name %>.login', escaped with
27
+ # the standard h() function.
28
+ # * :content_method => :<%= file_name %>_instance_method_to_call_for_content_text
29
+ # * :title_method => :<%= file_name %>_instance_method_to_call_for_title_attribute
30
+ # * as well as link_to()'s standard options
31
+ #
32
+ # Examples:
33
+ # link_to_<%= file_name %> @<%= file_name %>
34
+ # # => <a href="/<%= table_name %>/3" title="barmy">barmy</a>
35
+ #
36
+ # # if you've added a .name attribute:
37
+ # content_tag :span, :class => :vcard do
38
+ # (link_to_<%= file_name %> <%= file_name %>, :class => 'fn n', :title_method => :login, :content_method => :name) +
39
+ # ': ' + (content_tag :span, <%= file_name %>.email, :class => 'email')
40
+ # end
41
+ # # => <span class="vcard"><a href="/<%= table_name %>/3" title="barmy" class="fn n">Cyril Fotheringay-Phipps</a>: <span class="email">barmy@blandings.com</span></span>
42
+ #
43
+ # link_to_<%= file_name %> @<%= file_name %>, :content_text => 'Your user page'
44
+ # # => <a href="/<%= table_name %>/3" title="barmy" class="nickname">Your user page</a>
45
+ #
46
+ def link_to_<%= file_name %>(<%= file_name %>, options={})
47
+ raise "Invalid <%= file_name %>" unless <%= file_name %>
48
+ options.reverse_merge! :content_method => :login, :title_method => :login, :class => :nickname
49
+ content_text = options.delete(:content_text)
50
+ content_text ||= <%= file_name %>.send(options.delete(:content_method))
51
+ options[:title] ||= <%= file_name %>.send(options.delete(:title_method))
52
+ link_to h(content_text), <%= model_controller_routing_name.singularize %>_path(<%= file_name %>), options
53
+ end
54
+
55
+ #
56
+ # Link to login page using remote ip address as link content
57
+ #
58
+ # The :title (and thus, tooltip) is set to the IP address
59
+ #
60
+ # Examples:
61
+ # link_to_login_with_IP
62
+ # # => <a href="/login" title="169.69.69.69">169.69.69.69</a>
63
+ #
64
+ # link_to_login_with_IP :content_text => 'not signed in'
65
+ # # => <a href="/login" title="169.69.69.69">not signed in</a>
66
+ #
67
+ def link_to_login_with_IP content_text=nil, options={}
68
+ ip_addr = request.remote_ip
69
+ content_text ||= ip_addr
70
+ options.reverse_merge! :title => ip_addr
71
+ if tag = options.delete(:tag)
72
+ content_tag tag, h(content_text), options
73
+ else
74
+ link_to h(content_text), login_path, options
75
+ end
76
+ end
77
+
78
+ #
79
+ # Link to the current user's page (using link_to_<%= file_name %>) or to the login page
80
+ # (using link_to_login_with_IP).
81
+ #
82
+ def link_to_current_<%= file_name %>(options={})
83
+ if current_<%= file_name %>
84
+ link_to_<%= file_name %> current_<%= file_name %>, options
85
+ else
86
+ content_text = options.delete(:content_text) || 'not signed in'
87
+ # kill ignored options from link_to_<%= file_name %>
88
+ [:content_method, :title_method].each{|opt| options.delete(opt)}
89
+ link_to_login_with_IP content_text, options
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,157 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ include ApplicationHelper
3
+ include <%= model_controller_class_name %>Helper
4
+
5
+ describe "<%= model_controller_class_name %>Helper.link_to_<%= file_name %>" do
6
+ before do
7
+ @<%= file_name %> = <%= class_name %>.new({
8
+ :name => '<%= class_name %> Name',
9
+ :login => '<%= file_name %>_name',
10
+ })
11
+ @<%= file_name %>.id = 1 # set non-attr_accessible specifically
12
+ end
13
+
14
+ it "should give an error on a nil <%= file_name %>" do
15
+ lambda { link_to_<%= file_name %>(nil) }.should raise_error('Invalid <%= file_name %>')
16
+ end
17
+
18
+ it "should link to the given <%= file_name %>" do
19
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a[href='/<%= table_name %>/1']")
20
+ end
21
+
22
+ it "should use given link text if :content_text is specified" do
23
+ link_to_<%= file_name %>(@<%= file_name %>, :content_text => 'Hello there!').should have_tag("a", 'Hello there!')
24
+ end
25
+
26
+ it "should use the login as link text with no :content_method specified" do
27
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a", '<%= file_name %>_name')
28
+ end
29
+
30
+ it "should use the name as link text with :content_method => :name" do
31
+ link_to_<%= file_name %>(@<%= file_name %>, :content_method => :name).should have_tag("a", '<%= class_name %> Name')
32
+ end
33
+
34
+ it "should use the login as title with no :title_method specified" do
35
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a[title='<%= file_name %>_name']")
36
+ end
37
+
38
+ it "should use the name as link title with :content_method => :name" do
39
+ link_to_<%= file_name %>(@<%= file_name %>, :title_method => :name).should have_tag("a[title='<%= class_name %> Name']")
40
+ end
41
+
42
+ it "should have nickname as a class by default" do
43
+ link_to_<%= file_name %>(@<%= file_name %>).should have_tag("a.nickname")
44
+ end
45
+
46
+ it "should take other classes and no longer have the nickname class" do
47
+ result = link_to_<%= file_name %>(@<%= file_name %>, :class => 'foo bar')
48
+ result.should have_tag("a.foo")
49
+ result.should have_tag("a.bar")
50
+ end
51
+ end
52
+
53
+ describe "<%= model_controller_class_name %>Helper.link_to_signin_with_IP" do
54
+ before do
55
+ end
56
+
57
+ it "should link to the signin_path" do
58
+ link_to_signin_with_IP().should have_tag("a[href='/signin']")
59
+ end
60
+
61
+ it "should use given link text if :content_text is specified" do
62
+ link_to_signin_with_IP(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
63
+ end
64
+
65
+ it "should use the login as link text with no :content_method specified" do
66
+ link_to_signin_with_IP().should have_tag("a", '0.0.0.0')
67
+ end
68
+
69
+ it "should use the ip address as title" do
70
+ link_to_signin_with_IP().should have_tag("a[title='0.0.0.0']")
71
+ end
72
+
73
+ it "should by default be like school in summer and have no class" do
74
+ link_to_signin_with_IP().should_not have_tag("a.nickname")
75
+ end
76
+
77
+ it "should have some class if you tell it to" do
78
+ result = link_to_signin_with_IP(:class => 'foo bar')
79
+ result.should have_tag("a.foo")
80
+ result.should have_tag("a.bar")
81
+ end
82
+ end
83
+
84
+ describe "<%= model_controller_class_name %>Helper.link_to_current_<%= file_name %>, When logged in" do
85
+ include AuthenticatedTestHelper
86
+ before do
87
+ log_in
88
+ end
89
+
90
+ it "should link to the given <%= file_name %>" do
91
+ link_to_current_<%= file_name %>().should have_tag("a[href='/<%= table_name %>/1']")
92
+ end
93
+
94
+ it "should use given link text if :content_text is specified" do
95
+ link_to_current_<%= file_name %>(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
96
+ end
97
+
98
+ it "should use the login as link text with no :content_method specified" do
99
+ link_to_current_<%= file_name %>().should have_tag("a", 'quentin')
100
+ end
101
+
102
+ it "should use the name as link text with :content_method => :name" do
103
+ link_to_current_<%= file_name %>(:content_method => :name).should have_tag("a", 'Quentin')
104
+ end
105
+
106
+ it "should use the login as title with no :title_method specified" do
107
+ link_to_current_<%= file_name %>().should have_tag("a[title='quentin']")
108
+ end
109
+
110
+ it "should use the name as link title with :content_method => :name" do
111
+ link_to_current_<%= file_name %>(:title_method => :name).should have_tag("a[title='Quentin']")
112
+ end
113
+
114
+ it "should have nickname as a class" do
115
+ link_to_current_<%= file_name %>().should have_tag("a.nickname")
116
+ end
117
+
118
+ it "should take other classes and no longer have the nickname class" do
119
+ result = link_to_current_<%= file_name %>(:class => 'foo bar')
120
+ result.should have_tag("a.foo")
121
+ result.should have_tag("a.bar")
122
+ end
123
+ end
124
+
125
+
126
+
127
+ describe "<%= model_controller_class_name %>Helper.link_to_current_<%= file_name %>, When logged out" do
128
+ include AuthenticatedTestHelper
129
+ before do
130
+ end
131
+
132
+ it "should link to the signin_path" do
133
+ link_to_current_<%= file_name %>().should have_tag("a[href='/signin']")
134
+ end
135
+
136
+ it "should use given link text if :content_text is specified" do
137
+ link_to_current_<%= file_name %>(:content_text => 'Hello there!').should have_tag("a", 'Hello there!')
138
+ end
139
+
140
+ it "should use the IP address as link text with no :content_method specified" do
141
+ link_to_current_<%= file_name %>().should have_tag("a", '0.0.0.0')
142
+ end
143
+
144
+ it "should use the ip address as title" do
145
+ link_to_current_<%= file_name %>().should have_tag("a[title='0.0.0.0']")
146
+ end
147
+
148
+ it "should by default be like school in summer and have no class" do
149
+ link_to_current_<%= file_name %>().should_not have_tag("a.nickname")
150
+ end
151
+
152
+ it "should have some class if you tell it to" do
153
+ result = link_to_current_<%= file_name %>(:class => 'foo bar')
154
+ result.should have_tag("a.foo")
155
+ result.should have_tag("a.bar")
156
+ end
157
+ end