Witam
Powili przerabiam sobie oficjalny tutorial RoR. Mam klopot przy jednym z testów, jest to test z rozdzialu 9, listingu 9.13:
[code]before(:each) do @user = Factory(:user) @attr = { :email => @user.email, :password => @user.password }
end
it “should sign the user in” do
post :create, :session => @attr
controller.current_user.should == @user
controller.should be_signed_in
end[/code]
Test nie przechodzi dostaje info:
[code]Failures:
SessionsController POST ‘create’ with valid email and password should sign the user in
Failure/Error: controller.current_user.should == @user
expected: #<User id: 1, name: “Michael Hartl”, email: "mhartl@example.com", created_at: “2010-10-18 17:34:28”,
updated_at: “2010-10-18 17:34:28”, encrypted_password: “bc370d4fd8b199e6a4a8e93aed5e21e9971f67197bcfad344c9…”,
salt: “c0ea2938645c213ebb6710b597c7f7a0ce2cc784645bf7d15ed…”>,
got: nil (using ==)
[code]class SessionsController < ApplicationController
def new @title = “Sign in”
end
def create
user = User.authenticate(params[:session][:email],
params[:session][:password])
if user.nil?
# Create an error message and re-render the signin form.
flash.now[:error] = “Invalid email/password combination.” @title = “Sign in”
render ‘new’
else
# Sign the user in and redirect to the user’s show page.
sign_in user
redirect_to user
end
end
def destroy
end
end[/code]
SessionHelper:
[code]module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:rememember_token] = [user.id, user.salt]
current_user = user
end
def current_user=(user) @current_user = user
end
def current_user @current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end[/code]
W modelu user mam metode:
def self.authenticate_with_salt(id, cookie_salt)
user = find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
[code=ruby]it “should sign the user in” do
post :create, :session => @attr
response.flash.now[:error].should be_nil
controller.current_user.should == @user
controller.should be_signed_in
end[/code]
Jeśli dostaniesz błąd na tej dodanej linijce to znaczy że masz złe dane w teście. Jeśli nie, to jest coś nie tak z wywołaniem controller.current_user - sprawdź dokładnie czy czegoś nie pominąłeś w tutorialu.
Failure/Error: response.flash.now[:error].should be_nil
undefined method `now' for {}:Hash
Sam flash bez ‘now’ przechodzi bez echa. Nadal pojawia sie ten sam blad.
Co to znaczy ze mam zle dane w tescie? Mam teraz dwie bazy danych development i test. Baza test jest pusta. Czy powinien byc w niej record uzytkownika ktorego mam zdefiniowanego w factory? Jest jekies polecenie ktore wypelni mi baze danych, tabele users tym recordem?
rake db:test:clone # Recreate the test database from…
rake db:test:clone_structure # Recreate the test databases fro…
rake db:test:load # Recreate the test database from…
rake db:test:prepare # Check for pending migrations an…
rake db:test:purge # Empty the test database
ogólnie poczytaj to co wypluje
rake --tasks
Dadzą ci one kopie danych z bazy, a do testu z pliku powinno z automatu jak dobrze kojarzę wczytać
Uporalem sie z tematem. Informacja dla innych uzytkownikow.
Sprawe rozwiazalo dodanie “self”:
def sign_in(user)
cookies.permanent.signed[:rememember_token] = [user.id, user.salt]
self.current_user = user
end
Gdzies wyczytałem ze jest to wymagane na “niektórych” systemach, ckolwiek znaczy slowo “niektorych”.
Dygresja: Strasznie mnie drazni ten brak konsekwencji w roznych projektach open source. Skoro framework jest multiplatformowy to ten sam kod ma dzialac na kazdej platformie. Tutaj mamy typowa sytuacje ze srodowiska open source: jeden mowi ze cos nie dziala a drugi na to “u mnie dziala”. Mam nadzieje ze wiecej takich kwiatkow nie spotkam w dalszej przygodzie z rails’ami.
To ktoś coś źle napisał.
Taka konstrukcja w każdymrubim zadziała tak samo - stworzy Ci zmienną lokalną ‘current_user’. Zawsze.
Jak chcesz przypisać coś używając metody current_user=() to musisz użyć tego self. Przypisanie bez selfa => zmienna lokalna.
Z odczytem jest tak: jeśli linijkę wcześniej użyłeś przypisania x=1, to każde następne odwołanie do x będzie oznaczało zmienną o tej nazwie. Jeśli parser nie napotkał przypisania, wtedy będzie szukał metody o tej nazwie.
To dość częsta przyczyna problemów w rubim. Przynajmniej dopóki się człowiek nie przyzwyczai i nie polubi.