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