Afternoon! Working on provider verification tests ...
# pact-js
p
Afternoon! Working on provider verification tests and in some environments it's possible the test would be run multiple times. I'd like to clean up any data that's created Seems the easiest approach is to inspect the response body to get the record ID's that have been created and clean them up in an afterAll() method. Would the requestFilter be the place to do this and, if so, is there a way to know if the function is being run in the context of the request or response stages? Seems like the same function is run for both thinking
❤️ 1
t
It’s better to use the state setup and teardown functions- they’re for this exact use case
☝️ 1
p
Thanks @Timothy Jones, can you point me to an example of a state teardown? I've not come across it being used that way, only for the setup.
t
Huh, for some reason they’re not documented
@Matt (pactflow.io / pact-js / pact-go) ^ This is probably why there are a lot of questions about this
👍 1
Anyway, the type is:
Copy code
export type StateFuncWithSetup = {
  setup?: StateFunc;
  teardown?: StateFunc;
};
So you just go:
Copy code
'Whatever your state name is': {
    setup: (parameters) => {
      // do your setup here
      // return a promise if you need to
    },
    teardown: (parameters) => {
      // do your teardown here
      // return a promise if you need to
    },
  },
m
I’ll add to the docs. Thanks team
🙌 1
p
Thanks for adding this!
Attempting to use the setup/teardown and I am running into an issue in TS complaining about the type.
Copy code
(property) 'my state': {
    setup: () => Promise<void>;
    teardown: () => Promise<void>;
}
Type '{ setup: () => Promise<void>; teardown: () => Promise<void>; }' is not assignable to type 'StateHandler & ((state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>)'.
  Type '{ setup: () => Promise<void>; teardown: () => Promise<void>; }' is not assignable to type 'StateFuncWithSetup & ((state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>)'.
    Type '{ setup: () => Promise<void>; teardown: () => Promise<void>; }' is not assignable to type '(state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>'.
      Type '{ setup: () => Promise<void>; teardown: () => Promise<void>; }' provides no match for the signature '(state: string, params?: { [name: string]: string; } | undefined): Promise<unknown>'.ts(2322)
Could I have the wrong type defs? (using
"@pact-foundation/pact": "^10.4.1"
which seems to be latest).
Although, it seems right looking at the types. Must be something silly I'm doing.
Okay, we managed to work around it by creating our own type to make sure the right StateHandlers was being referred to. It's hacky, but works. Not sure if this is an issue with the pact types and needs a bug raising?
Copy code
type ShimmedVerifierOptions = Omit<VerifierOptions, 'stateHandlers'> & {
  stateHandlers: StateHandlers;
};

const opts: ShimmedVerifierOptions = {
...
stateHandlers: {
    'my state': {
      setup: async () => {
        console.log('setup');
      teardown: async () => {
       console.log('teardown');
      },
    },
  },
};

...

async () => await new Verifier(opts as VerifierOptions).verifyProvider(),
t
You’re not doing anything wrong. This is a problem in a recent version where there are two unrelated definitions with the same name, which typescript is merging.
I thought I opened an issue about this, but it looks like I didn’t. Yes please, an issue would be great. The problem is that Pact exports two incompatible
interfaces
called
StateHandler
. To work around it, you can: 1) Downgrade to before the interfaces were merged (I’m not sure when this was) 2) Define your state handlers explicitly as one of the types it accepts (so typescript doesn’t try to figure it out) 3) Use a type assertion as you’re doing (I personally don’t like this way, as it might hide other problems).
Oh, actually, your way seems reasonably safe. But I agree, not ideal.
I think you could avoid the
as VerifierOptions
by not importing
StateHandlers
and instead defining it yourself to match exactly one of the state handler definitions.
(apologies for the vagueness, although I still answer pact questions, I’m not a maintainer any more)
p
Thanks for the replies @Timothy Jones! I appreciate the help. Sorry for the delay, I was out over the weekend. Will get an issue raised up when I get a moment later this week.
🙌 2
Raised. First time submitting an issue, so shout if you guys need anything more.
t
That’s a great first issue, Paul! If everyone wrote issues like this one, I’d be pretty happy.
❤️ 1
p
A bit of a necro thread (sorry). I just got back to this code to remove our shimmed VerifierOptions and noticed that even though we now have
StateHandlers
and
MessageStateHandlers
their union via
VerifierOptions
means a
StateFuncWithSetup
can't satisfy the
MessageStateHandler
type. So while simple
StateFunc
handlers are typing correctly, the
StateFuncWithSetup
are not. Here's an example:
Copy code
import { MessageStateHandlers, Verifier, VerifierOptions } from '@pact-foundation/pact';

// This is fine.
const stateHandlers: StateHandlers = {
  key: {
    setup: async () => {
      // setup
    },
  },
};

// This is not
const unionStateHandlers: StateHandlers & MessageStateHandlers = {
  key: {
    setup: async () => {
      // setup
    },
  },
};

/* VerifierOptions results in:
* stateHandlers expecting `(property) ProxyOptions.stateHandlers?: (StateHandlers & MessageStateHandlers) | undefined`
*/
I don't think I'm doing anything incorrect here, but if I am just being a dummy please do point it out 🙂 Happy to raise a new issue if you'd like?
t
Have you updated to the latest?
m
oh wait lol, that was you 😆 (I should have looked up)
you’ll need to be on the 11.x line, because the fix for your issue was a breaking change
p
I really need to work out why my slack notifications are busted, sorry for the tardy reply here guys. Yes, I'm on the 11.x line. I think my above example is followable, but if you'd like something more concrete let me know and I can try to carve out a little time to put it together.
t
Have you updated to the latest?
Also, your example above doesn’t have your definition of
StateHandlers
If you’re using the internally exported
StateHandlers
, then I don’t know why you’d expect
StateHandlers & MessageStateHandlers
to compile. What are you trying to achieve?
The two pact types
StateHandlers
and
MessageStateHandlers
are not compatible
StateHandlers and MessageStateHandlers their union via VerifierOptions means a StateFuncWithSetup can’t satisfy the MessageStateHandler type.
Yes, that’s right. This is the problem that separating the types corrected. In your example, you’re putting them back together?
I don’t know why they are different types to be honest. There’s probably a bigger issue (and maybe a bug) for a maintainer to look at.