2020-02-12 14:50:18 +00:00
require 'rails_helper'
RSpec . describe 'Error handling' , type : :request do
shared_examples 'JSON response format' do
2021-02-10 08:11:02 +00:00
2020-02-12 14:50:18 +00:00
let ( :as ) { :json }
it { expect ( response ) . to have_http_status ( http_status ) }
it { expect ( json_response ) . to be_a_kind_of ( Hash ) }
2020-02-13 11:55:19 +00:00
it do
# There is a special case where we mask technical errors and return
# a random error code that can be easily found in the logs by an
# administrator. However, this makes it hard to check for the exact error
# message. Therefore we only check for the substring in this particular case
2020-03-06 14:31:43 +00:00
if message == 'Please contact your administrator' || message == 'Mysql2::Error' || message == 'PG::ForeignKeyViolation'
2020-02-13 11:55:19 +00:00
expect ( json_response [ 'error' ] ) . to include ( message )
else
expect ( json_response [ 'error' ] ) . to eq ( message )
end
end
2020-02-12 14:50:18 +00:00
end
shared_examples 'HTML response format' do
let ( :as ) { :html }
it { expect ( response ) . to have_http_status ( http_status ) }
it { expect ( response . body ) . to include ( '<html' ) }
it { expect ( response . body ) . to include ( " <title> #{ title } </title> " ) }
it { expect ( response . body ) . to include ( " <h1> #{ headline } </h1> " ) }
it { expect ( response . body ) . to include ( message ) }
end
context 'URL route does not exist' do
before do
get '/not_existing_url' , as : as
end
let ( :message ) { 'No route matches [GET] /not_existing_url' }
let ( :http_status ) { :not_found }
context 'requesting JSON' do
include_examples 'JSON response format'
end
context 'requesting HTML' do
let ( :title ) { '404: Not Found' }
let ( :headline ) { '404: Requested resource was not found' }
include_examples 'HTML response format'
end
end
context 'request is not authenticated' do
before do
2021-02-04 08:28:41 +00:00
authenticated_as ( create ( :agent ) , password : 'wrongpw' )
2020-02-12 14:50:18 +00:00
get '/api/v1/organizations' , as : as
end
2021-02-04 08:28:41 +00:00
let ( :message ) { 'Invalid BasicAuth credentials' }
2020-02-12 14:50:18 +00:00
let ( :http_status ) { :unauthorized }
context 'requesting JSON' do
include_examples 'JSON response format'
end
context 'requesting HTML' do
let ( :title ) { '401: Unauthorized' }
let ( :headline ) { '401: Unauthorized' }
include_examples 'HTML response format'
end
end
2021-02-04 08:28:41 +00:00
context 'request is forbidden' do
before do
get '/api/v1/organizations' , as : as
end
let ( :message ) { 'Authentication required' }
let ( :http_status ) { :forbidden }
context 'requesting JSON' do
include_examples 'JSON response format'
end
context 'requesting HTML' do
let ( :title ) { '403: Forbidden' }
let ( :headline ) { '403: Forbidden' }
include_examples 'HTML response format'
end
end
2020-02-12 14:50:18 +00:00
context 'exception is raised' do
before do
2021-02-10 08:11:02 +00:00
authenticated_as ( create ( user ) )
2020-02-12 14:50:18 +00:00
get '/tests/raised_exception' , params : { exception : exception . name , message : message } , as : as
end
2020-03-06 14:31:43 +00:00
shared_examples 'exception check' do | message , exception , http_status , title , headline |
2020-02-12 14:50:18 +00:00
context " #{ exception } is raised " do
2021-02-10 08:11:02 +00:00
2020-02-12 14:50:18 +00:00
let ( :exception ) { exception }
let ( :http_status ) { http_status }
2020-03-06 14:31:43 +00:00
let ( :message ) { message }
2020-02-12 14:50:18 +00:00
context 'requesting JSON' do
include_examples 'JSON response format'
end
context 'requesting HTML' do
let ( :title ) { title }
let ( :headline ) { headline }
include_examples 'HTML response format'
end
end
end
2021-02-04 08:28:41 +00:00
shared_examples 'handles exception' do | exception , http_status , title , headline , message = 'some error message' |
include_examples 'exception check' , message , exception , http_status , title , headline
2020-03-06 14:31:43 +00:00
end
shared_examples 'masks exception' do | exception , http_status , title , headline |
include_examples 'exception check' , 'Please contact your administrator' , exception , http_status , title , headline
end
2021-02-10 08:11:02 +00:00
context 'with agent user' do
let ( :user ) { :agent }
include_examples 'handles exception' , Exceptions :: NotAuthorized , :unauthorized , '401: Unauthorized' , '401: Unauthorized'
include_examples 'handles exception' , Exceptions :: Forbidden , :forbidden , '403: Forbidden' , '403: Forbidden'
include_examples 'handles exception' , Pundit :: NotAuthorizedError , :forbidden , '403: Forbidden' , '403: Forbidden' , 'Not authorized'
include_examples 'handles exception' , ActiveRecord :: RecordNotFound , :not_found , '404: Not Found' , '404: Requested resource was not found'
include_examples 'handles exception' , Exceptions :: UnprocessableEntity , :unprocessable_entity , '422: Unprocessable Entity' , '422: The change you wanted was rejected.'
include_examples 'masks exception' , ArgumentError , :unprocessable_entity , '422: Unprocessable Entity' , '422: The change you wanted was rejected.'
include_examples 'masks exception' , StandardError , :internal_server_error , '500: Something went wrong' , " 500: We're sorry, but something went wrong. "
end
context 'with admin user' do
let ( :user ) { :admin }
include_examples 'handles exception' , Exceptions :: NotAuthorized , :unauthorized , '401: Unauthorized' , '401: Unauthorized'
include_examples 'handles exception' , Exceptions :: Forbidden , :forbidden , '403: Forbidden' , '403: Forbidden'
include_examples 'handles exception' , Pundit :: NotAuthorizedError , :forbidden , '403: Forbidden' , '403: Forbidden' , 'Not authorized'
include_examples 'handles exception' , ActiveRecord :: RecordNotFound , :not_found , '404: Not Found' , '404: Requested resource was not found'
include_examples 'handles exception' , Exceptions :: UnprocessableEntity , :unprocessable_entity , '422: Unprocessable Entity' , '422: The change you wanted was rejected.'
include_examples 'handles exception' , ArgumentError , :unprocessable_entity , '422: Unprocessable Entity' , '422: The change you wanted was rejected.'
include_examples 'handles exception' , StandardError , :internal_server_error , '500: Something went wrong' , " 500: We're sorry, but something went wrong. "
end
2020-02-12 14:50:18 +00:00
end
end