Testing
In order to authorize a request when testing your API you will need to pass the four headers through with your request, the easiest way to gain appropriate values for those headers is to use resource.create_new_auth_token e.g.
1
request.headers.merge! resource.create_new_auth_token
2
get '/api/authenticated_resource'
3
# success
Copied!
Check #75 if you have any problem or doubt.

Testing with Rspec

(a) General Request Specs

Below are some generic examples which may assist in helping you devise (pun intended) your own tests:
1
# spec/requests/authentication_test_spec.rb
2
3
require 'rails_helper'
4
include ActionController::RespondWith
5
6
# The authentication header looks something like this:
7
# {"access-token"=>"abcd1dMVlvW2BT67xIAS_A", "token-type"=>"Bearer", "client"=>"LSJEVZ7Pq6DX5LXvOWMq1w", "expiry"=>"1519086891", "uid"=>"[email protected]"}
8
9
describe 'Whether access is ocurring properly', type: :request do
10
before(:each) do
11
@current_user = FactoryBot.create(:user)
12
@client = FactoryBot.create(:client)
13
end
14
15
context 'context: general authentication via API, ' do
16
it "doesn't give you anything if you don't log in" do
17
get api_client_path(@client)
18
expect(response.status).to eq(401)
19
end
20
21
it 'gives you an authentication code if you are an existing user and you satisfy the password' do
22
login
23
# puts "#{response.headers.inspect}"
24
# puts "#{response.body.inspect}"
25
expect(response.has_header?('access-token')).to eq(true)
26
end
27
28
it 'gives you a status 200 on signing in ' do
29
login
30
expect(response.status).to eq(200)
31
end
32
33
it 'first get a token, then access a restricted page' do
34
login
35
auth_params = get_auth_params_from_login_response_headers(response)
36
new_client = FactoryBot.create(:client)
37
get api_find_client_by_name_path(new_client.name), headers: auth_params
38
expect(response).to have_http_status(:success)
39
end
40
41
it 'deny access to a restricted page with an incorrect token' do
42
login
43
auth_params = get_auth_params_from_login_response_headers(response).tap do |h|
44
h.each do |k, _v|
45
if k == 'access-token'
46
h[k] = '123'
47
end end
48
end
49
new_client = FactoryBot.create(:client)
50
get api_find_client_by_name_path(new_client.name), headers: auth_params
51
expect(response).not_to have_http_status(:success)
52
end
53
end
54
55
RSpec.shared_examples 'use authentication tokens of different ages' do |token_age, http_status|
56
let(:vary_authentication_age) { token_age }
57
58
it 'uses the given parameter' do
59
expect(vary_authentication_age(token_age)).to have_http_status(http_status)
60
end
61
62
def vary_authentication_age(token_age)
63
login
64
auth_params = get_auth_params_from_login_response_headers(response)
65
new_client = FactoryBot.create(:client)
66
get api_find_client_by_name_path(new_client.name), headers: auth_params
67
expect(response).to have_http_status(:success)
68
69
allow(Time).to receive(:now).and_return(Time.now + token_age)
70
71
get api_find_client_by_name_path(new_client.name), headers: auth_params
72
response
73
end
74
end
75
76
context 'test access tokens of varying ages' do
77
include_examples 'use authentication tokens of different ages', 2.days, :success
78
include_examples 'use authentication tokens of different ages', 5.years, :unauthorized
79
end
80
81
def login
82
post api_user_session_path, params: { email: @current_user.email, password: 'password' }.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }
83
end
84
85
def get_auth_params_from_login_response_headers(response)
86
client = response.headers['client']
87
token = response.headers['access-token']
88
expiry = response.headers['expiry']
89
token_type = response.headers['token-type']
90
uid = response.headers['uid']
91
92
auth_params = {
93
'access-token' => token,
94
'client' => client,
95
'uid' => uid,
96
'expiry' => expiry,
97
'token-type' => token_type
98
}
99
auth_params
100
end
101
end
Copied!

(b) How to create an authorization header from Scratch

1
require 'rails_helper'
2
include ActionController::RespondWith
3
4
def create_auth_header_from_scratch
5
# You need to set up factory bot to use this method
6
@current_user = FactoryBot.create(:user)
7
8
# create token
9
token = DeviseTokenAuth::TokenFactory.create
10
11
# store client + token in user's token hash
12
@current_user.tokens[token.client] = {
13
token: token.token_hash,
14
expiry: token.expiry
15
}
16
17
# Now we have to pretend like an API user has already logged in.
18
# (When the user actually logs in, the server will send the user
19
# - assuming that the user has correctly and successfully logged in
20
# - four auth headers. We are to then use these headers to access
21
# things which are typically restricted
22
# The following assumes that the user has received those headers
23
# and that they are then using those headers to make a request
24
25
new_auth_header = @current_user.build_auth_header(token.token, token.client)
26
27
puts 'This is the new auth header'
28
puts new_auth_header.to_s
29
30
# update response with the header that will be required by the next request
31
puts response.headers.merge!(new_auth_header).to_s
32
end
Copied!

Further Examples of Request Specs

Last modified 1yr ago