interagent / interagent/committee

assert_response_schema_confirm : impossible to validate integers in Headers

Open
#345 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
955
Forks
145
Avg merge
5d 4h
Merged PRs (30d)
6

Description

Hello,

I am using committee-rails and committee to add schema validation tests for the responses of our APIs. We also use Pagy response pagination gem that adds headers to the request (total number of result pages, current pages, etc.) , so our OpenAPI definition specifies these headers as integers:

          headers:
            Current-Page:
              schema:
                type: integer
              description: |
                [RFC288 Pagination header](https://tools.ietf.org/html/rfc8288): Current page number
              example: 2

However, when using `assert_response_schema_confirm(200) to check the JSON schema for the response, we get the error:

Invalid response for OpenAPI schema /Users/fgarzon/Dev/fft_api_doc/fft_server/openapi.yaml
- Headers: {"Content-Type"=>"application/json; charset=utf-8", "Link"=>"<http://www.example.com/api/v2/parcels?reference=162&page=1>; rel=\"first\", <http://www.example.com/api/v2/parcels?reference=162&page=1>; rel=\"last\"", "Current-Page"=>"1", "Page-Items"=>"5", "Total-Pages"=>"1", "Total-Count"=>"1", "ETag"=>"W/\"9edc3cf0bb6c09890b9df541eb9fe866\"", "Cache-Control"=>"max-age=0, private, must-revalidate", "X-Request-Id"=>"e9f565bc-f208-4c57-930e-5aa30c16b477", "X-Runtime"=>"0.003913", "Content-Length"=>"193"}
- Body: [{"id":6043,"reference":"162","type":"internal","status":"waiting","cancellable":true,"item_count":1,"description":"return 142","allow_bulk_handing":true,"to_hand_to":"Transporteur (Interne)"}]
Request:
- Path: /api/v2/parcels?reference=162
- Method: GET
- Body:
ERROR["test_0001_returns the expected parcel", #<Minitest::Reporters::Suite:0x00007fed4c77f010 @name="with reference filter">, 11.45178499999929]
 test_0001_returns the expected parcel#with reference filter (11.45s)
Minitest::UnexpectedError:         Committee::InvalidResponse: #/paths/~1parcels/get/responses/200/headers/Current-Page/schema expected integer, but received String: "1"
            test/support/assertions.rb:22:in `assert_response_v2_api'
            test/integration/parcels/index_test.rb:141:in `block (2 levels) in <class:ParcelsIndexTest>'

You can see in the verbose output above, the ActionDispatch::Response::Header object that stores the response headers stores the "integer values" as strings. But when sent on the wire, they are in integer format:

$ curl -v -u runner:<a password> -H "Accept: application/json"  http://localhost:3000/api/v2/parcels
*   Trying ::1:3000...
* Connected to localhost (::1) port 3000 (#0)
* Server auth using Basic with user 'runner'
> GET /api/v2/parcels HTTP/1.1
> Host: localhost:3000
> Authorization: Basic <some b64 string>
> User-Agent: curl/7.77.0
> Accept: application/json
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Link: <http://localhost:3000/api/v2/parcels?page=1>; rel="first", <http://localhost:3000/api/v2/parcels?page=1>; rel="last"
< Current-Page: 1
< Page-Items: 5
< Total-Pages: 1
< Total-Count: 1
< ETag: W/"b26995e4184fe0b06e6811d07105e9ea"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: ec7cb80a-35cc-425c-9aa1-d202b3b8e09b
< X-Runtime: 0.887195
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact

My question is: why does the committee validation for this header fail ? Am I missing something here ? Thank you in advance

  def assert_response_v2_api(code)
    assert_response(code)
    return unless ENV["V2_API_OPENAPI_SCHEMA_FILE"]

    begin
      assert_response_schema_confirm(code)
    rescue Committee::InvalidResponse => exception
      puts <<~INFO

        Invalid response for OpenAPI schema #{ENV['V2_API_OPENAPI_SCHEMA_FILE']}
        - Headers: #{response.headers}
        - Body: #{response.body}
        Request:
        - Path: #{request.fullpath}
        - Method: #{request.method}
        - Body: #{request.body&.string}
      INFO
      raise exception
    end
  end

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with test/support/assertions.rb and the failing case in test/integration/parcels/index_test.rb. Trace how assert_response_schema_confirm reads ActionDispatch response headers and compare that path with the wire-format behavior shown in the issue. Done means the integer header validation behavior is defined and covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rails, ruby
Domain
api, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.