Module: OpenapiRuby::Adapters::Minitest::DSL

Defined in:
lib/openapi_ruby/adapters/minitest.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



12
13
14
15
16
# File 'lib/openapi_ruby/adapters/minitest.rb', line 12

def self.included(base)
  base.extend ClassMethods
  base.class_attribute :_openapi_contexts, default: []
  base.class_attribute :_openapi_schema_name, default: nil
end

Instance Method Details

#assert_api_response(method, expected_status, params: {}, headers: {}, body: nil, path_params: {}, api_path: nil, &block) ⇒ Object

Raises:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/openapi_ruby/adapters/minitest.rb', line 45

def assert_api_response(method, expected_status, params: {}, headers: {}, body: nil, path_params: {},
  api_path: nil, &block)
  context = find_context_for(method, path_params, params, expected_status, api_path)
  raise OpenapiRuby::Error, "No api_path defined for #{method.upcase} in #{self.class}" unless context

  operation = context.operations[method.to_s]
  raise OpenapiRuby::Error, "No #{method.upcase} operation defined" unless operation

  response_ctx = operation.responses[expected_status.to_s]
  raise OpenapiRuby::Error, "No response #{expected_status} defined for #{method.upcase}" unless response_ctx

  # Build the request path with base path from schema server URL
  base_path = resolve_base_path(context.schema_name)
  path = "#{base_path}#{expand_path(context.path_template, params.merge(path_params))}"

  # Resolve security scheme parameters
  security_params = resolve_security_params(operation, context.schema_name)
  security_params.each do |param|
    val = params[param[:name].to_sym] || params[param[:name]]
    next if val.nil?

    case param[:in].to_s
    when "header" then headers[param[:name]] = val
    when "query" then params[param[:name]] = val
    when "cookie" then headers["Cookie"] = "#{param[:name]}=#{val}"
    end
  end

  # Default Accept header for API requests
  headers["Accept"] ||= "application/json"

  # Build query params (exclude path params)
  query_params = params.reject { |k, _| path_param_names(context).include?(k.to_s) }

  # Execute the request
  if body
    content_type = operation.request_body_definition&.dig("content")&.keys&.first || "application/json"
    request_args = if content_type.include?("form-data") || content_type.include?("x-www-form-urlencoded")
      {params: body, headers: headers}
    else
      {
        params: body.is_a?(String) ? body : body.to_json,
        headers: headers.merge("Content-Type" => content_type)
      }
    end
    # Append query params to path when body is present
    if query_params.any?
      query_string = query_params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
      path = "#{path}?#{query_string}"
    end
  else
    request_args = {params: query_params, headers: headers}
  end

  # Validate the request against the declared operation (skip for error responses,
  # since those tests intentionally send invalid data)
  if OpenapiRuby.configuration.test_request_validation && expected_status < 400
    document_hash = build_validation_document(context.schema_name)
    req_errors = Testing::RequestValidator.new(document_hash).validate(
      operation: operation,
      path_context: context,
      params: params,
      headers: headers,
      body: body,
      path_params: path_params
    )
    assert req_errors.empty?, "Request validation failed:\n#{req_errors.join("\n")}"
  end

  send(method, path, **request_args)

  # Validate response
  assert_equal expected_status, response.status,
    "Expected status #{expected_status}, got #{response.status}\nResponse body: #{response.body}"

  if response_ctx.schema_definition
    validator = Testing::ResponseValidator.new
    body_data = parse_response_body
    errors = validator.validate(
      response_body: body_data,
      status_code: response.status,
      response_context: response_ctx
    )
    assert errors.empty?, "Response validation failed:\n#{errors.join("\n")}"
  end

  # Execute additional assertions
  instance_eval(&block) if block
end

#parsed_bodyObject



135
136
137
# File 'lib/openapi_ruby/adapters/minitest.rb', line 135

def parsed_body
  parse_response_body
end