znsio / specmatic

Turn your contracts into executable specifications. Contract Driven Development - Collaboratively Design & Independently Deploy MicroServices & MicroFrontends.
https://specmatic.io
MIT License
280 stars 52 forks source link

Specmatic Stub does not generate correct response for single JSON string #1087

Open noelmccrory opened 6 months ago

noelmccrory commented 6 months ago

Description I have a Spring Boot API which uses an enum as the ResponseEntity type:

public ResponseEntity<DocumentStatus> getDocumentStatus(@PathVariable UUID id)

When I call my API it produces the following response:

content-type: application/json
body: "COMPLETE"

(Note: the double quotes which make this valid json)

The OpenAPI Spec (which was autogenerated from springdoc) has:

        '200':
          description: OK
          content:
            'application/json':
              schema:
                type: string
                enum:
                  - IN_PROGRESS
                  - COMPLETE
                  - FAILED
              examples:
                GET_DOCUMENT_STATUS:
                  value: COMPLETE

When I run the Specmatic Stub and call this endpoint, it returns the following:

    200 OK
    X-Specmatic-Result: success
    Content-Type: text/plain

    COMPLETE

Note: The double quotes are missing and the Content Type is wrong. This then results in an error on the consumer tests:

Could not extract response: no suitable HttpMessageConverter found for response type [class com.xxxx.model.DocumentStatus] and content type [text/plain]

Even if I update an API Spec to force the double quotes, it still results in Content-Type: text/plain:

        '200':
          description: OK
          content:
            'application/json':
              schema:
                type: string
                enum:
                  - '"IN_PROGRESS"'
                  - '"COMPLETE"'
                  - '"FAILED"'
              examples:
                GET_DOCUMENT_STATUS:
                  value: '"COMPLETE"'

Steps to reproduce See above.

Expected behavior Content-Type should be application/json and the string in the response body should be wrapped in double quotes.

Screenshots N/A

System Information:

Additional context It looks like a similar issue was present on the request generation - https://github.com/znsio/specmatic/issues/898

It seems similar to this issue - https://github.com/mock-server/mockserver/issues/1101

This is valid JSON according to https://jsonlint.com/

image
noelmccrory commented 6 months ago

I was able to workaround this by using a stub expectation file, rather than an example in the API Spec.

{
  "http-request": {
    "path": "/document/(docid:uuid)/document-status",
    "method": "GET"
  },
  "http-response": {
    "status": 200,
    "body": "COMPLETE",
    "headers": {
      "Content-Type": "application/json"
    }
  }
}
noelmccrory commented 6 months ago

It looks like there are similar issues for Contract Tests. I get the following error:

  Request to http://localhost:60199 at 2024-5-2 3:13:13.389
    GET /document/e49c9039-5c89-4396-9dff-f3b9a32cacc9/document-status
    Authorization: Bearer abcdef
    Accept-Charset: UTF-8
    Accept: */*
    Content-Type: NOT SENT

  Response at 2024-5-2 3:13:13.389
    200 OK
    Content-Type: application/json

    "COMPLETE"

 Scenario: GET /document/(id:uuid)/document-status -> 200 | EX:GET_DOCUMENT_STATUS has FAILED
Reason: Testing scenario "GET /document/(id:uuid)/document-status. Response: OK"
    API: GET /document/(id:uuid)/document-status -> 200

      >> RESPONSE.BODY

         Contract expected ("IN_PROGRESS" or "COMPLETE" or "FAILED") but response contained "\"COMPLETE\""

Interestingly, this is returning an application/json response, but seems like another part of Specmatic is expecting it to be just plaintext.

yogeshnikam671 commented 6 months ago

Hey @noelmccrory, thanks for reporting this. Really appreciate the detailed logs that you have shared! We will try to reproduce the issue and share the root cause with you in a while. We will then plan to fix it as per the root cause analysis.