Skip to content

Commit

Permalink
Merge pull request #1095 from TimothyJones/master
Browse files Browse the repository at this point in the history
docs: Improve distinction between Pact and PactFlow
  • Loading branch information
mefellows committed Jun 18, 2023
2 parents fc16b3f + 6b8aa43 commit 3e85d5c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 80 deletions.
112 changes: 55 additions & 57 deletions docs/matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,31 @@ Often times, you find yourself having to re-write regular expressions for common
### Match based on type

```javascript
const { like, string } = Matchers
const { like, string } = Matchers;

provider.addInteraction({
state: "Has some animals",
uponReceiving: "a request for an animal",
state: 'Has some animals',
uponReceiving: 'a request for an animal',
withRequest: {
method: "GET",
path: "/animals/1",
method: 'GET',
path: '/animals/1',
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
'Content-Type': 'application/json; charset=utf-8',
},
body: {
id: 1,
name: string("Billy"),
name: string('Billy'),
address: like({
street: "123 Smith St",
suburb: "Smithsville",
street: '123 Smith St',
suburb: 'Smithsville',
postcode: 7777,
}),
},
},
})
});
```

Note that you can wrap a `like` around a single value or an object. When wrapped around an object, all values and child object values will be matched according to types, unless overridden by something more specific like a `term`.
Expand All @@ -80,59 +80,59 @@ Note that you can wrap a `like` around a single value or an object. When wrapped
Matching provides the ability to specify flexible length arrays. For example:

```javascript
pact.eachLike(obj, { min: 3 })
pact.eachLike(obj, { min: 3 });
```

Where `obj` can be any javascript object, value or Pact.Match. It takes optional argument (`{ min: 3 }`) where min is greater than 0 and defaults to 1 if not provided.

Below is an example that uses all of the Pact Matchers.

```javascript
const { somethingLike: like, term, eachLike } = pact
const { somethingLike: like, term, eachLike } = pact;

const animalBodyExpectation = {
id: 1,
first_name: "Billy",
last_name: "Goat",
animal: "goat",
first_name: 'Billy',
last_name: 'Goat',
animal: 'goat',
age: 21,
gender: term({
matcher: "F|M",
generate: "M",
matcher: 'F|M',
generate: 'M',
}),
location: {
description: "Melbourne Zoo",
country: "Australia",
description: 'Melbourne Zoo',
country: 'Australia',
post_code: 3000,
},
eligibility: {
available: true,
previously_married: false,
},
children: eachLike({ name: "Sally", age: 2 }),
}
children: eachLike({ name: 'Sally', age: 2 }),
};

// Define animal list payload, reusing existing object matcher
// Note that using eachLike ensure that all values are matched by type
const animalListExpectation = eachLike(animalBodyExpectation, {
min: MIN_ANIMALS,
})
});

provider.addInteraction({
state: "Has some animals",
uponReceiving: "a request for all animals",
state: 'Has some animals',
uponReceiving: 'a request for all animals',
withRequest: {
method: "GET",
path: "/animals/available",
method: 'GET',
path: '/animals/available',
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
'Content-Type': 'application/json; charset=utf-8',
},
body: animalListExpectation,
},
})
});
```

### Match by regular expression
Expand All @@ -142,30 +142,30 @@ If none of the above matchers or formats work, you can write your own regex matc
The underlying mock service is written in Ruby, so the regular expression must be in a Ruby format, not a Javascript format.

```javascript
const { term } = pact
const { term } = pact;

provider.addInteraction({
state: "Has some animals",
uponReceiving: "a request for an animal",
state: 'Has some animals',
uponReceiving: 'a request for an animal',
withRequest: {
method: "GET",
path: "/animals/1",
method: 'GET',
path: '/animals/1',
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
'Content-Type': 'application/json; charset=utf-8',
},
body: {
id: 100,
name: "billy",
name: 'billy',
gender: term({
matcher: "F|M",
generate: "F",
matcher: 'F|M',
generate: 'F',
}),
},
},
})
});
```

## V3 Matching rules
Expand All @@ -175,7 +175,7 @@ V3 only matching rules are found in the export `MatchersV3` of the `@pact-founda
For example:

```javascript
const { PactV3, MatchersV3 } = require("@pact-foundation/pact")
const { PactV3, MatchersV3 } = require('@pact-foundation/pact');
const {
eachLike,
atLeastLike,
Expand All @@ -185,27 +185,27 @@ const {
string,
regex,
like,
} = MatchersV3
} = MatchersV3;

const animalBodyExpectation = {
id: integer(1),
available_from: timestamp("yyyy-MM-dd'T'HH:mm:ss.SSSX"),
first_name: string("Billy"),
last_name: string("Goat"),
animal: string("goat"),
first_name: string('Billy'),
last_name: string('Goat'),
animal: string('goat'),
age: integer(21),
gender: regex("F|M", "M"),
gender: regex('F|M', 'M'),
location: {
description: string("Melbourne Zoo"),
country: string("Australia"),
description: string('Melbourne Zoo'),
country: string('Australia'),
post_code: integer(3000),
},
eligibility: {
available: boolean(true),
previously_married: boolean(false),
},
interests: eachLike("walks in the garden/meadow"),
}
interests: eachLike('walks in the garden/meadow'),
};
```

| Matcher | Parameters | Description |
Expand All @@ -228,9 +228,9 @@ const animalBodyExpectation = {
| `date` | format: string, example?: string | String value that must match the provided date format string. See [Java SimpleDateFormat](https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html) for details on the format string. If the example value is omitted, a value will be generated using a Date generator and the current system date. |
| `includes` | value: string | Value that must include the example value as a substring. |
| `nullValue` | | Value that must be null. This will only match the JSON Null value. For other content types, it will match if the attribute is missing. |
|`arrayContaining`| variants... | Matches the items in an array against a number of variants. Matching is successful if each variant occurs once in the array. Variants may be objects containing matching rules. |
| `eachKeyLike` | key: string, template: any | Object where the keys itself is ignored, but the values must match a particular shape. Variants may be objects containing matching rules |
|`fromProviderState`| expression: string, exampleValue: string | Sets a type matcher and a provider state generator. See the section below. |
| `arrayContaining` | variants... | Matches the items in an array against a number of variants. Matching is successful if each variant occurs once in the array. Variants may be objects containing matching rules. |
| `eachKeyLike` | key: string, template: any | Object where the keys itself is ignored, but the values must match a particular shape. Variants may be objects containing matching rules |
| `fromProviderState` | expression: string, exampleValue: string | Sets a type matcher and a provider state generator. See the section below. |

#### Array contains matcher

Expand All @@ -239,10 +239,10 @@ by matching each item against each of the variants, and the matching succeeds if
items in the list is not important.

The variants can have a totally different structure, and can have their own matching rules to apply. For an example of how
these can be used to match a hypermedia format like Siren, see [Example Pact + Siren project](https://github.com/pactflow/example-siren).
these can be used to match a hypermedia format like Siren, see [Example Pact + Siren project](https://github.com/pactflow/example-siren), hosted by our friends at [PactFlow](https://pactflow.io/).

| function | description |
|----------|-------------|
| function | description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `arrayContaining` | Matches the items in an array against a number of variants. Matching is successful if each variant occurs once in the array. Variants may be objects containing matching rules. |

```js
Expand Down Expand Up @@ -290,13 +290,11 @@ stateHandlers: {
},
```


## A note about typescript

Because of the way interfaces work in typescript, if you are
passing a typed object to a matcher, and that type is an interface (say `Foo`):


```javascript
interface Foo {
a: string;
Expand Down Expand Up @@ -330,4 +328,4 @@ This is one of the rare places where `type` differs from `interface`. You have t
const f: InterfaceToTemplate<Foo> = { a: "working example" };
```

[specification]: https://github.com/pact-foundation/pact-specification
[specification]: https://github.com/pact-foundation/pact-specification
37 changes: 18 additions & 19 deletions docs/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,28 @@ To dynamically retrieve pacts from a Pact Broker for a provider, provide the bro

```js
const opts = {
pactBroker: "http://my-broker",
provider: "Animal Profile Service",
consumerVersionTags: ["master", "test", "prod"],
}
pactBroker: 'http://my-broker',
provider: 'Animal Profile Service',
consumerVersionTags: ['master', 'test', 'prod'],
};
```

To verify a pact at a specific URL (eg. when running a pact verification triggered by a 'contract content changed' webhook, or when verifying a pact from your local machine, or a network location that's not the Pact Broker, set just the `pactUrls`, eg:

```js
const opts = {
pactUrls: [process.env.PACT_URL],
}
};
```

To publish the verification results back to the Pact Broker, you need to enable the 'publish' flag, set the provider version and optional provider version tags:

```js
const opts = {
publishVerificationResult: true, //generally you'd do something like `process.env.CI === 'true'`
providerVersion: "version", //recommended to be the git sha
providerVersionTags: ["tag"], //optional, recommended to be the git branch
}
providerVersion: 'version', //recommended to be the git sha
providerVersionTags: ['tag'], //optional, recommended to be the git branch
};
```

If your broker has a self signed certificate, set the environment variable `SSL_CERT_FILE` (or `SSL_CERT_DIR`) pointing to a copy of your certificate.
Expand Down Expand Up @@ -149,7 +149,6 @@ Read more about [Provider States](https://docs.pact.io/getting_started/provider_

Provider States can optionally take a setup and teardown function. These are useful in situations where you'd like to cleanup data specific to the provider state.


```js
'Whatever your state name is': {
setup: (parameters) => {
Expand Down Expand Up @@ -213,14 +212,14 @@ Mobile is an exception to this rule - it is common to have multiple versions of
```js
consumerVersionSelectors: [
{
tag: "prod",
tag: 'prod',
all: true,
},
{
tag: "master",
tag: 'master',
latest: true,
},
]
];
```

_NOTE: Using the `all` flag requires you to ensure you delete any tags associated with application versions that are no longer in production (e.g. if decommissioned from the app store)_
Expand Down Expand Up @@ -277,7 +276,7 @@ If any of the middleware or hooks fail, the tests will also fail.

### Publishing Pacts to a Broker

Sharing is caring - to simplify sharing Pacts between Consumers and Providers, we have created the [Pact Broker](https://pactflow.io).
Sharing is caring - to simplify sharing Pacts between Consumers and Providers, we have created the [Pact Broker](https://docs.pact.io/pact_broker).

The Broker:

Expand All @@ -289,7 +288,7 @@ The Broker:
- integrates with other systems, such as Slack or your CI server, via webhooks
- ...and much much [more](https://docs.pact.io/getting_started/sharing_pacts).

[Host your own](https://github.com/pact-foundation/pact_broker), or signup for a free hosted [Pact Broker](https://pactflow.io).
[Host your own using the open source docker image](https://docs.pact.io/pact_broker/docker_images), or sign-up for a [free hosted Pact Broker](https://pactflow.io) with our friends at PactFlow.

#### Publish in npm scripts

Expand All @@ -311,7 +310,7 @@ access token instead of a password, use the environment variable

#### Publishing Verification Results to a Pact Broker

If you're using a Pact Broker (e.g. a hosted one at https://pactflow.io), you can
If you're using a [Pact Broker](https://docs.pact.io/pact_broker), (e.g. a hosted one with our friends at [PactFlow](https://pactflow.io)), you can
publish your verification results so that consumers can query if they are safe
to release.

Expand All @@ -324,8 +323,8 @@ To publish the verification results back to the Pact Broker, you need to enable
```js
const opts = {
publishVerificationResult: true, //recommended to only publish from CI by setting the value to `process.env.CI === 'true'`
providerVersion: "version", //recommended to be the git sha eg. process.env.MY_CI_COMMIT
providerVersionBranch: "master", //recommended to be the git branch eg. process.env.MY_GIT_SHA
providerVersionTags: ["tag"], //optional, recommended to be the git branch eg. process.env.MY_CI_BRANCH
}
providerVersion: 'version', //recommended to be the git sha eg. process.env.MY_CI_COMMIT
providerVersionBranch: 'master', //recommended to be the git branch eg. process.env.MY_GIT_SHA
providerVersionTags: ['tag'], //optional, recommended to be the git branch eg. process.env.MY_CI_BRANCH
};
```
2 changes: 1 addition & 1 deletion examples/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ curl -X GET http://localhost:8080/suggestions/1

## Viewing contracts with the Pact Broker

A test [Pact Boker](https://github.com/bethesque/pact_broker) is running at https://test.pactflow.io:
A test [Pact Boker](https://github.com/pact-foundation/pact_broker) is running at https://test.pactflow.io - very kindly provided by PactFlow:

- Username: `dXfltyFMgNOFZAxr8io9wJ37iUpY42M`
- Password: `O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1`
Expand Down
4 changes: 2 additions & 2 deletions examples/e2e/test/provider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ describe('Pact Verification', () => {
// ),
// ],

// If you're NOT using PactFlow, use the username/password option as per below
// If you're using the open source Pact Broker, use the username/password option as per below
pactBrokerUsername:
process.env.PACT_BROKER_USERNAME || 'dXfltyFMgNOFZAxr8io9wJ37iUpY42M',
pactBrokerPassword:
process.env.PACT_BROKER_PASSWORD || 'O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1',

// if you're using PactFlow, you must authenticate using the bearer token option
// if you're using a PactFlow broker, you must authenticate using the bearer token option
// You can obtain the token from https://<your broker>.pactflow.io/settings/api-tokens
// pactBrokerToken: "<insert your token here"
publishVerificationResult: true,
Expand Down
2 changes: 1 addition & 1 deletion examples/serverless/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ To use any of the commands below, ensure you have valid [AWS credentials](https:

### Pact Broker integration

Using the test broker at https://test.pactflow.io (user/pass: `dXfltyFMgNOFZAxr8io9wJ37iUpY42M` / `O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1`), we make use of the [`can-i-deploy` tool](https://github.com/pact-foundation/pact_broker/wiki/Provider-verification-results#querying) (available from the [Pact CLI suite](https://github.com/pact-foundation/pact-ruby-standalone/releases) but also bundled as part of `pact`), that ensures it is safe to deploy the consumer or provider before a releasing a change.
[PactFlow](https://pactflow.io) have kindly provided a test broker for the Pact Foundation to use. Using the test broker, https://test.pactflow.io (user/pass: `dXfltyFMgNOFZAxr8io9wJ37iUpY42M` / `O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1`), we make use of the [`can-i-deploy` tool](https://github.com/pact-foundation/pact_broker/wiki/Provider-verification-results#querying) (available from the [Pact CLI suite](https://github.com/pact-foundation/pact-ruby-standalone/releases) but also bundled as part of `pact`), that ensures it is safe to deploy the consumer or provider before a releasing a change.

Whenever we create, change or verify a contract with Pact, the results are shared with the broker, which is then able to determine compatibility between components at any point in time.

Expand Down

0 comments on commit 3e85d5c

Please sign in to comment.