Integrationstests für Capybara, Devise, CanCan und RSpec: gültiges Vorzeichen bei 302 Weiterleitungen zu example.com
Update: Siehe Ende des Beitrags, um zu erfahren, wie die Spezifikationen jetzt funktionieren, da ich meine Spezifikationen in den Spezifikationen / Anforderungen anstelle der Spezifikationen / Controller habe. Ich frage mich immer noch, wie ich einen gültigen angemeldeten Benutzer für Integrationstests mit meinen Controllern bekomme.
Ich arbeite zum ersten Mal mit Devise und CanCan und habe Schwierigkeiten, die grundlegendsten Integrationstests durchzuführen, bei denen ich überprüfe, ob ein angemeldeter Benutzer ... nun ... angemeldet ist. Ich habe unzählige Beiträge gelesen und Antworten zum Thema Integrationstests für Devise und RSpec (dh Beschleunigung durch direkten Zugriff auf die Sitzung überhttps://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara, http://schneems.com/post/15948562424/speed-up-capybara-tests-with-devise, undCapybara, RSpec und Devise: Wie können Integrationstests beschleunigt werden, indem langsame Anmeldungen umgangen und Sitzungen direkt eingerichtet werden?Aber ich konnte nicht einmal einen Standardbeitrag wie erwartet zum Laufen bringen und bin ratlos:
Die Entwicklungsumgebung funktioniert einwandfrei (kann sich anmelden und zur richtigen Seite weitergeleitet werden, wobei der Navigationsanmeldelink in Abmelden geändert wird usw.).test.log zeigt keine Probleme an, bis eine 302-Umleitung zu ausgeführt wirdhttp://www.example.com anstelle meines root_path.Aufgrund der Vielzahl von Benutzern mit ähnlichen Problemen und unterschiedlichen Lösungen bin ich offensichtlich nicht der einzige, der dieses Problem hatte, da verschiedene Aspekte der Sitzung usw. in verschiedenen Szenarien nicht verfügbar sind.
Abgespeckter Test:
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
...
Relevante log.test Ausgabe:
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)
Abgestufte Strecken.rb:
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users
Abgespeckte Fähigkeit:
class Ability beinhaltet CanCan :: Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.has_role? :admin
can :manage, :all
end
...
Und um genau zu sein, das aktuelle Gemfile:
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
Es gibt einen anderen Benutzer, der Probleme mit dieser grundlegenden Aufgabe hatte, aber es stellte sich heraus, dass es einfach ein Syntaxfehler war (sieheLogin Integrationstest mit rspec / deviseIch bin mir also sicher, dass mir etwas sehr Offensichtliches fehlt.
Aktualisieren:
Du machst wohl Scherze. Nachdem ich es für ein paar Stunden stehen gelassen hatte, stellte sich heraus, dass ich diese Spezifikation aus irgendeinem Grund in Spec / Controllern hatte, als ich sie einfach auf Spec / Requests umstellte, was alles grün machte.
Ich zitiere:
Wenn Sie Rails verwenden, geben Sie Ihre Capybara-Spezifikationen in spec / request oder spec / integration ein.
Gefunden amhttps://github.com/jnicklas/capybara#readme
Ich frage mich jedoch immer noch, wie ich für zukünftige Anforderungen Integrationstests auf meinen Controllern durchführen kann, für die ein angemeldeter Benutzer erforderlich ist. Für andere Nicht-Devise-Apps war dies in der Vergangenheit so einfach wie etwas folgende:
describe SomeController do
let(:user) { FactoryGirl.create(:user) }
before { valid_sign_in user }
...
wo mein helfer ist einfach
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