2016-09-06 11 views
11

Podążam za tym post w sprawie konfigurowania uwierzytelniania na trasach mojej aplikacji Rails 4.Trasa uwierzytelniona nie działa w przypadku testu Rspec

Oto mój plik routes.rb:

Rails.application.routes.draw do 

    devise_for :employees, :controllers => { registrations: 'employees/registrations' } 
    devise_for :clients 


    authenticate :employee do 
    resources :quotation_requests, only: [:show, :edit,:index, :update, :destroy] 
    end 

    resources :quotation_requests, only: [:new, :create] 

    get '/dashboard' => 'dashboard#show', as: 'show_dashboard' 
    root to: 'home#index' 
end 

Oto mój plik quotation_requests_controller_spec.rb:

require 'rails_helper' 

RSpec.describe QuotationRequestsController, type: :controller do 


    describe "GET index" do 
     it "renders :index template" do 
      get :index 
      expect(response).to render_template(:index) 
     end 

     it "assigns quotation requests to template" do 
      quotation_requests = FactoryGirl.create_list(:quotation_request, 3) 
      get :index 
      expect(assigns(:quotation_requests)).to match_array(quotation_requests) 
     end 

    end 

    describe "GET edit" do 
     let(:quotation_request) { FactoryGirl.create(:quotation_request)} 

     it "renders :edit template" do 
      get :edit, id: quotation_request 
      expect(response).to render_template(:edit) 
     end 
     it "assigns the requested quotation request to template" do 
      get :edit, id: quotation_request 
      expect(assigns(:quotation_request)).to eq(quotation_request) 
     end 
    end 

    describe "PUT update" do 
     let(:quotation_request) { FactoryGirl.create(:quotation_request)} 

     context "valid data" do 
      new_text = Faker::Lorem.sentence(word_count=500) 
      let(:valid_data) { FactoryGirl.attributes_for(:quotation_request, sample_text: new_text)} 

      it "redirects to quotation_request#showtemplate" do 
       put :update, id: quotation_request, quotation_request: valid_data 
       expect(response).to redirect_to(quotation_request) 
      end 
      it "updates quotation request in the database" do 
       put :update, id: quotation_request, quotation_request: valid_data 
       quotation_request.reload #need to reload the object because we have just updated it in the database so need to get the new values 
       expect(quotation_request.sample_text).to eq(new_text) 
      end 
     end 

     context "invalid data" do 
      let(:invalid_data) { FactoryGirl.attributes_for(:quotation_request, sample_text: "", number_of_words: 400)} 

      it "renders the :edit template" do 
       put :update, id: quotation_request, quotation_request: invalid_data 
       expect(response).to render_template(:edit) 
      end 
      it "does not update the quotation_request in the database" do 
       put :update, id: quotation_request, quotation_request: invalid_data 
       quotation_request.reload 
       expect(quotation_request.number_of_words).not_to eq(400) 
      end 
     end 
    end 

    describe "GET new", new: true do 
     it "renders :new template" do 
      get :new 
      expect(response).to render_template(:new) 
     end 
     it "assigns new QuotationRequest to @quotation_request" do 
      get :new 
      expect(assigns(:quotation_request)).to be_a_new(QuotationRequest) 
     end 
    end 

    describe "GET show" do 

     #this test requires that there be a quotation request in the database 
     let(:quotation_request) { FactoryGirl.create(:quotation_request) } 

     context 'invalid request' do 

      it "does not render :show template if an employee or client is not signed in" do 

       #setup 
       quotation_request = create(:quotation_request) 

       #exercise 
       get :show, id: quotation_request 

       #verification 
       expect(response).to_not render_template(:show) 

      end 

     end 

     context 'valid request' do 

      sign_in_proofreader 

      it "renders :show template if an employee or client is signed in" do 

       #setup 
       quotation_request = create(:quotation_request) 


       #exercise 
       get :show, id: quotation_request 

       #verification 
       expect(response).to render_template(:show) 
      end 

      it "assigns requested quotation_request to @quotation_request" do 
       get :show, id: quotation_request 
       expect(assigns(:quotation_request)).to eq(quotation_request) 
      end 

     end 
    end 

    describe "POST create", post: true do 
     context "valid data" do 
      let(:valid_data) {FactoryGirl.nested_attributes_for(:quotation_request)} 

      it "redirects to quotation_requests#show" do 
       post :create, quotation_request: valid_data 
       expect(response).to redirect_to(quotation_request_path(assigns[:quotation_request])) 
      end 

      it "creates new quotation_request in database" do 
      expect { 
       post :create, quotation_request: valid_data 
       }.to change(QuotationRequest, :count).by(1) 
      end 
     end 

     context "invalid data" do 
     let(:invalid_data) {FactoryGirl.nested_attributes_for(:quotation_request).merge(sample_text: 'not enough sample text')} 

      it "renders :new template" do 
       post :create, quotation_request: invalid_data 
       expect(response).to render_template(:new) 
      end 

      it "doesn't creates new quotation_request in database" do 
       expect { 
        post :create, quotation_request: invalid_data 
       }.not_to change(QuotationRequest, :count) 
      end 
     end 
    end 

    describe "DELETE destroy" do 

     let(:quotation_request) { FactoryGirl.create(:quotation_request) } 

     it "redirects to the quotation request#index" do 
      delete :destroy, id: quotation_request 
      expect(response).to redirect_to(quotation_requests_path) 
     end 
     it "delets the quotation request from the database" do 
      delete :destroy, id: quotation_request 
      expect(QuotationRequest.exists?(quotation_request.id)).to be_falsy 
     end 

    end 
end 

Moja quotation_requests_controller.rb

class QuotationRequestsController < ApplicationController 
# before_action :authenticate_employee!, :only => [:show] 

    def index 
     @quotation_requests = QuotationRequest.all 
    end 

    def new 
     @quotation_request = QuotationRequest.new 
     @quotation_request.build_client 
    end 

    def edit 
     @quotation_request = QuotationRequest.find(params[:id]) 
    end 

    def create 
     client = Client.find_or_create(quotation_request_params[:client_attributes]) 
     @quotation_request = QuotationRequest.new(quotation_request_params.except(:client_attributes).merge(client: client)) 
     if @quotation_request.save 
     ClientMailer.quotation_request_created(client.email, @quotation_request.id).deliver_now 
     redirect_to @quotation_request, notice: 'Thank you.' 
     else 
     render :new 
     end 
    end 

    def show 
     @quotation_request = QuotationRequest.find(params[:id]) 
    end 

    def update 
     @quotation_request = QuotationRequest.find(params[:id]) 
     if @quotation_request.update(quotation_request_params) 
      redirect_to @quotation_request 
     else 
      render :edit 
     end 
    end 

    def destroy 
     QuotationRequest.destroy(params[:id]) 
     redirect_to quotation_requests_path 
    end 

    private 

    def quotation_request_params 
     params.require(:quotation_request).permit(:number_of_words, :return_date, :sample_text, :client_attributes => [:first_name, :last_name, :email]) 
    end 

end 

wiem uwierzytelniania trasy działa, ponieważ jeśli przetestuję je w przeglądarce, przekierowuję na znak_ na stronie. Jednak testy nie przechodzą w Rspec.

jeśli mogę umieścić ten kod w quotation_requests_controller.rb:

before_action :authenticate_employee!, :only => [:show] 

W rspec testy przechodzą. Z jakiegoś powodu Rspec nie rejestruje uwierzytelniania tras.

Tutaj jest wyjście z RSpec dla badań prowadzonych z uwierzytelnionych trasach:

QuotationRequestsController 
    GET index 
    valid request 
     renders :index template for signed in employee 
     assigns quotation requests to template 
    invalid request 
     does not render :index template without a signed in employee (FAILED - 1) 
    GET edit 
    valid request 
     renders :edit template with a signed in employee 
     assigns the requested quotation request to template 
    invalid request 
     does not render the :edit template without a signed in employee (FAILED - 2) 
    PUT update 
    valid request 
     valid data 
     redirects to quotation_request#showtemplate 
     updates quotation request in the database 
     invalid data 
     renders the :edit template 
     does not update the quotation_request in the database 
    invalid request 
     redirects user to the sign in page (FAILED - 3) 
    GET new 
    renders :new template 
    assigns new QuotationRequest to @quotation_request 
    GET show 
    invalid request 
     does not render :show template if an employee or client is not signed in (FAILED - 4) 
    valid request 
     renders :show template if an employee or client is signed in 
     assigns requested quotation_request to @quotation_request 
    POST create 
    valid data 
     redirects to quotation_requests#show 
     creates new quotation_request in database 
    invalid data 
     renders :new template 
     doesn't creates new quotation_request in database 
    DELETE destroy 
    valid request 
     redirects to the quotation request#index 
     delets the quotation request from the database 
    invalid request 
     does not delete the quotation request without a signed in employee (FAILED - 5) 

Failures: 

    1) QuotationRequestsController GET index invalid request does not render :index template without a signed in employee 
    Failure/Error: expect(response).to_not render_template(:index) 
     Didn't expect to render index 
    # ./spec/controllers/quotation_requests_controller_spec.rb:43:in `block (4 levels) in <top (required)>' 
    # -e:1:in `<main>' 

    2) QuotationRequestsController GET edit invalid request does not render the :edit template without a signed in employee 
    Failure/Error: expect(response).to_not render_template(:edit) 
     Didn't expect to render edit 
    # ./spec/controllers/quotation_requests_controller_spec.rb:92:in `block (4 levels) in <top (required)>' 
    # -e:1:in `<main>' 

    3) QuotationRequestsController PUT update invalid request redirects user to the sign in page 
    Failure/Error: expect(response).to_not redirect_to(quotation_request) 
     Didn't expect to redirect to #<QuotationRequest:0x007fe7eb69c8c0> 
    # ./spec/controllers/quotation_requests_controller_spec.rb:182:in `block (4 levels) in <top (required)>' 
    # -e:1:in `<main>' 

    4) QuotationRequestsController GET show invalid request does not render :show template if an employee or client is not signed in 
    Failure/Error: expect(response).to_not render_template(:show) 
     Didn't expect to render show 
    # ./spec/controllers/quotation_requests_controller_spec.rb:217:in `block (4 levels) in <top (required)>' 
    # -e:1:in `<main>' 

    5) QuotationRequestsController DELETE destroy invalid request does not delete the quotation request without a signed in employee 
    Failure/Error: expect(QuotationRequest.exists?(quotation_request.id)).to be_truthy 

     expected: truthy value 
      got: false 
    # ./spec/controllers/quotation_requests_controller_spec.rb:361:in `block (4 levels) in <top (required)>' 
    # -e:1:in `<main>' 

Finished in 2.11 seconds (files took 1.75 seconds to load) 
23 examples, 5 failures 

Failed examples: 

rspec ./spec/controllers/quotation_requests_controller_spec.rb:37 # QuotationRequestsController GET index invalid request does not render :index template without a signed in employee 
rspec ./spec/controllers/quotation_requests_controller_spec.rb:83 # QuotationRequestsController GET edit invalid request does not render the :edit template without a signed in employee 
rspec ./spec/controllers/quotation_requests_controller_spec.rb:171 # QuotationRequestsController PUT update invalid request redirects user to the sign in page 
rspec ./spec/controllers/quotation_requests_controller_spec.rb:208 # QuotationRequestsController GET show invalid request does not render :show template if an employee or client is not signed in 
rspec ./spec/cont 

Dlaczego trasy pisałem nie działać w testach RSpec?

+0

Proszę podać dane wyjściowe z przebiegu rspec. – dodo121

Odpowiedz

2

Domyślam się, że używasz rspec-rails w swojej aplikacji rails. Rspec-rails oferuje wiele wygodnych dla ciebie metod, ale wprowadza także czarną magię, która może prowadzić do nieoczekiwanych rezultatów - takich jak ta.

As you can see here to jest wyjaśnione w komentarzach do specyfikacji Kontroler:

# Supports a simple DSL for specifying behavior of ApplicationController. 
# Creates an anonymous subclass of ApplicationController and evals the 
# `body` in that context. Also sets up implicit routes for this 
# controller, that are separate from those defined in "config/routes.rb". 

Chyba logikę Oto, funkcje kontrolera są różne od trasy i powinny być badane oddzielnie (i rzeczywiście rspec barierki oferuje grupę testową do routingu), więc nie potrzebujemy tras dla specyfikacji kontrolera, co oznacza, że ​​powinieneś być w stanie przetestować kontroler bez konfigurowania tras.

W moim przekonaniu przetestowanie przekierowania dla nieuwierzytelnionych użytkowników jest raczej testem integracyjnym, ponieważ wymaga współpracy wielu części aplikacji i jako takie nie powinno być testowane w kontekście kontrolera, ale raczej jako cecha w jakiś test blackboxa.

Możesz pisać testy integracyjne, umieszczając je w jednym z tych katalogów spec/requests, spec/api, and spec/integration lub jawnie deklarują typ z

RSpec.describe "Something", type: :request do 

lub umieścić go w spec/features lub zadeklarować typ jak

RSpec.describe "Something", type: :feature do 

zależności na którym poziomie chcesz przetestować przekierowanie (czyli: przetestuj cykl żądanie-odpowiedź lub uruchom go w symulowanej przeglądarce). Więcej informacji na ten temat można znaleźć w dokumentacji testów integracji pod numerem rspec-rails github page.

+0

Dziękuję bardzo za wyjaśnienie tego. Teraz mogę kontynuować wdrażanie uwierzytelniania na trasach, na których powinno być. – chell

Powiązane problemy