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

Validate min = 0 #304

Open
tienvx opened this issue Jul 28, 2023 · 2 comments
Open

Validate min = 0 #304

tienvx opened this issue Jul 28, 2023 · 2 comments

Comments

@tienvx
Copy link
Contributor

tienvx commented Jul 28, 2023

According to https://docs.pact.io/faq#why-is-there-no-support-for-specifying-optional-attributes, array with min=0 is not supported at all.

... This is why you can only specify an array with minimum length 1 OR a zero length array.

But I still can set min = 0 in consumer test. Pact file is generated. Provider verification is passed if attribute/field is empty array. Here is how I did it:

Instead of using eachLike in pact-js, I replace it with custom code like this

children: {
    value: [uuid(child)],
    getValue: () => [uuid(child)],
    pact:matcher:type': 'type',
    min: 0,
}
Full consumer test
describe('Test', () => {
  test('User has full information', async () => {
      const user = {
          id: uuid(id),
          rels: {
              children: {
                  value: [uuid(child)],
                  getValue: () => [uuid(child)],
                  'pact:matcher:type': 'type',
                  min: 0,
              }
          }
      };
      pact.addInteraction({
          states: [{ description: 'Users with full information' }],
          uponReceiving: 'get list users with full information',
          withRequest: {
              method: 'GET',
              path: '/tree',
              headers: {
                  Accept: '*/*',
              }
          },
          willRespondWith: {
              status: 200,
              headers: {
                  'Content-Type': 'application/json',
              },
              body: eachLike(user),
          },
      });

      await pact.executeTest(async (mockserver: V3MockServer) => {
          await waitPort({
              host: '127.0.0.1',
              port: mockserver.port,
          });
          await fetch(`${mockserver.url}/tree`);
      });
  });
});

Consumer test is passed and pact file is generated without any error from ffi library:

Pact file
{
"consumer": {
  "name": "admin"
},
"interactions": [
  {
    "description": "get list users with full information",
    "pending": false,
    "providerStates": [
      {
        "name": "Users with full information"
      }
    ],
    "request": {
      "headers": {
        "Accept": [
          "*/*"
        ]
      },
      "method": "GET",
      "path": "/tree"
    },
    "response": {
      "body": {
        "content": [
          {
            "id": "45e6cec9-f5ea-4d2e-b563-001a04b188e3",
            "rels": {
              "children": [
                "11d5e38c-705c-40ba-9839-e276c9958a81"
              ]
            }
          }
        ],
        "contentType": "application/json",
        "encoded": false
      },
      "headers": {
        "Content-Type": [
          "application/json"
        ]
      },
      "matchingRules": {
        "body": {
          "$": {
            "combine": "AND",
            "matchers": [
              {
                "match": "type",
                "min": 1
              }
            ]
          },
          "$[*].id": {
            "combine": "AND",
            "matchers": [
              {
                "match": "regex",
                "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
              }
            ]
          },
          "$[*].rels.children": {
            "combine": "AND",
            "matchers": [
              {
                "match": "type",
                "min": 0
              }
            ]
          },
          "$[*].rels.children[*]": {
            "combine": "AND",
            "matchers": [
              {
                "match": "regex",
                "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
              }
            ]
          }
        },
        "header": {}
      },
      "status": 200
    },
    "type": "Synchronous/HTTP"
  }
],
"metadata": {
  "pact-js": {
    "version": "12.1.0"
  },
  "pactRust": {
    "ffi": "0.4.6",
    "models": "1.1.8"
  },
  "pactSpecification": {
    "version": "4.0"
  }
},
"provider": {
  "name": "relationship"
}
}

Provider response look like this:

Provider response
[
{
  "data": {
    "avatar": "https://via.placeholder.com/640x480.png/001188?text=sit",
    "birthday": "1975-02-08T12:07:56+00:00",
    "first name": "Miller",
    "gender": "O",
    "last name": "Gutkowski"
  },
  "id": "ee02fd8e-f119-3765-8ae7-7aa44040cc42",
  "rels": {
    "children": [],
    "father": "45dc0132-ead3-3d02-a80b-aa5c8562d32c",
    "mother": "8c67af20-fb87-3129-8f52-61c498a3a2c4",
    "spouses": []
  }
},
{
  "data": {
    "avatar": "https://via.placeholder.com/640x480.png/003311?text=dolor",
    "birthday": "2014-01-16T01:05:18+00:00",
    "first name": "Pearl",
    "gender": "F",
    "last name": "Wisozk"
  },
  "id": "8c67af20-fb87-3129-8f52-61c498a3a2c4",
  "rels": {
    "children": [
      "ee02fd8e-f119-3765-8ae7-7aa44040cc42"
    ],
    "father": null,
    "mother": null,
    "spouses": [
      "45dc0132-ead3-3d02-a80b-aa5c8562d32c"
    ]
  }
},
{
  "data": {
    "avatar": "https://via.placeholder.com/640x480.png/00aabb?text=ut",
    "birthday": "1970-09-21T18:29:04+00:00",
    "first name": "Mavis",
    "gender": "M",
    "last name": "Altenwerth"
  },
  "id": "45dc0132-ead3-3d02-a80b-aa5c8562d32c",
  "rels": {
    "children": [
      "ee02fd8e-f119-3765-8ae7-7aa44040cc42"
    ],
    "father": null,
    "mother": null,
    "spouses": [
      "8c67af20-fb87-3129-8f52-61c498a3a2c4"
    ]
  }
}
]

Provider verification is passed as expected, indicate that min=0 is supported by ffi library (it should not support according to the article above):

Verifying a pact between admin and relationship

  get list users with full information (0s loading, 53ms verification)
     Given Users with full information
    returns a response which
      has status code 200 (OK)
      includes headers
        "Content-Type" with value "application/json" (OK)
      has a matching body (OK)
Provider verification full log

provider-verification-log.txt

Updated: Slack's discussion https://pact-foundation.slack.com/archives/C9VBGLUM9/p1690524409460549

@rholshausen
Copy link
Contributor

This is were I disagree with the statement linked above. I believe that things should be explicit and we should avoid implicit rules. If you want the matching to not accept empty arrays, you must set min = 1. If you set min = 0, then you have declared your intent and the Rust matching will accept that.

@tienvx
Copy link
Contributor Author

tienvx commented Aug 24, 2023

@mefellows so maybe we can remove the statement from that article instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants