2016-09-06 32 views
11

私のRails 4アプリケーションのルートに認証を設定することについては、これに続くpostです。ここでRspecテストで認証されたルートが動作しません

は私の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 

は私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 

マイ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 

私は、ルート認証を知っています私がブラウザでそれらをテストすると、私はsign_にリダイレクトされるページ内。ただし、テストはRspecで合格しません。私はquotation_requests_controller.rbでこのコードを置けば

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

RSpecのテストが合格します。したがって、何らかの理由でRspecはルートの認証を登録しません。ここで

は、テストのためのRSpecのからの出力は、認証されたルートで実行されます。

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 

は、なぜ私が書かれているルートはRSpecのテストでは動作しないのですか?

+0

rspec runの出力を提供してください。 – dodo121

答えて

2

あなたはあなたのレールアプリでrspec-railsを使用しています。 Rspec-railsは多くの便利な方法を設定しますが、黒い魔法もいくつか導入されています。

は、コントローラの仕様のためにコメントで説明されて

As you can see here :私はここにロジックを推測

# 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". 

は、コントローラの機能は、ルーティングとは異なり、個別にテストする必要があります(実際RSpecのレールは、テストグループを提供していますルーティングのために)、コントローラ仕様のためのルートは必要ありません。つまり、ルートを設定せずにコントローラをテストできるはずです。

私の意見では、認証されていないユーザーのリダイレクトをテストすることは、アプリケーションの複数の部分を連携させる必要があるため、コントローラのコンテキストでテストするべきではないため、いくつかのブラックボックステスト。

あなたはこれらのディレクトリの1 spec/requests, spec/api, and spec/integrationでそれらを配置することによって、または明示的に

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

または

によって
RSpec.describe "Something", type: :feature do 

としてspec/featuresに置くか、型を宣言して自分のタイプを宣言することによって、統合テストを書くことができますどのレベルでリダイレクトをテストするか(つまり、リクエスト/レスポンスサイクルをテストするか、シミュレートされたブラウザで実行することを意味します)。 詳細については、rspec-rails github pageの統合テストのドキュメントを参照してください。

+0

ありがとうございました。今、私は先に進んで、どこにあるべきなのかの中で認証を実装することができます。 – chell

関連する問題