Hi, do we have any example on how to use dynamic i...
# pact-js
f
Hi, do we have any example on how to use dynamic ids for V3?
m
f
Thank you. I’ll have a look. How long till the v3 version goes past beta, do you know? Also, is it safe to start using it now?
Sorry, I tried but couldn’t do. I’m a bit confused perhaps with the Javascript syntax, not sure. Tried to do this for our project with some drafts here https://github.com/francislainy/mbfrontend/blob/master/src/pact/getLocation.pact.spec.js https://github.com/francislainy/mbfrontend/blob/master/src/pact/getLocationV3.pact.spec.js but no success.
m
What's the issue - is it not being injected on the provider test (I can't see a provider test there)
f
No, the provider is java.
The contract is not generating.
m
What's the error?
f
I think there may be different errors. I’m not a Javascript person and may be mixing up versions and getting the syntax wrong here.
m
What version of pact do you have installed?
npm list @pact-foundation/pact
f
Copy code
"devDependencies": {
  "@pact-foundation/pact": "^9.17.2",
  "@pact-foundation/pact-node": "^10.17.1",
  "chai": "^4.3.6",
  "jest-pact": "^0.9.0-beta.v3"
}
message has been deleted
The list command gives me an error.
The whole project is here.
m
Ahh, that's wrong dependency if you need V3. You'll need to be on beta (sorry I assumed you must have been on that version because you were asking about V3) https://github.com/pact-foundation/pact-js#pact-js-v3
f
I think I had that yet, maybe it got removed once I did some reversions. I’ll add back in again and see what I get when triggering this.
👍 1
message has been deleted
Did some changes. I think it’s closer now but still not there yet.
m
is there a reason why you call
getlocation
twice?
Also, does that function send a request with a query string? I can’t see it accepting any params, so just checking
I’m confused as to why the trace logs aren’t showinsg up there which would have (a lot) more detail - maybe Intellij is swallowing the output?
f
No, I deleted the first call.
I get confused with javascript so mixed up two examples together. I get the same error using only the second only though.
Copy code
return provider.executeTest(async (mockserver) => {

    return getLocation(mockserver.url, '100')
        .then((result) => {
            expect(result.title).to.equal('Test');
        });
});
This is what I have now.
m
what does
getLocation
look like?
f
Copy code
exports.getLocation = (basiUrl = BASE_URL, id) => {
    return axios.request({
        method: "GET",
        baseURL: BASE_URL,
        url: `${BASE_URL}/api/mb/location/${id}`,
        headers: {Accept: "application/json"},
    })
}
m
where is the query string?
f
dont’ know.. Where it should be?
m
In your test setup, you’ve told pact that you expect your code to send a request with a query string - but your implementation isn’t sending a query string
f
I only need the dynamic id and copied that from the example.
m
message has been deleted
f
I thought that was the syntax for the v3 to work?
m
OK will the dynamic ID is on the query string there, move the
fromProviderState
from the query to the path
fromProviderState
is the matcher, the example uses a query string but you can use that matcher in other places - you want it on the
path
I have to run, but will check in later
👍 1
f
Copy code
.withRequest({
    method: 'GET',
    path: `/api/mb/location/fromProviderState(${id}, '100')`,
    headers: {Accept: 'application/hal+json'},
})
I think I’m messing up here on this syntax.
m
The path property accepts the matcher function, you can't put the function in the string
f
Sorry Matt, true apologies, but I don’t know Javascript enough to know what I can do or not here I’m afraid.
I’m more on a trial and error kind of copying and pasting at the moment and changing commas around.
I tried these two but that’s not it either.
Copy code
// path:  {'/api/mb/location/id': fromProviderState('${id}', '100')},
path:  fromProviderState(`/api/mb/location/${id}`, '100'),
Copy code
path: fromProviderState('/api/mb/location/${id}', '/api/mb/location/100'),
message has been deleted
m
Hello!
So yes, looks like you have the correct use
f
hmm..
m
I’d like to know why you aren’t getting better logs - you should see what the mock server actually receives
f
don’t know..
m
I can see in your test declaration, you are expecting a hal+json
Accept
header, but your axios client just sends
application/json
f
Changed that now but got the same error.
message has been deleted
message has been deleted
These logs here you mean?
400 error.
m
Any chance you could please paste the full log as text, not a screenshot?
f
Sure, let me save it here
I was thinking to do something where we call the api directly within the same file, similar to what we have here? https://github.com/francislainy/mbfrontend/blob/master/src/pact/getLocations.pact.spec.js
But then I tried and don’t really know how to do it.
And perhaps not even ideal if not using the exact endpoint the consumer triggers?
m
Thanks. Where did you say your current code is? I’ll take a quick look but then I have to go - might be best pairing with somebody who knows JS if you can?
Sure, but if you’re saying the syntax seems correct now I wouldn’t know what to ask them?
The api call works fine outside pact for the react app.
m
thanks, looking at the code now
f
Thanks a lot.
m
you’re not actually using the passed in URL, it’s still using
BASE_URL
(note
basiUrl
is not actually used)(
Copy code
exports.getLocation = (basiUrl = BASE_URL, id) => {
    return axios.request({
        method: "GET",
        baseURL: BASE_URL,
        url: `${BASE_URL}/api/mb/location/${id}`,
        headers: {Accept: "application/json"},
    })
}
so the request isn’t going to the mock server - it’s going to
const BASE_URL = '<http://localhost:8081>';
👍 1
Copy code
...
[2022-04-13T13:07:04Z DEBUG pact_mock_server::mock_server] Started mock server on 127.0.0.1:51431
  console.error
    Error: Error: connect ECONNREFUSED 127.0.0.1:8081
        at Object.dispatchError (/private/tmp/mbfrontend/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:63:19)
        at Request.<anonymous> (/private/tmp/mbfrontend/node_modules/jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js:655:18)
        at Request.emit (events.js:327:22)
        at ClientRequest.<anonymous> (/private/tmp/mbfrontend/node_modules/jsdom/lib/jsdom/living/helpers/http-request.js:121:14)
        at ClientRequest.emit (events.js:315:20)
        at Socket.socketErrorListener (_http_client.js:469:9)
        at Socket.emit (events.js:315:20)
        at emitErrorNT (internal/streams/destroy.js:106:8)
        at emitErrorCloseNT (internal/streams/destroy.js:74:3)
        at processTicksAndRejections (internal/process/task_queues.js:80:21) undefined

      at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
      at Object.dispatchError (node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:66:53)
      at Request.<anonymous> (node_modules/jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js:655:18)
      at ClientRequest.<anonymous> (node_modules/jsdom/lib/jsdom/living/helpers/http-request.js:121:14)

[2022-04-13 13:07:04.403 +0000] ERROR (44671 on macfellows): pact@10.0.0-beta.59: Network Error
f
Cool, that makes sense. Let me try again.
m
also, Intellij (or something) is not properly printing out your logs. I’m guessing this would have been a lot easier to spot if it did. The error above is not a Pact log, it’s a JS error and I couldn’t see it in your log file
worth talking to that JS team member to get a better local setup - something aint right
Working method:
Copy code
exports.getLocation = (baseUrl = BASE_URL, id) => {
  return axios.request({
    method: "GET",
    baseURL: baseUrl,
    url: `${baseUrl}/api/mb/location/${id}`,
    headers: { Accept: "application/json" },
  });
};
f
Yes, I can confirm I got the contract to generate now. 🙂
👍 1
Awesome!
I’ll try to write the Java provider verification and see how it goes.
Thanks very much.
m
you’re welcome 🙌
f
Sorry @Matt (pactflow.io / pact-js / pact-go), we’re now heading to do the migration for our main application. There however we use jest-pact and the syntax is quite different. Below there’s a picture of what we did yesterday here with you on our sample project and our real case scenario. Do you have any suggestion on how to add v3 here, should we keep jest-pact or get rid of it altogether? Thank you.
We have the dynamic ids as part of the body instead of the path this time.
message has been deleted
Should the syntax change somehow as we’re getting errors with it?
Copy code
const requestBodyParameters = {
  client: 'googleclassroom',
  path: '/passthrough',
  requestUrl: fromProviderState(
    '/v1/courses/${courseId}/courseWork/{courseWorkId}',
    '/v1/courses/476794168462/courseWork/481002261081',
  ),
  requestHttpVerb: 'DELETE',
  body: null,
  headers: {},
  pathVariables: {},
  query: null,
};
m
That's an overly zealous eslint complaining, not a real problem. I'd suggest working with a JS Dev of that project that has set the rules up. It's not a pact problem.
👍 1
f
Cool, thanks. Yes, I just realised that. Apologies for misunderstanding this.
m
Haha all good 👍
🙂 1