Logo: Relish

  1. Sign up
  2. Sign in

Project: RSpec Rails 2-14

anonymous controller

Use the controller method to define an anonymous controller derived from
ApplicationController. This is useful for specifying behavior like global
error handling.

To specify a different base class, you can pass the class explicitly to the
controller method:

controller(BaseController)

You can also configure RSpec to use the described class:

RSpec.configure do |c|
  c.infer_base_class_for_anonymous_controllers = true
end

describe BaseController do
  controller { ... }
Scenarios
specify error handling in ApplicationController
Given
a file named "spec/controllers/application_controller_spec.rb" with:
require "spec_helper"

class ApplicationController < ActionController::Base
  class AccessDenied < StandardError; end

  rescue_from AccessDenied, :with => :access_denied

private

  def access_denied
    redirect_to "/401.html"
  end
end

describe ApplicationController do
  controller do
    def index
      raise ApplicationController::AccessDenied
    end
  end

  describe "handling AccessDenied exceptions" do
    it "redirects to the /401.html page" do
      get :index
      expect(response).to redirect_to("/401.html")
    end
  end
end
When
I run rspec spec
Then
the examples should all pass
specify error handling in subclass of ApplicationController
Given
a file named "spec/controllers/application_controller_subclass_spec.rb" with:
require "spec_helper"

class ApplicationController < ActionController::Base
  class AccessDenied < StandardError; end
end

class ApplicationControllerSubclass < ApplicationController

  rescue_from ApplicationController::AccessDenied, :with => :access_denied

private

  def access_denied
    redirect_to "/401.html"
  end
end

describe ApplicationControllerSubclass do
  controller(ApplicationControllerSubclass) do
    def index
      raise ApplicationController::AccessDenied
    end
  end

  describe "handling AccessDenied exceptions" do
    it "redirects to the /401.html page" do
      get :index
      expect(response).to redirect_to("/401.html")
    end
  end
end
When
I run rspec spec
Then
the examples should all pass
infer base class from the described class
Given
a file named "spec/controllers/base_class_can_be_inferred_spec.rb" with:
require "spec_helper"

RSpec.configure do |c|
  c.infer_base_class_for_anonymous_controllers = true
end

class ApplicationController < ActionController::Base; end

class ApplicationControllerSubclass < ApplicationController; end

describe ApplicationControllerSubclass do
  controller do
    def index
      render :text => "Hello World"
    end
  end

  it "creates an anonymous controller derived from ApplicationControllerSubclass" do
    expect(controller).to be_a_kind_of(ApplicationControllerSubclass)
  end
end
When
I run rspec spec
Then
the examples should all pass
invoke around filter in base class
Given
a file named "spec/controllers/application_controller_around_filter_spec.rb" with:
require "spec_helper"

class ApplicationController < ActionController::Base
  around_filter :an_around_filter

  def an_around_filter
    @callback_invoked = true
    yield
  end
end

describe ApplicationController do
  controller do
    def index
      render :nothing => true
    end
  end

  it "invokes the callback" do
    get :index

    expect(assigns[:callback_invoked]).to be_true
  end
end
When
I run rspec spec
Then
the examples should all pass
anonymous controllers only create resource routes
Given
a file named "spec/controllers/application_controller_spec.rb" with:
require "spec_helper"

describe ApplicationController do
  controller do
    def index
      render :text => "index called"
    end

    def create
      render :text => "create called"
    end

    def new
      render :text => "new called"
    end

    def show
      render :text => "show called"
    end

    def edit
      render :text => "edit called"
    end

    def update
      render :text => "update called"
    end

    def destroy
      render :text => "destroy called"
    end

    def willerror
      render :text => "will not render"
    end
  end

  describe "#index" do
    it "responds to GET" do
      get :index
      expect(response.body).to eq "index called"
    end

    it "also responds to POST" do
      post :index
      expect(response.body).to eq "index called"
    end

    it "also responds to PUT" do
      put :index
      expect(response.body).to eq "index called"
    end

    it "also responds to DELETE" do
      delete :index
      expect(response.body).to eq "index called"
    end
  end

  describe "#create" do
    it "responds to POST" do
      post :create
      expect(response.body).to eq "create called"
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :create)
        expect(response.body).to eq "create called"
      end
    end
  end

  describe "#new" do
    it "responds to GET" do
      get :new
      expect(response.body).to eq "new called"
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :new)
        expect(response.body).to eq "new called"
      end
    end
  end

  describe "#edit" do
    it "responds to GET" do
      get :edit, :id => "anyid"
      expect(response.body).to eq "edit called"
    end

    it "requires the :id parameter" do
      expect { get :edit }.to raise_error(ActionController::RoutingError)
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :edit, {:id => "anyid"})
        expect(response.body).to eq "edit called"
      end
    end
  end

  describe "#show" do
    it "responds to GET" do
      get :show, :id => "anyid"
      expect(response.body).to eq "show called"
    end

    it "requires the :id parameter" do
      expect { get :show }.to raise_error(ActionController::RoutingError)
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :show, {:id => "anyid"})
        expect(response.body).to eq "show called"
      end
    end
  end

  describe "#update" do
    it "responds to PUT" do
      put :update, :id => "anyid"
      expect(response.body).to eq "update called"
    end

    it "requires the :id parameter" do
      expect { put :update }.to raise_error(ActionController::RoutingError)
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :update, {:id => "anyid"})
        expect(response.body).to eq "update called"
      end
    end
  end

  describe "#destroy" do
    it "responds to DELETE" do
      delete :destroy, :id => "anyid"
      expect(response.body).to eq "destroy called"
    end

    it "requires the :id parameter" do
      expect { delete :destroy }.to raise_error(ActionController::RoutingError)
    end

    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :destroy, {:id => "anyid"})
        expect(response.body).to eq "destroy called"
      end
    end
  end

  describe "#willerror" do
    it "cannot be called" do
      expect { get :willerror }.to raise_error(ActionController::RoutingError)
    end
  end
end
When
I run rspec spec
Then
the examples should all pass
draw custom routes for anonymous controllers
Given
a file named "spec/controllers/application_controller_spec.rb" with:
require "spec_helper"

describe ApplicationController do
  controller do
    def custom
      render :text => "custom called"
    end
  end

  specify "a custom action can be requested if routes are drawn manually" do
    routes.draw { get "custom" => "anonymous#custom" }

    get :custom
    expect(response.body).to eq "custom called"
  end
end
When
I run rspec spec
Then
the examples should all pass
refer to application routes in the controller under test
Given
a file named "spec/controllers/application_controller_spec.rb" with:
require "spec_helper"

Rails.application.routes.draw do
  match "/login" => "sessions#new", :as => "login", :via => "get"
end

describe ApplicationController do
  controller do
    def index
      redirect_to login_url
    end
  end

  it "redirects to the login page" do
    get :index
    expect(response).to redirect_to("/login")
  end
end
When
I run rspec spec
Then
the examples should all pass

Last published about 1 month ago by alindeman.