2018-10-17 14:08:20 -04:00
# frozen_string_literal: true
2020-09-24 23:09:30 -04:00
RSpec . describe QA :: Resource :: ApiFabricator do
2018-11-02 05:32:28 -04:00
let ( :resource_without_api_support ) do
2018-10-17 14:08:20 -04:00
Class . new do
def self . name
2018-11-02 05:32:28 -04:00
'FooBarResource'
2018-10-17 14:08:20 -04:00
end
end
end
2018-11-02 05:32:28 -04:00
let ( :resource_with_api_support ) do
2018-10-17 14:08:20 -04:00
Class . new do
def self . name
2018-11-02 05:32:28 -04:00
'FooBarResource'
2018-10-17 14:08:20 -04:00
end
def api_get_path
'/foo'
end
def api_post_path
'/bar'
end
def api_post_body
{ name : 'John Doe' }
end
end
end
before do
allow ( subject ) . to receive ( :current_url ) . and_return ( '' )
end
2018-11-02 05:32:28 -04:00
subject { resource . tap { | f | f . include ( described_class ) } . new }
2018-10-17 14:08:20 -04:00
describe '#api_support?' do
let ( :api_client ) { spy ( 'Runtime::API::Client' ) }
let ( :api_client_instance ) { double ( 'API Client' ) }
2018-11-02 05:32:28 -04:00
context 'when resource does not support fabrication via the API' do
let ( :resource ) { resource_without_api_support }
2018-10-17 14:08:20 -04:00
it 'returns false' do
expect ( subject ) . not_to be_api_support
end
end
2018-11-02 05:32:28 -04:00
context 'when resource supports fabrication via the API' do
let ( :resource ) { resource_with_api_support }
2018-10-17 14:08:20 -04:00
it 'returns false' do
expect ( subject ) . to be_api_support
end
end
end
describe '#fabricate_via_api!' do
let ( :api_client ) { spy ( 'Runtime::API::Client' ) }
let ( :api_client_instance ) { double ( 'API Client' ) }
before do
stub_const ( 'QA::Runtime::API::Client' , api_client )
allow ( api_client ) . to receive ( :new ) . and_return ( api_client_instance )
allow ( api_client_instance ) . to receive ( :personal_access_token ) . and_return ( 'foo' )
end
2018-11-02 05:32:28 -04:00
context 'when resource does not support fabrication via the API' do
let ( :resource ) { resource_without_api_support }
2018-10-17 14:08:20 -04:00
it 'raises a NotImplementedError exception' do
2018-11-02 05:32:28 -04:00
expect { subject . fabricate_via_api! } . to raise_error ( NotImplementedError , " Resource FooBarResource does not support fabrication via the API! " )
2018-10-17 14:08:20 -04:00
end
end
2018-11-02 05:32:28 -04:00
context 'when resource supports fabrication via the API' do
let ( :resource ) { resource_with_api_support }
2018-10-17 14:08:20 -04:00
let ( :api_request ) { spy ( 'Runtime::API::Request' ) }
let ( :resource_web_url ) { 'http://example.org/api/v4/foo' }
2018-11-02 05:32:28 -04:00
let ( :response ) { { id : 1 , name : 'John Doe' , web_url : resource_web_url } }
let ( :raw_post ) { double ( 'Raw POST response' , code : 201 , body : response . to_json ) }
2018-10-17 14:08:20 -04:00
before do
stub_const ( 'QA::Runtime::API::Request' , api_request )
allow ( api_request ) . to receive ( :new ) . and_return ( double ( url : resource_web_url ) )
end
context 'when creating a resource' do
before do
allow ( subject ) . to receive ( :post ) . with ( resource_web_url , subject . api_post_body ) . and_return ( raw_post )
end
it 'returns the resource URL' do
expect ( api_request ) . to receive ( :new ) . with ( api_client_instance , subject . api_post_path ) . and_return ( double ( url : resource_web_url ) )
expect ( subject ) . to receive ( :post ) . with ( resource_web_url , subject . api_post_body ) . and_return ( raw_post )
expect ( subject . fabricate_via_api! ) . to eq ( resource_web_url )
end
it 'populates api_resource with the resource' do
subject . fabricate_via_api!
2018-11-02 05:32:28 -04:00
expect ( subject . api_resource ) . to eq ( response )
2018-10-17 14:08:20 -04:00
end
context 'when the POST fails' do
let ( :post_response ) { { error : " Name already taken. " } }
let ( :raw_post ) { double ( 'Raw POST response' , code : 400 , body : post_response . to_json ) }
it 'raises a ResourceFabricationFailedError exception' do
expect ( api_request ) . to receive ( :new ) . with ( api_client_instance , subject . api_post_path ) . and_return ( double ( url : resource_web_url ) )
expect ( subject ) . to receive ( :post ) . with ( resource_web_url , subject . api_post_body ) . and_return ( raw_post )
2018-11-02 05:32:28 -04:00
expect { subject . fabricate_via_api! } . to raise_error ( described_class :: ResourceFabricationFailedError , " Fabrication of FooBarResource using the API failed (400) with ` #{ raw_post } `. " )
2018-10-17 14:08:20 -04:00
expect ( subject . api_resource ) . to be_nil
end
end
end
2020-02-06 16:08:48 -05:00
describe '#transform_api_resource' do
2018-11-02 05:32:28 -04:00
let ( :resource ) do
2018-10-17 14:08:20 -04:00
Class . new do
def self . name
2018-11-02 05:32:28 -04:00
'FooBarResource'
2018-10-17 14:08:20 -04:00
end
def api_get_path
'/foo'
end
def api_post_path
'/bar'
end
def api_post_body
{ name : 'John Doe' }
end
def transform_api_resource ( resource )
resource [ :new ] = 'foobar'
resource
end
end
end
2018-11-02 05:32:28 -04:00
let ( :response ) { { existing : 'foo' , web_url : resource_web_url } }
2018-10-17 14:08:20 -04:00
let ( :transformed_resource ) { { existing : 'foo' , new : 'foobar' , web_url : resource_web_url } }
it 'transforms the resource' do
expect ( subject ) . to receive ( :post ) . with ( resource_web_url , subject . api_post_body ) . and_return ( raw_post )
2018-11-02 05:32:28 -04:00
expect ( subject ) . to receive ( :transform_api_resource ) . with ( response ) . and_return ( transformed_resource )
2018-10-17 14:08:20 -04:00
subject . fabricate_via_api!
end
end
end
end
end