-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Testing protected controllers
Tim Liner edited this page Jan 8, 2019
·
14 revisions
Few things you should be aware of when testing controllers protected by doorkeeper.
in the majority of cases, you'll only need to stub the doorkeeper_token
method in your controller:
describe Api::V1::ProfilesController do
describe 'GET #index' do
let(:token) { double :acceptable? => true }
before do
allow(controller).to receive(:doorkeeper_token) { token }
# controller.stub(:doorkeeper_token) { token } # => RSpec 2
end
it 'responds with 200' do
get :index, :format => :json
response.status.should eq(200)
end
end
end
Stubbing :acceptable? => true
will bypass the doorkeeper filter, since the token is valid. If you prefer to return false
then the response status will be 401 unauthorized
.
If you have an action that requires a specific scope, you will need to stub the token scope:
# controllers/api/v1/profiles_controller.rb
class Api::V1::ProfilesController < ApiController
before_action :only => [:create] do
doorkeeper_authorize! :write
end
# ...
def create
respond_with 'api_v1', Profile.create!(params[:profile])
end
end
# spec/controllers/api/v1/profiles_controller_spec.rb
describe 'POST #create (with scopes)' do
let(:token) do
stub :acceptable? => true, :scopes => [:write]
end
before do
allow(controller).to receive(:doorkeeper_token) { token }
# controller.stub(:doorkeeper_token) { token } # => RSpec 2
end
it 'creates the profile' do
Profile.should_receive(:create!) { stub_model(Profile) }
post :create, :format => :json
response.status.should eq(201)
end
end
If you need to test the controller fully integrated with your app, you'll need to create the necessary models:
describe Api::V1::CredentialsController do
describe 'GET #me (integrated)' do
let!(:application) { Factory :application } # OAuth application
let!(:user) { Factory :user }
let!(:token) { Factory :access_token, :application => application, :resource_owner_id => user.id }
it 'responds with 200' do
get :me, :format => :json, :access_token => token.token
response.status.should eq(200)
end
it 'returns the user as json' do
get :me, :format => :json, :access_token => token.token
response.body.should == user.to_json
end
end
end
You can accomplish the same test above with MiniTest (no Rspec) by creating a mock Token and stubbing the acceptable?
method:
describe API::V1::ProfilesController do
describe 'unauthorized' do
it "should return unauthorized" do
get :index
assert_response :unauthorized
end
end
describe 'authorized' do
let(:user) { users(:one) }
let(:token) { Minitest::Mock.new }
setup do
token.expect(:acceptable?, true, [Doorkeeper::OAuth::Scopes])
end
it "should return success" do
@controller.stub :doorkeeper_token, token do
get :index
assert_response :success
end
end
end
end
For more examples, check the doorkeeper provider app on Github here.