mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
support for defined schema dialect property on validate transaction
This commit is contained in:
@@ -30,11 +30,22 @@ function getLocalDraft(schema) {
|
|||||||
/**
|
/**
|
||||||
* Gets the correct validator according to the draft
|
* Gets the correct validator according to the draft
|
||||||
*
|
*
|
||||||
* @param {string} draft - the draft identifier
|
* @param {string} draftToUse - the draft to use in validation
|
||||||
* @returns {string} the id
|
* @returns {string} the draft identifier
|
||||||
*/
|
*/
|
||||||
function getAjvValidator(draft) {
|
function getAjvValidator(draftToUse) {
|
||||||
return draft === specialDraft ? validateSchemaAJVDraft04 : validateSchemaAJV;
|
return draftToUse === specialDraft ? validateSchemaAJVDraft04 : validateSchemaAJV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the draft to use in validation
|
||||||
|
*
|
||||||
|
* @param {string} localDraft - the draft from the schema object
|
||||||
|
* @param {string} jsonSchemaDialect - the draft from the OAS object
|
||||||
|
* @returns {string} the draft to use
|
||||||
|
*/
|
||||||
|
function getDraftToUse(localDraft, jsonSchemaDialect) {
|
||||||
|
return localDraft ? localDraft : jsonSchemaDialect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,13 +55,15 @@ function getAjvValidator(draft) {
|
|||||||
* @param {*} schema - schema to validate
|
* @param {*} schema - schema to validate
|
||||||
* @param {*} valueToUse - value to validate schema against
|
* @param {*} valueToUse - value to validate schema against
|
||||||
* @param {*} options - a standard list of options that's globally passed around. Check options.js for more.
|
* @param {*} options - a standard list of options that's globally passed around. Check options.js for more.
|
||||||
|
* @param {string} jsonSchemaDialect - the defined schema in the OAS object
|
||||||
* @returns {*} - Found Validation Errors
|
* @returns {*} - Found Validation Errors
|
||||||
*/
|
*/
|
||||||
function validateSchema (schema, valueToUse, options = {}) {
|
function validateSchema (schema, valueToUse, options = {}, jsonSchemaDialect) {
|
||||||
let validate,
|
let validate,
|
||||||
compoundResult,
|
compoundResult,
|
||||||
filteredValidationError,
|
filteredValidationError,
|
||||||
draftToUse = getLocalDraft(schema);
|
localDraft = getLocalDraft(schema),
|
||||||
|
draftToUse = getDraftToUse(localDraft, jsonSchemaDialect);
|
||||||
const validator = getAjvValidator(draftToUse);
|
const validator = getAjvValidator(draftToUse);
|
||||||
compoundResult = validator(schema, valueToUse, draftToUse);
|
compoundResult = validator(schema, valueToUse, draftToUse);
|
||||||
if (compoundResult.filteredValidationError) {
|
if (compoundResult.filteredValidationError) {
|
||||||
@@ -96,5 +109,6 @@ function validateSchema (schema, valueToUse, options = {}) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
validateSchema,
|
validateSchema,
|
||||||
getLocalDraft,
|
getLocalDraft,
|
||||||
getAjvValidator
|
getAjvValidator,
|
||||||
|
getDraftToUse
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3037,11 +3037,12 @@ module.exports = {
|
|||||||
* @param {Object} components - Components in the spec that the schema might refer to
|
* @param {Object} components - Components in the spec that the schema might refer to
|
||||||
* @param {Object} options - Global options
|
* @param {Object} options - Global options
|
||||||
* @param {Object} schemaCache object storing schemaFaker and schmeResolution caches
|
* @param {Object} schemaCache object storing schemaFaker and schmeResolution caches
|
||||||
|
* @param {string} jsonSchemaDialect The schema dialect defined in the OAS object
|
||||||
* @param {Function} callback - For return
|
* @param {Function} callback - For return
|
||||||
* @returns {Array} array of mismatches
|
* @returns {Array} array of mismatches
|
||||||
*/
|
*/
|
||||||
checkValueAgainstSchema: function (property, jsonPathPrefix, txnParamName, value, schemaPathPrefix, openApiSchemaObj,
|
checkValueAgainstSchema: function (property, jsonPathPrefix, txnParamName, value, schemaPathPrefix, openApiSchemaObj,
|
||||||
parameterSourceOption, components, options, schemaCache, callback) {
|
parameterSourceOption, components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||||
|
|
||||||
let mismatches = [],
|
let mismatches = [],
|
||||||
jsonValue,
|
jsonValue,
|
||||||
@@ -3075,7 +3076,7 @@ module.exports = {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.checkValueAgainstSchema(property, jsonPathPrefix, txnParamName, value,
|
this.checkValueAgainstSchema(property, jsonPathPrefix, txnParamName, value,
|
||||||
`${schemaPathPrefix}.${schema.oneOf ? 'oneOf' : 'anyOf'}[${_.findIndex(compositeSchema, elementSchema)}]`,
|
`${schemaPathPrefix}.${schema.oneOf ? 'oneOf' : 'anyOf'}[${_.findIndex(compositeSchema, elementSchema)}]`,
|
||||||
elementSchema, parameterSourceOption, components, options, schemaCache, cb);
|
elementSchema, parameterSourceOption, components, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, results) => {
|
}, (err, results) => {
|
||||||
let sortedResults;
|
let sortedResults;
|
||||||
@@ -3167,7 +3168,7 @@ module.exports = {
|
|||||||
// only do AJV if type is array or object
|
// only do AJV if type is array or object
|
||||||
// simpler cases are handled by a type check
|
// simpler cases are handled by a type check
|
||||||
if (isCorrectType && needJsonMatching) {
|
if (isCorrectType && needJsonMatching) {
|
||||||
let filteredValidationError = validateSchema(schema, valueToUse, options);
|
let filteredValidationError = validateSchema(schema, valueToUse, options, jsonSchemaDialect);
|
||||||
|
|
||||||
if (!_.isEmpty(filteredValidationError)) {
|
if (!_.isEmpty(filteredValidationError)) {
|
||||||
let mismatchObj,
|
let mismatchObj,
|
||||||
@@ -3312,6 +3313,7 @@ module.exports = {
|
|||||||
* @param {*} components the components + paths from the OAS spec that need to be used to resolve $refs
|
* @param {*} components the components + paths from the OAS spec that need to be used to resolve $refs
|
||||||
* @param {*} options OAS options
|
* @param {*} options OAS options
|
||||||
* @param {*} schemaCache object storing schemaFaker and schmeResolution caches
|
* @param {*} schemaCache object storing schemaFaker and schmeResolution caches
|
||||||
|
* @param {string} jsonSchemaDialect Defined schema dialect at the OAS object
|
||||||
* @param {*} callback Callback
|
* @param {*} callback Callback
|
||||||
* @returns {array} mismatches (in the callback)
|
* @returns {array} mismatches (in the callback)
|
||||||
*/
|
*/
|
||||||
@@ -3322,6 +3324,7 @@ module.exports = {
|
|||||||
components,
|
components,
|
||||||
options,
|
options,
|
||||||
schemaCache,
|
schemaCache,
|
||||||
|
jsonSchemaDialect,
|
||||||
callback) {
|
callback) {
|
||||||
|
|
||||||
// schema path should have all parameters needed
|
// schema path should have all parameters needed
|
||||||
@@ -3390,7 +3393,7 @@ module.exports = {
|
|||||||
schemaPathVar.pathPrefix + '[?(@.name==\'' + schemaPathVar.name + '\')]',
|
schemaPathVar.pathPrefix + '[?(@.name==\'' + schemaPathVar.name + '\')]',
|
||||||
schemaPathVar.schema,
|
schemaPathVar.schema,
|
||||||
PARAMETER_SOURCE.REQUEST,
|
PARAMETER_SOURCE.REQUEST,
|
||||||
components, options, schemaCache, cb);
|
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
let mismatches = [],
|
let mismatches = [],
|
||||||
@@ -3540,7 +3543,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkQueryParams(requestUrl, transactionPathPrefix, schemaPath, components, options,
|
checkQueryParams(requestUrl, transactionPathPrefix, schemaPath, components, options,
|
||||||
schemaCache, callback) {
|
schemaCache, jsonSchemaDialect, callback) {
|
||||||
let parsedUrl = require('url').parse(requestUrl),
|
let parsedUrl = require('url').parse(requestUrl),
|
||||||
schemaParams = _.filter(schemaPath.parameters, (param) => { return param.in === 'query'; }),
|
schemaParams = _.filter(schemaPath.parameters, (param) => { return param.in === 'query'; }),
|
||||||
requestQueryArray = [],
|
requestQueryArray = [],
|
||||||
@@ -3682,7 +3685,7 @@ module.exports = {
|
|||||||
schemaParam.pathPrefix + '[?(@.name==\'' + schemaParam.name + '\')]',
|
schemaParam.pathPrefix + '[?(@.name==\'' + schemaParam.name + '\')]',
|
||||||
schemaParam.schema,
|
schemaParam.schema,
|
||||||
PARAMETER_SOURCE.REQUEST,
|
PARAMETER_SOURCE.REQUEST,
|
||||||
components, options, schemaCache, cb
|
components, options, schemaCache, jsonSchemaDialect, cb
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
@@ -3846,7 +3849,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkRequestHeaders: function (headers, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
checkRequestHeaders: function (headers, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||||
components, options, schemaCache, callback) {
|
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||||
let schemaHeaders = _.filter(schemaPath.parameters, (param) => { return param.in === 'header'; }),
|
let schemaHeaders = _.filter(schemaPath.parameters, (param) => { return param.in === 'header'; }),
|
||||||
// key name of headers which are added by security schemes
|
// key name of headers which are added by security schemes
|
||||||
securityHeaders = _.map(this.getSecurityParams(_.get(components, 'components'), 'header'), 'name'),
|
securityHeaders = _.map(this.getSecurityParams(_.get(components, 'components'), 'header'), 'name'),
|
||||||
@@ -3904,7 +3907,7 @@ module.exports = {
|
|||||||
schemaHeader.pathPrefix + '[?(@.name==\'' + schemaHeader.name + '\')]',
|
schemaHeader.pathPrefix + '[?(@.name==\'' + schemaHeader.name + '\')]',
|
||||||
schemaHeader.schema,
|
schemaHeader.schema,
|
||||||
PARAMETER_SOURCE.REQUEST,
|
PARAMETER_SOURCE.REQUEST,
|
||||||
components, options, schemaCache, cb
|
components, options, schemaCache, jsonSchemaDialect, cb
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
@@ -3962,7 +3965,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkResponseHeaders: function (schemaResponse, headers, transactionPathPrefix, schemaPathPrefix,
|
checkResponseHeaders: function (schemaResponse, headers, transactionPathPrefix, schemaPathPrefix,
|
||||||
components, options, schemaCache, callback) {
|
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||||
// 0. Need to find relevant response from schemaPath.responses
|
// 0. Need to find relevant response from schemaPath.responses
|
||||||
let schemaHeaders,
|
let schemaHeaders,
|
||||||
// filter out headers which need explicit handling according to schema (other than parameters object)
|
// filter out headers which need explicit handling according to schema (other than parameters object)
|
||||||
@@ -4018,7 +4021,7 @@ module.exports = {
|
|||||||
schemaPathPrefix + '.headers[' + pHeader.key + ']',
|
schemaPathPrefix + '.headers[' + pHeader.key + ']',
|
||||||
schemaHeader.schema,
|
schemaHeader.schema,
|
||||||
PARAMETER_SOURCE.RESPONSE,
|
PARAMETER_SOURCE.RESPONSE,
|
||||||
components, options, schemaCache, cb
|
components, options, schemaCache, jsonSchemaDialect, cb
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
@@ -4071,7 +4074,7 @@ module.exports = {
|
|||||||
|
|
||||||
// Only application/json and application/x-www-form-urlencoded is validated for now
|
// Only application/json and application/x-www-form-urlencoded is validated for now
|
||||||
checkRequestBody: function (requestBody, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
checkRequestBody: function (requestBody, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||||
components, options, schemaCache, callback) {
|
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||||
// check for body modes
|
// check for body modes
|
||||||
let jsonSchemaBody,
|
let jsonSchemaBody,
|
||||||
jsonContentType,
|
jsonContentType,
|
||||||
@@ -4102,6 +4105,7 @@ module.exports = {
|
|||||||
components,
|
components,
|
||||||
_.extend({}, options, { shortValidationErrors: true }),
|
_.extend({}, options, { shortValidationErrors: true }),
|
||||||
schemaCache,
|
schemaCache,
|
||||||
|
jsonSchemaDialect,
|
||||||
callback
|
callback
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -4220,7 +4224,7 @@ module.exports = {
|
|||||||
pathPrefix + '.properties[' + schemaParam.name + ']',
|
pathPrefix + '.properties[' + schemaParam.name + ']',
|
||||||
schemaParam.schema,
|
schemaParam.schema,
|
||||||
PARAMETER_SOURCE.REQUEST,
|
PARAMETER_SOURCE.REQUEST,
|
||||||
components, options, schemaCache, cb
|
components, options, schemaCache, jsonSchemaDialect, cb
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
@@ -4286,7 +4290,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkResponseBody: function (schemaResponse, body, transactionPathPrefix, schemaPathPrefix,
|
checkResponseBody: function (schemaResponse, body, transactionPathPrefix, schemaPathPrefix,
|
||||||
components, options, schemaCache, callback) {
|
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||||
let schemaContent,
|
let schemaContent,
|
||||||
jsonContentType,
|
jsonContentType,
|
||||||
mismatchProperty = 'RESPONSE_BODY';
|
mismatchProperty = 'RESPONSE_BODY';
|
||||||
@@ -4324,13 +4328,14 @@ module.exports = {
|
|||||||
components,
|
components,
|
||||||
_.extend({}, options, { shortValidationErrors: true }),
|
_.extend({}, options, { shortValidationErrors: true }),
|
||||||
schemaCache,
|
schemaCache,
|
||||||
|
jsonSchemaDialect,
|
||||||
callback
|
callback
|
||||||
);
|
);
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
checkResponses: function (responses, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
checkResponses: function (responses, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||||
components, options, schemaCache, cb) {
|
components, options, schemaCache, jsonSchemaDialect, cb) {
|
||||||
// responses is an array of repsonses recd. for one Postman request
|
// responses is an array of repsonses recd. for one Postman request
|
||||||
// we've already determined the schemaPath against which all responses need to be validated
|
// we've already determined the schemaPath against which all responses need to be validated
|
||||||
// loop through all responses
|
// loop through all responses
|
||||||
@@ -4369,13 +4374,15 @@ module.exports = {
|
|||||||
headers: (cb) => {
|
headers: (cb) => {
|
||||||
this.checkResponseHeaders(thisSchemaResponse, response.header,
|
this.checkResponseHeaders(thisSchemaResponse, response.header,
|
||||||
transactionPathPrefix + '[' + response.id + '].header',
|
transactionPathPrefix + '[' + response.id + '].header',
|
||||||
schemaPathPrefix + '.responses.' + responsePathPrefix, components, options, schemaCache, cb);
|
schemaPathPrefix + '.responses.' + responsePathPrefix,
|
||||||
|
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
},
|
},
|
||||||
body: (cb) => {
|
body: (cb) => {
|
||||||
// assume it's JSON at this point
|
// assume it's JSON at this point
|
||||||
this.checkResponseBody(thisSchemaResponse, response.body,
|
this.checkResponseBody(thisSchemaResponse, response.body,
|
||||||
transactionPathPrefix + '[' + response.id + '].body',
|
transactionPathPrefix + '[' + response.id + '].body',
|
||||||
schemaPathPrefix + '.responses.' + responsePathPrefix, components, options, schemaCache, cb);
|
schemaPathPrefix + '.responses.' + responsePathPrefix,
|
||||||
|
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
}
|
}
|
||||||
}, (err, result) => {
|
}, (err, result) => {
|
||||||
return responseCallback(null, {
|
return responseCallback(null, {
|
||||||
|
|||||||
@@ -378,7 +378,8 @@ class SchemaPack {
|
|||||||
schemaResolutionCache: this.schemaResolutionCache,
|
schemaResolutionCache: this.schemaResolutionCache,
|
||||||
schemaFakerCache: this.schemaFakerCache
|
schemaFakerCache: this.schemaFakerCache
|
||||||
},
|
},
|
||||||
matchedEndpoints = [];
|
matchedEndpoints = [],
|
||||||
|
jsonSchemaDialect = schema.jsonSchemaDialect;
|
||||||
|
|
||||||
// Only change the stack limit if the optimizeConversion option is true
|
// Only change the stack limit if the optimizeConversion option is true
|
||||||
if (options.optimizeConversion) {
|
if (options.optimizeConversion) {
|
||||||
@@ -498,23 +499,23 @@ class SchemaPack {
|
|||||||
},
|
},
|
||||||
path: function(cb) {
|
path: function(cb) {
|
||||||
schemaUtils.checkPathVariables(matchedPath.pathVariables, '$.request.url.variable', matchedPath.path,
|
schemaUtils.checkPathVariables(matchedPath.pathVariables, '$.request.url.variable', matchedPath.path,
|
||||||
componentsAndPaths, options, schemaCache, cb);
|
componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
},
|
},
|
||||||
queryparams: function(cb) {
|
queryparams: function(cb) {
|
||||||
schemaUtils.checkQueryParams(requestUrl, '$.request.url.query', matchedPath.path,
|
schemaUtils.checkQueryParams(requestUrl, '$.request.url.query', matchedPath.path,
|
||||||
componentsAndPaths, options, schemaCache, cb);
|
componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
},
|
},
|
||||||
headers: function(cb) {
|
headers: function(cb) {
|
||||||
schemaUtils.checkRequestHeaders(transaction.request.header, '$.request.header', matchedPath.jsonPath,
|
schemaUtils.checkRequestHeaders(transaction.request.header, '$.request.header', matchedPath.jsonPath,
|
||||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
},
|
},
|
||||||
requestBody: function(cb) {
|
requestBody: function(cb) {
|
||||||
schemaUtils.checkRequestBody(transaction.request.body, '$.request.body', matchedPath.jsonPath,
|
schemaUtils.checkRequestBody(transaction.request.body, '$.request.body', matchedPath.jsonPath,
|
||||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
},
|
},
|
||||||
responses: function (cb) {
|
responses: function (cb) {
|
||||||
schemaUtils.checkResponses(transaction.response, '$.responses', matchedPath.jsonPath,
|
schemaUtils.checkResponses(transaction.response, '$.responses', matchedPath.jsonPath,
|
||||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||||
}
|
}
|
||||||
}, (err, result) => {
|
}, (err, result) => {
|
||||||
let allMismatches = _.concat(result.metadata, result.queryparams, result.headers, result.path,
|
let allMismatches = _.concat(result.metadata, result.queryparams, result.headers, result.path,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
const { getLocalDraft, getAjvValidator, validateSchema } = require('../../lib/ajValidation/ajvValidation'),
|
const { getLocalDraft,
|
||||||
|
getAjvValidator,
|
||||||
|
validateSchema,
|
||||||
|
getDraftToUse } = require('../../lib/ajValidation/ajvValidation'),
|
||||||
{ validateSchemaAJVDraft04 } = require('../../lib/ajValidation/ajvValidatorDraft04'),
|
{ validateSchemaAJVDraft04 } = require('../../lib/ajValidation/ajvValidatorDraft04'),
|
||||||
expect = require('chai').expect;
|
expect = require('chai').expect;
|
||||||
|
|
||||||
@@ -300,3 +303,26 @@ describe('validateSchema', function () {
|
|||||||
expect(result.filteredValidationError).to.be.undefined;
|
expect(result.filteredValidationError).to.be.undefined;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getDraftToUse', function() {
|
||||||
|
it('should return the ajv draft 04 when $schema undefined and jsonSchemaDialect is the 04', function() {
|
||||||
|
let draftToUse = getDraftToUse(undefined, 'http://json-schema.org/draft-04/schema#');
|
||||||
|
expect(draftToUse).to.equal('http://json-schema.org/draft-04/schema#');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the ajv draft 06 when $schema is 06 and jsonSchemaDialect is the 04', function() {
|
||||||
|
let draftToUse = getDraftToUse('http://json-schema.org/draft-06/schema#',
|
||||||
|
'http://json-schema.org/draft-04/schema#');
|
||||||
|
expect(draftToUse).to.equal('http://json-schema.org/draft-06/schema#');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the ajv draft 06 when $schema is 06 and jsonSchemaDialect is undefined', function() {
|
||||||
|
let draftToUse = getDraftToUse('http://json-schema.org/draft-06/schema#', undefined);
|
||||||
|
expect(draftToUse).to.equal('http://json-schema.org/draft-06/schema#');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined when $schema and jsonSchemaDialect are undefined', function() {
|
||||||
|
let draftToUse = getDraftToUse(undefined, undefined);
|
||||||
|
expect(draftToUse).to.equal(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user