Skip to content

Commit

Permalink
feat(message): fix message structure sent to consumer verify(). #166
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Apr 1, 2018
1 parent 0d46776 commit ee1ddf0
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 34 deletions.
72 changes: 61 additions & 11 deletions examples/serverless/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,31 @@ The very basic architecture is as follows:
## Overview
<!-- TOC -->

- [Overview](#overview)
- [Test Services with Pact](#test-services-with-pact)
- [Deployment](#deployment)
- [Pact Broker integration](#pact-broker-integration)
- [Running deployment](#running-deployment)
- [Running](#running)
- [Further reading](#further-reading)
- [Serverless example](#serverless-example)
- [Overview](#overview)
- [Test Services with Pact](#test-services-with-pact)
- [Deployment](#deployment)
- [Pact Broker integration](#pact-broker-integration)
- [Running deployment](#running-deployment)
- [Running](#running)
- [Cleaning up](#cleaning-up)
- [Further reading](#further-reading)

<!-- /TOC -->

**Message Producer**

Small utility that when invoked, publishes an "event" message to an SQS queue.
Small utility that when invoked, publishes an "event" message to an SNS topic.

**Message Consumer**

Lambda function that reads from SQS and processes the data - by incrementing a simple counter.
Lambda function that reads from the SNS topic and processes the data - by incrementing a simple counter.

**Getting Started**

```
npm i
```

## Test Services with Pact

Expand All @@ -46,6 +54,12 @@ npm run test:provider

## Deployment

You can run this stack in AWS. It uses services within the [free tier](https://aws.amazon.com/free/?awsf.default=categories%23alwaysfree) to reduce potential costs.

To use any of the commandsn belowe, ensure you have valid [AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) for your environment.

Serverless

### Pact Broker integration

Using the test broker at https://test.pact.dius.com.au (user/pass: `dXfltyFMgNOFZAxr8io9wJ37iUpY42M` / `O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1`), we integrate the `can-i-deploy` facility, that ensure it is safe to deploy the consumer or provider before a change.
Expand All @@ -61,8 +75,6 @@ npm run can-i-deploy:provider

### Running deployment

Ensure you have valid AWS credentials in your environment and have installed serverless framework (`npm i -g serverless`), and then run;

```sh
npm run deploy
```
Expand All @@ -82,11 +94,49 @@ serverless deploy -f consumer
serverless invoke -f provider -l
```

You should see something like:

```sh
matt λ serverless invoke -f provider -l
{
"id": 65,
"event": "an update to something useful",
"type": "update"
}
--------------------------------------------------------------------
START RequestId: 87050842-3536-11e8-ba23-e7bc78dfd40c Version: $LATEST
END RequestId: 87050842-3536-11e8-ba23-e7bc78dfd40c
REPORT RequestId: 87050842-3536-11e8-ba23-e7bc78dfd40c Duration: 169.04 ms Billed Duration: 200 ms Memory Size: 1024 MB Max Memory Used: 40 MB
```

**Watching the consumer**
```sh
serverless logs -f consumer -t
```

When an event is published to the topic, your consumer should log to console something like the following:

```sh
matt λ serverless logs -f consumer -t
START RequestId: 8784bf84-3536-11e8-be0c-038b85b513b9 Version: $LATEST
2018-04-01 08:54:55.878 (+10:00) 8784bf84-3536-11e8-be0c-038b85b513b9 Received event from SNS
2018-04-01 08:54:55.878 (+10:00) 8784bf84-3536-11e8-be0c-038b85b513b9 Event: { id: 65,
event: 'an update to something useful',
type: 'update' }
...
2018-04-01 08:54:55.881 (+10:00) 8784bf84-3536-11e8-be0c-038b85b513b9 Event count: 1
END RequestId: 8784bf84-3536-11e8-be0c-038b85b513b9
REPORT RequestId: 8784bf84-3536-11e8-be0c-038b85b513b9 Duration: 5.55 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 32 MB
```
## Cleaning up
When you are done with your serverless stack, simply run:
```
serverless remove -v
```
## Further reading
For further reading and introduction into the topic of asynchronous services contract testing, see this [article](https://dius.com.au/2017/09/22/contract-testing-serverless-and-asynchronous-applications/)
Expand Down
4 changes: 3 additions & 1 deletion examples/serverless/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
"can-i-deploy": "npm run can-i-deploy:consumer && npm run can-i-deploy:provider",
"can-i-deploy:consumer": "$(find ../../ -name pact-broker | grep -e 'bin/pact-broker$' | head -n 1) can-i-deploy --pacticipant SNSPactEventConsumer --latest --broker-base-url https://test.pact.dius.com.au --broker-username dXfltyFMgNOFZAxr8io9wJ37iUpY42M --broker-password O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1",
"can-i-deploy:provider": "$(find ../../ -name pact-broker | grep -e 'bin/pact-broker$' | head -n 1) can-i-deploy --pacticipant SNSPactEventProvider --latest --broker-base-url https://test.pact.dius.com.au --broker-username dXfltyFMgNOFZAxr8io9wJ37iUpY42M --broker-password O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1",
"create-stack": "serverless deploy -v",
"deploy": "npm run deploy:consumer && npm run deploy:provider",
"deploy:consumer": "npm run can-i-deploy && serverless deploy -f consumer",
"deploy:provider": "npm run can-i-deploy && serverless deploy -f provider"
},
"devDependencies": {
"chai": "^3.5.0",
"mocha": "^3.5.3"
"mocha": "^3.5.3",
"serverless": "^1.26.1"
},
"keywords": [
"pact",
Expand Down
2 changes: 1 addition & 1 deletion examples/serverless/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ provider:
Action:
- "sns:*"
environment:
- TOPIC_ARN: { "Fn::Join": ["", ["arn:aws:sns:us-east-1:", { "Ref": "AWS::AccountId" }, ":pact-events"] ] }
TOPIC_ARN: { "Fn::Join": ["", ["arn:aws:sns:us-east-1:", { "Ref": "AWS::AccountId" }, ":pact-events"] ] }

package:
individually: true
Expand Down
81 changes: 68 additions & 13 deletions src/dsl/matchers.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* tslint:disable:no-unused-expression no-empty */
/* tslint:disable:no-unused-expression no-empty object-literal-sort-keys */
import * as chai from "chai";
const expect = require("chai").expect;
import { Interaction } from "./interaction";
Expand All @@ -7,7 +7,10 @@ import {
integer, ipv4Address, ipv6Address, ISO8601_DATE_FORMAT, iso8601Date,
iso8601DateTime, iso8601DateTimeWithMillis, iso8601Time, rfc3339Timestamp, somethingLike, term, uuid,
validateExample,
extractPayload,
isMatcher,
} from "./matchers";
import { json } from "express";

describe("Matcher", () => {

Expand Down Expand Up @@ -53,7 +56,7 @@ describe("Matcher", () => {
matcher: "\\w+",
});

expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand Down Expand Up @@ -101,7 +104,7 @@ describe("Matcher", () => {
};

const match = somethingLike("myspecialvalue");
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand Down Expand Up @@ -137,7 +140,7 @@ describe("Matcher", () => {
};

const match = eachLike(null, { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -150,7 +153,7 @@ describe("Matcher", () => {
};

const match = eachLike({ a: 1 }, { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -171,7 +174,7 @@ describe("Matcher", () => {
};

const match = eachLike([1, 2, 3], { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -184,7 +187,7 @@ describe("Matcher", () => {
};

const match = eachLike("test", { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -203,7 +206,7 @@ describe("Matcher", () => {
};

const match = eachLike({ id: somethingLike(10) }, { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand Down Expand Up @@ -234,7 +237,7 @@ describe("Matcher", () => {
}),
}, { min: 1 });

expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -251,7 +254,7 @@ describe("Matcher", () => {
};

const match = eachLike(eachLike("blue", { min: 1 }), { min: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand Down Expand Up @@ -308,7 +311,7 @@ describe("Matcher", () => {
}, { min: 1 }),
{ min: 1 });

expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});
});
Expand All @@ -322,7 +325,7 @@ describe("Matcher", () => {
};

const match = eachLike({ a: 1 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});

Expand All @@ -335,7 +338,7 @@ describe("Matcher", () => {
};

const match = eachLike({ a: 1 }, { min: 3 });
expect(match).to.eql(expected);
expect(JSON.stringify(match)).to.deep.include(JSON.stringify(expected));
});
});
});
Expand Down Expand Up @@ -511,5 +514,57 @@ describe("Matcher", () => {
});
});
});

describe("#extractPayload", () => {
describe("when given a simple matcher", () => {
it("should remove all matching guff", () => {
const expected = "myawesomeword";

const matcher = term({
generate: "myawesomeword",
matcher: "\\w+",
});

expect(isMatcher(matcher)).to.eq(true);
expect(extractPayload(matcher)).to.eql(expected);

});
});
describe("when given a complex nested object with matchers", () => {
it("should remove all matching guff", () => {
const o = {
stringMatcher: {
awesomeSetting: somethingLike("a string"),
},
anotherStringMatcher: {
nestedSetting: {
anotherStringMatcherSubSetting: somethingLike(true),
},
anotherSetting: term({ generate: "this", matcher: "this|that" }),
},
arrayMatcher: {
lotsOfValues: eachLike("useful", { min: 3 }),
},
};

const expected = {
stringMatcher: {
awesomeSetting: "a string",
},
anotherStringMatcher: {
nestedSetting: {
anotherStringMatcherSubSetting: true,
},
anotherSetting: "this",
},
arrayMatcher: {
lotsOfValues: ["useful", "useful", "useful"],
},
};

expect(extractPayload(o)).to.deep.eql(expected);
});
});
});
});
});
Loading

0 comments on commit ee1ddf0

Please sign in to comment.