Testes de integração Capivara, Devise, CanCan e RSpec: login válido em redirecionamentos 302 para example.com
Update: veja o final do post para saber como as especificações funcionam agora que tenho minhas especificações em spec / requests em vez de spec / controllers. Ainda estou querendo saber como obter um usuário com login válido para testes de integração com meus controladores.
Estou trabalhando com o Devise e o CanCan pela primeira vez e estou tendo dificuldades em fazer o mais básico dos testes de integração, pois estou verificando se um usuário logado está ... bem ... logado. Li inúmeros posts e respostas lidando com os testes de integração do Devise e do RSpec (isto é, acelerando-os acessando a sessão diretamente viahttps://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara, http://schneems.com/post/15948562424/speed-up-capybara-tests-with-deviseeCapybara, RSpec e Devise: alguma maneira de tornar os testes de integração mais rápidos contornando o login lento e definindo a sessão diretamente?, mas eu não consegui nem conseguir um post padrão funcionando como esperado e estou confuso:
O ambiente de desenvolvimento funciona bem (pode efetuar login e ser redirecionado para a página apropriada, com o link de login de navegação alterado para o logout, etc.).test.log indica que não há problemas até que ele faça um redirecionamento 302 parahttp://www.example.com em vez do meu root_path.Pela quantidade de usuários com problemas semelhantes com soluções variadas, obviamente não sou o único que teve esse problema, já que vários aspectos da sessão, etc., estão indisponíveis em diferentes cenários.
Teste descascado:
subject { page }
describe 'should be able to log in' do
before do
visit '/users/sign_in'
user = FactoryGirl.create(:admin)
#user.add_role :admin
fill_in 'Username', with: user.username
fill_in 'Password', with: user.password
click_on 'Sign in'
end
it { should have_link 'Logout' }
end
...
Saída log.test relevante:
Started POST "/users/sign_in" for 127.0.0.1 at 2012-11-06 17:31:10 -0800
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "user"=>{"username"=>"username1", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
[1m[36mUser Load (0.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."username" = 'username1' LIMIT 1[0m
[1m[35m (0.0ms)[0m SAVEPOINT active_record_1
[1m[36m (0.0ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m SAVEPOINT active_record_1
[1m[36m (0.1ms)[0m [1mUPDATE "users" SET "last_sign_in_at" = '2012-11-07 01:31:10.722712', "current_sign_in_at" = '2012-11-07 01:31:10.722712', "last_sign_in_ip" = '127.0.0.1', "current_sign_in_ip" = '127.0.0.1', "sign_in_count" = 1, "updated_at" = '2012-11- 07 01:31:10.723051' WHERE "users"."id" = 1[0m
[1m[35m (0.0ms)[0m RELEASE SAVEPOINT active_record_1
Redirected to http://www.example.com/
Completed 302 Found in 12ms (ActiveRecord: 0.0ms)
Desmontado routes.rb:
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users
Despojado de Habilidade:
habilidade de classe inclui CanCan :: Habilidade
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
end
...
E para ser minucioso, o Gemfile atual:
source 'https://rubygems.org'
gem 'rails', '3.2.8'
gem "bootstrap-sass", "~> 2.1.0.1"
gem 'faker', '1.1.2'
gem 'will_paginate', '~> 3.0.3'
gem 'bootstrap-will_paginate', '~> 0.0.9'
gem 'jquery-rails'
gem 'client_side_validations'
gem 'thin'
gem "devise", "~> 2.1.2"
gem "cancan", "~> 1.6.8"
gem "rolify", "~> 3.2.0"
gem "simple_form", "~> 2.0.4"
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end
group :development, :test do
gem 'sqlite3', '1.3.5'
gem "rspec-rails", "~> 2.11.4"
gem 'guard-rspec', '1.2.1'
#gem 'listen', github: 'guard/listen', branch: 'polling/double'
gem 'guard-spork'
gem 'guard-cucumber'
gem 'spork', '0.9.2'
gem "factory_girl_rails", ">= 4.1.0"
end
group :development do
gem 'annotate', '2.5.0'
gem "quiet_assets", ">= 1.0.1"
end
group :test do
gem 'capybara', ">= 1.1.2"
gem "email_spec", ">= 1.2.1"
gem "cucumber-rails", ">= 1.3.0", :require => false
gem "database_cleaner", ">= 0.9.1"
gem "launchy", ">= 2.1.2"
gem 'rb-fsevent', '0.9.1', :require => false
gem 'growl', '1.0.3'
gem 'terminal-notifier-guard'
end
group :production do
gem 'pg', '0.12.2'
end
Há outro usuário que teve problemas com essa tarefa básica, mas acabou sendo simplesmente um erro de sintaxeTeste de integração de login com rspec / legue) então tenho certeza de que estou sentindo falta de algo muito óbvio.
Atualizar:
Você tem que estar brincando comigo. Depois de deixá-lo por algumas horas, descobri que eu tinha essa especificação por algum motivo em spec / controllers, quando simplesmente mudava para spec / requests, tudo ficava verde.
Eu cito:
Se você estiver usando o Rails, coloque suas especificações Capybara em spec / requests ou spec / integration.
Encontrado emhttps://github.com/jnicklas/capybara#readme
No entanto, eu ainda estou me perguntando como para futuros requisitos eu posso fazer testes de integração em meus controladores que precisarão ter um usuário logado .... para outros aplicativos não-Devise no passado, isso tem sido tão simples como algo como Os seguintes:
describe SomeController do
let(:user) { FactoryGirl.create(:user) }
before { valid_sign_in user }
...
onde meu ajudante é simplesmente
def valid_sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
uncheck(:remember_me)
click_button "Sign In"
# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token
end