PactNet Provider test fails because of 404 when running the test - pact

I have a consumer that has successfully created a pact file:
{
"consumer": {
"name": "CakeService"
},
"provider": {
"name": "CoolPersonService"
},
"interactions": [
{
"description": "A GET request to get a person who is cool",
"providerState": "There is a person who has IsCool set to 'true'6",
"request": {
"method": "get",
"path": "/CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a",
"headers": {
"X-Requested-With": "XMLHttpRequest",
"CallerName": "Pact_Test#Local"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": {
"FirstName": "Some",
"LastName": "Name",
"IsCool": true
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
The problem is the test for the provider. It gets a 404 for
/CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a
but if I send a GET to that route using an HTTP client, I get a 200 response and the expected data is returned.
Here's the output from the test run:
Test Name: EnsureSomethingApiHonoursPactwithConsumer
Test Outcome: Failed
Result Message:
Test method PactTests.PactTests.EnsureSomethingApiHonoursPactwithConsumer threw exception:
PactNet.PactFailureException: Pact verification failed. See output for details.
If the output is empty please provide a custom config.Outputters (IOutput) for your test framework, as we couldn't write to the console.
Result StandardOutput:
[2018-07-13 10:59:05] INFO WEBrick 1.3.1
[2018-07-13 10:59:05] INFO ruby 2.2.2 (2015-04-13) [i386-mingw32]
..........++++++
..........++++++
[2018-07-13 10:59:07] INFO
[2018-07-13 10:59:07] INFO WEBrick::HTTPServer#start: pid=109760 port=9222
[2018-07-13 10:59:07] ERROR Errno::ECONNRESET: An existing connection was forcibly closed by the remote host.
C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:61:in `sysread'
C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:61:in `fill_rbuff'
C:/redacted/PactTests/bin/Debug/pact-win32/lib/ruby/lib/ruby/2.2.0/openssl/buffering.rb:301:in `eof?'
C:/redacted/PactTests/bin/Debug/pact-win32/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/httpserver.rb:80:in `run'
C:/redacted/PactTests/bin/Debug/pact-win32/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/server.rb:191:in `block in start_thread'
INFO: Reading pact at C:/redacted/PactTests/Pacts/cakeservice-coolpersonservice.json
Verifying a pact between CakeService and CoolPersonService
Given There is a person who has IsCool set to 'true'6
A GET request to get a person who is cool
with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a
returns a response which
DEBUG: Setting up provider state 'There is a person who has IsCool set to 'true'6' for consumer 'CakeService' using provider state server at https://localhost/CoolPersonService/provider-states
I, [2018-07-13T10:59:11.805597 #102868] INFO -- request: POST https://localhost/CoolPersonService/provider-states
D, [2018-07-13T10:59:11.805597 #102868] DEBUG -- request: User-Agent: "Faraday v0.15.0"
Content-Type: "application/json"
I, [2018-07-13T10:59:23.352124 #102868] INFO -- response: Status 200
D, [2018-07-13T10:59:23.352625 #102868] DEBUG -- response: content-type: "application/json; charset=utf-8"
server: "redacted"
x-powered-by: "redacted"
date: "Fri, 13 Jul 2018 08:59:23 GMT"
connection: "close"
content-length: "84"
has status code 200 (FAILED - 1)
has a matching body (FAILED - 2)
includes headers
"Content-Type" which equals "application/json; charset=utf-8" (FAILED - 3)
Failures:
1) Verifying a pact between CakeService and CoolPersonService Given There is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which has status code 200
Failure/Error: expect(response_status).to eql expected_response_status
expected: 200
got: 404
(compared using eql?)
2) Verifying a pact between CakeService and CoolPersonService Given There
is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which has a matching body
>Failure/Error: expect(response_body).to match_term expected_response_body, diff_options, example
Encoding::UndefinedConversionError:
"\xC3" from ASCII-8BIT to UTF-8
3) Verifying a pact between CakeService and CoolPersonService Given There is a person who has IsCool set to 'true'6 A GET request to get a person who is cool with GET /CoolPersonService/persons/e674a2d0-57e6-471d-96dd-a91c0077283a returns a response which includes headers "Content-Type" which equals "application/json; charset=utf-8"
Failure/Error: expect(header_value).to match_header(name, expected_header_value)
Expected header "Content-Type" to equal "application/json; charset=utf-8", but was "text/html; charset=utf-8"
1 interaction, 1 failure
Failed interactions:
To re-run just this failing interaction, change the verify method to '.Verify(description: "A GET request to get a person who is cool", providerState: "There is a person who has IsCool set to 'true'6")'. Please do not check in this change! # A GET request to get a person who is cool given There is a person who has IsCool set to 'true'6
Here's the test method for the provider:
[TestMethod]
[TestCategory("Pact")]
public void EnsureSomethingApiHonoursPactwithConsumer()
{
const string serviceUri = "https://localhost/CoolPersonService";
var config = new PactVerifierConfig
{
Verbose = true
};
IPactVerifier pactVerifier = new PactVerifier(config);
pactVerifier
//.ProviderState($"{serviceUri}/provider-states")
.ProviderState($"{serviceUri}/provider-states")
.ServiceProvider("CoolPersonService", serviceUri)
.HonoursPactWith("CakeService")
.PactUri(#"C:\repos\Pact\API_CoolPersonService\PactTests\Pacts\cakeservice-coolpersonservice.json")
.Verify();
}

If you do a GET to a resource, and you get a 404, to me it sounds like the expected data is not present on the server - and that implies that the provider state has not been set up correctly.
Please read about provider states here https://docs.pact.io/getting-started/provider-states and here https://docs.pact.io/implementation-guides/ruby/provider-states#non-ruby-applications
If you do a POST to the same route and receive the response you expected from a GET, it may be that you have just created a new resource, and it is returning the body of the newly created resource.
I see that you are also having some encoding issues (Encoding::UndefinedConversionError: "\xC3" from ASCII-8BIT to UTF-8) I believe this has been fixed in the latest version of the underlying library (called the "pact standalone") so please ensure you have the latest version of pact-net. If you already do have the latest version of pact-net, then please raise an issue for the standalone to be upgraded.

For those still stumped by the issue, the "\xC3" from ASCII-8BIT to UTF-8 error also happens because the response by your provider couldn't be encoded e.g. your provider returns a 500 with a text/html response.

Related

Failed to fetch for application/octet-stream for small subset of users

I have two versions of an API I can toggle via a feature flag. (One that returns application/json and another that returns application/octet-stream)
When I enabled the feature flag to use the new application/octet-stream There seems to be a small subset of users for the API where they received failed to fetch. The users where the octet-stream API works and doesn't have the same browser versions and OS. The different users have same browser versions and operating system.
This is the request header I send for both API.
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"authorization": "...",
"content-type": "application/json",
"sec-ch-ua": "\".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\"", // They would be using Chrome and it might be v102
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "// I believe this would be Windows 10",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
},
"referrer": "...",
"referrerPolicy": "no-referrer-when-downgrade",
"body": "...",
"method": "POST",
"mode": "cors",
"credentials": "include"
This is the error from the logs (its similar to errors where there's no connection but the server receives the request and the other APIs seem to be returning correctly based on the logs)
"error": {
"message": "Failed to fetch",
"name": "TypeError",
"stack": "TypeError: Failed to fetch\n (...the chunks it failed at)"
},
Does anyone know what could be causing this issue? Am I missing an request or response header like maybe changing accept-encoding? or is it maybe a corporate firewall?
I had the same problem. The main cause of this - free space on disk where Chrome catalog located. See details https://stackoverflow.com/questions/10988569/storage-limits-on-chrome-browser,

Why "Invalid snak data" on updating wikibase?

I am trying to learn how to update values on Wikidata using the API. Login and csrf cookies work ok, but when I try to update a value I get an invalid-snak error.
The request body looks like this:
POST /w/api.php HTTP/1.1
Accept-Encoding: gzip
Content-Length: 178
User-Agent: Mojolicious (Perl)
Host: test.wikidata.org
Content-Type: application/x-www-form-urlencoded
Cookie: [omitted]
action=wbcreateclaim&bot=1&entity=Q3345&format=json&property=P9876&snaktype=value&token=[omitted]&value=%7B%22entity-type%22%3A%22Q1917%22%7D
and the response is:
{
"error": {
"code": "invalid-snak",
"info": "Invalid snak data.",
"messages": [
{
"name": "wikibase-api-invalid-snak",
"parameters": [],
"html": {
"*": "Invalid snak data."
}
}
],
"*": "See https://test.wikidata.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
},
"servedby": "mw1386"
}
I've tried various ways to succeed with an update by changing the value - no results. The only update I succeeded with is one with snaktype=novalue - which would confirm that the issue is with the snak vaue alone.
So the question is, what's the right way to make an update to a snakvalue?
The problem is that you are stating value={"entity-type":"Q1917"}, but Q1917 is not an entity-type!
You should instead state value={"entity-type":"item","numeric-id":1917}.
For deepen the topic, see the Wikidata API's documentation.

Amazon Advertising API: ASINs report request returns “Missing campaign type”

Request to API-Endpoint:
POST https://advertising-api-eu.amazon.com/v2/asins/report
Official documentation:
https://advertising.amazon.com/API/docs/en-us/reference/sponsored-products/2/reports
Headers:
Authorization: Bearer Atza|xxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Amazon-Advertising-API-ClientId: xxxxxxxxxxxxxxxxxxxxxxxxxx
Amazon-Advertising-API-SCOPE: xxxxxxxxxxxxxxxxxxxxxxx
Request:
{
"segment": "query",
"reportDate":"20200201",
"metrics": "campaignName,campaignId,adGroupName,adGroupId,keywordId,keywordText,asin,otherAsin,currency,matchType,attributedUnitsOrdered30d,attributedUnitsOrdered30dOtherSKU,attributedSales30dOtherSKU"
}
Response:
{
"code": "400",
"details": "Missing campaign type",
"requestId": "7Q8PMWM2618KAS0VEG87"
}
Question:
I think the error message is misleading (because i checked the documentation twice and because of my former experiences with the API).
But what is the real error? How can i get a ASINs report?
I asked Amazon Support and they replied:
"Asin report would need campaignType in the payload to succeed the operation. We have a documentation update pending on this. Please be noted that query segmentation is only allowed for keyword, target and productAds report. An example payload:-
GET https://advertising-api.amazon.com/v2/asins/report"
{
"reportDate":"20200201",
"campaignType": "sponsoredProducts",
"metrics":"campaignName,
campaignId,
adGroupName,
adGroupId,
keywordId,
keywordText,
asin,
otherAsin,
currency,
matchType,
attributedUnitsOrdered30d,
attributedUnitsOrdered30dOtherSKU,
attributedSales30dOtherSKU"
}

LinkedIn API request fails with "Unpermitted fields present in RESOURCE_KEY: Data Processing Exception while processing fields [/memberId]"

I'm trying the following request:
GET https://api.linkedin.com/v2/people/(id:urn:li:person:<person id>)?oauth2_access_token=<token>&projection=(results*(localizedFirstName,vanityName))
But I always get a:
{
"serviceErrorCode": 100,
"message": "Unpermitted fields present in RESOURCE_KEY: Data Processing Exception while processing fields [/memberId]",
"status": 403
}
If I try to do it using the alternative API:
GET https://api.linkedin.com/v2/people?ids=List((id:urn:li:person:<person id>))&oauth2_access_token=<token>&projection=(results*(localizedFirstName,vanityName))
An Internal Server Error is returned:
{
"message": "Internal Server Error",
"status": 500
}
I'm using Google Chrome to perform those requests.
I tried using Postman too.
Headers:
X-Restli-Protocol-Version: 2.0.0
Authorization: Bearer <token>
Got:
{
"serviceErrorCode": 0,
"message": "Syntax exception in path variables",
"status": 400
}
My app permissions are:
r_emailaddress
r_ads
w_organization_social
rw_ads
r_basicprofile
r_liteprofile
r_ads_reporting
r_organization_social
rw_organization_admin
w_member_social
I tried other APIs (socialActivity, ugcPosts) and everything looks fine.
I checked my API usages at https://www.linkedin.com/developers/apps/<id>/usage and people usage is currently 0%.
The tested user profiles are also public.
You should only use the id (instead of the urn). also the fields projection is wrong:
Use:
projection=(localizedFirstName,vanityName)
Instead of:
projection=(results*(localizedFirstName,vanityName))
As example:
curl -H "X-Restli-Protocol-Version: 2.0.0" \
"https://api.linkedin.com/v2/me?oauth2_access_token=<TOKEN>&projection=(id)"
Will return
{
"id": <ID>
}
and use it as:
curl -H "X-Restli-Protocol-Version: 2.0.0" \
"https://api.linkedin.com/v2/people/(id:<ID>)?oauth2_access_token=<TOKEN>&projection=(localizedFirstName,vanityName)"
So:
{
"vanityName": "<VANITY-NAME>",
"localizedFirstName": "<NAME>"
}
Hope this help
id parameter needs only person_id but you are providing urn.Try this https://api.linkedin.com/v2/people/(id:person_id) and don't forgot to include X-RestLi-Protocol-Version:2.0.0 in header while making call.

google flex endpoint 403 forbidden

I've developed some google flex endpoints. They work locally but when I deploy the app (gcloud app deploy) I get a http status 403 forbidden. I'm using ajax to call the endpoint like this:
var echoEndpoint = function() {
$.ajax(userBaseUrl+'/echo', {
headers: {'Authorization': 'Bearer ' + userIdToken},
type: 'GET',
data: "key=my special key"
})
}
I'm protecting the endpoint with an apikey and passing the userIdToken in the header. The above code produces the 403 forbidden. But if I remove the header it works. albeit no user token. Here is the code that will NOT produce the 403
var echoEndpoint = function() {
$.ajax(userBaseUrl+'/echo', {
type: 'GET',
data: "key=my special key"
})
}
here is my paths section of my openapi.yaml
.....
paths:
"/echo":
get:
description: "Echo a test message."
operationId: "echo"
produces:
- "application/json"
responses:
200:
description: "Echo"
schema:
$ref: "#/definitions/echoMessage"
x-security:
- firebase:
audiences:
- "my project-id"
....
definitions:
echoMessage:
properties:
message:
type: "string"
Do I need to specify in my openapi.yaml that I'm sending a header in the request? If so how and where? I tried to put it in the definitions section but that yields a INVALID_ARGUMENT error when trying to deploy.
Did you define "firebase" in "securityDefinitions" as shown in this example (https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/appengine/flexible/endpoints/openapi.yaml#L108"?

Resources