znsio / specmatic

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

Password format for strings expects an object #747

Closed GeekBeardLinks closed 8 months ago

GeekBeardLinks commented 1 year ago

Description OpenAPI defines format: password as a hint to UI (and probably to Specmatic) to mask the value.

When you add format: password to an string property to an OpenAPI spec Specmatic expects the property value for an example to be an object instead of a string.

If no example is provided then Spectmatic sends an empty object as the property value.

Steps to reproduce Using files: openapi.yaml

openapi: 3.0.1
info:
  title: RealWorld Conduit API
  description: Conduit API documentation
  contact:
    name: RealWorld
    url: https://realworld.how
  license:
    name: MIT License
    url: https://opensource.org/licenses/MIT
  version: 1.0.0
tags:
  - name: Articles
  - name: Comments
  - name: Favorites
  - name: Profile
  - name: Tags
  - name: User and Authentication
servers:
  - url: https://api.realworld.io/api
paths:
  /users:
    post:
      tags:
        - User and Authentication
      description: Register a new user
      operationId: CreateUser
      requestBody:
        $ref: '#/components/requestBodies/NewUserRequest'
      responses:
        '201':
          $ref: '#/components/responses/UserResponse'
      x-codegen-request-body-name: body
components:
  schemas:
    NewUser:
      required:
        - email
        - password
        - username
      type: object
      properties:
        username:
          type: string
        email:
          type: string
        password:
          type: string
          format: password
    User:
      required:
        - bio
        - email
        - image
        - token
        - username
      type: object
      properties:
        email:
          type: string
        token:
          type: string
        username:
          type: string
        bio:
          type: string
          nullable: true
        image:
          type: string
  requestBodies:
    NewUserRequest:
      required: true
      description: Details of the new user to register
      content:
        application/json:
          schema:
            required:
              - user
            type: object
            properties:
              user:
                $ref: '#/components/schemas/NewUser'
  responses:
    UserResponse:
      description: User
      content:
        application/json:
          schema:
            required:
              - user
            type: object
            properties:
              user:
                $ref: '#/components/schemas/User'

openapi.spec

Feature: Conduit API

  Background:
    Given openapi ./openapi.yaml

  Scenario Outline: Create User
    When POST /users
    Then status 201
    Examples:
      | username        | password            | email           |
      | johndoe234      | johndoe234Password  | john@doe234.com |

Run with example: specmatic test --testBaseURL=https://api.realworld.io/api openapi.spec Run without example: specmatic test --testBaseURL=https://api.realworld.io/api openapi.yaml

Expected behavior Expect an string value in the passed exampled for the password property. Send an string value for the password property if no example is passed. Ideally mask the password in the output.

Relevant output With example

Reason: In scenario "POST /users. Response: User"
           API: POST /users -> 201

             >> REQUEST.BODY.user.password

                Exception thrown:
                Format error in example of "password"
                Contract expected json object but found value johndoe234Password

Without Example

  Request to https://api.realworld.io/api at 2023-9-25 4:24:16.107
    POST /api/users
    Host: api.realworld.io
    Accept-Charset: UTF-8
    Accept: */*

    {
        "user": {
            "password": {
            },
            "email": "TCEEO",
            "username": "JOFCU"
        }
    }

System Information:

joelrosario commented 1 year ago

Hi @GeekBeardLinks good catch! This is definitely a bug.

If you happen to have the time to send us a PR with tests that fixes this, we'd be grateful :-)

GeekBeardLinks commented 12 months ago

Kotlin is not my thing, but I can try it (I will ask my colleagues for some help). Any clue as to what files I should look at?

harikrishnan83 commented 8 months ago

@GeekBeardLinks apologies for the radio silence on this issue. The fix should be available in our upcoming release. cc @joelrosario

harikrishnan83 commented 7 months ago

@GeekBeardLinks The fix is now available as part of release 1.2.15.