Additional properties not causing validation failure in inline (nested) object definitions

Issue #131 resolved
Nikhil Raman created an issue

Current behavior

  1. Consumer is setting a field in the response PactDslJsonBody (inside an array) in Pact definition which is not present on Provider swagger spec.
  2. We are using ValidatedPactProviderRule
  3. Tests are passing.

Expected behavior

Fail the test with proper messages.

Version used

  • com.atlassian.oai:swagger-request-validator-core:1.4.5
  • com.atlassian.oai:swagger-request-validator-pact:1.4.5

Swagger

paths:
  /v1/Users/{userId}/organization-permissions:
    get:
      summary: Gives back a users permissions to organizations
      tags:
        - Users
        - Organization
      produces:
        - "application/json"
      parameters:
        -
          name: userId
          in: path
          description: The id of the user
          required: true
          type: string
          maxLength: 255
      responses:
        200:
          description: Ok
          schema:
            $ref: '#/definitions/OrgPermissionsResponse'
        404:
          description: User does not exist.
          schema:
            $ref: '#/definitions/NonScimError'
        500:
          description: Internal server error.
          schema:
            $ref: '#/definitions/NonScimError'
definitions:
  OrgPermissionsResponse:
    type: object
    description: |
      An object containing a list of organisations and the permissions that the given user has on them.
    properties:
      organisationPermissions:
        type: array
        items:
          orgId:
            type: string
          permissions:
            type: array
            items:
              type: string
          productList:
            type: array
            items:
              type: string

Pact definition

@Pact(provider = PROVIDER_ID, consumer = CONSUMER_ID)
    public PactFragment getOrganizationPermissions(PactDslWithProvider builder) {
        PactDslJsonBody pactDslJsonBody = new PactDslJsonBody();
        pactDslJsonBody.array("organisationPermissions")
                .object()
                .stringValue("orgId", "test-org-id")
                .array("permissions").string(MANAGE_PERMISSION).closeArray()
                // Extra fields in response : products
                .array("products").string(IDENTITY_MANAGER).closeArray()
                .closeObject()
                .closeArray();

        return builder
                .uponReceiving("a request to get organization permissions")
                .method("GET")
                .path("/v1/Users/" + USER_ID + "/organization-permissions")
                .headers(ImmutableMap.of("Authorization", "Bearer pactToken"))
                .willRespondWith()
                .status(200)
                .body(pactDslJsonBody.asBody())
                .toFragment();
    }

Comments (8)

  1. James Navin

    I tried to reproduce the problem on a branch but am not having much luck:

    https://bitbucket.org/atlassian/swagger-request-validator/src/141cc395317253bb20d50381b609ed93d8e8e766/swagger-request-validator-pact/src/test/java/com/atlassian/oai/validator/pact/PactConsumerValidationTest.java

    In this test I am simulating having additional fields in the response body and it is failing appropriately.

    Could you take a look at the test and see if you can spot what Im doing differently to you?

    Also - can I double check that you don't have a .swagger-validator or swagger-validator.properties config somewhere that might be overriding the validation level to make it non-error? (you should be able to set a breakpoint at com/atlassian/oai/validator/pact/ValidatedPactProviderRule.java:88 and check for what the contents of the validation report are)

  2. James Navin

    Ok - Ive worked out what the problem is.

    There are two things going on here:

    • In your example the array definitions are actually malformed - the properties on the inner objects need to be under properties

    e.g.

    properties:
          organisationPermissions:
            type: array
            items:
              type: string // HERE
              properties:  // HERE
                orgId:
                    type: string
                permissions:
                    type: array
                    items:
                      type: string
              productList:
                type: array
                items:
                  type: string
    
    • Looks like there is a bug where the additionalProperties check isn't working for inline object definitions within arrays or objects
  3. James Navin

    As a workaround for now - if you split your schema definitions out and use a $ref the validation will be applied correctly

    e.g.

    OrgPermissionsResponse:
        type: object
        description: |
          An object containing a list of organisations and the permissions that the given user has on them.
        properties:
          organisationPermissions:
            type: array
            items:
              $ref: '#/definitions/OrgPermission'
      OrgPermission:
        type: object
        properties:
          orgId:
            type: string
          permissions:
            type: array
            items:
              type: string
          productList:
            type: array
            items:
              type: string
    
  4. Log in to comment