Fixing issue #478, path variables matching validation

The path variables provided in transactions will be validated with the path variables in spec. If they does not match it will be generated a mismatch with INVALID_VALUE reasonCode.
This commit is contained in:
Erik Mendoza
2022-02-24 20:51:55 -06:00
parent 4b3555a97f
commit 44c4d2ed54
7 changed files with 877 additions and 14 deletions

View File

@@ -3404,35 +3404,38 @@ module.exports = {
}, (err, res) => {
let mismatches = [],
mismatchObj;
const unmatchedSchemaVariableNames = determinedPathVariables.filter((pathVariable) => {
return !pathVariable._varMatched;
}).map((schemaPathVar) => {
return schemaPathVar.key;
});
if (err) {
return callback(err);
}
// go through required schemaPathVariables, and params that aren't found in the given transaction are errors
_.each(schemaPathVariables, (pathVar) => {
_.each(schemaPathVariables, (pathVar, index) => {
if (!_.find(determinedPathVariables, (param) => {
// only consider variable matching if url path variables is not allowed
return param.key === pathVar.name && (options.allowUrlPathVarMatching || param._varMatched);
})) {
const unmatchedSchemaVariables = _.filter(determinedPathVariables, (pathVariable) => {
return !pathVariable._varMatched;
}),
unmatchedSchemaVariableNames = _.map(unmatchedSchemaVariables, (schemaVariable) => {
return schemaVariable.key;
});
let reasonCode,
reason;
reason,
key,
currentUnmatchedVariableInTransaction = unmatchedVariablesFromTransaction[index],
isInvalidValue = currentUnmatchedVariableInTransaction !== undefined;
if (unmatchedSchemaVariableNames.length > 0 && unmatchedVariablesFromTransaction.length > 0) {
if (unmatchedSchemaVariableNames.length > 0 && isInvalidValue) {
reasonCode = 'INVALID_VALUE';
reason = `Some provided path variables in transaction (${unmatchedVariablesFromTransaction.join(',')})` +
` does not match with path variables expected in schema (${unmatchedSchemaVariableNames.join(',')})`;
reason = `The ${currentUnmatchedVariableInTransaction} path variable does not match with path variable` +
` expected in in schema at this position (${unmatchedSchemaVariableNames[index]})`;
key = currentUnmatchedVariableInTransaction;
}
else {
reasonCode = 'MISSING_IN_REQUEST';
reason = `The required path variable "${pathVar.name}" was not found in the transaction`;
key = null;
}
// assign parameter example(s) as schema examples;
@@ -3449,7 +3452,7 @@ module.exports = {
if (options.suggestAvailableFixes) {
mismatchObj.suggestedFix = {
key: pathVar.name,
actualValue: null,
actualValue: key,
suggestedValue: {
key: pathVar.name,
value: safeSchemaFaker(pathVar.schema || {}, 'example', PROCESSING_TYPE.VALIDATION,

View File

@@ -496,7 +496,11 @@ class SchemaPack {
_.forEach(matchedPath.pathVariables, (pathVar) => {
let mappedPathVar = _.find(transactionPathVariables, (transactionPathVar) => {
let matched = transactionPathVar.key === pathVar.key;
if (!matched && isNotALocalServerPathVar(transactionPathVar.key)) {
if (
!matched &&
isNotALocalServerPathVar(transactionPathVar.key) &&
!matchedPath.unmatchedVariablesFromTransaction.includes(transactionPathVar.key)
) {
matchedPath.unmatchedVariablesFromTransaction.push(transactionPathVar.key);
}
return matched;

View File

@@ -0,0 +1,225 @@
{
"item": [
{
"id": "1c9e80af-cc42-47c7-beae-f4b78e1bd3e1",
"name": "Info for a specific pet",
"request": {
"name": "Info for a specific pet",
"description": {},
"url": {
"path": [
"pets",
":petId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) A test id"
}
]
},
"header": [
{
"key": "Accept",
"value": "application/json"
}
],
"method": "GET",
"auth": null
},
"response": [
{
"id": "291f119a-d162-4676-83c0-91ce6595407b",
"name": "Expected response to a valid request",
"originalRequest": {
"url": {
"path": [
"pets",
":petId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) The id of the pet to retrieve"
}
]
},
"method": "GET",
"body": {}
},
"status": "OK",
"code": 200,
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"id\": -74238905,\n \"name\": \"et aliqua officia\",\n \"tag\": \"qui do\"\n}",
"cookie": [],
"_postman_previewlanguage": "json"
},
{
"id": "c00295c6-c859-46a4-8aae-8e2a6a2f64f3",
"name": "unexpected error",
"originalRequest": {
"url": {
"path": [
"pets",
":petId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) The id of the pet to retrieve"
}
]
},
"method": "GET",
"body": {}
},
"status": "Internal Server Error",
"code": 500,
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"code\": -79318973,\n \"message\": \"ex c\"\n}",
"cookie": [],
"_postman_previewlanguage": "json"
}
],
"event": []
}
],
"event": [],
"variable": [
{
"description": {
"content": "Assigned by the service provider",
"type": "text/plain"
},
"type": "any",
"value": "demo",
"key": "username"
},
{
"description": {
"content": " (This can only be one of 8843,443)",
"type": "text/plain"
},
"type": "any",
"value": "8843",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "v2",
"key": "basePath"
},
{
"type": "string",
"value": "https://{{username}}.myTestServer.com:{{port}}/{{basePath}}",
"key": "baseUrl"
}
],
"info": {
"_postman_id": "a1d9a3d3-6195-46b3-95ff-016edd9b283d",
"name": "Swagger Petstore",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"description": {
"content": "",
"type": "text/plain"
}
}
}

View File

@@ -0,0 +1,84 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: https://{username}.myTestServer.com:{port}/{basePath}
description: Common url for all operations in this path
variables:
username:
default: demo
description: Assigned by the service provider
port:
enum:
- '8843'
- '443'
default: '8843'
basePath:
default: v2
paths:
/pets/{peterId}/{correctName}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: peterId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
- name: correctName
in: path
required: true
description: A test id
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -0,0 +1,233 @@
{
"item": [
{
"id": "1c9e80af-cc42-47c7-beae-f4b78e1bd3e1",
"name": "Info for a specific pet",
"request": {
"name": "Info for a specific pet",
"description": {},
"url": {
"path": [
"pets",
":petId",
"wrongNamedId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) A test id"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "wrongNamedId",
"description": "(Required) The id of the pet to retrieve"
}
]
},
"header": [
{
"key": "Accept",
"value": "application/json"
}
],
"method": "GET",
"auth": null
},
"response": [
{
"id": "291f119a-d162-4676-83c0-91ce6595407b",
"name": "Expected response to a valid request",
"originalRequest": {
"url": {
"path": [
"pets",
":petId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) The id of the pet to retrieve"
}
]
},
"method": "GET",
"body": {}
},
"status": "OK",
"code": 200,
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"id\": -74238905,\n \"name\": \"et aliqua officia\",\n \"tag\": \"qui do\"\n}",
"cookie": [],
"_postman_previewlanguage": "json"
},
{
"id": "c00295c6-c859-46a4-8aae-8e2a6a2f64f3",
"name": "unexpected error",
"originalRequest": {
"url": {
"path": [
"pets",
":petId"
],
"host": [
"{{baseUrl}}"
],
"query": [],
"variable": [
{
"description": "Assigned by the service provider",
"type": "any",
"value": "{{username}}",
"key": "username"
},
{
"description": " (This can only be one of 8843,443)",
"type": "any",
"value": "{{port}}",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "{{basePath}}",
"key": "basePath"
},
{
"disabled": false,
"type": "any",
"value": "<string>",
"key": "petId",
"description": "(Required) The id of the pet to retrieve"
}
]
},
"method": "GET",
"body": {}
},
"status": "Internal Server Error",
"code": 500,
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": "{\n \"code\": -79318973,\n \"message\": \"ex c\"\n}",
"cookie": [],
"_postman_previewlanguage": "json"
}
],
"event": []
}
],
"event": [],
"variable": [
{
"description": {
"content": "Assigned by the service provider",
"type": "text/plain"
},
"type": "any",
"value": "demo",
"key": "username"
},
{
"description": {
"content": " (This can only be one of 8843,443)",
"type": "text/plain"
},
"type": "any",
"value": "8843",
"key": "port"
},
{
"description": {
"content": "",
"type": "text/plain"
},
"type": "any",
"value": "v2",
"key": "basePath"
},
{
"type": "string",
"value": "https://{{username}}.myTestServer.com:{{port}}/{{basePath}}",
"key": "baseUrl"
}
],
"info": {
"_postman_id": "a1d9a3d3-6195-46b3-95ff-016edd9b283d",
"name": "Swagger Petstore",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"description": {
"content": "",
"type": "text/plain"
}
}
}

View File

@@ -0,0 +1,84 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: https://{username}.myTestServer.com:{port}/{basePath}
description: Common url for all operations in this path
variables:
username:
default: demo
description: Assigned by the service provider
port:
enum:
- '8843'
- '443'
default: '8843'
basePath:
default: v2
paths:
/pets/{peterId}/{correctName}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: peterId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
- name: correctName
in: path
required: true
description: A test id
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -1308,3 +1308,233 @@ describe('VALIDATE FUNCTION TESTS ', function () {
});
});
});
describe('validateTransaction method. Path variables matching validation (issue #478)', function() {
it('Should validate correctly while a path param in spec does not matches with collection' +
' (issue#478)', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(issueFolder + '/issueSpec.yaml', 'utf-8'),
issueCollection = fs.readFileSync(issueFolder + '/issueCollection.json', 'utf-8'),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(1);
expect(resultObj.mismatches[0].reasonCode).to.be.equal('INVALID_VALUE');
expect(resultObj.mismatches[0].reason).to.be.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
done();
});
});
it('Should validate correctly while a path param in spec does not matches with collection' +
' (issue#478), allowUrlPathVarMatching: true', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(issueFolder + '/issueSpec.yaml', 'utf-8'),
issueCollection = fs.readFileSync(issueFolder + '/issueCollection.json', 'utf-8'),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: true });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(0);
done();
});
});
it('Should validate correctly when a path param in spec does not matches with collection ' +
'and there are path variables in local servers object (issue#478)', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(issueFolder + '/local-servers-path-variables-spec.yaml', 'utf-8'),
issueCollection = fs.readFileSync(issueFolder + '/local-servers-path-variables-collection.json', 'utf-8'),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(1);
expect(resultObj.mismatches[0].reason).to.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
expect(resultObj.mismatches[0].reasonCode).to.equal('INVALID_VALUE');
done();
});
});
it('Should validate correctly when a path param in spec does not matches with collection ' +
'and there are path variables in global servers object (issue#478)', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(issueFolder + '/global-servers-path-variables-spec.yaml', 'utf-8'),
issueCollection = fs.readFileSync(issueFolder + '/global-servers-path-variables-collection.json', 'utf-8'),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(1);
expect(resultObj.mismatches[0].reason).to.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
expect(resultObj.mismatches[0].reasonCode).to.equal('INVALID_VALUE');
done();
});
});
it('Should validate correctly when a path param in spec does not matches with collection ' +
'and there are path variables in global servers object (issue#478), suggestAvailableFixes: true', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(issueFolder + '/global-servers-path-variables-spec.yaml', 'utf-8'),
issueCollection = fs.readFileSync(issueFolder + '/global-servers-path-variables-collection.json', 'utf-8'),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack(
{ type: 'string', data: issueSpec },
{ allowUrlPathVarMatching: false, suggestAvailableFixes: true });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(1);
expect(resultObj.mismatches[0].reason).to.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
expect(resultObj.mismatches[0].reasonCode).to.equal('INVALID_VALUE');
done();
});
});
it('Should validate correctly when two path params in spec does not matches with collection ' +
'and there are path variables in global servers object (issue#478), suggestAvailableFixes: true', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-wrong-spec.yaml', 'utf-8'
),
issueCollection = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-wrong-collection.json', 'utf-8'
),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack(
{ type: 'string', data: issueSpec },
{ allowUrlPathVarMatching: false, suggestAvailableFixes: true });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(2);
expect(resultObj.mismatches[0].reason).to.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
expect(resultObj.mismatches[0].reasonCode).to.equal('INVALID_VALUE');
expect(resultObj.mismatches[1].reason).to.equal(
'The wrongNamedId path variable does not match with path ' +
'variable expected in in schema at this position (correctName)'
);
expect(resultObj.mismatches[1].reasonCode).to.equal('INVALID_VALUE');
done();
});
});
it('Should validate correctly when one path param in spec does not matches with collection ' +
', global servers and one path var is not provided (issue#478), suggestAvailableFixes: true', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-missing-one-spec.yaml', 'utf-8'
),
issueCollection = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-missing-one-collection.json', 'utf-8'
),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack(
{ type: 'string', data: issueSpec },
{ allowUrlPathVarMatching: false, suggestAvailableFixes: true });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(2);
expect(resultObj.mismatches[0].reason).to.equal(
'The petId path variable does not match with path variable' +
' expected in in schema at this position (peterId)'
);
expect(resultObj.mismatches[0].reasonCode).to.equal('INVALID_VALUE');
expect(resultObj.mismatches[1].reason).to.equal(
'The required path variable "correctName" was not found in the transaction'
);
expect(resultObj.mismatches[1].reasonCode).to.equal('MISSING_IN_REQUEST');
done();
});
});
it('Should validate correctly when one path param in spec does not matches with collection ' +
', global servers and one path var is not provided (issue#478), ' +
'suggestAvailableFixes: true, allowUrlPathVarMatching: true', function(done) {
let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'),
issueSpec = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-missing-one-spec.yaml', 'utf-8'
),
issueCollection = fs.readFileSync(
issueFolder + '/global-servers-path-variables-two-vars-missing-one-collection.json', 'utf-8'
),
resultObj,
historyRequest = [],
schemaPack = new Converter.SchemaPack(
{ type: 'string', data: issueSpec },
{ allowUrlPathVarMatching: true, suggestAvailableFixes: true });
getAllTransactions(JSON.parse(issueCollection), historyRequest);
schemaPack.validateTransaction(historyRequest, (err, result) => {
// Schema is sample petsore with one of parameter as empty, expect no mismatch / error
expect(err).to.be.null;
expect(result).to.be.an('object');
resultObj = result.requests[historyRequest[0].id].endpoints[0];
expect(resultObj.mismatches).to.have.length(0);
done();
});
});
});