merbful_authentication 0.1.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 (42) hide show
  1. data/LICENSE +25 -0
  2. data/README +69 -0
  3. data/Rakefile +35 -0
  4. data/TODO +5 -0
  5. data/activerecord_generators/merbful_authentication_model/merbful_authentication_model_generator.rb +65 -0
  6. data/activerecord_generators/merbful_authentication_model/templates/authenticated_system_orm_map.rb +34 -0
  7. data/activerecord_generators/merbful_authentication_model/templates/migration.rb +20 -0
  8. data/activerecord_generators/merbful_authentication_model/templates/model.rb +63 -0
  9. data/datamapper_generators/merbful_authentication_model/merbful_authentication_model_generator.rb +60 -0
  10. data/datamapper_generators/merbful_authentication_model/templates/authenticated_system_orm_map.rb +34 -0
  11. data/datamapper_generators/merbful_authentication_model/templates/model.rb +78 -0
  12. data/lib/merbful_authentication.rb +10 -0
  13. data/lib/merbful_authentication/merbtasks.rb +6 -0
  14. data/merb_generators/authentication/USAGE +5 -0
  15. data/merb_generators/authentication/authentication_generator.rb +256 -0
  16. data/merb_generators/authentication/templates/activation.html.erb +1 -0
  17. data/merb_generators/authentication/templates/activation.text.erb +1 -0
  18. data/merb_generators/authentication/templates/authenticated_system_controller.rb +132 -0
  19. data/merb_generators/authentication/templates/authenticated_system_model.rb +97 -0
  20. data/merb_generators/authentication/templates/login.html.erb +14 -0
  21. data/merb_generators/authentication/templates/mail_controller.rb +13 -0
  22. data/merb_generators/authentication/templates/model_controller.rb +33 -0
  23. data/merb_generators/authentication/templates/new_model.html.erb +18 -0
  24. data/merb_generators/authentication/templates/session_controller.rb +33 -0
  25. data/merb_generators/authentication/templates/signup.html.erb +8 -0
  26. data/merb_generators/authentication/templates/signup.text.erb +8 -0
  27. data/rspec_generators/merbful_authentication_tests/merbful_authentication_tests_generator.rb +83 -0
  28. data/rspec_generators/merbful_authentication_tests/templates/authenticated_system_spec_helper.rb +22 -0
  29. data/rspec_generators/merbful_authentication_tests/templates/model_controller_spec.rb +78 -0
  30. data/rspec_generators/merbful_authentication_tests/templates/model_spec.rb +357 -0
  31. data/rspec_generators/merbful_authentication_tests/templates/model_spec_helper.rb +8 -0
  32. data/rspec_generators/merbful_authentication_tests/templates/session_controller_spec.rb +101 -0
  33. data/rspec_generators/merbful_authentication_tests/templates/user_mailer_spec.rb +70 -0
  34. data/test_unit_generators/merbful_authentication_tests/USAGE +5 -0
  35. data/test_unit_generators/merbful_authentication_tests/merbful_authentication_tests_generator.rb +84 -0
  36. data/test_unit_generators/merbful_authentication_tests/templates/authenticated_system_test_helper.rb +50 -0
  37. data/test_unit_generators/merbful_authentication_tests/templates/functional_test.rb +92 -0
  38. data/test_unit_generators/merbful_authentication_tests/templates/mailer_test.rb +66 -0
  39. data/test_unit_generators/merbful_authentication_tests/templates/model_functional_test.rb +92 -0
  40. data/test_unit_generators/merbful_authentication_tests/templates/model_test_helper.rb +8 -0
  41. data/test_unit_generators/merbful_authentication_tests/templates/unit_test.rb +142 -0
  42. metadata +114 -0
@@ -0,0 +1,14 @@
1
+ <%% form_tag :action => url(:login) do -%>
2
+ <p><label for="login">Login</label><br/>
3
+ <%%= text_field :name => "login" %></p>
4
+
5
+ <p><label for="password">Password</label><br/>
6
+ <%%= password_field :name => "password" %></p>
7
+
8
+ <!-- Uncomment this if you want this functionality
9
+ <p><label for="remember_me">Remember me:</label>
10
+ <%%= checkbox_field :name => 'remember_me' %></p>
11
+ -->
12
+
13
+ <p><%%= submit_button 'Log in' %></p>
14
+ <%% end -%>
@@ -0,0 +1,13 @@
1
+ class <%= class_name %>Mailer < Merb::MailController
2
+
3
+ def signup_notification
4
+ @<%= singular_name %> = params[:<%= singular_name %>]
5
+ render_mail
6
+ end
7
+
8
+ def activation_notification
9
+ @<%= singular_name %> = params[:<%= singular_name %>]
10
+ render_mail
11
+ end
12
+
13
+ end
@@ -0,0 +1,33 @@
1
+ class <%= model_controller_class_name %> < Application
2
+ provides :xml
3
+ include AuthenticatedSystem::Controller
4
+
5
+ skip_before :login_required
6
+
7
+ def new(<%= singular_name %> = {})
8
+ only_provides :html
9
+ @<%= singular_name %> = <%= class_name %>.new(<%= singular_name %>)
10
+ render @<%= singular_name %>
11
+ end
12
+
13
+ def create(<%= singular_name %>)
14
+ cookies.delete :auth_token
15
+
16
+ @<%= singular_name %> = <%= class_name %>.new(<%= singular_name %>)
17
+ if @<%= singular_name %>.save
18
+ redirect_back_or_default('/')
19
+ else
20
+ render :action => :new
21
+ end
22
+ end
23
+
24
+ <% if include_activation -%>
25
+ def activate(activation_code)
26
+ self.current_<%= singular_name %> = <%= class_name %>.find_activated_authenticated_model(activation_code)
27
+ if logged_in? && !current_<%= singular_name %>.active?
28
+ current_<%= singular_name %>.activate
29
+ end
30
+ redirect_back_or_default('/')
31
+ end
32
+ <% end -%>
33
+ end
@@ -0,0 +1,18 @@
1
+ <%%= error_messages_for @user %>
2
+ <%% form_for @user, :action => url(:users) do %>
3
+ <p>
4
+ <%%= text_control :login, :label => "Login" %>
5
+ </p>
6
+ <p>
7
+ <%%= text_control :email, :label => "Email" %>
8
+ </p>
9
+ <p>
10
+ <%%= password_control :password, :label => "Password" %>
11
+ </p>
12
+ <p>
13
+ <%%= password_control :password_confirmation, :label => "Password Confirmation" %>
14
+ </p>
15
+ <p>
16
+ <%%= submit_button "Sign up" %>
17
+ </p>
18
+ <%% end %>
@@ -0,0 +1,33 @@
1
+ require 'lib/authenticated_system_controller'
2
+ class <%= controller_class_name %> < Application
3
+
4
+ # Be sure to include AuthenticationSystem in Application Controller instead
5
+ include AuthenticatedSystem::Controller
6
+
7
+ skip_before :login_required
8
+
9
+ def new
10
+ render
11
+ end
12
+
13
+ def create(login = "", password = "")
14
+ self.current_<%= singular_name %> = <%= class_name %>.authenticate(login, password)
15
+ if logged_in?
16
+ if params[:remember_me] == "1"
17
+ self.current_<%= singular_name %>.remember_me
18
+ cookies[:auth_token] = { :value => self.current_<%= singular_name %>.remember_token , :expires => self.current_<%= singular_name %>.remember_token_expires_at }
19
+ end
20
+ redirect_back_or_default('/')
21
+ else
22
+ render :action => "new"
23
+ end
24
+ end
25
+
26
+ def destroy
27
+ self.current_<%= singular_name %>.forget_me if logged_in?
28
+ cookies.delete :auth_token
29
+ reset_session
30
+ redirect_back_or_default('/')
31
+ end
32
+
33
+ end
@@ -0,0 +1,8 @@
1
+ Your account has been created.
2
+
3
+ Username: <%%= @<%= singular_name %>.login %>
4
+ Password: <%%= @<%= singular_name %>.password %>
5
+
6
+ Visit this url to activate your account:
7
+
8
+ <%%= url(:<%= singular_name %>_activation, :activation_code => @<%= singular_name %>.activation_code) %>
@@ -0,0 +1,8 @@
1
+ Your account has been created.
2
+
3
+ Username: <%%= @<%= singular_name %>.login %>
4
+ Password: <%%= @<%= singular_name %>.password %>
5
+
6
+ Visit this url to activate your account:
7
+
8
+ <%%= url(:<%= singular_name %>_activation, :activation_code => @<%= singular_name %>.activation_code) %>
@@ -0,0 +1,83 @@
1
+ class MerbfulAuthenticationTestsGenerator < RubiGen::Base
2
+
3
+ attr_reader :name,
4
+ :class_name,
5
+ :class_path,
6
+ :file_name,
7
+ :class_nesting,
8
+ :class_nesting_depth,
9
+ :plural_name,
10
+ :singular_name,
11
+ :controller_name,
12
+ :controller_class_path,
13
+ :controller_file_path,
14
+ :controller_class_nesting,
15
+ :controller_class_nesting_depth,
16
+ :controller_class_name,
17
+ :controller_singular_name,
18
+ :controller_plural_name,
19
+ :model_controller_name,
20
+ :model_controller_class_path,
21
+ :model_controller_file_path,
22
+ :model_controller_class_nesting,
23
+ :model_controller_class_nesting_depth,
24
+ :model_controller_class_name,
25
+ :model_controller_singular_name,
26
+ :model_controller_plural_name,
27
+ :include_activation
28
+
29
+ def initialize(runtime_args, runtime_options = {})
30
+ super
31
+ usage if args.empty?
32
+ @name = args.shift
33
+ extract_options
34
+ runtime_options.each{ |k,v| self.instance_variable_set("@#{k}", v) }
35
+ end
36
+
37
+ def manifest
38
+ record do |m|
39
+ # Ensure appropriate folder(s) exists
40
+ m.directory "spec"
41
+ m.directory "spec/models"
42
+ m.directory "spec/controllers"
43
+ m.directory "spec/mailers"
44
+ # Create stubs
45
+ m.template "model_spec_helper.rb", File.join("spec", "#{file_name}_spec_helper.rb")
46
+ m.template "authenticated_system_spec_helper.rb", File.join("spec", "authenticated_system_spec_helper.rb")
47
+ m.template "session_controller_spec.rb", File.join("spec/controllers", "#{controller_file_path}_spec.rb")
48
+ m.template "model_controller_spec.rb", File.join("spec/controllers", "#{model_controller_file_path}_spec.rb")
49
+ m.template "model_spec.rb", File.join('spec/models', "#{file_name}_spec.rb")
50
+
51
+ if include_activation
52
+ m.template "user_mailer_spec.rb", File.join("spec/mailers", "#{singular_name}_mailer_spec.rb")
53
+ end
54
+ end
55
+ end
56
+
57
+ protected
58
+ def banner
59
+ <<-EOS
60
+ Creates a ...
61
+
62
+ USAGE: #{$0} #{spec.name} name"
63
+ EOS
64
+ end
65
+
66
+ def add_options!(opts)
67
+ # opts.separator ''
68
+ # opts.separator 'Options:'
69
+ # For each option below, place the default
70
+ # at the top of the file next to "default_options"
71
+ # opts.on("-a", "--author=\"Your Name\"", String,
72
+ # "Some comment about this option",
73
+ # "Default: none") { |options[:author]| }
74
+ # opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
75
+ end
76
+
77
+ def extract_options
78
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
79
+ # Templates can access these value via the attr_reader-generated methods, but not the
80
+ # raw instance variable value.
81
+ # @author = options[:author]
82
+ end
83
+ end
@@ -0,0 +1,22 @@
1
+ class Merb::Controller
2
+ require "merb/session/memory_session"
3
+ Merb::MemorySessionContainer.setup
4
+ include ::Merb::SessionMixin
5
+ self.session_secret_key = "foo to the bar to the baz"
6
+ end
7
+
8
+ class Merb::Mailer
9
+ self.delivery_method = :test_send
10
+ end
11
+
12
+ class Hash
13
+
14
+ def with( opts )
15
+ self.merge(opts)
16
+ end
17
+
18
+ def without(*args)
19
+ self.dup.delete_if{ |k,v| args.include?(k)}
20
+ end
21
+
22
+ end
@@ -0,0 +1,78 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+ require File.join( File.dirname(__FILE__), "..", "<%= singular_name %>_spec_helper")
3
+ require File.join( File.dirname(__FILE__), "..", "authenticated_system_spec_helper")
4
+
5
+ describe <%= model_controller_class_name %> do
6
+
7
+ include <%= class_name %>SpecHelper
8
+
9
+ before(:each) do
10
+ <%= class_name %>.clear_database_table
11
+ end
12
+
13
+ it 'allows signup' do
14
+ lambda do
15
+ create_<%= singular_name %>
16
+ controller.should redirect
17
+ end.should change(<%= class_name %>, :count).by(1)
18
+ end
19
+
20
+ it 'requires login on signup' do
21
+ lambda do
22
+ create_<%= singular_name %>(:login => nil)
23
+ controller.assigns(:<%= singular_name %>).errors.on(:login).should_not be_nil
24
+ controller.should be_successful
25
+ end.should_not change(<%= class_name %>, :count)
26
+ end
27
+
28
+ it 'requires password on signup' do
29
+ lambda do
30
+ create_<%= singular_name %>(:password => nil)
31
+ controller.assigns(:<%= singular_name %>).errors.on(:password).should_not be_nil
32
+ controller.should be_successful
33
+ end.should_not change(<%= class_name %>, :count)
34
+ end
35
+
36
+ it 'requires password confirmation on signup' do
37
+ lambda do
38
+ create_<%= singular_name %>(:password_confirmation => nil)
39
+ controller.assigns(:<%= singular_name %>).errors.on(:password_confirmation).should_not be_nil
40
+ controller.should be_successful
41
+ end.should_not change(<%= class_name %>, :count)
42
+ end
43
+
44
+ it 'requires email on signup' do
45
+ lambda do
46
+ create_<%= singular_name %>(:email => nil)
47
+ controller.assigns(:<%= singular_name %>).errors.on(:email).should_not be_nil
48
+ controller.should be_successful
49
+ end.should_not change(<%= class_name %>, :count)
50
+ end
51
+
52
+ <% if include_activation -%>
53
+ it "should have a route for <%= singular_name %> activation" do
54
+ with_route("/<%= model_controller_plural_name %>/activate/1234") do |params|
55
+ params[:controller].should == "<%= model_controller_class_name %>"
56
+ params[:action].should == "activate"
57
+ params[:activation_code].should == "1234"
58
+ end
59
+ end
60
+
61
+ it 'activates <%= singular_name %>' do
62
+ create_<%= singular_name %>(:login => "aaron", :password => "test", :password_confirmation => "test")
63
+ @<%= singular_name %> = controller.assigns(:<%= singular_name %>)
64
+ <%= class_name %>.authenticate('aaron', 'test').should be_nil
65
+ get "/<%= model_controller_plural_name %>/activate/1234"
66
+ controller.should redirect_to("/")
67
+ end
68
+
69
+ it 'does not activate <%= singular_name %> without key' do
70
+ get "/<%= model_controller_plural_name %>/activate"
71
+ controller.should be_missing
72
+ end
73
+ <% end -%>
74
+
75
+ def create_<%= singular_name %>(options = {})
76
+ post "/<%= model_controller_plural_name %>", :<%= singular_name %> => valid_<%= singular_name %>_hash.merge(options)
77
+ end
78
+ end
@@ -0,0 +1,357 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+ require File.join( File.dirname(__FILE__), "..", "<%= singular_name %>_spec_helper")
3
+ require File.join( File.dirname(__FILE__), "..", "authenticated_system_spec_helper")
4
+
5
+ describe <%= class_name %> do
6
+ include <%= class_name %>SpecHelper
7
+
8
+ before(:each) do
9
+ <%= class_name %>.clear_database_table
10
+ <% if include_activation -%>
11
+ <%= class_name %>Mailer.stub!(:activation_notification).and_return(true)
12
+ <% end -%>
13
+ end
14
+
15
+ it "should have a login field" do
16
+ <%= singular_name %> = <%= class_name %>.new
17
+ <%= singular_name %>.should respond_to(:login)
18
+ <%= singular_name %>.valid?
19
+ <%= singular_name %>.errors.on(:login).should_not be_nil
20
+ end
21
+
22
+ it "should fail login if there are less than 3 chars" do
23
+ <%= singular_name %> = <%= class_name %>.new
24
+ <%= singular_name %>.login = "AB"
25
+ <%= singular_name %>.valid?
26
+ <%= singular_name %>.errors.on(:login).should_not be_nil
27
+ end
28
+
29
+ it "should not fail login with between 3 and 40 chars" do
30
+ <%= singular_name %> = <%= class_name %>.new
31
+ [3,40].each do |num|
32
+ <%= singular_name %>.login = "a" * num
33
+ <%= singular_name %>.valid?
34
+ <%= singular_name %>.errors.on(:login).should be_nil
35
+ end
36
+ end
37
+
38
+ it "should fail login with over 90 chars" do
39
+ <%= singular_name %> = <%= class_name %>.new
40
+ <%= singular_name %>.login = "A" * 41
41
+ <%= singular_name %>.valid?
42
+ <%= singular_name %>.errors.on(:login).should_not be_nil
43
+ end
44
+
45
+ it "should make a valid <%= singular_name %>" do
46
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
47
+ <%= singular_name %>.save
48
+ <%= singular_name %>.errors.should be_empty
49
+
50
+ end
51
+
52
+ it "should make sure login is unique" do
53
+ <%= singular_name %> = <%= class_name %>.new( valid_<%= singular_name %>_hash.with(:login => "Daniel") )
54
+ <%= singular_name %>2 = <%= class_name %>.new( valid_<%= singular_name %>_hash.with(:login => "Daniel"))
55
+ <%= singular_name %>.save.should be_true
56
+ <%= singular_name %>.login = "Daniel"
57
+ <%= singular_name %>2.save.should be_false
58
+ <%= singular_name %>2.errors.on(:login).should_not be_nil
59
+ end
60
+
61
+ it "should make sure login is unique regardless of case" do
62
+ <%= class_name %>.find_with_conditions(:login => "Daniel").should be_nil
63
+ <%= singular_name %> = <%= class_name %>.new( valid_<%= singular_name %>_hash.with(:login => "Daniel") )
64
+ <%= singular_name %>2 = <%= class_name %>.new( valid_<%= singular_name %>_hash.with(:login => "daniel"))
65
+ <%= singular_name %>.save.should be_true
66
+ <%= singular_name %>.login = "Daniel"
67
+ <%= singular_name %>2.save.should be_false
68
+ <%= singular_name %>2.errors.on(:login).should_not be_nil
69
+ end
70
+
71
+ it "should downcase logins" do
72
+ <%= singular_name %> = <%= class_name %>.new( valid_<%= singular_name %>_hash.with(:login => "DaNieL"))
73
+ <%= singular_name %>.login.should == "daniel"
74
+ end
75
+
76
+ it "should authenticate a <%= singular_name %> using a class method" do
77
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
78
+ <%= singular_name %>.save
79
+ <% if include_activation -%>
80
+ <%= singular_name %>.activate
81
+ <% end -%>
82
+ <%= class_name %>.authenticate(valid_<%= singular_name %>_hash[:login], valid_<%= singular_name %>_hash[:password]).should_not be_nil
83
+ end
84
+
85
+ it "should not authenticate a <%= singular_name %> using the wrong password" do
86
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
87
+ <%= singular_name %>.save
88
+ <% if include_activation -%>
89
+ <%= singular_name %>.activate
90
+ <% end -%>
91
+ <%= class_name %>.authenticate(valid_<%= singular_name %>_hash[:login], "not_the_password").should be_nil
92
+ end
93
+
94
+ it "should not authenticate a <%= singular_name %> using the wrong login" do
95
+ <%= singular_name %> = <%= class_name %>.create(valid_<%= singular_name %>_hash)
96
+ <% if include_activation -%>
97
+ <%= singular_name %>.activate
98
+ <% end -%>
99
+ <%= class_name %>.authenticate("not_the_login", valid_<%= singular_name %>_hash[:password]).should be_nil
100
+ end
101
+
102
+ it "should not authenticate a <%= singular_name %> that does not exist" do
103
+ <%= class_name %>.authenticate("i_dont_exist", "password").should be_nil
104
+ end
105
+
106
+ <% if include_activation -%>
107
+ it "should send a please activate email" do
108
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
109
+ <%= class_name %>Mailer.should_receive(:dispatch_and_deliver) do |action, mail_args, mailer_params|
110
+ action.should == :signup_notification
111
+ [:from, :to, :subject].each{ |f| mail_args.keys.should include(f)}
112
+ mail_args[:to].should == <%= singular_name %>.email
113
+ mailer_params[:<%= singular_name %>].should == <%= singular_name %>
114
+ end
115
+ <%= singular_name %>.save
116
+ end
117
+
118
+ it "should not send a please activate email when updating" do
119
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
120
+ <%= singular_name %>.save
121
+ <%= class_name %>Mailer.should_not_receive(:signup_notification)
122
+ <%= singular_name %>.login = "not in the valid hash for login"
123
+ <%= singular_name %>.save
124
+ end
125
+ <% end -%>
126
+ end
127
+
128
+ describe <%= class_name %>, "the password fields for <%= class_name %>" do
129
+ include <%= class_name %>SpecHelper
130
+
131
+ before(:each) do
132
+ <%= class_name %>.clear_database_table
133
+ @<%= singular_name %> = <%= class_name %>.new( valid_<%= singular_name %>_hash )
134
+ <% if include_activation -%>
135
+ <%= class_name %>Mailer.stub!(:activation_notification).and_return(true)
136
+ <% end -%>
137
+ end
138
+
139
+ it "should respond to password" do
140
+ @<%= singular_name %>.should respond_to(:password)
141
+ end
142
+
143
+ it "should respond to password_confirmation" do
144
+ @<%= singular_name %>.should respond_to(:password_confirmation)
145
+ end
146
+
147
+ it "should have a protected password_required method" do
148
+ @<%= singular_name %>.protected_methods.should include("password_required?")
149
+ end
150
+
151
+ it "should respond to crypted_password" do
152
+ @<%= singular_name %>.should respond_to(:crypted_password)
153
+ end
154
+
155
+ it "should require password if password is required" do
156
+ <%= singular_name %> = <%= class_name %>.new( valid_<%= singular_name %>_hash.without(:password))
157
+ <%= singular_name %>.stub!(:password_required?).and_return(true)
158
+ <%= singular_name %>.valid?
159
+ <%= singular_name %>.errors.on(:password).should_not be_nil
160
+ <%= singular_name %>.errors.on(:password).should_not be_empty
161
+ end
162
+
163
+ it "should set the salt" do
164
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
165
+ <%= singular_name %>.salt.should be_nil
166
+ <%= singular_name %>.send(:encrypt_password)
167
+ <%= singular_name %>.salt.should_not be_nil
168
+ end
169
+
170
+ it "should require the password on create" do
171
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash.without(:password))
172
+ <%= singular_name %>.save
173
+ <%= singular_name %>.errors.on(:password).should_not be_nil
174
+ <%= singular_name %>.errors.on(:password).should_not be_empty
175
+ end
176
+
177
+ it "should require password_confirmation if the password_required?" do
178
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash.without(:password_confirmation))
179
+ <%= singular_name %>.save
180
+ (<%= singular_name %>.errors.on(:password) || <%= singular_name %>.errors.on(:password_confirmation)).should_not be_nil
181
+ end
182
+
183
+ it "should fail when password is outside 4 and 40 chars" do
184
+ [3,41].each do |num|
185
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash.with(:password => ("a" * num)))
186
+ <%= singular_name %>.valid?
187
+ <%= singular_name %>.errors.on(:password).should_not be_nil
188
+ end
189
+ end
190
+
191
+ it "should pass when password is within 4 and 40 chars" do
192
+ [4,30,40].each do |num|
193
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash.with(:password => ("a" * num), :password_confirmation => ("a" * num)))
194
+ <%= singular_name %>.valid?
195
+ <%= singular_name %>.errors.on(:password).should be_nil
196
+ end
197
+ end
198
+
199
+ it "should autenticate against a password" do
200
+ <%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
201
+ <%= singular_name %>.save
202
+ <%= singular_name %>.should be_authenticated(valid_<%= singular_name %>_hash[:password])
203
+ end
204
+
205
+ it "should not require a password when saving an existing <%= singular_name %>" do
206
+ <%= singular_name %> = <%= class_name %>.create(valid_<%= singular_name %>_hash)
207
+ <%= singular_name %> = <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login])
208
+ <%= singular_name %>.password.should be_nil
209
+ <%= singular_name %>.password_confirmation.should be_nil
210
+ <%= singular_name %>.login = "some_different_login_to_allow_saving"
211
+ (<%= singular_name %>.save).should be_true
212
+ end
213
+
214
+ end
215
+
216
+ <% if include_activation -%>
217
+ describe <%= class_name %>, "activation" do
218
+ include <%= class_name %>SpecHelper
219
+
220
+
221
+ before(:each) do
222
+ <%= class_name %>.clear_database_table
223
+ @<%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
224
+ end
225
+
226
+ it "should have an activation_code as an attribute" do
227
+ @<%= singular_name %>.attributes.keys.any?{|a| a.to_s == "activation_code"}.should_not be_nil
228
+ end
229
+
230
+ it "should create an activation code on create" do
231
+ @<%= singular_name %>.activation_code.should be_nil
232
+ @<%= singular_name %>.save
233
+ @<%= singular_name %>.activation_code.should_not be_nil
234
+ end
235
+
236
+ it "should not be active when created" do
237
+ @<%= singular_name %>.should_not be_activated
238
+ @<%= singular_name %>.save
239
+ @<%= singular_name %>.should_not be_activated
240
+ end
241
+
242
+ it "should respond to activate" do
243
+ @<%= singular_name %>.should respond_to(:activate)
244
+ end
245
+
246
+ it "should activate a <%= singular_name %> when activate is called" do
247
+ @<%= singular_name %>.should_not be_activated
248
+ @<%= singular_name %>.save
249
+ @<%= singular_name %>.activate
250
+ @<%= singular_name %>.should be_activated
251
+ <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login]).should be_activated
252
+ end
253
+
254
+ it "should should show recently activated when the instance is activated" do
255
+ @<%= singular_name %>.should_not be_recently_activated
256
+ @<%= singular_name %>.activate
257
+ @<%= singular_name %>.should be_recently_activated
258
+ end
259
+
260
+ it "should not show recently activated when the instance is fresh" do
261
+ @<%= singular_name %>.activate
262
+ @<%= singular_name %> = nil
263
+ <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login]).should_not be_recently_activated
264
+ end
265
+
266
+ it "should send out a welcome email to confirm that the account is activated" do
267
+ @<%= singular_name %>.save
268
+ <%= class_name %>Mailer.should_receive(:dispatch_and_deliver) do |action, mail_args, mailer_params|
269
+ action.should == :activation_notification
270
+ mail_args.keys.should include(:from)
271
+ mail_args.keys.should include(:to)
272
+ mail_args.keys.should include(:subject)
273
+ mail_args[:to].should == @<%= singular_name %>.email
274
+ mailer_params[:<%= singular_name %>].should == @<%= singular_name %>
275
+ end
276
+ @<%= singular_name %>.activate
277
+ end
278
+
279
+ end
280
+ <% end -%>
281
+
282
+ describe <%= class_name %>, "remember_me" do
283
+ include <%= class_name %>SpecHelper
284
+
285
+ predicate_matchers[:remember_token] = :remember_token?
286
+
287
+ before do
288
+ <%= class_name %>.clear_database_table
289
+ @<%= singular_name %> = <%= class_name %>.new(valid_<%= singular_name %>_hash)
290
+ end
291
+
292
+ it "should have a remember_token_expires_at attribute" do
293
+ @<%= singular_name %>.attributes.keys.any?{|a| a.to_s == "remember_token_expires_at"}.should_not be_nil
294
+ end
295
+
296
+ it "should respond to remember_token?" do
297
+ @<%= singular_name %>.should respond_to(:remember_token?)
298
+ end
299
+
300
+ it "should return true if remember_token_expires_at is set and is in the future" do
301
+ @<%= singular_name %>.remember_token_expires_at = DateTime.now + 3600
302
+ @<%= singular_name %>.should remember_token
303
+ end
304
+
305
+ it "should set remember_token_expires_at to a specific date" do
306
+ time = Time.mktime(2009,12,25)
307
+ @<%= singular_name %>.remember_me_until(time)
308
+ @<%= singular_name %>.remember_token_expires_at.should == time
309
+ end
310
+
311
+ it "should set the remember_me token when remembering" do
312
+ time = Time.mktime(2009,12,25)
313
+ @<%= singular_name %>.remember_me_until(time)
314
+ @<%= singular_name %>.remember_token.should_not be_nil
315
+ @<%= singular_name %>.save
316
+ <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login]).remember_token.should_not be_nil
317
+ end
318
+
319
+ it "should remember me for" do
320
+ t = Time.now
321
+ Time.stub!(:now).and_return(t)
322
+ today = Time.now
323
+ remember_until = today + (2* Merb::Const::WEEK)
324
+ @<%= singular_name %>.remember_me_for( Merb::Const::WEEK * 2)
325
+ @<%= singular_name %>.remember_token_expires_at.should == (remember_until)
326
+ end
327
+
328
+ it "should remember_me for two weeks" do
329
+ t = Time.now
330
+ Time.stub!(:now).and_return(t)
331
+ @<%= singular_name %>.remember_me
332
+ @<%= singular_name %>.remember_token_expires_at.should == (Time.now + (2 * Merb::Const::WEEK ))
333
+ end
334
+
335
+ it "should forget me" do
336
+ @<%= singular_name %>.remember_me
337
+ @<%= singular_name %>.save
338
+ @<%= singular_name %>.forget_me
339
+ @<%= singular_name %>.remember_token.should be_nil
340
+ @<%= singular_name %>.remember_token_expires_at.should be_nil
341
+ end
342
+
343
+ it "should persist the forget me to the database" do
344
+ @<%= singular_name %>.remember_me
345
+ @<%= singular_name %>.save
346
+
347
+ @<%= singular_name %> = <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login])
348
+ @<%= singular_name %>.remember_token.should_not be_nil
349
+
350
+ @<%= singular_name %>.forget_me
351
+
352
+ @<%= singular_name %> = <%= class_name %>.find_with_conditions(:login => valid_<%= singular_name %>_hash[:login])
353
+ @<%= singular_name %>.remember_token.should be_nil
354
+ @<%= singular_name %>.remember_token_expires_at.should be_nil
355
+ end
356
+
357
+ end