Reputation: 1607
If you have succeeded in testing post, put, and delete http methods of a Rails API protected with the doorkeeper OAuth2 provider gem, please share and I'll give you the love.
The doorkeeper wiki documentation and sample application show pretty well how to test a get method. I succeeded testing a post with something like what follows using the Capybara test driver with Cucumber. Failed to test any API that routes from put or delete. Failed to post using an rspec test.
@user = create :user
@client = create(:oauth_application)
@token = create(:oauth_token, :application => @client, :resource_owner_id => @user)
json_for_new_entry = {
date_attr: Time.now.to_date,
decimal_attr: '1.1',
string_attr: 'oath2, you make me blue',
bool_attr: false,
int_attr: 1
}.to_json
page.driver.header 'Authorization', "Bearer #{@token.token}"
page.driver.post api_entry_path, json_for_new_entry,
'CONTENT_TYPE' => 'application/json'
The factories are nothing special:
factory :user, :class => User do |user|
sequence :email do |n| "user#{n}@example.com" end
pwd = "password"
password pwd
end
factory :oauth_application, :class => Doorkeeper::Application do
sequence(:name) { |n| "application_name_#{n}" }
#redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
redirect_uri 'http://localhost:3000/'
end
factory :oauth_token, :class => Doorkeeper::AccessToken do
association :application, :factory => :oauth_application
association :resource_owner_id, :factory => :user
end
My environment is a little behind latest versions:
Upvotes: 4
Views: 5632
Reputation: 1274
I used the answer that Moustafa gave, but I wanted to DRY it up so I put the following into spec/support/doorkeeper_oauth.rb
:
shared_context "doorkeeper_oauth", oauth: true do
let(:dummy_token) { double(:acceptable? => true) }
before do
if controller.present?
allow(controller).to receive(:doorkeeper_token) { dummy_token }
end
end
Then, in your controller spec you change the opening line slightly:
describe Api::V2::WidgetsController, oauth: true do
which pulls in the shared context via the "metadata" method.
edit: I have used this for at least GET and POST, which success in both cases.
Upvotes: 3
Reputation: 2268
You can use the example included in doorkeeper wiki as follow
describe Api::V1::ProfilesController do
describe 'GET #index' do
let(:token) { double :acceptable? => true }
before do
controller.stub(:doorkeeper_token) { token }
# allow(controller).to receive(:doorkeeper_token) {token} # => RSpec 3
end
it 'responds with 200' do
get :index, :format => :json
response.status.should eq(200)
end
end
end
Upvotes: 6
Reputation: 3501
Assuming the intention of your test is to verify the underlying API functionality and not the doorkeeper protection then this is the hack I use:
In my base controller:
module Api
class BaseController < ActionController::Base
doorkeeper_for :all unless Rails.env.test?
private
def current_user
if Rails.env.test? && $test_user
$test_user
else
@current_user ||= User.find(doorkeeper_token.resource_owner_id)
end
end
end
end
In my tests I have a login helper:
def login(user)
$test_user = user
end
def logout
$test_user = nil
end
I'm not proud of that code but nonetheless I can now get on with my life instead of worrying about how to make rails/doorkeeper/capybara et al work together during testing.
Upvotes: 5