pact-foundation / pact-js

JS version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
https://pact.io
Other
1.63k stars 346 forks source link

Question - How to fix "Pact Binary Error: WARN: Ignoring unsupported matching rules" #205

Closed cchen-kenzan closed 6 years ago

cchen-kenzan commented 6 years ago

Software versions

Note: The pact tests seem to be running correctly, but getting the following Pact binary errors and wondering how we can resolve them.

Expected behaviour

I want to be able to clear out these Pact binary errors.

Actual behaviour

I'm gettting the following errors when I'm running my interactions to create the pact contracts:

    Pact Binary Error: WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body']['createdDate']
    WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body']['lastModified']
    WARN: Ignoring unsupported matching rules {"match"=>"regex", "regex"=>"^[A-Za-z0-9 -().\\/+]+$"} for path $['body']['description']
    WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body']['id']

Steps to reproduce

We are matching using like in the following manner:

const { Pact, Matchers } = require('@pact-foundation/pact');
const { like, eachLike, regex } = Matchers;

const skillData = {
  createdDate: 1531427089,
  lastModified: 1531427089,
  description: 'Test Description',
  sourceLink: 'http://www.test.com',
  name: 'Test Name',
  id: 123
};

const skillMatchers = {
  createdDate: like(skillData.createdDate),
  lastModified: like(skillData.lastModified),
  description: regex({
    matcher: '^[A-Za-z0-9 -()./+]+$',
    generate: skillData.description
  }),
  id: like(skillData.id),
  name: regex({
    matcher: '^[A-Za-z0-9& ,.!_]+$',
    generate: skillData.name
  }),
  sourceLink: regex({
    matcher: '^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$',
    generate: skillData.sourceLink
  })
};

  describe('the getAllSkills function', () => {
    beforeAll(() => {
      return provider.addInteraction({
        uponReceiving: 'a GET request to get all skills',
        withRequest: {
          method: 'GET',
          path: '/api/skills',
          query: 'sort=name'
        },
        willRespondWith: {
          status: 200,
          headers: resHeaders,
          body: eachLike(skillMatchers)
        }
      });
    });

    it('returns all the skills', () => {
      expect.assertions(2);
      return skillsApi.getAllSkills()
        .then(skills => {
          expect(Array.isArray(skills)).toBe(true);
          expect(skills).toEqual([skillData]);
        });
    });
  });
mefellows commented 6 years ago

@cchen-kenzan is it just those top 4 that are showing up as ignored, or all of the body keys?

Can you please also let us know which version of @pact-foundation/pact you have? (you've shown pact-node which is a related, important lib).

Also there is a micro version upgrade on pact-node you might like to try to see if it addresses your issue.

@bethesque any ideas? I can imagine that the eachLike matcher cascades, but would further assume that the issue would be present on the other keys and not just the four mentioned.

bethesque commented 6 years ago

I believe I've fixed this in the very latest version of pact support. Does the js library version mentioned above have the latest standalone?

mefellows commented 6 years ago

It should be at 1.54.1 which was the latest, as of 2 hours ago. Does it need 1.54.2?

bethesque commented 6 years ago

No, that was an unrelated fix. Bother. I was sure I'd fixed this! @cchen-kenzan can you throw together a git repo that recreates the issue so I can reproduce this on my machine?

mefellows commented 6 years ago

@bethesque sorry, just to be clear, the version of standalone in v6.19.8 of pact-node is 1.54.1, which we need @cchen-kenzan to test first (they are currently on 6.19.7).

bethesque commented 6 years ago

Oh, right. Please update @cchen-kenzan!

cchen-kenzan commented 6 years ago

Thanks @bethesque and @mefellows it seems to have resolved most of my issues, but I'm still getting one pact binary error/warning on the following code:

const personSkillObj = like({
  lastModified: 1531427089,
  learningPath: false,
  proficiency: 1,
  name: 'Test Skill'
});

const personObj = like({
  id: 10000,
  lastModified: 1531427089,
  name: 'Test User',
  radars: eachLike(12345),
  reports: eachLike('Test Report'),
  role: term({
    matcher: 'User|SiteAdmin|TechradarAdmin',
    generate: 'User'
  }),
  username: 'testuser',
  skills: eachLike(personSkillObj)
});

describe('the getAllPeople function', () => {
    beforeAll(() => {
      return provider.addInteraction({
        uponReceiving: 'a GET request to get all people',
        withRequest: {
          method: 'GET',
          path: '/api/persons'
        },
        willRespondWith: {
          status: 200,
          headers: resHeaders,
          body: eachLike(personObj)
        }
      });
    });

    it('should return all the people', () => {
      expect.assertions(2);
      return teamApi.getAllPeople()
        .then(people => {
          expect(Array.isArray(people)).toBe(true);
          expect(people[0].id).toBe(10000);
        });
    });
  });

This is the unsupported matching rule:

[2018-08-03T18:23:51.336Z] ERROR: pact-node@6.19.8/19589 on clairech01-mac:
    Pact Binary Error: WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body'][*]
    WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body'][*]['skills'][*]

I think it may have to do with using eachLike in a nested fashion.

bethesque commented 6 years ago

Yes, I think that is why, but I thought I'd fixed that part. I'll try using your example and see if I can reproduce it.

bethesque commented 6 years ago

Ok, v1.54.3 of the standalone should fix this!!!!

czebe commented 6 years ago

What is this version number for? How can we know our package was updated? pact standalone cli is at 6.19.8 pact-support is at 1.7.2

mefellows commented 6 years ago

All you need to check this is that your version of pact-node is at least v6.19.8 or above.

czebe commented 6 years ago

I'm still getting this error when using matching rule on query parameters. Shouldn't this be supported too?

bethesque commented 6 years ago

Dammit! This is like whackamole. Please provide your code.

The matching is correct, it's just that when you have nested likes, it's complicated to ensure that you get the correct warnings.

czebe commented 6 years ago

My spec is not even nested:

provider.addInteraction({
  uponReceiving: "existing product request",
  state: "product exists and user is authorized to access resource",
  withRequest: {
    method: "GET",
    path: "/products",
    query: {
      id:  term({
        generate: "123",
        matcher: "[1-9][0-9]*" // <-- This is causing the error
      })
    }
  },
  willRespondWith: {
     ...
  }
});
bethesque commented 6 years ago

I've worked out why the warning is there for the query, I just need to work out what to do about it. It can be safely ignored.

jkrnak commented 6 years ago

I have similar problem with an array rule. I'm using pact-1.54.4 I don't think the warning is ignorable, it actually is begin ignored by the pact-provider-verifier standalone.

My matching rule is:

          "$.body.features[*].properties.price": {
            "match": "type"
          },

And I get WARN: Ignoring unsupported matching rules {"match"=>"type"} for path $['body']['features'][*]['properties']['price']

ps: I'm assuming I'm reporting this to the wrong repo, sorry about it. If you tell me where this should be reported @bethesque I'll create an issue in that repo.

ps2: pact is awesome! :) keep up the good work!

bethesque commented 6 years ago

Thanks! The issue belongs in the pact-support repository. Can you raise the issue there please? How are you creating it through the DSL?

Most these warnings have actually been false positives - they occur because there is more than one place in the JSON hierarchy that turns the "match by type" (Pact.like) logic on, and once it's turned on, a repeated "match by type" (nesting a Pact.like) is redundant. It's been remarkably tricky to work out all the nesting cases and make sure that rules that are genuinely not being applied get logged, while making sure the redundant ones aren't!

jkrnak commented 6 years ago

Thanks, I've opened the issue: https://github.com/pact-foundation/pact-support/issues/61