Table of Contents
Test model with Sorcery authentication
See ActivityLogger application
To pass the tests, in views use
Evaluate 'current_user' to avoid “undefined method `admin?' for nil:NilClass”
if current_user && current_user.admin?
user_spec.rb
require 'rails_helper'
describe "Integration test", type: :feature do
before(:each) do
admin = FactoryGirl.create(:user_admin)
login_user_post(admin.email, "123")
end
it "signs me in" do
expect(page).to have_content 'You are being redirected'
end
context "when checking validations" do
it "rejects without name" do
user = FactoryGirl.build :user, name: ""
expect(user.valid?).to be false
expect(user.errors["name"].present?).to be true
end
...
FactoryGirl
FactoryGirl.define do
factory :user do
factory :user_admin do
name {Faker::Name.name}
email {Faker::Internet.email}
admin {true}
password {"123"}
password_confirmation {"123"}
end
end
end
spec/support/sorcery.rb
module Sorcery
module TestHelpers
module Rails
module Integration
def login_user_post(email, password)
page.driver.post(user_sessions_url, { email: email, password: password } )
end
end
end
end
end
spec_helper.rb
config.include Sorcery::TestHelpers::Rails::Controller, type: :controller config.include Sorcery::TestHelpers::Rails::Integration, type: :feature
Speed up tests changing encryption algorithm to md5
Rails.application.config.sorcery.configure do |config|
config.user_config do |user|
user.encryption_algorithm = :md5 if Rails.env.test?
end
end
Testing forms with multiple parameters
Application: SAAP
# gates_controller_spec.rb
describe "POST add loop" do
it "adds a loop to the gate" do
gate = Gate.create! valid_attributes
loop = FactoryGirl.create :loop
expect {
post :add_loop, {id: gate.id, :loop => {:id => loop.id}}
}.to change(gate.loops, :count).by(1)
end
end
# _add_loops.html.erb
<h3>Add loops</h3>
<%= form_tag :area_add_loop do %>
<div class="field">
<%= label_tag :loop %>
<%= collection_select nil, nil, Loop.all, nil, nil, include_blank: true %>
</div>
<div class="actions">
<%= submit_tag :Add %>
</div>
<% end %>
class GatesController < ApplicationController
before_action :set_gate, only: [:show, :edit, :update, :destroy, :add_loop, :remove_loop]
def add_loop
unless (loop_id = params['loop']['id']).empty?
loop = Loop.find(loop_id)
@gate.loops << loop unless @gate.loops.include?(loop)
end
render :edit
end
...