lib/rspec/rails/api/dsl/example.rb in rspec-rails-api-0.3.4 vs lib/rspec/rails/api/dsl/example.rb in rspec-rails-api-0.4.0
- old
+ new
@@ -4,11 +4,20 @@
module Rails
module Api
module DSL
# These methods will be available in examples (i.e.: 'for_code')
module Example
- def visit(example, path_params: {}, payload: {}, headers: {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
+ ##
+ # Visits the current example and tests the response
+ #
+ # @param example [Hash] Current example
+ # @param path_params [Hash] Path parameters definition
+ # @param payload [Hash] Request body
+ # @param headers [Hash] Custom headers
+ #
+ # @return [void]
+ def test_response_of(example, path_params: {}, payload: {}, headers: {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
raise 'Missing context. Call visit with for_code context.' unless example
status_code = prepare_status_code example.class.description
request_params = prepare_request_params example.class.module_parent.description,
@@ -21,41 +30,76 @@
check_response(response, status_code)
return if example.class.description.match?(/-> test (\d+)(.*)/)
- set_request_example example.class.metadata[:rrad], request_params, status_code, response.body
+ set_request_example example.class.metadata[:rra], request_params, status_code, response.body
end
+ private
+
+ ##
+ # Searches for a defined entity in metadata
+ #
+ # @param entity [Symbol] Entity reference
+ #
+ # @return [RSpec::Rails::Api::EntityConfig, Hash] Defined entity
def defined(entity)
- current_resource = self.class.metadata[:rrad].current_resource
+ return { type: entity.to_s.split('_').last.to_sym } if PRIMITIVES.include? entity
+
+ current_resource = rra_metadata.current_resource
raise '@current_resource is unset' unless current_resource
- entities = self.class.metadata[:rrad].resources[current_resource][:entities]
+ entities = rra_metadata.resources[current_resource][:entities]
out = entities[entity]
- raise "Unkown entity '#{entity}' in resource '#{current_resource}'" unless out
+ raise "Unknown entity '#{entity}' in resource '#{current_resource}'" unless out
out.expand_with(entities)
end
- private
-
- def check_response(response, expected_code)
+ ##
+ # Performs various tests on the response
+ #
+ # @param response [ActionDispatch::TestResponse] The response
+ # @param expected_code [Number] Code to test for
+ def check_response(response, expected_code) # rubocop:disable Metrics/AbcSize
expect(response.status).to eq expected_code
expect(response.headers['Content-Type']).to eq 'application/json; charset=utf-8' if expected_code != 204
+ expectations = rra_current_example[:expectations]
+ expect(response).to have_many defined(expectations[:many]) if expectations[:many]
+ expect(response).to have_one defined(expectations[:one]) if expectations[:one]
+ expect(response.body).to eq '' if expectations[:none]
end
- def set_request_example(rrad_metadata, request_params, status_code = nil, response = nil)
- rrad_metadata.add_request_example(url: request_params[:example_url],
- action: request_params[:action],
- status_code: status_code,
- response: response,
- path_params: request_params[:path_params],
- params: request_params[:params])
+ ##
+ # Adds a request example information to metadata
+ #
+ # @param rra_metadata [RSpec::Rails::Api::Metadata]
+ # @param request_params [Hash]
+ # @param status_code [Integer, nil]
+ # @param response [String, nil]
+ #
+ # @return [void]
+ def set_request_example(rra_metadata, request_params, status_code = nil, response = nil)
+ rra_metadata.add_request_example(url: request_params[:example_url],
+ action: request_params[:action],
+ status_code: status_code,
+ response: response,
+ path_params: request_params[:path_params],
+ params: request_params[:params])
end
+ ##
+ # Prepares the options for a request
+ #
+ # @param description [String] RSpec example description
+ # @param request_params [Hash] Request parameters
+ # @param payload [Hash] Request body
+ # @param request_headers [Hash] Custom headers
+ #
+ # @return [Hash] Options for the request
def prepare_request_params(description, request_params = {}, payload = {}, request_headers = {})
example_params = description.split
{
action: example_params[0].downcase,
@@ -64,11 +108,17 @@
params: payload,
headers: prepare_request_headers(request_headers),
}
end
+ ##
# Replace path params by values
+ #
+ # @param url [String] Url definition
+ # @param request_params [Hash] Request parameters
+ #
+ # @return [String] Actual path to visit
def prepare_request_url(url, request_params)
url.gsub(/(?::(\w*))/) do |e|
symbol = e.sub(':', '').to_sym
if request_params.key?(symbol)
request_params[symbol]
@@ -78,22 +128,50 @@
puts "! Define #{symbol} (let(:#{symbol}){ value }) or pass it to 'visit'"
end
end
end
+ ##
+ # Prepares request headers
+ #
+ # @param headers [Hash] Custom headers
+ #
+ # @return [Hash] Headers to use in request
def prepare_request_headers(headers = {})
{
'Accept' => 'application/json',
'Content-Type' => 'application/json',
}.merge headers
end
+ ##
+ # Extracts status code from RSpec example description
+ #
+ # @param description [String] RSpec example description
+ #
+ # @return [Integer] Status code
def prepare_status_code(description)
code_match = /->(?: test)? (\d+) - .*/.match description
raise 'Please provide a numerical code for the "for_code" block' unless code_match
code_match[1].to_i
+ end
+
+ ##
+ # Returns the current example configuration from metadata
+ #
+ # @return [Hash] Current example configuration
+ def rra_current_example
+ self.class.metadata[:rra_current_example]
+ end
+
+ ##
+ # Returns the whole Rspec-rails-API metadata object
+ #
+ # @return [RSpec::Rails::Api::Metadata] Rspec-rails-API metadata object
+ def rra_metadata
+ self.class.metadata[:rra]
end
end
end
end
end