Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Specs for baked out functionality (redux) #51

Merged
merged 20 commits into from

2 participants

@christiannelson

No description provided.

@christiannelson christiannelson merged commit c62f473 into master
@christiannelson christiannelson deleted the features/improve_coverage branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 27, 2012
  1. @christiannelson
  2. @christiannelson

    Registration spec.

    christiannelson authored
  3. @christiannelson
  4. @christiannelson

    No empty specs needed.

    christiannelson authored
  5. @christiannelson
  6. @christiannelson
  7. @christiannelson

    Sign out helper.

    christiannelson authored
  8. @christiannelson
  9. @christiannelson
  10. @christiannelson

    Comment tweaks

    christiannelson authored
  11. @squanto @christiannelson

    Add activation acceptance coverage

    squanto authored christiannelson committed
  12. @squanto @christiannelson

    Add unsuccessful registration acceptance coverage

    squanto authored christiannelson committed
  13. @squanto @christiannelson

    Fix authorization for password reset controller.

    squanto authored christiannelson committed
  14. @christiannelson
  15. @christiannelson
  16. @christiannelson

    Finishing touches on specs:

    christiannelson authored
    - Better spec descriptions
    - Use path/url helpers in feature specs
    - Rename routes
  17. @christiannelson
  18. @christiannelson
  19. @christiannelson
  20. @christiannelson

    Update the change log.

    christiannelson authored
This page is out of date. Refresh to see the latest.
Showing with 273 additions and 171 deletions.
  1. +5 −2 CHANGES.md
  2. +3 −0  app_prototype/Gemfile
  3. +6 −8 app_prototype/app/controllers/password_resets_controller.rb
  4. +1 −1  app_prototype/app/controllers/registrations_controller.rb
  5. +5 −2 app_prototype/app/models/user.rb
  6. +1 −1  app_prototype/app/views/layouts/application.html.slim
  7. +2 −3 app_prototype/app/views/password_resets/edit.html.slim
  8. +2 −2 app_prototype/app/views/password_resets/new.html.slim
  9. +1 −2  app_prototype/app/views/registrations/new.html.slim
  10. +1 −1  app_prototype/app/views/user_mailer/activation_needed_email.html.erb
  11. +1 −1  app_prototype/app/views/user_mailer/activation_needed_email.text.erb
  12. +1 −1  app_prototype/app/views/user_mailer/reset_password_email.html.erb
  13. +1 −1  app_prototype/app/views/user_mailer/reset_password_email.text.erb
  14. +2 −2 app_prototype/app/views/user_sessions/new.html.slim
  15. +1 −1  app_prototype/app/views/users/show.html.slim
  16. +1 −0  app_prototype/config/application.rb
  17. +11 −0 app_prototype/config/initializers/email.rb
  18. +9 −5 app_prototype/config/routes.rb
  19. +21 −21 app_prototype/lib/templates/rspec/scaffold/controller_spec.rb
  20. +2 −2 app_prototype/public/index.html
  21. +7 −7 app_prototype/spec/controllers/user_sessions_controller_spec.rb
  22. +22 −22 app_prototype/spec/controllers/users_controller_spec.rb
  23. +2 −0  app_prototype/spec/factories/users.rb
  24. +18 −0 app_prototype/spec/features/activation_spec.rb
  25. +41 −0 app_prototype/spec/features/password_reset_spec.rb
  26. +39 −0 app_prototype/spec/features/registration_spec.rb
  27. +0 −10 app_prototype/spec/features/registrations_spec.rb
  28. +30 −0 app_prototype/spec/features/sign_in_spec.rb
  29. +0 −32 app_prototype/spec/features/user_sessions_spec.rb
  30. +0 −15 app_prototype/spec/helpers/users_helper_spec.rb
  31. +15 −15 app_prototype/spec/mailers/user_mailer_spec.rb
  32. +13 −6 app_prototype/spec/models/user_spec.rb
  33. +5 −0 app_prototype/spec/spec_helper.rb
  34. +2 −2 app_prototype/spec/support/user_sessions_feature_helper.rb
  35. +0 −1  app_prototype/spec/views/users/edit.html.slim_spec.rb
  36. +0 −1  app_prototype/spec/views/users/index.html.slim_spec.rb
  37. +0 −1  app_prototype/spec/views/users/new.html.slim_spec.rb
  38. +2 −3 app_prototype/spec/views/users/show.html.slim_spec.rb
View
7 CHANGES.md
@@ -5,5 +5,8 @@
* Basic usage information.
* Added guard-livereload to Guardfile.
* Gemfile, rvmrc, rbenv files configured with the ruby version used to generate the app.
-* Better specs for auth flows (register, password reset, sign in).
-* Hardcode 1.9.3-p327 so that app_prototype is executable without futzing.
+* Better specs for auth flows (register, password reset, sign in) (~98% coverage).
+* Use the new rspec expect(...).to syntax ([more info](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax)).
+* Hardcode 1.9.3-p327 so that app_prototype is executable without futzing.
+* Consistent hostnames across environments.
+* Use mailcatcher when it's running locally ([more info](http://www.mikeperham.com/2012/12/09/12-gems-of-christmas-4-mailcatcher-and-mail_view/)).
View
3  app_prototype/Gemfile
@@ -26,6 +26,7 @@ end
group :test, :development do
gem 'rspec-rails', '~> 2.12.0'
gem 'capybara', github: 'jnicklas/capybara' # Switch from github once issue #882 is resolved.
+ gem 'capybara-email'
gem 'factory_girl_rails'
gem 'jasminerice'
gem 'timecop'
@@ -34,6 +35,8 @@ end
group :development do
gem 'foreman'
+ gem 'launchy'
+ gem 'mailcatcher'
gem 'guard'
gem 'guard-rspec'
gem 'guard-jasmine'
View
14 app_prototype/app/controllers/password_resets_controller.rb
@@ -1,32 +1,30 @@
class PasswordResetsController < ApplicationController
skip_before_filter :require_login
+ skip_authorization_check
def create
@user = User.find_by_email(params[:email])
-
+
# Send an email to the user with instructions on how to reset their password.
@user.deliver_reset_password_instructions! if @user
-
+
# Tell the user instructions have been sent whether or not email was found.
# This is to not leak information to attackers about which emails exist in the system.
redirect_to sign_in_path, notice: "Password reset instructions have been sent to your email."
end
def edit
- @user = User.load_from_reset_password_token(params[:id])
- @token = params[:id]
+ @token = params[:token]
+ @user = User.load_from_reset_password_token(@token)
not_authenticated if !@user
end
-
+
def update
@token = params[:token] # needed to render the form again in case of error
@user = User.load_from_reset_password_token(@token)
not_authenticated if !@user
- # Makes the password confirmation validation work.
- @user.password_confirmation = params[:user][:password_confirmation]
-
# Clear the temporary token and update the password.
if @user.change_password!(params[:user][:password])
redirect_to sign_in_path, notice: "Password was successfully updated."
View
2  app_prototype/app/controllers/registrations_controller.rb
@@ -7,7 +7,7 @@ def new
end
def create
- @user = User.new(params[:user])
+ @user = User.new(params[:user]) # TODO Safe attributes
if @user.save
redirect_to sign_in_path, notice: "Thanks for signing up. Please check your email for activation instructions."
View
7 app_prototype/app/models/user.rb
@@ -4,14 +4,17 @@ class User < ActiveRecord::Base
authenticates_with_sorcery!
+ validates :name,
+ length: { maximum: 30 }
+
validates :email,
presence: true,
- email: true
+ email: true,
+ uniqueness: true
validates :password,
presence: true,
length: { minimum: 6 },
- confirmation: true,
if: :password
end
View
2  app_prototype/app/views/layouts/application.html.slim
@@ -22,7 +22,7 @@ html
ul.dropdown-menu
li= link_to 'Sign Out', sign_out_path
- else
- li= link_to 'Sign in', sign_in_path
+ li= link_to 'Sign In', sign_in_path
- flash.each do |name, msg|
= content_tag :div, raw(msg), class: "alert #{alert_class(name)}"
View
5 app_prototype/app/views/password_resets/edit.html.slim
@@ -1,13 +1,12 @@
.page-header
h1 Reset Your Password
-= simple_form_for(@user, url: password_reset_path(@user)) do |f|
+= simple_form_for(@user, url: reset_password_path(@user)) do |f|
= f.error_notification
.form-inputs
= f.input :email, disabled: true
- = f.input :password, required: true, autofocus: true
- = f.input :password_confirmation, required: true
+ = f.input :password, label: 'New Password', required: true, autofocus: true
= hidden_field_tag :token, @token
.form-actions
View
4 app_prototype/app/views/password_resets/new.html.slim
@@ -1,11 +1,11 @@
.page-header
h1 Password Reset
-= form_tag(password_resets_path, method: :post) do
+= form_tag(forgotten_password_path, method: :post) do
.control-group
= label_tag :email, nil, class: 'control-label'
.controls
= text_field_tag :email, nil, placeholder: 'joe@example.com'
.form-actions
- = submit_tag "Reset my password!", class: 'btn btn-primary'
+ = submit_tag 'Reset My Password', class: 'btn btn-primary'
View
3  app_prototype/app/views/registrations/new.html.slim
@@ -8,7 +8,6 @@
= f.input :name, autofocus: true
= f.input :email
= f.input :password
- = f.input :password_confirmation
.form-actions
- = f.button :submit, 'Sign up', class: 'btn btn-primary'
+ = f.button :submit, 'Sign Up', class: 'btn btn-primary'
View
2  app_prototype/app/views/user_mailer/activation_needed_email.html.erb
@@ -10,7 +10,7 @@
your username is: <%= @user.email %>.<br/>
</p>
<p>
- To login to the site, just follow this link: <%= link_to activate_registration_url(@user.activation_token), activate_registration_url(@user.activation_token) %>.
+ To login to the site, just follow this link: <%= link_to activation_url(@user.activation_token), activation_url(@user.activation_token) %>.
</p>
<p>Thanks for joining and have a great day!</p>
</body>
View
2  app_prototype/app/views/user_mailer/activation_needed_email.text.erb
@@ -4,6 +4,6 @@ Welcome to example.com, <%= @user.email %>
You have successfully signed up to example.com,
your username is: <%= @user.email %>.
-To login to the site, just follow this link: <%= activate_registration_url(@user.activation_token) %>
+To login to the site, just follow this link: <%= activation_url(@user.activation_token) %>
Thanks for joining and have a great day!
View
2  app_prototype/app/views/user_mailer/reset_password_email.html.erb
@@ -9,7 +9,7 @@
You have requested to reset your password.
</p>
<p>
- To choose a new password, just follow this link: <%= link_to edit_password_reset_url(@user.reset_password_token), edit_password_reset_url(@user.reset_password_token) %>.
+ To choose a new password, just follow this link: <%= link_to reset_password_url(@user.reset_password_token), reset_password_url(@user.reset_password_token) %>.
</p>
<p>Have a great day!</p>
</body>
View
2  app_prototype/app/views/user_mailer/reset_password_email.text.erb
@@ -3,6 +3,6 @@ Hello, <%= @user.email %>
You have requested to reset your password.
-To choose a new password, just follow this link: edit_password_reset_url(@user.reset_password_token)
+To choose a new password, just follow this link: <%= reset_password_url(@user.reset_password_token) %>
Have a great day!
View
4 app_prototype/app/views/user_sessions/new.html.slim
@@ -6,8 +6,8 @@
= f.input :password
ul.unstyled
- li= link_to 'Sign up', sign_up_path
- li= link_to 'Reset forgotten password', new_password_reset_path
+ li= link_to 'Sign Up', sign_up_path
+ li= link_to 'Reset Password', forgotten_password_path
.form-actions
= f.button :submit, 'Sign In', class: 'btn btn-primary'
View
2  app_prototype/app/views/users/show.html.slim
@@ -14,4 +14,4 @@ dl
- if can?(:destroy, @user)
'
- = link_to'Destroy', user_path(@user), method: :delete, data: { confirm: "Are you sure?" }, class: 'btn btn-danger'
+ = link_to 'Destroy', user_path(@user), method: :delete, data: { confirm: "Are you sure?" }, class: 'btn btn-danger'
View
1  app_prototype/config/application.rb
@@ -22,6 +22,7 @@ class Application < Rails::Application
#generate.helper false
generate.routing_specs false
#generate.view_specs false
+ generate.request_specs false
end
# Settings in config/environments/* take precedence over those specified here.
View
11 app_prototype/config/initializers/email.rb
@@ -0,0 +1,11 @@
+# http://www.mikeperham.com/2012/12/09/12-gems-of-christmas-4-mailcatcher-and-mail_view/
+
+begin
+ sock = TCPSocket.new('localhost', 1025)
+ sock.close
+ catcher = true
+rescue
+ catcher = false
+end
+
+ActionMailer::Base.smtp_settings = (Rails.env.development? && catcher) ? { host: 'localhost', port: '1025', } : {}
View
14 app_prototype/config/routes.rb
@@ -5,12 +5,16 @@
resources :user_sessions, only: [:new, :create, :destroy]
- resources :registrations, only: [:new, :create, :activate]
- match 'sign_up' => 'registrations#new', via: :get
- match 'sign_up' => 'registrations#create', via: :post
- match 'sign_up/:token/activate' => 'registrations#activate', via: :get, as: :activate_registration
+ #resources :registrations, only: [:new, :create, :activate]
+ match 'sign_up' => 'registrations#new', via: :get, as: :sign_up
+ match 'sign_up' => 'registrations#create', via: :post, as: :sign_up
+ match 'activate/:token' => 'registrations#activate', via: :get, as: :activation
- resources :password_resets, only: [:new, :create, :edit, :update]
+ #resources :password_resets, only: [:new, :create, :edit, :update]
+ match 'forgotten_password' => 'password_resets#new', via: :get, as: :forgotten_password
+ match 'forgotten_password' => 'password_resets#create', via: :post, as: :forgotten_password
+ match 'reset_password/:token' => 'password_resets#edit', via: :get, as: :reset_password
+ match 'reset_password/:id' => 'password_resets#update', via: :put
resources :users
View
42 app_prototype/lib/templates/rspec/scaffold/controller_spec.rb
@@ -22,39 +22,39 @@ def valid_session
end
<% unless options[:singleton] -%>
- describe "GET index" do
+ describe "#index" do
it "assigns all <%= table_name.pluralize %> as @<%= table_name.pluralize %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
get :index, {}, valid_session
- assigns(:<%= table_name %>).should eq([<%= file_name %>])
+ expect(assigns(:<%= table_name %>)).to eq([<%= file_name %>])
end
end
<% end -%>
- describe "GET show" do
+ describe "#show" do
it "assigns the requested <%= ns_file_name %> as @<%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
get :show, { :id => <%= file_name %>.to_param }, valid_session
- assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to eq(<%= file_name %>)
end
end
- describe "GET new" do
+ describe "#new" do
it "assigns a new <%= ns_file_name %> as @<%= ns_file_name %>" do
get :new, {}, valid_session
- assigns(:<%= ns_file_name %>).should be_a_new(<%= class_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to be_a_new(<%= class_name %>)
end
end
- describe "GET edit" do
+ describe "#edit" do
it "assigns the requested <%= ns_file_name %> as @<%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
get :edit, { :id => <%= file_name %>.to_param }, valid_session
- assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to eq(<%= file_name %>)
end
end
- describe "POST create" do
+ describe "#create" do
describe "with valid params" do
it "creates a new <%= class_name %>" do
expect {
@@ -64,13 +64,13 @@ def valid_session
it "assigns a newly created <%= ns_file_name %> as @<%= ns_file_name %>" do
post :create, {:<%= ns_file_name %> => valid_attributes }, valid_session
- assigns(:<%= ns_file_name %>).should be_a(<%= class_name %>)
- assigns(:<%= ns_file_name %>).should be_persisted
+ expect(assigns(:<%= ns_file_name %>)).to be_a(<%= class_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to be_persisted
end
it "redirects to the created <%= ns_file_name %>" do
post :create, { :<%= ns_file_name %> => valid_attributes }, valid_session
- response.should redirect_to(<%= class_name %>.last)
+ expect(response).to redirect_to(<%= class_name %>.last)
end
end
@@ -79,19 +79,19 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
<%= class_name %>.any_instance.stub(:save).and_return(false)
post :create, { :<%= ns_file_name %> => <%= formatted_hash(example_invalid_attributes) %> }, valid_session
- assigns(:<%= ns_file_name %>).should be_a_new(<%= class_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to be_a_new(<%= class_name %>)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
<%= class_name %>.any_instance.stub(:save).and_return(false)
post :create, { :<%= ns_file_name %> => <%= formatted_hash(example_invalid_attributes) %> }, valid_session
- response.should render_template("new")
+ expect(response).to render_template("new")
end
end
end
- describe "PUT update" do
+ describe "#update" do
describe "with valid params" do
it "updates the requested <%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
@@ -106,13 +106,13 @@ def valid_session
it "assigns the requested <%= ns_file_name %> as @<%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
put :update, { :id => <%= file_name %>.to_param, :<%= ns_file_name %> => valid_attributes }, valid_session
- assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to eq(<%= file_name %>)
end
it "redirects to the <%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
put :update, { :id => <%= file_name %>.to_param, :<%= ns_file_name %> => valid_attributes }, valid_session
- response.should redirect_to(<%= file_name %>)
+ expect(response).to redirect_to(<%= file_name %>)
end
end
@@ -122,7 +122,7 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
<%= class_name %>.any_instance.stub(:save).and_return(false)
put :update, { :id => <%= file_name %>.to_param, :<%= ns_file_name %> => <%= formatted_hash(example_invalid_attributes) %> }, valid_session
- assigns(:<%= ns_file_name %>).should eq(<%= file_name %>)
+ expect(assigns(:<%= ns_file_name %>)).to eq(<%= file_name %>)
end
it "re-renders the 'edit' template" do
@@ -130,12 +130,12 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
<%= class_name %>.any_instance.stub(:save).and_return(false)
put :update, { :id => <%= file_name %>.to_param, :<%= ns_file_name %> => <%= formatted_hash(example_invalid_attributes) %> }, valid_session
- response.should render_template("edit")
+ expect(response).to render_template("edit")
end
end
end
- describe "DELETE destroy" do
+ describe "#destroy" do
it "destroys the requested <%= ns_file_name %>" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
expect {
@@ -146,7 +146,7 @@ def valid_session
it "redirects to the <%= table_name %> list" do
<%= file_name %> = <%= class_name %>.create! valid_attributes
delete :destroy, { :id => <%= file_name %>.to_param }, valid_session
- response.should redirect_to(<%= index_helper %>_url)
+ expect(response).to redirect_to(<%= index_helper %>_url)
end
end
View
4 app_prototype/public/index.html
@@ -15,7 +15,7 @@
<div class="container">
<div class="brand">Project_prototype</div>
<ul class="nav pull-right">
- <li><a href="/sign_in">Sign in</a></li>
+ <li><a href="/sign_in">Sign In</a></li>
</ul>
</div>
</nav>
@@ -29,7 +29,7 @@
<p>Custom generator templates create views that are bootstrap compatible and specs that are factory-aware and follow best practices.</p>
<p>This application also includes authentication and an example of authorization (sign in as user@example.com / password).</p>
- <p><a class="btn btn-primary btn-large" href="sign_in">Sign in</a></p>
+ <p><a class="btn btn-primary btn-large" href="sign_in">Sign In</a></p>
</div>
</div>
<div class="push"></div>
View
14 app_prototype/spec/controllers/user_sessions_controller_spec.rb
@@ -2,19 +2,19 @@
describe UserSessionsController do
- describe "GET new" do
+ describe "#new" do
it "assigns a new user as @user" do
get :new
- assigns(:user_session).should_not be_nil
+ expect(assigns(:user_session)).to_not be_nil
end
end
- describe "POST create" do
+ describe "#create" do
describe "with valid params" do
it "redirect to the target page" do
subject.stub(:login) { build_stubbed :user }
post :create, { user_session: { email: 'valid', password: 'valid' } }, { return_to_url: 'url' }
- response.should redirect_to('url')
+ expect(response).to redirect_to('url')
end
end
@@ -22,12 +22,12 @@
it "re-renders the 'new' template" do
subject.stub(:login) { nil }
post :create, { user_session: { email: 'invalid', password: 'invalid' } }
- response.should render_template('new')
+ expect(response).to render_template('new')
end
end
end
- describe "DELETE destroy" do
+ describe "#destroy" do
it "destroys the requested user session" do
subject.should_receive(:logout)
delete :destroy
@@ -35,7 +35,7 @@
it "redirects to the sign in page" do
delete :destroy
- response.should redirect_to(sign_in_url)
+ expect(response).to redirect_to(sign_in_url)
end
end
View
44 app_prototype/spec/controllers/users_controller_spec.rb
@@ -9,7 +9,7 @@ def valid_attributes
attributes_for :user
end
- # This should return the minimal set of values that should be in the session
+ # This returns the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# UsersController. Be sure to keep this updated too.
def valid_session
@@ -20,38 +20,38 @@ def valid_session
login_user build :admin
end
- describe "GET index" do
+ describe "#index" do
it "assigns all users as @users" do
user = User.create! valid_attributes
get :index, {}, valid_session
- assigns(:users).should eq([user])
+ expect(assigns(:users)).to eq([user])
end
end
- describe "GET show" do
+ describe "#show" do
it "assigns the requested user as @user" do
user = User.create! valid_attributes
get :show, { id: user.to_param }, valid_session
- assigns(:user).should eq(user)
+ expect(assigns(:user)).to eq(user)
end
end
- describe "GET new" do
+ describe "#new" do
it "assigns a new user as @user" do
get :new, {}, valid_session
- assigns(:user).should be_a_new(User)
+ expect(assigns(:user)).to be_a_new(User)
end
end
- describe "GET edit" do
+ describe "#edit" do
it "assigns the requested user as @user" do
user = User.create! valid_attributes
get :edit, { id: user.to_param }, valid_session
- assigns(:user).should eq(user)
+ expect(assigns(:user)).to eq(user)
end
end
- describe "POST create" do
+ describe "#create" do
describe "with valid params" do
it "creates a new User" do
expect {
@@ -61,13 +61,13 @@ def valid_session
it "assigns a newly created user as @user" do
post :create, {user: valid_attributes }, valid_session
- assigns(:user).should be_a(User)
- assigns(:user).should be_persisted
+ expect(assigns(:user)).to be_a(User)
+ expect(assigns(:user)).to be_persisted
end
it "redirects to the created user" do
post :create, { user: valid_attributes }, valid_session
- response.should redirect_to(User.last)
+ expect(response).to redirect_to(User.last)
end
end
@@ -76,19 +76,19 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:save).and_return(false)
post :create, { user: { "email" => "invalid value" } }, valid_session
- assigns(:user).should be_a_new(User)
+ expect(assigns(:user)).to be_a_new(User)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:save).and_return(false)
post :create, { user: { "email" => "invalid value" } }, valid_session
- response.should render_template("new")
+ expect(response).to render_template("new")
end
end
end
- describe "PUT update" do
+ describe "#update" do
describe "with valid params" do
it "updates the requested user" do
user = User.create! valid_attributes
@@ -103,13 +103,13 @@ def valid_session
it "assigns the requested user as @user" do
user = User.create! valid_attributes
put :update, { id: user.to_param, user: valid_attributes }, valid_session
- assigns(:user).should eq(user)
+ expect(assigns(:user)).to eq(user)
end
it "redirects to the user" do
user = User.create! valid_attributes
put :update, { id: user.to_param, user: valid_attributes }, valid_session
- response.should redirect_to(user)
+ expect(response).to redirect_to(user)
end
end
@@ -119,7 +119,7 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:save).and_return(false)
put :update, { id: user.to_param, user: { "email" => "invalid value" } }, valid_session
- assigns(:user).should eq(user)
+ expect(assigns(:user)).to eq(user)
end
it "re-renders the 'edit' template" do
@@ -127,12 +127,12 @@ def valid_session
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:save).and_return(false)
put :update, { id: user.to_param, user: { "email" => "invalid value" } }, valid_session
- response.should render_template("edit")
+ expect(response).to render_template("edit")
end
end
end
- describe "DELETE destroy" do
+ describe "#destroy" do
it "destroys the requested user" do
user = User.create! valid_attributes
expect {
@@ -143,7 +143,7 @@ def valid_session
it "redirects to the users list" do
user = User.create! valid_attributes
delete :destroy, { id: user.to_param }, valid_session
- response.should redirect_to(users_url)
+ expect(response).to redirect_to(users_url)
end
end
View
2  app_prototype/spec/factories/users.rb
@@ -1,3 +1,5 @@
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
FactoryGirl.define do
factory :user do
sequence(:email) { |n| "person#{n}@example.com" }
View
18 app_prototype/spec/features/activation_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+feature "Activation" do
+ scenario "with a valid token should activate the user and sign them in" do
+ @user = create(:user)
+ visit activation_path(@user.activation_token)
+
+ expect(current_path).to eq sign_in_path
+ expect(page).to have_content "Your account has been activated and you're now signed in."
+ end
+
+ scenario "with an invalid token should send the user to sign in" do
+ visit activation_path('BOGUS')
+
+ expect(current_path).to eq sign_in_path
+ expect(page).to have_content "Please sign in first."
+ end
+end
View
41 app_prototype/spec/features/password_reset_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+feature "Password Reset" do
+ background do
+ clear_emails
+ @user = create(:user)
+ @user.activate!
+
+ visit sign_in_path
+ click_link 'Reset Password'
+
+ fill_in 'Email', with: @user.email
+ click_button 'Reset My Password'
+
+ @user.reload
+ end
+
+ after do
+ @user.destroy
+ end
+
+ scenario "displays a message about the password reset email" do
+ expect(page).to have_content "Password reset instructions have been sent to your email."
+ expect(current_path).to eq sign_in_path
+ end
+
+ scenario "sends a password reset email with url" do
+ expect(open_email(@user.email)).to_not be_nil
+ expect(current_email).to have_content reset_password_path(@user.reset_password_token)
+ end
+
+ scenario "resets the password" do
+ visit reset_password_path(@user.reset_password_token)
+
+ fill_in 'New Password', with: 'som3_g00d_p@ssword'
+ click_button 'Reset Password'
+
+ expect(page).to have_content "Password was successfully updated."
+ expect(current_path).to eq sign_in_path
+ end
+end
View
39 app_prototype/spec/features/registration_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+# http://www.elabs.se/blog/51-simple-tricks-to-clean-up-your-capybara-tests
+
+feature "Registration" do
+ background do
+ clear_emails
+
+ @email = 'stan@example.com'
+
+ visit sign_up_path
+
+ within '#new_user' do
+ fill_in 'Email', with: @email
+ fill_in 'Name', with: 'Stan'
+ fill_in 'Password', with: 'p@ssword'
+ click_button 'Sign Up'
+ end
+
+ @user = User.find_by_email(@email)
+ end
+
+ after do
+ @user.destroy
+ end
+
+ it "creates a new user" do
+ expect(@user).to_not be_nil
+ end
+
+ it "displays a message about activation" do
+ expect(find('.alert')).to have_content "Thanks for signing up. Please check your email for activation instructions."
+ end
+
+ it "sends the activation email with url" do
+ expect(open_email(@email)).to_not be_nil
+ expect(current_email).to have_content activation_path(@user.activation_token)
+ end
+end
View
10 app_prototype/spec/features/registrations_spec.rb
@@ -1,10 +0,0 @@
-require 'spec_helper'
-
-# http://www.elabs.se/blog/51-simple-tricks-to-clean-up-your-capybara-tests
-
-feature "Registrations" do
-
- scenario "sign up" do
- visit sign_up_path
- end
-end
View
30 app_prototype/spec/features/sign_in_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+feature "Sign In" do
+ background(:all) do
+ @user = create(:user)
+ @user.activate!
+ end
+
+ after(:all) do
+ @user.destroy
+ end
+
+ scenario "authenticates with valid credentials" do
+ sign_in(@user.email, 'password')
+
+ expect(find('.alert')).to have_content("Successfully signed in")
+ end
+
+ scenario "displays a generic error message with an invalid email" do
+ sign_in('this is not valid', 'password')
+
+ expect(find('.alert')).to have_content("Sign in failed")
+ end
+
+ scenario "displays a generic error message with an invalid password" do
+ sign_in(@user.email, 'this is not valid')
+
+ expect(find('.alert')).to have_content("Sign in failed")
+ end
+end
View
32 app_prototype/spec/features/user_sessions_spec.rb
@@ -1,32 +0,0 @@
-require 'spec_helper'
-
-feature "User Sessions" do
-
- background(:all) do
- @user = create(:user)
- @user.activate!
- end
-
- after(:all) do
- @user.destroy
- end
-
- scenario "Sign in with valid credentials" do
- sign_in(@user.email, 'password')
-
- find('.alert').should have_content("Successfully signed in")
- end
-
- scenario "Sign in with an invalid email" do
- sign_in('this is not valid', 'password')
-
- find('.alert').should have_content("Sign in failed")
- end
-
- scenario "Sign in with an invalid password" do
- sign_in(@user.email, 'this is not valid')
-
- find('.alert').should have_content("Sign in failed")
- end
-
-end
View
15 app_prototype/spec/helpers/users_helper_spec.rb
@@ -1,15 +0,0 @@
-require 'spec_helper'
-
-# Specs in this file have access to a helper object that includes
-# the UsersHelper. For example:
-#
-# describe UsersHelper do
-# describe "string concat" do
-# it "concats two strings with spaces" do
-# helper.concat_strings("this","that").should == "this that"
-# end
-# end
-# end
-describe UsersHelper do
- pending "add some examples to (or delete) #{__FILE__}"
-end
View
30 app_prototype/spec/mailers/user_mailer_spec.rb
@@ -3,45 +3,45 @@
describe UserMailer do
let(:user) { build_stubbed(:user, activation_state: 'pending', activation_token: 'ABC', reset_password_token: 'XYZ') }
- describe "activation_needed_email" do
+ describe "#activation_needed_email" do
let(:mail) { UserMailer.activation_needed_email(user) }
it "renders the headers" do
- mail.subject.should eq("Welcome to My Awesome Site!")
- mail.to.should eq([user.email])
- mail.from.should eq(['notifications@example.com'])
+ expect(mail.subject).to eq "Welcome to My Awesome Site!"
+ expect(mail.to).to eq [user.email]
+ expect(mail.from).to eq %w(notifications@example.com)
end
it "renders the body" do
- mail.body.encoded.should match("Welcome to")
+ expect(mail.body.encoded).to match "Welcome to"
end
end
- describe "activation_success_email" do
+ describe "#activation_success_email" do
let(:mail) { UserMailer.activation_success_email(user) }
it "renders the headers" do
- mail.subject.should eq("Your account has been activated!")
- mail.to.should eq([user.email])
- mail.from.should eq(['notifications@example.com'])
+ expect(mail.subject).to eq "Your account has been activated!"
+ expect(mail.to).to eq [user.email]
+ expect(mail.from).to eq %w(notifications@example.com)
end
it "renders the body" do
- mail.body.encoded.should match("You have successfully activated")
+ expect(mail.body.encoded).to match "You have successfully activated"
end
end
- describe "reset_password_email" do
+ describe "#reset_password_email" do
let(:mail) { UserMailer.reset_password_email(user) }
it "renders the headers" do
- mail.subject.should eq("Password reset requested")
- mail.to.should eq([user.email])
- mail.from.should eq(['notifications@example.com'])
+ expect(mail.subject).to eq "Password reset requested"
+ expect(mail.to).to eq [user.email]
+ expect(mail.from).to eq %w(notifications@example.com)
end
it "renders the body" do
- mail.body.encoded.should match("You have requested to reset your password.")
+ expect(mail.body.encoded).to match "You have requested to reset your password."
end
end
View
19 app_prototype/spec/models/user_spec.rb
@@ -7,23 +7,30 @@
describe "name" do
it "is required" do
- subject.should_not accept_values(:email, nil, '')
+ expect(subject).to_not accept_values(:email, nil, '')
end
- it "should be less than 30 characters"
+ it "should be less than 30 characters" do
+ expect(subject).to accept_values(:name, 'a' * 30)
+ expect(subject).to_not accept_values(:name, 'a' * 31)
+ end
end
describe "email" do
it "is required" do
- subject.should_not accept_values(:email, nil, '', ' ')
+ expect(subject).to_not accept_values(:email, nil, '', ' ')
end
it "must be properly formatted" do
- subject.should accept_values(:email, 'a@b.com', 'a@b.c.com')
- subject.should_not accept_values(:email, 'a@b', 'a.b.com')
+ expect(subject).to accept_values(:email, 'a@b.com', 'a@b.c.com')
+ expect(subject).to_not accept_values(:email, 'a@b', 'a.b.com')
end
- it "must be unique"
+ it "must be unique" do
+ subject.save
+ stunt_double = subject.dup
+ expect(stunt_double).to_not accept_values(:email, subject.email)
+ end
end
end
end
View
5 app_prototype/spec/spec_helper.rb
@@ -29,6 +29,7 @@ def format(result)
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
+require 'capybara/email/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
@@ -48,6 +49,10 @@ def format(result)
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
View
4 app_prototype/spec/support/user_sessions_feature_helper.rb
@@ -10,8 +10,8 @@ def sign_in(email, password)
end
end
- def sign_out(user = @current_user)
- # TODO
+ def sign_out
+ visit sign_out_path
end
end
View
1  app_prototype/spec/views/users/edit.html.slim_spec.rb
@@ -11,7 +11,6 @@
it "renders the edit user form" do
render
- # Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", action: users_path(@user), method: "post" do
assert_select "input#user_email", name: "user[email]"
assert_select "input#user_name", name: "user[name]"
View
1  app_prototype/spec/views/users/index.html.slim_spec.rb
@@ -16,7 +16,6 @@
it "renders a list of users" do
render
- # Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "tr>td", text: "Email".to_s, count: 2
assert_select "tr>td", text: "Name".to_s, count: 2
end
View
1  app_prototype/spec/views/users/new.html.slim_spec.rb
@@ -11,7 +11,6 @@
it "renders new user form" do
render
- # Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", action: users_path, method: "post" do
assert_select "input#user_email", name: "user[email]"
assert_select "input#user_name", name: "user[name]"
View
5 app_prototype/spec/views/users/show.html.slim_spec.rb
@@ -10,8 +10,7 @@
it "renders attributes in <p>" do
render
- # Run the generator again with the --webrat flag if you want to use webrat matchers
- rendered.should match(/Email/)
- rendered.should match(/Name/)
+ expect(rendered).to match /Email/
+ expect(rendered).to match /Name/
end
end
Something went wrong with that request. Please try again.