Hi,
I searched documentations to run pact-web within karma for Angular testing. I could successfully run the tiny example of NomiJ located here : https://github.com/NomiJ/Pact-Angular2-Example.
I could adapt this example for POST requests with the following PACT code :
provider = Pact({consumer: 'my_consumer', provider: 'my_provider', web: true});
provider.addInteraction({
uponReceiving: 'a request for ...',
withRequest: {
method: 'POST',
path: '/context/rest/api/v1/...'
},
willRespondWith: {
status: 200,
headers: {'Content-Type': 'application/json'},
body: {reply: 'Ok'}
}
})
And my service code :
this.http.post('/context/rest/api/v1/...', null).map(response => response.json());
The unit test is working perfectly fine and a my_consumer-my_provider.json file is generated.
Now when I do change "POST" method for "PUT", I do receive this error :
Failed: Response with status: 0 for URL: null
Please note that I did activate CORS for pact in my karma.conf.js :
frameworks: ['jasmine', '@angular/cli', 'pact'],
pact: {cors: true},
It seems this type of message is known to come from CORS middleware. I could figure out karma is running on 9876 port and pact-web on 1234, which may be considered as two different origins. I do not see any reason why PUT and POST should not behave the same way. To my understanding, the difference between them is semantic and not technical.
Is there a way to configure pact-web to accept cross-origin requests for PUT like it does for POST by default ?
Should not this cross-origin requests be also activated by default for PUT ?
Thank you in advance for your help.
You might be right, I think we need to add the cors flag to karma-pact when in starts the mock service. I'll leave this open and address it there.
Actually, sorry, can you please try adding the following to the karma config:
pact: {
cors: true
}
This should enable CORS for the pact mock server.
This option is already active. My original post does contain this piece of my karma.conf.js (added it by editing my original question, but only a few minutes after posting it) :
frameworks: ['jasmine', '@angular/cli', 'pact'],
pact: {cors: true},
Without pact: {cors: true}, it neither work for POST nor PUT, which is expected. With this flag however, it does work for POST but not for PUT.
Thanks for the detailed report and sorry I didn't see that before I replied.
One thing you might want to experiment with is _disabling_ the pact plugin for Karma, i.e.:
frameworks: ['jasmine', '@angular/cli']
This basically starts and stops the underlying mock server, which you can start for yourself as follows:
./node_modules/.bin/pact-mock-service --cors true --port 1234
Now you can isolate some of the problems.
λ curl -v localhost:1234
* Rebuilt URL to: localhost:1234/
* Trying ::1...
* Connected to localhost (::1) port 1234 (#0)
> GET / HTTP/1.1
> Host: localhost:1234
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json
< Access-Control-Allow-Origin: *
< Server: WEBrick/1.3.1 (Ruby/2.2.2/2015-04-13) OpenSSL/1.0.2d
< Date: Tue, 30 May 2017 10:44:43 GMT
< Content-Length: 67
< Connection: Keep-Alive
<
* Connection #0 to host localhost left intact
{"message":"No interaction found for GET /","interaction_diffs":[]}
As you can see, the Access-Control-Allow-Origin: * header is coming back, but nothing to do with methods or anything, and further more, a cURL with OPTIONS is returning a 500 which means pre-flight requests won't work.
GET and POST (and HEAD) requests don't require a pre-flight, which probably explains why they work. PUT and others do.
So after all of this, it looks like we don't support the OPTIONS pre-flight check. I'll raise a defect over at the underlying library we use for this.
Thank you for the analysis and detailed explanation why this is happening. In the meantime, I found an ugly workaround with this karma configuration :
browsers: ['Chrome_without_security'],
customLaunchers: {
Chrome_without_security: {
base: 'Chrome',
flags: ['--disable-web-security']
}
},
Because PACT's are entirely development tests and are not in any case going to a production server, this might be ok to bypass the cross-origins check with this configuration.
This might serve other users as well as long as the underlying problem in the mock server is not corrected for PUT requests.
Thanks - we'll properly address the underlying issues, but this is good to
know!
On Tue, May 30, 2017 at 9:35 PM, Wisdomb33r notifications@github.com
wrote:
Thank you for the analysis and detailed explanation why this is happening.
In the meantime, I found an ugly workaround with this karma configuration :browsers: ['Chrome_without_security'], customLaunchers: { Chrome_without_security: { base: 'Chrome', flags: ['--disable-web-security'] } },Because PACT's are entirely development tests and are not in any case
going to a production server, this might be ok to bypass the cross-origins
check with this configuration.This might serve other users as well as long as the underlying problem in
the mock server is not corrected for PUT requests.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/pact-foundation/pact-js/issues/58#issuecomment-304851559,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AADSjDPFwKMJNIwlYBGyVMZeZKo3chJ1ks5r-_8OgaJpZM4NpK2w
.
--
Matt Fellows
I'm a bit late to this party, but does this documentation help? https://github.com/pact-foundation/pact-mock_service/wiki/Using-the-mock-service-with-CORS
@Wisdomb33r can you please check the advice of @bethesque? This actually makes a lot of sense as it could give you a false sense of security if you expect the stub server to do this for you automatically.
@Wisdomb33r how did you get it to work? I'm, getting:
ERROR [karma]: Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 56:13 in the original .ts file), resolving symbol AppModule in MyProject/src/app/app.module.ts
angular-cli in karma is giving me that error, perhaps de versions I'm using? I've tried with Angular2 and 4
@carlosmmelo If you look at my first post, I posted a link a NomiJ example. I took it almost strictly copy-pasted and it worked as-is. Apparently I had the same library versions than him. I'm sorry but I never saw your error message and do not understand what might be wrong.
@mefellows Back from holidays. Things to do prior to this test, but I'll read the documentation from @bethesque and give a feedback when I have a few time.
@mefellows In my case, we should not have to deal with CORS in real life. Backends are accessed through a proxy which is dispatching according to the REST context. This means the --disable-web-security option I'm already using and which is also referenced in the documentation of @bethesque should do the trick. It is debatable if OPTIONS method should be considered as part of the consumer contract or not. I know too little about cross-origins and pre-flight requests to answer if adding explicitly an interaction for OPTIONS does make sense or not.
I agree, not in your case. And I think it's a matter of preference whether you test it in the contract in the situation where you would have CORS in real life. Sometimes CORS configs screw things up, so are worth testing, but if they're stable and you know they already work, then they might not be worth the hassle. I'll close this issue now, feel free to reopen if you have further queries.