Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specmatic Stub handling of binary responses (MimeType & Content) #750

Open
aeoncl opened this issue Sep 27, 2023 · 2 comments
Open

Specmatic Stub handling of binary responses (MimeType & Content) #750

aeoncl opened this issue Sep 27, 2023 · 2 comments
Assignees
Labels
bug Something isn't working enhancement Improvement to an existing feature

Comments

@aeoncl
Copy link
Contributor

aeoncl commented Sep 27, 2023

Description
I have an API that has application/pdf as return type for one of the endpoints. Currently, if i generate a stub from an interaction, i have no way to load bytes in the response (using externalValue). I can only type an inline string.

This has two effects:

  • first i cannot correctly mock this interaction, because the calling app will need valid bytes to be sent back.
  • second, the mime type sent back is incorrect, Specmatic looks at the pattern from the response example to generate the response. This means if Specmatic parses the example body as a StringValue, it will set the return MimeType to text/plain, which isn't compatible with the contract.

There are multiple behaviors that adds up to create the mimetype behaviour:

  • Specmatic creates the example patterns from the example body, and doesn't look at the contract at all. This is why what is a "String format Binary" in the contract turns in a simple String in the example, generating the incorrect mimeType
  • Specmatic doesn't use the contract at all for responses MimeTypes, just the Value class of the body

Steps to reproduce

1. Here's what you need, there is a contract, an interraction & 1 pdf files:

Contract:

openapi: 3.0.3
info:
  contact:
    url: http://balbala
  title: GigaUpload Service
  description: Service to upload things and break Specmatic :( sorry guyz
  version: 1.0.0
servers:
  - url: "http://{hostname}:{port}/{basePath}/"
    variables:
      hostname:
        default: localhost
      port:
        default: "8080"
      basePath:
        default: rest
  - url: "http://localhost:9000"
tags:
  - name: UploadStuff
paths:
  "/uploadstuff":
    post:
      tags:
        - UploadStuff
      operationId: UploadStuffToServer
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                uploadRequest:
                  $ref: "#/components/schemas/UploadRequest"
                pdfFiles:
                  type: array
                  items:
                    type: string
                    format: binary
              required:
                - uploadRequest
                - pdfFiles
            encoding:
              UploadRequest:
                contentType: application/json
              pdfFiles:
                contentType: application/pdf
      responses:
        "200":
          description: "The document has been sent successfully send and...we're sending it back, because reasons. You're not my dad."
          content:
            application/pdf:
              schema:
                type: string
                format: binary
components:
  schemas:
    UploadRequest:
      type: object
      title: UploadRequest
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        coolNameYourFriendsGiveYou:
          type: string
          minLength: 1
          maxLength: 255
      required:
        - name
        - coolNameYourFriendsGiveYou

Interraction:

{
  "http-request": {
    "method": "POST",
    "path": "/uploadstuff",
    "multipart-formdata": [
      {
        "name": "pdfFiles",
        "file": "(string)",
        "filename": "%%changeme%%\\test.pdf",
        "contentType": "application/pdf"
      },
      {
        "name": "uploadRequest",
        "content": {
          "name": "Chris",
          "coolNameYourFriendsGiveYou": "C-Dawg"
        },
        "contentType": "application/json"
      }
    ]
  },
  "http-response": {
    "status": 200,
    "body": "feafaefaf"
  }
}

PdfFile:
test.pdf

Don't forget to update the file path in the interaction

2. Run specmatic in stub mode with the interaction loaded

3. Make a POST request to localhost:9000/uploadstuff of type multipart/form-data

The parts are:

  • uploadRequest of type json:
{
    "coolNameYourFriendsGiveYou": "C-Dawg",
    "name": "Chris"
}
  • pdfFiles: contains your test.pdf

image

Expected behavior
I Expect the response to be of mimetype application/pdf like it's written in the contract.
I Expect valid pdf bytes to be the body of the response

Screenshots
Response mimetype is text/plain:
image

System Information:

  • OS & version: Windows 11
  • Browser & version: Insomnia 2023
  • Specmatic version: 0.77
  • JDK version: OpenJDK 17

Additional context
There are multiple ways we could solve these problems:

  • Add support for externalValue in the responses
  • At the OpenAPI parsing time (in OpenAPISpecification.kt) set the mimetype to the HttpResponsePattern from the contract and drop using the body value as MimeType source
@aeoncl
Copy link
Contributor Author

aeoncl commented Sep 27, 2023

This was hard to convey, let me know if something is not clear !
I will investigate the possible fixes that i talk about in the additional context. Please tell me what you think about them, how would you go about fixing this / adding this feature?

@harikrishnan83 harikrishnan83 self-assigned this Sep 27, 2023
@joelrosario
Copy link
Member

@aeoncl really appreciate the effort you have put into this detailed explanation. We'll read through it and get back to you.

@joelrosario joelrosario added bug Something isn't working enhancement Improvement to an existing feature labels Feb 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement Improvement to an existing feature
Projects
None yet
Development

No branches or pull requests

3 participants