1

I would like to write a test to make sure that "expert" users can create articles, and "basic" users cannot. For example, basic user cannot go here: "http://0.0.0.0:3000/articles/new". Below is a shortened version of my articles controller, followed by the articles test. The controller works, but I would like the test to prove it out. I'm not sure what to put where it says "code goes here". Thanks.

articles_controller:

class ArticlesController < ApplicationController
  load_and_authorize_resource

      # GET /articles/new
      # GET /articles/new.json
      def new
        puts "in articles new"
        @article = Article.new

        respond_to do |format|
          format.html # new.html.erb
          format.json { render json: @article }
        end
      end
    end

articles_controller_spec:

    describe ArticlesController do

  before (:each) do
    @user = FactoryGirl.create(:user)
    @user.role = "basic"
    sign_in @user
  end

  describe "create article" do
    it "should not create new article" do
      #code goes here
    end
  end
end
dt1000
  • 3,684
  • 6
  • 43
  • 65

3 Answers3

2

Testing CanCan abilities from your Controllers' specs will blow up your specs soon.

I prefer to test abilities in spec/models/ability_spec.rb using cancan/matchers

ck3g
  • 5,829
  • 3
  • 32
  • 52
  • I am actually trying to decide whether to test my abilities in the model or the controller spec. Can you explain why you think I testing in the model spec is the preferred way? – Emeka Feb 13 '16 at 21:39
  • 1
    It's faster, requires less code to cover most of cases and all the tests would be in the same place. – ck3g Feb 15 '16 at 06:19
  • After my 10th spec trying to parse json from the controller I think I'm starting to agree. Much easier to just test the ability than the whole controller depending on an ability. – Emeka Feb 18 '16 at 22:48
0

in your spec file, you can do it like:

describe "create article" do
  it "should not create new article" do
    get :new
    expect(response).not_to render_template("new")
  end
end

In document of cancan , see https://github.com/ryanb/cancan/wiki/Testing-Abilities, you can get details.

Bigxiang
  • 6,252
  • 3
  • 22
  • 20
0

Instead of testing what shouldn't happen, consider the simpler test of what should happen:

it "should return 401" do
  get :new
  expect(response.status).to eq(401)
end
Ryan Mohr
  • 811
  • 8
  • 10