Comparing version 1.0.13 to 1.0.14
{ | ||
"name": "pactum", | ||
"version": "1.0.13", | ||
"version": "1.0.14", | ||
"description": "REST API endpoint testing tool with a mock server & compatible with pact.io for contract testing", | ||
@@ -10,3 +10,4 @@ "main": "src/index.js", | ||
"scripts": { | ||
"test": "mocha --timeout 10000 ./test/unit/", | ||
"test": "mocha --timeout 10000 ./test/**/*", | ||
"test:unit": "mocha --timeout 10000 ./test/unit/", | ||
"test:component": "mocha --timeout 10000 ./test/component/" | ||
@@ -41,2 +42,3 @@ }, | ||
"phin": "^3.4.1", | ||
"pino": "^5.16.0", | ||
"polka": "^0.5.2" | ||
@@ -43,0 +45,0 @@ }, |
625
README.md
# pactum | ||
## Introduction | ||
pactum is a REST API Testing Tool that combines the implementation of consumer driven contract library [Pact](https://docs.pact.io) for Javascript. | ||
**pactum** is a REST API Testing Tool that combines the implementation of consumer driven contract library [Pact](https://docs.pact.io) for JavaScript. | ||
## Documentation | ||
* [Pactum](https://github.com/ASaiAnudeep/pactum/wiki) | ||
* [Component Testing](https://github.com/ASaiAnudeep/pactum/wiki/Component-Testing) | ||
* [Mock Server](https://github.com/ASaiAnudeep/pactum/wiki/Mock-Server) | ||
## Installation | ||
``` | ||
```Shell | ||
npm install --save-dev pactum | ||
npm install --save-dev mocha | ||
``` | ||
## Table of contents | ||
## Usage | ||
* [Introduction](#introduction) | ||
* [Installation](#installation) | ||
* [Table of contents](#table-of-contents) | ||
* [Usage](#usage) | ||
* [Getting Started](#getting-started) | ||
* [Basics](#basics) | ||
* [HTTP Request](#http-request) | ||
* [Component Testing](#component-testing) | ||
* [Component Testing with Mock Server](#component-testing-with-mock-server) | ||
* [Mock Interaction](#mock-interaction) | ||
* [Contract Testing with Mock Server](#contract-testing-with-mock-server) | ||
* [Pact Interaction](#pact-interaction) | ||
* [Mock Server](#mock-server) | ||
### Component Testing | ||
## Usage | ||
Running a single component test expectation. | ||
```javascript | ||
```JavaScript | ||
const pactum = require('pactum'); | ||
@@ -44,3 +34,3 @@ | ||
```bash | ||
```Shell | ||
# mocha is a test framework | ||
@@ -50,46 +40,10 @@ mocha /path/to/test | ||
Running a component test with the help of a mock server & a single mock interaction. If the mock interaction is not exercised, the test will fail. | ||
Learn more about pactum as a component tester [here](https://github.com/ASaiAnudeep/pactum/wiki/Component-Testing) | ||
```javascript | ||
const pactum = require('pactum'); | ||
### Contract Testing | ||
before(async () => { | ||
await pactum.mock.start(); | ||
}); | ||
Running a contract test with the help of a mock server & a single pact interaction. | ||
If the pact interaction is not exercised, the test will fail. | ||
it('GET - one interaction', async () => { | ||
await pactum | ||
.addMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/projects/1' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 1, | ||
name: 'fake' | ||
} | ||
} | ||
}) | ||
.get('http://localhost:9393/api/projects/1') | ||
.expectStatus(200) | ||
.expectJsonLike({ | ||
id: 1, | ||
name: 'fake' | ||
}) | ||
.toss(); | ||
}); | ||
after(async () => { | ||
await pactum.mock.stop(); | ||
}); | ||
``` | ||
Running a component test with the help of a mock server & a single pact interaction. If the mock interaction is not exercised, the test will fail. | ||
```javascript | ||
```JavaScript | ||
const pactum = require('pactum'); | ||
@@ -137,501 +91,8 @@ | ||
### Mock Server | ||
## Getting Started | ||
Running **pactum** as a standalone mock server. | ||
### Basics | ||
| Method | Description | | ||
| ---------- | -------------------------------------------- | | ||
| get | performs a GET request on the resource | | ||
| expectStatus | expects a status code on the response | | ||
| toss | executes the test case and returns a promise | | ||
Create a javascript file named `test.js` | ||
```javascript | ||
// imports pactum library | ||
const pactum = require('pactum'); | ||
// this is a test step in mocha | ||
it('should be a teapot', async () => { | ||
await pactum // pactum returns a promise | ||
.get('http://httpbin.org/status/200') // will fetch a response from the url | ||
.expectStatus(200) // sets an expectation on the response | ||
.toss(); // executes the test case | ||
}); | ||
``` | ||
Running the test with [mocha](https://mochajs.org/#getting-started) | ||
```bash | ||
mocha /path/to/test.js | ||
``` | ||
[^ TOC](#table-of-contents) | ||
### HTTP Request | ||
HTTP requests are messages sent by the client to initiate an action on the server. | ||
| Method | Description | | ||
| -------------------------- | ------------------------------------------------- | | ||
| `get('url')` | this is a HTTP method to be performed on resource | | ||
| `withQuery('postId', '1')` | set of parameters attached to the url | | ||
| `withHeaders({})` | request headers | | ||
| `withBody('Hello')` | request body | | ||
| `withJson({id: 1})` | request json object | | ||
```javascript | ||
const pactum = require('pactum'); | ||
// performs a get request with query | ||
it('GET - with query', async () => { | ||
await pactum | ||
.get('https://jsonplaceholder.typicode.com/comments') | ||
.withQuery('postId', 1) | ||
.withQuery('id', 1) | ||
.expectStatus(200) | ||
.toss(); | ||
}); | ||
// performs a post request with JSON | ||
it('POST', async () => { | ||
await pactum | ||
.post('https://jsonplaceholder.typicode.com/posts') | ||
.withJson({ | ||
title: 'foo', | ||
body: 'bar', | ||
userId: 1 | ||
}) | ||
.expectStatus(201) | ||
.toss(); | ||
}); | ||
// performs a post request with headers & body | ||
it('POST - with body', async () => { | ||
await pactum | ||
.post('https://jsonplaceholder.typicode.com/posts') | ||
.withHeaders({ | ||
"content-type": "application/json" | ||
}) | ||
.withBody({ | ||
title: 'foo', | ||
body: 'bar', | ||
userId: 1 | ||
}) | ||
.expectStatus(201) | ||
.toss(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
#### HTTP Methods | ||
The request method indicates the method to be performed on the resource identified by the given Request-URI. | ||
| Method | Description | Usage | | ||
| -------- | ------------------------------------------ | ------------------------------------- | | ||
| get | performs a GET request on the resource | `await pactum.get('url').toss()` | | ||
| post | performs a POST request on the resource | `await pactum.post('url').toss()` | | ||
| put | performs a PUT request on the resource | `await pactum.put('url').toss()` | | ||
| delete | performs a DELETE request on the resource | `await pactum.delete('url').toss()` | | ||
| patch | performs a PATCH request on the resource | `await pactum.patch('url').toss()` | | ||
| head | performs a HEAD request on the resource | `await pactum.head('url').toss()` | | ||
```javascript | ||
// performs a delete request | ||
it('DELETE', async () => { | ||
await pactum | ||
.delete('https://jsonplaceholder.typicode.com/posts/1') | ||
.expectStatus(200) | ||
.toss(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
### HTTP Expectations | ||
| Method | Description | | ||
| --------------------------------------- | --------------------------------------------------------------------------- | | ||
| `expectStatus(201)` | check HTTP status | | ||
| `expectHeader('key', 'value')` | check HTTP header key + value (RegExp) | | ||
| `expectHeaderContains('key', 'value')` | check HTTP header key contains partial value (RegExp) | | ||
| `expectBody('value')` | check exact match of body | | ||
| `expectBodyContains('value')` | check body contains the value (RegExp) | | ||
| `expectJson({json})` | check exact match of json | | ||
| `expectJsonLike({json})` | check json contains partial value (RegExp) | | ||
| `expectJsonSchema({schema})` | validate [json-schema](https://json-schema.org/learn/) | | ||
| `expectJsonQuery('path', 'value')` | validate [json-query](https://www.npmjs.com/package/json-query) | | ||
| `expectResponseTime(10)` | check if request completes within a specified duration (ms) | | ||
```javascript | ||
const pactum = require('pactum'); | ||
it('GET', async () => { | ||
await pactum | ||
.get('https://jsonplaceholder.typicode.com/posts/1') | ||
.expectStatus(200) | ||
.expectHeader('content-type', 'application/json; charset=utf-8') | ||
.expectHeader('connection', /\w+/) | ||
.expectHeaderContains('content-type', 'application/json') | ||
.expectJson({ | ||
"userId": 1, | ||
"id": 1, | ||
"title": "some title", | ||
"body": "some body" | ||
}) | ||
.expectJsonLike({ | ||
userId: 1, | ||
id: 1 | ||
}) | ||
.expectJsonLike({ | ||
title: "some title", | ||
body: "some body" | ||
}) | ||
.expectJsonSchema({ | ||
"properties": { | ||
"userId": { | ||
"type": "number" | ||
} | ||
}, | ||
"required": ["userId", "id"] | ||
}) | ||
.expectJsonSchema({ | ||
"properties": { | ||
"title": { | ||
"type": "string" | ||
} | ||
}, | ||
"required": ["title", "body"] | ||
}) | ||
.expectResponseTime(1000) | ||
.toss(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
## Component Testing | ||
Read more about testing RESTFull services [here](#http-request) | ||
Component testing is defined as a software testing type, in which the testing is performed on each individual component separately without integrating with other components. | ||
Lets assume you have an order-service which is a RESTFull API service running on port 3000. | ||
Here if the order-service has external dependencies, they are mocked using different library. | ||
```javascript | ||
const pactum = require('pactum'); | ||
it('should fetch order details', async () => { | ||
await pactum | ||
// assume you have an order-service running locally on port 3000 | ||
.get('http://localhost:3000/api/orders/123') | ||
// set an expectation of 200 | ||
.expectStatus(200) | ||
// set an expectation on the response body | ||
.expectJson({ | ||
orderId: '123', | ||
price: '3030', | ||
currency: 'INR' | ||
}) | ||
// execute the test case | ||
.toss(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
## Component Testing with Mock Server | ||
Read more about component testing [here](#component-testing) | ||
Lets assume you have an order-service which is a RESTFull API service running on port 3000. Consider if order-service depends on a currency-service to fetch the prices. | ||
Start the order-service & overwrite the endpoint of currency-service to http://localhost:9393 | ||
```javascript | ||
const pactum = require('pactum'); | ||
before(async () => { | ||
// starts the mock service on port 9393 (port number can be modified) | ||
await pactum.mock.start(); | ||
}); | ||
it('should fetch order details', async () => { | ||
await pactum | ||
// here we are training the mock server to act as currency-service | ||
// if the order-service fails to make a call to this endpoint then | ||
// the test will fail with - Interaction Not Exercised | ||
// after the execution of this spec, the mock interaction will be removed | ||
.addMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/currency/INR' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 'INR', | ||
description: 'Indian Rupee' | ||
} | ||
} | ||
}) | ||
.get('http://localhost:3000/api/orders/123') | ||
.expectStatus(200) | ||
.expectJson({ | ||
orderId: '123', | ||
price: '3030', | ||
currency: 'INR' | ||
}) | ||
.toss(); | ||
}); | ||
after(async () => { | ||
// stops the mock service on port 9393 (port number can be modified) | ||
await pactum.mock.stop(); | ||
}); | ||
``` | ||
If the order-service interacts with multiple services, we can add multiple mock interactions. | ||
```javascript | ||
const pactum = require('pactum'); | ||
before(async () => { | ||
await pactum.mock.start(); | ||
}); | ||
it('should fetch order details', async () => { | ||
await pactum | ||
// if the order-service fails to make a call to this endpoint then | ||
// the test will fail with - Interaction Not Exercised | ||
.addMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/currency/INR' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 'INR', | ||
description: 'Indian Rupee' | ||
} | ||
} | ||
}) | ||
// if the order-service fails to make a call to this endpoint then | ||
// the test will fail with - Interaction Not Exercised | ||
.addMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/allocations/123' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: [12, 13] | ||
} | ||
}) | ||
.get('http://localhost:3000/api/orders/123') | ||
.expectStatus(200) | ||
.expectJson({ | ||
orderId: '123', | ||
price: '3030', | ||
currency: 'INR' | ||
}) | ||
.toss(); | ||
}); | ||
after(async () => { | ||
await pactum.mock.stop(); | ||
}); | ||
``` | ||
The scope of each interaction added through `pactum.addMockInteraction()` will be restricted to current spec (`it` block) | ||
To add mock interactions that will be consumed in all the specs use - `pactum.mock.addDefaultMockInteraction()` | ||
```javascript | ||
const pactum = require('pactum'); | ||
before(async () => { | ||
await pactum.mock.start(); | ||
// adds a default mock interaction | ||
pactum.mock.addDefaultMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/currency/INR' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 'INR', | ||
description: 'Indian Rupee' | ||
} | ||
} | ||
}) | ||
}); | ||
it('should fetch order details for id 123', async () => { | ||
await pactum | ||
.get('http://localhost:3000/api/orders/123') | ||
.expectStatus(200) | ||
.expectJson({ | ||
orderId: '123', | ||
price: '3030', | ||
currency: 'INR' | ||
}) | ||
.toss(); | ||
}); | ||
it('should fetch order details for id 124', async () => { | ||
await pactum | ||
.get('http://localhost:3000/api/orders/124') | ||
.expectStatus(200) | ||
.expectJson({ | ||
orderId: '124', | ||
price: '5643', | ||
currency: 'INR' | ||
}) | ||
.toss(); | ||
}); | ||
after(async () => { | ||
// removes all default interactions | ||
pactum.mock.removeDefaultInteractions(); | ||
await pactum.mock.stop(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
### Mock Interaction | ||
Methods to add a mock interaction: | ||
* `pactum.addMockInteraction()` | ||
* `pactum.mock.addDefaultMockInteraction()` | ||
| Property | Type | Required | Description | | ||
| ----------------------- | ------- | -------- | -------------------------- | | ||
| id | string | optional | id of the interaction | | ||
| consumer | string | optional | name of the consumer | | ||
| provider | string | optional | name of the provider | | ||
| state | string | optional | state of the provider | | ||
| uponReceiving | string | optional | description of the request | | ||
| withRequest | object | required | request details | | ||
| withRequest.method | string | required | HTTP method | | ||
| withRequest.path | string | required | api path | | ||
| withRequest.headers | object | optional | request headers | | ||
| withRequest.query | object | optional | query parameters | | ||
| withRequest.body | any | optional | request body | | ||
| withRequest.ignoreQuery | boolean | optional | ignore request query | | ||
| withRequest.ignoreBody | boolean | optional | ignore request body | | ||
| willRespondWith | object | required | response details | | ||
| willRespondWith.status | number | required | response status code | | ||
| willRespondWith.headers | object | optional | response headers | | ||
| willRespondWith.body | any | required | response body | | ||
## Contract Testing with Mock Server | ||
Contract testing is a technique for testing an integration point by checking each application in isolation to ensure the messages it sends or receives conform to a shared understanding that is documented in a **contract**. | ||
In a single spec we can use multiple mock interactions & multiple pact interactions. | ||
```javascript | ||
const pactum = require('pactum'); | ||
before(async () => { | ||
await pactum.mock.start(); | ||
}); | ||
it('should fetch order details', async () => { | ||
await pactum | ||
// here we are training the mock server to act as currency-service | ||
// if the order-service fails to make a call to this endpoint then | ||
// the test will fail with - Interaction Not Exercised | ||
// after the execution of this spec, the pact interaction will be removed | ||
.addPactInteraction({ | ||
consumer: 'order-service', | ||
provider: 'currency-service', | ||
state: 'there is INR currency', | ||
uponReceiving: 'a request for INR currency', | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/currency/INR' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 'INR', | ||
description: 'Indian Rupee' | ||
} | ||
} | ||
}) | ||
.get('http://localhost:3000/api/orders/123') | ||
.expectStatus(200) | ||
.expectJson({ | ||
orderId: '123', | ||
price: '3030', | ||
currency: 'INR' | ||
}) | ||
.toss(); | ||
}); | ||
after(async () => { | ||
await pactum.mock.stop(); | ||
}); | ||
``` | ||
[^ TOC](#table-of-contents) | ||
### Pact Interaction | ||
Methods to add a pact interaction: | ||
* `pactum.addPactInteraction()` | ||
* `pactum.mock.addDefaultPactInteraction()` | ||
| Property | Type | Required | Description | | ||
| ----------------------- | ------- | -------- | -------------------------- | | ||
| id | string | optional | id of the interaction | | ||
| consumer | string | required | name of the consumer | | ||
| provider | string | required | name of the provider | | ||
| state | string | required | state of the provider | | ||
| uponReceiving | string | required | description of the request | | ||
| withRequest | object | required | request details | | ||
| withRequest.method | string | required | HTTP method | | ||
| withRequest.path | string | required | api path | | ||
| withRequest.headers | object | optional | request headers | | ||
| withRequest.query | object | optional | query parameters | | ||
| withRequest.body | any | optional | request body | | ||
| willRespondWith | object | required | response details | | ||
| willRespondWith.status | number | required | response status code | | ||
| willRespondWith.headers | object | optional | response headers | | ||
| willRespondWith.body | any | required | response body | | ||
[^ TOC](#table-of-contents) | ||
## Mock Server | ||
Pactum can also be used as a mock server | ||
```javascript | ||
// The below code will run the pactum server on port 3000 | ||
const pactum = require('pactum'); | ||
pactum.mock.setDefaultPort(3000); | ||
@@ -641,48 +102,2 @@ pactum.mock.start(); | ||
Use `addDefaultMockInteraction()` and `addDefaultPactInteraction()` to add default interactions to the mock server. | ||
To add multiple use `addDefaultMockInteractions()` and `addDefaultPactInteractions()`. | ||
```javascript | ||
// The below code will run the pactum server on port 3000 | ||
// with a mock interaction & a pact interaction | ||
const pactum = require('pactum'); | ||
pactum.mock.setDefaultPort(3000); | ||
pactum.mock.addDefaultMockInteraction({ | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/projects/1' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 1, | ||
name: 'fake' | ||
} | ||
} | ||
}); | ||
pactum.mock.addDefaultPactInteraction({ | ||
consumer: 'consumer-service', | ||
provider: 'project-service', | ||
state: 'there is a project with id 1', | ||
uponReceiving: 'a request for project 1', | ||
withRequest: { | ||
method: 'GET', | ||
path: '/api/projects/1' | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: { | ||
id: 1, | ||
name: 'fake' | ||
} | ||
} | ||
}); | ||
pactum.mock.start(); | ||
``` | ||
Learn more about pactum as a mock server [here](https://github.com/ASaiAnudeep/pactum/wiki/Mock-Server) |
@@ -164,12 +164,27 @@ const helper = { | ||
getValidInteraction(req, interactions) { | ||
for (let [id, interaction] of interactions) { | ||
/** | ||
* returns a matching interaction | ||
* @param {object} req - req object | ||
* @param {Map<string, object>} interactions - interactions | ||
*/ | ||
getMatchingInteraction(req, interactions) { | ||
const ids = Array.from(interactions.keys()); | ||
for (let i = ids.length - 1; i >= 0; i--) { | ||
const interaction = interactions.get(ids[i]); | ||
const isValidMethod = (interaction.withRequest.method === req.method); | ||
if (!isValidMethod) { | ||
continue; | ||
} | ||
const isValidPath = (interaction.withRequest.path === req.path); | ||
if (!isValidPath) { | ||
continue; | ||
} | ||
let isValidQuery = true; | ||
if (Object.keys(req.query).length > 0) { | ||
isValidQuery = this.validateQuery(req.query, interaction.withRequest.query); | ||
if (!interaction.withRequest.ignoreQuery) { | ||
if (Object.keys(req.query).length > 0 || interaction.withRequest.query) { | ||
isValidQuery = this.validateQuery(req.query, interaction.withRequest.query); | ||
} | ||
} | ||
if (interaction.withRequest.ignoreQuery) { | ||
isValidQuery = true; | ||
if (!isValidQuery) { | ||
continue; | ||
} | ||
@@ -181,12 +196,11 @@ let isValidHeaders = true; | ||
let isValidBody = true; | ||
if (typeof req.body === 'object') { | ||
if (Object.keys(req.body).length > 0) { | ||
if (!interaction.withRequest.ignoreBody) { | ||
if (typeof req.body === 'object') { | ||
if (Object.keys(req.body).length > 0) { | ||
isValidBody = this.validateBody(req.body, interaction.withRequest.body); | ||
} | ||
} else if (req.body) { | ||
isValidBody = this.validateBody(req.body, interaction.withRequest.body); | ||
} | ||
} else if (req.body) { | ||
isValidBody = this.validateBody(req.body, interaction.withRequest.body); | ||
} | ||
if (interaction.withRequest.ignoreBody) { | ||
isValidBody = true; | ||
} | ||
if (isValidMethod && isValidPath && isValidQuery && isValidHeaders && isValidBody) { | ||
@@ -193,0 +207,0 @@ return interaction; |
const fs = require('fs'); | ||
const config = require('../config'); | ||
const helper = require('./helper'); | ||
const log = require('./logger'); | ||
const Interaction = require('../models/interaction'); | ||
@@ -69,5 +70,10 @@ const { Contract, PactInteraction } = require('../models/contract'); | ||
if (!this.interactionExerciseCounter.has(id)) { | ||
console.log('PACTUM', 'Pact interaction not exercised'); | ||
console.log('PACTUM', 'Request', interaction.request); | ||
console.log('PACTUM', 'Response', { status: interaction.response.status, body: interaction.response.body }); | ||
log.warn('Pact interaction not exercised'); | ||
log.warn({ | ||
request: interaction.request, | ||
response: { | ||
status: interaction.response.status, | ||
body: interaction.response.body | ||
} | ||
}); | ||
} | ||
@@ -74,0 +80,0 @@ delete interaction.id; |
@@ -7,2 +7,3 @@ const polka = require('polka'); | ||
const store = require('../helpers/store'); | ||
const log = require('../helpers/logger') | ||
const config = require('../config'); | ||
@@ -19,2 +20,3 @@ | ||
start() { | ||
log.trace(`Starting mock server on port ${config.mock.port}`); | ||
return new Promise((resolve) => { | ||
@@ -27,5 +29,7 @@ if (!this.app) { | ||
this.app.listen(config.mock.port, () => { | ||
console.log('PACTUM mock server is listening on port', config.mock.port); | ||
log.info(`Mock server is listening on port ${config.mock.port}`); | ||
resolve(); | ||
}); | ||
} else { | ||
log.warn(`Mock server is already running on port ${config.mock.port}`); | ||
} | ||
@@ -36,10 +40,11 @@ }); | ||
stop() { | ||
log.trace(`Stopping mock server on port ${config.mock.port}`); | ||
return new Promise((resolve) => { | ||
if (this.app) { | ||
this.app.server.close(() => { | ||
console.log('PACTUM mock server stopped on port', config.mock.port); | ||
log.info(`Mock server stopped on port ${config.mock.port}`); | ||
resolve(); | ||
}); | ||
} else { | ||
console.log('No PACTUM mock server is running on port', config.mock.port); | ||
log.warn(`Mock server is not running on port ${config.mock.port}`); | ||
resolve(); | ||
@@ -102,5 +107,5 @@ } | ||
let interactionExercised = false; | ||
let interaction = helper.getValidInteraction(req, server.pactInteractions); | ||
let interaction = helper.getMatchingInteraction(req, server.pactInteractions); | ||
if (!interaction) { | ||
interaction = helper.getValidInteraction(req, server.mockInteractions); | ||
interaction = helper.getMatchingInteraction(req, server.mockInteractions); | ||
} | ||
@@ -120,8 +125,10 @@ if (interaction) { | ||
if (!interactionExercised) { | ||
console.log(); | ||
console.log('PACTUM', 'Interaction not found for'); | ||
console.log('PACTUM', req.method, req.path); | ||
console.log('PACTUM', 'Headers -', req.headers); | ||
console.log('PACTUM', 'Query -', req.query); | ||
console.log('PACTUM', 'Body -', req.body); | ||
log.warn('Interaction not found'); | ||
log.warn({ | ||
method: req.method, | ||
path: req.path, | ||
headers: req.headers, | ||
query: req.query, | ||
body: req.body | ||
}); | ||
res.status(404); | ||
@@ -147,3 +154,3 @@ res.send('Interaction Not Found'); | ||
} catch (error) { | ||
console.log(`Error saving mock interaction - ${error}`); | ||
log.error(`Error saving mock interaction - ${error}`); | ||
res.status(400); | ||
@@ -165,3 +172,3 @@ res.send({ error: error.message }); | ||
} catch (error) { | ||
console.error(`Error fetching mock interaction - ${error}`); | ||
log.error(`Error fetching mock interaction - ${error}`); | ||
res.status(500); | ||
@@ -181,3 +188,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error fetching mock interactions - ${error}`); | ||
log.error(`Error fetching mock interactions - ${error}`); | ||
res.status(500); | ||
@@ -200,3 +207,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error deleting mock interaction - ${error}`); | ||
log.error(`Error deleting mock interaction - ${error}`); | ||
res.status(500); | ||
@@ -213,3 +220,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error deleting mock interactions - ${error}`); | ||
log.error(`Error deleting mock interactions - ${error}`); | ||
res.status(500); | ||
@@ -228,3 +235,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.log(`Error saving pact interaction - ${error}`); | ||
log.error(`Error saving pact interaction - ${error}`); | ||
res.status(400); | ||
@@ -246,3 +253,3 @@ res.send({ error: error.message }); | ||
} catch (error) { | ||
console.error(`Error fetching pact interaction - ${error}`); | ||
log.error(`Error fetching pact interaction - ${error}`); | ||
res.status(500); | ||
@@ -262,3 +269,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error fetching pact interactions - ${error}`); | ||
log.error(`Error fetching pact interactions - ${error}`); | ||
res.status(500); | ||
@@ -281,3 +288,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error deleting mock interaction - ${error}`); | ||
log.error(`Error deleting mock interaction - ${error}`); | ||
res.status(500); | ||
@@ -294,3 +301,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.error(`Error deleting pact interactions - ${error}`); | ||
log.error(`Error deleting pact interactions - ${error}`); | ||
res.status(500); | ||
@@ -307,3 +314,3 @@ res.send({ error: `Internal System Error` }); | ||
} catch (error) { | ||
console.log(`Error saving pacts - ${error}`); | ||
log.error(`Error saving pacts - ${error}`); | ||
res.status(500); | ||
@@ -345,2 +352,3 @@ res.send({ error: error.message }); | ||
if (typeof data === 'object') { | ||
this.res.setHeader('Content-Type', 'application/json'); | ||
this.res.end(JSON.stringify(data)); | ||
@@ -347,0 +355,0 @@ } else { |
@@ -5,2 +5,3 @@ const phin = require('phin'); | ||
const helper = require('../helpers/helper'); | ||
const log = require('../helpers/logger'); | ||
const { PactumRequestError } = require('../helpers/errors'); | ||
@@ -486,3 +487,2 @@ | ||
if (error.response) { | ||
console.log('Normal', error); | ||
this._response = error.response; | ||
@@ -492,3 +492,3 @@ } else { | ||
err = error | ||
console.log('Error performing request', error); | ||
log.warn('Error performing request', error); | ||
this._response = error; | ||
@@ -495,0 +495,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17
2029
70057
5
99
8
+ Addedpino@^5.16.0
+ Addedatomic-sleep@1.0.0(transitive)
+ Addedfast-redact@2.1.0(transitive)
+ Addedfast-safe-stringify@2.1.1(transitive)
+ Addedflatstr@1.0.12(transitive)
+ Addedpino@5.17.0(transitive)
+ Addedpino-std-serializers@2.5.0(transitive)
+ Addedquick-format-unescaped@3.0.3(transitive)
+ Addedsonic-boom@0.7.7(transitive)