Skip to content

Commit 00bd252

Browse files
authored
Chore/implement contract testing (#9)
implement consumer driven contract testing
1 parent 49f67bf commit 00bd252

File tree

12 files changed

+2443
-99
lines changed

12 files changed

+2443
-99
lines changed

.github/workflows/ci.yml

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,13 @@ on:
1010

1111
jobs:
1212

13-
api:
14-
name: API Build & Test
15-
runs-on: ubuntu-latest
16-
defaults:
17-
run:
18-
working-directory: api
19-
20-
steps:
21-
- name: Checkout Repository
22-
uses: actions/checkout@v4
23-
24-
- name: Setup Node.js
25-
uses: actions/setup-node@v4
26-
with:
27-
node-version: 18
28-
cache: yarn
29-
cache-dependency-path: api/yarn.lock # Specify the path to your yarn.lock
30-
31-
- name: Install Dependencies (API)
32-
working-directory: api
33-
run: yarn install --frozen-lockfile
34-
35-
#- name: Lint API
36-
# run: npm run lint
37-
38-
- name: Create .env file
39-
run: |
40-
cp .env-dev .env
41-
working-directory: api # Ensure it is created inside `api/`
42-
43-
- name: Run Tests (API)
44-
run: yarn test
45-
46-
- name: Build API
47-
run: yarn build
48-
4913
# Webapp (Next.js) Build & Test
5014
webapp:
5115
name: Webapp Build & Test
5216
runs-on: ubuntu-latest
5317
defaults:
54-
run:
55-
working-directory: webapp
18+
run:
19+
working-directory: webapp
5620

5721
steps:
5822
- name: Checkout Repository
@@ -65,14 +29,17 @@ jobs:
6529
cache: yarn
6630
cache-dependency-path: webapp/yarn.lock # Specify the path to your yarn.lock
6731

68-
- name: Install Dependencies (Webapp)
32+
- name: Install Dependencies
6933
run: yarn install --frozen-lockfile
7034

7135
- name: Lint Webapp
7236
run: yarn lint
7337

74-
- name: Run Tests (Webapp)
75-
run: npm test
38+
- name: Run Tests
39+
run: yarn test
40+
41+
- name: Run Contract Testings
42+
run: yarn test:contract
7643

7744
- name: Restore cache Next.js build
7845
uses: actions/cache@v3
@@ -84,7 +51,7 @@ jobs:
8451
${{ runner.os }}-nextjs-
8552
8653
- name: Build Webapp
87-
run: |
54+
run: |
8855
yarn build
8956
ls -la
9057
@@ -94,6 +61,47 @@ jobs:
9461
path: webapp/.next
9562
key: ${{ runner.os }}-nextjs-${{ github.ref_name }}-${{ hashFiles('webapp/yarn.lock') }}
9663

64+
65+
api:
66+
name: API Build & Test
67+
runs-on: ubuntu-latest
68+
needs: webapp
69+
defaults:
70+
run:
71+
working-directory: api
72+
73+
steps:
74+
- name: Checkout Repository
75+
uses: actions/checkout@v4
76+
77+
- name: Setup Node.js
78+
uses: actions/setup-node@v4
79+
with:
80+
node-version: 18
81+
cache: yarn
82+
cache-dependency-path: api/yarn.lock # Specify the path to your yarn.lock
83+
84+
- name: Install Dependencies
85+
working-directory: api
86+
run: yarn install --frozen-lockfile
87+
88+
#- name: Lint API
89+
# run: npm run lint
90+
91+
- name: Create .env file
92+
run: |
93+
cp .env-dev .env
94+
working-directory: api # Ensure it is created inside `api/`
95+
96+
- name: Run Tests
97+
run: yarn test
98+
99+
- name: Run Contract Testings
100+
run: yarn test:contract
101+
102+
- name: Build API
103+
run: yarn build
104+
97105
# Merge Blocker: Ensure Both Builds Pass
98106
merge_guard:
99107
name: Ensure All Jobs Passed

api/package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"start:debug": "nest start --debug --watch",
1414
"start:prod": "node dist/main",
1515
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
16-
"test": "jest",
16+
"test": "jest --testMatch '**/src/**/*.spec.ts'",
17+
"test:contract": "jest --testMatch '**/test/pact/**/*.spec.ts'",
1718
"test:watch": "jest --watch",
1819
"test:cov": "jest --coverage",
1920
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
@@ -34,6 +35,8 @@
3435
"@nestjs/cli": "^10.0.0",
3536
"@nestjs/schematics": "10.0.0",
3637
"@nestjs/testing": "10.0.0",
38+
"@pact-foundation/pact": "13.2.0",
39+
"@pact-foundation/pact-node": "10.18.0",
3740
"@types/express": "5.0.0",
3841
"@types/jest": "29.5.2",
3942
"@types/node": "20.3.1",
@@ -59,8 +62,10 @@
5962
"json",
6063
"ts"
6164
],
62-
"rootDir": "src",
63-
"testRegex": ".*\\.spec\\.ts$",
65+
"rootDir": ".",
66+
"testMatch": [
67+
"**/?(*.)+(spec).ts"
68+
],
6469
"transform": {
6570
"^.+\\.(t|j)s$": "ts-jest"
6671
},

api/src/shorten-url/create-shorten-url/create-shorten-url.controller.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { Body, Controller, Logger, Post } from '@nestjs/common';
1+
import {
2+
Body,
3+
Controller,
4+
HttpCode,
5+
HttpStatus,
6+
Logger,
7+
Post,
8+
} from '@nestjs/common';
29
import { CreateShortenUrlUsecase } from './create-shorten-url.usecase';
310
import { CreateShortenUrlDto } from './create-shorten-url.dto';
411

@@ -7,6 +14,7 @@ export class CreateShortenUrlController {
714
constructor(private readonly shortenUrlUsecase: CreateShortenUrlUsecase) {}
815

916
@Post()
17+
@HttpCode(HttpStatus.CREATED)
1018
async shortenUrl(
1119
@Body() request: CreateShortenUrlDto,
1220
): Promise<{ shortenedUrl: string }> {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Verifier } from '@pact-foundation/pact';
2+
import path from 'path';
3+
import { INestApplication } from '@nestjs/common';
4+
import { Test } from '@nestjs/testing';
5+
import { AppModule } from '../../src/app.module';
6+
7+
let app: INestApplication;
8+
9+
beforeAll(async () => {
10+
const moduleFixture = await Test.createTestingModule({
11+
imports: [AppModule],
12+
}).compile();
13+
14+
app = moduleFixture.createNestApplication();
15+
await app.init();
16+
await app.listen(3001);
17+
});
18+
19+
afterAll(async () => {
20+
await app.close();
21+
});
22+
23+
describe('API consumers integration verification', () => {
24+
it('validates the expectations of the webapp consumer', async () => {
25+
await new Verifier({
26+
provider: 'api',
27+
providerBaseUrl: 'http://localhost:3001', // your Nest app
28+
pactUrls: [
29+
path.resolve(
30+
__dirname,
31+
'../../../webapp/__tests__/pact/pacts/webapp-backend-api.json',
32+
),
33+
],
34+
}).verifyProvider();
35+
});
36+
});

api/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"esModuleInterop": true,
34
"module": "commonjs",
45
"declaration": true,
56
"removeComments": true,

0 commit comments

Comments
 (0)