mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
Merge pull request #481 from postmanlabs/fix479/valueTypes
values like <integer> in validation
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
const { formatDataPath } = require('../common/schemaUtilsCommon');
|
||||
const { formatDataPath,
|
||||
formatSchemaPathFromAJVErrorToConvertToDataPath,
|
||||
isTypeValue } = require('../common/schemaUtilsCommon');
|
||||
|
||||
var _ = require('lodash');
|
||||
const IGNORED_KEYWORDS = ['propertyNames', 'const', 'additionalItems', 'dependencies'],
|
||||
@@ -97,6 +99,14 @@ function validateSchema (schema, valueToUse, options = {}, jsonSchemaDialect) {
|
||||
isPmVariable(dataPath === '' ? valueToUse : _.get(valueToUse, dataPath))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (validationError.keyword === 'type' || validationError.keyword === 'format') {
|
||||
let schemaDataPath = formatDataPath(formatSchemaPathFromAJVErrorToConvertToDataPath(validationError.schemaPath)),
|
||||
schemaToUse = schemaDataPath ? _.get(schema, schemaDataPath) : schema,
|
||||
valueToValidate = dataPath ? _.get(valueToUse, dataPath) : valueToUse;
|
||||
return !isTypeValue(valueToValidate, schemaToUse);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -110,5 +120,6 @@ module.exports = {
|
||||
validateSchema,
|
||||
getLocalDraft,
|
||||
getAjvValidator,
|
||||
getDraftToUse
|
||||
getDraftToUse,
|
||||
isTypeValue
|
||||
};
|
||||
|
||||
@@ -2,7 +2,207 @@
|
||||
* This file contains util functions that are common between versions
|
||||
*/
|
||||
|
||||
const parse = require('../parse.js');
|
||||
const parse = require('../parse.js'),
|
||||
_ = require('lodash'),
|
||||
typesMap = {
|
||||
integer: {
|
||||
int32: '<integer>',
|
||||
int64: '<long>'
|
||||
},
|
||||
number: {
|
||||
float: '<float>',
|
||||
double: '<double>'
|
||||
},
|
||||
string: {
|
||||
byte: '<byte>',
|
||||
binary: '<binary>',
|
||||
date: '<date>',
|
||||
'date-time': '<dateTime>',
|
||||
password: '<password>'
|
||||
},
|
||||
boolean: '<boolean>',
|
||||
array: '<array>',
|
||||
object: '<object>'
|
||||
},
|
||||
|
||||
/* eslint-disable arrow-body-style */
|
||||
schemaTypeToJsValidator = {
|
||||
'string': (d) => typeof d === 'string',
|
||||
'number': (d) => !isNaN(d),
|
||||
'integer': (d) => !isNaN(d) && Number.isInteger(Number(d)),
|
||||
'boolean': (d) => _.isBoolean(d) || d === 'true' || d === 'false',
|
||||
'array': (d) => Array.isArray(d),
|
||||
'object': (d) => typeof d === 'object' && !Array.isArray(d)
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the # character from the beginning of a schema path
|
||||
* @param {string} schemaPath - a defined schemaPath
|
||||
* @returns {string} - the schema path with # removed
|
||||
*/
|
||||
function removeSharpAndSlashFromFirstPosition(schemaPath) {
|
||||
return schemaPath[0] === '#' ? schemaPath.slice(2) : schemaPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the defined word from the last position of a schema path
|
||||
* @param {string} schemaPath - a defined schemaPath
|
||||
* @param {string} word - word to remove
|
||||
* @returns {string} - the schema path with type removed
|
||||
*/
|
||||
function removeWordFromLastPosition(schemaPath, word) {
|
||||
let splittedDataPath = schemaPath.split('/');
|
||||
if (splittedDataPath[splittedDataPath.length - 1] === word) {
|
||||
splittedDataPath.splice(-1);
|
||||
}
|
||||
return splittedDataPath.join('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
*
|
||||
* @param {string} value - Value to check for
|
||||
* @param {string} type - The type in the schemna
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function compareType(value, type) {
|
||||
return value === '<' + type + '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} types - The types in the schemna
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function isTypeValueArrayCheck(value, types) {
|
||||
return types.find((type) => {
|
||||
return compareType(value, type);
|
||||
}) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} types - The types in the schemna
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function checkValueOnlyTypes(value, types) {
|
||||
return Array.isArray(types) ? isTypeValueArrayCheck(value, types) : compareType(value, types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is postman variable or not
|
||||
*
|
||||
* @param {string} type - type to look for
|
||||
* @param {string} format - format from schema
|
||||
* @returns {Boolean} postman variable or not
|
||||
*/
|
||||
function getDefaultFromTypeAndFormat(type, format) {
|
||||
return typesMap[type][format];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} types - The types in the schema
|
||||
* @param {*} format - format from the schema
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function checkValueTypesAndFormat(value, types, format) {
|
||||
let typesNotInMapp = [],
|
||||
typesArray = Array.isArray(types) ? types : [types],
|
||||
found = typesArray.find((type) => {
|
||||
let defaultValue;
|
||||
if (typesMap.hasOwnProperty(type)) {
|
||||
defaultValue = getDefaultFromTypeAndFormat(type, format);
|
||||
|
||||
// in case the format is a custom format (email, hostname etc.)
|
||||
// https://swagger.io/docs/specification/data-models/data-types/#string
|
||||
if (!defaultValue && format) {
|
||||
defaultValue = '<' + format + '>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
typesNotInMapp.push(type);
|
||||
}
|
||||
return defaultValue === value;
|
||||
});
|
||||
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
|
||||
found = typesNotInMapp.find((type) => {
|
||||
let defaultValue;
|
||||
defaultValue = '<' + type + (format ? ('-' + format) : '') + '>';
|
||||
return defaultValue === value;
|
||||
});
|
||||
|
||||
return found !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is equal to the defined default
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} definedDefault - The defined default value of the schema
|
||||
* @returns {Boolean} wheter value is equal to the defined or not
|
||||
*/
|
||||
function checkValueEqualsDefault(value, definedDefault) {
|
||||
return value === definedDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} schema - The schema portion used in validation
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function isTypeValue(value, schema) {
|
||||
if (schema.hasOwnProperty('type') && schema.hasOwnProperty('default')) {
|
||||
const isDefault = checkValueEqualsDefault(value, schema.default);
|
||||
if (isDefault) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (schema.hasOwnProperty('type') && !schema.hasOwnProperty('format')) {
|
||||
return checkValueOnlyTypes(value, schema.type);
|
||||
}
|
||||
if (schema.hasOwnProperty('type') && schema.hasOwnProperty('format')) {
|
||||
return checkValueTypesAndFormat(value, schema.type, schema.format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if value is correcta according to schema
|
||||
* If the value should be numeric, it tries to convert and then validate
|
||||
* also validates if the value is a correct representation in the form of
|
||||
* <long> or <integer> etc for integers format 32 or format 64
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} schema - The schema portion used in validation
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
function checkIsCorrectType(value, schema) {
|
||||
if (schema.hasOwnProperty('type') &&
|
||||
typeof schemaTypeToJsValidator[schema.type] === 'function') {
|
||||
const isCorrectType = schemaTypeToJsValidator[schema.type](value);
|
||||
if (isCorrectType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isTypeValue(value, schema);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -54,15 +254,21 @@ module.exports = {
|
||||
isANumber = (value) => {
|
||||
return !isNaN(value);
|
||||
},
|
||||
formattedElements = splittedDataPath.map((element) => {
|
||||
formattedElements = splittedDataPath.map((element, index) => {
|
||||
if (element !== '' && isANumber(element)) {
|
||||
return `[${element}]`;
|
||||
}
|
||||
if (element === '' || element[0] === '.') {
|
||||
return element;
|
||||
}
|
||||
if (index === 0 && !initialDotIfExist) {
|
||||
return `${element}`;
|
||||
}
|
||||
return `.${element}`;
|
||||
}),
|
||||
formattedDataPath = formattedElements.join('');
|
||||
|
||||
return `${initialDotIfExist}${formattedDataPath}`;
|
||||
return `${formattedDataPath}`;
|
||||
},
|
||||
|
||||
handleExclusiveMaximum: function(schema, max) {
|
||||
@@ -101,5 +307,43 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
return min;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes initial "#/" from a schema path and the last "/type" segment
|
||||
* @param {string} schemaPath - The OAS 3.x specification specified in either YAML or JSON
|
||||
* @returns {string} - The schemaPath with initial #/ and last "/type" removed
|
||||
*/
|
||||
formatSchemaPathFromAJVErrorToConvertToDataPath: function (schemaPath) {
|
||||
return removeWordFromLastPosition(removeWordFromLastPosition(removeSharpAndSlashFromFirstPosition(schemaPath),
|
||||
'type'), 'format');
|
||||
},
|
||||
|
||||
typesMap,
|
||||
|
||||
/**
|
||||
* Checks if value is the representation of its type like:
|
||||
* "<integer>"
|
||||
* Works in array types
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} schema - The schema portion used in validation
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
isTypeValue,
|
||||
|
||||
/**
|
||||
* Checks if value is correcta according to schema
|
||||
* If the value should be numeric, it tries to convert and then validate
|
||||
* also validates if the value is a correct representation in the form of
|
||||
* <long> or <integer> etc for integers format 32 or format 64
|
||||
* @param {string} value - Value to check for
|
||||
* @param {*} schema - The schema portion used in validation
|
||||
* @returns {Boolean} the value is the representation of its type
|
||||
*/
|
||||
checkIsCorrectType,
|
||||
|
||||
|
||||
isKnownType: function(schema) {
|
||||
return typeof schemaTypeToJsValidator[schema.type] === 'function';
|
||||
}
|
||||
};
|
||||
|
||||
38
lib/deref.js
38
lib/deref.js
@@ -1,24 +1,9 @@
|
||||
const _ = require('lodash'),
|
||||
mergeAllOf = require('json-schema-merge-allof'),
|
||||
type = {
|
||||
integer: {
|
||||
int32: '<integer>',
|
||||
int64: '<long>'
|
||||
},
|
||||
number: {
|
||||
float: '<float>',
|
||||
double: '<double>'
|
||||
},
|
||||
string: {
|
||||
byte: '<byte>',
|
||||
binary: '<binary>',
|
||||
date: '<date>',
|
||||
'date-time': '<dateTime>',
|
||||
password: '<password>'
|
||||
},
|
||||
boolean: '<boolean>',
|
||||
array: '<array>',
|
||||
object: '<object>'
|
||||
{ typesMap } = require('./common/schemaUtilsCommon'),
|
||||
PARAMETER_SOURCE = {
|
||||
REQUEST: 'REQUEST',
|
||||
RESPONSE: 'RESPONSE'
|
||||
},
|
||||
SCHEMA_TYPES = {
|
||||
array: 'array',
|
||||
@@ -28,10 +13,6 @@ const _ = require('lodash'),
|
||||
object: 'object',
|
||||
string: 'string'
|
||||
},
|
||||
PARAMETER_SOURCE = {
|
||||
REQUEST: 'REQUEST',
|
||||
RESPONSE: 'RESPONSE'
|
||||
},
|
||||
// All formats supported by both ajv and json-schema-faker
|
||||
SUPPORTED_FORMATS = [
|
||||
'date', 'time', 'date-time',
|
||||
@@ -41,7 +22,10 @@ const _ = require('lodash'),
|
||||
'ipv4', 'ipv6',
|
||||
'regex',
|
||||
'uuid',
|
||||
'json-pointer'
|
||||
'json-pointer',
|
||||
'int64',
|
||||
'float',
|
||||
'double'
|
||||
],
|
||||
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X');
|
||||
|
||||
@@ -281,7 +265,7 @@ module.exports = {
|
||||
|
||||
// Override deefault value to appropriate type representation for parameter resolution to schema
|
||||
if (resolveFor === 'CONVERSION' && resolveTo === 'schema') {
|
||||
schema.default = type.object;
|
||||
schema.default = typesMap.object;
|
||||
}
|
||||
}
|
||||
else if (concreteUtils.compareTypes(schema.type, SCHEMA_TYPES.array) && schema.items) {
|
||||
@@ -321,8 +305,8 @@ module.exports = {
|
||||
if (!schema.hasOwnProperty('format')) {
|
||||
schema.default = '<' + schema.type + '>';
|
||||
}
|
||||
else if (type.hasOwnProperty(schema.type)) {
|
||||
schema.default = type[schema.type][schema.format];
|
||||
else if (typesMap.hasOwnProperty(schema.type)) {
|
||||
schema.default = typesMap[schema.type][schema.format];
|
||||
|
||||
// in case the format is a custom format (email, hostname etc.)
|
||||
// https://swagger.io/docs/specification/data-models/data-types/#string
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* utils.js contains other util functions
|
||||
*/
|
||||
|
||||
const { formatDataPath } = require('./common/schemaUtilsCommon.js'),
|
||||
const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/schemaUtilsCommon.js'),
|
||||
{ getConcreteSchemaUtils } = require('./common/versionUtils.js'),
|
||||
async = require('async'),
|
||||
sdk = require('postman-collection'),
|
||||
@@ -85,15 +85,6 @@ const { formatDataPath } = require('./common/schemaUtilsCommon.js'),
|
||||
'authorization'
|
||||
],
|
||||
|
||||
/* eslint-disable arrow-body-style */
|
||||
schemaTypeToJsValidator = {
|
||||
'string': (d) => typeof d === 'string',
|
||||
'number': (d) => !isNaN(d),
|
||||
'integer': (d) => !isNaN(d) && Number.isInteger(Number(d)),
|
||||
'boolean': (d) => _.isBoolean(d) || d === 'true' || d === 'false',
|
||||
'array': (d) => Array.isArray(d),
|
||||
'object': (d) => typeof d === 'object' && !Array.isArray(d)
|
||||
},
|
||||
crypto = require('crypto'),
|
||||
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X');
|
||||
/* eslint-enable */
|
||||
@@ -3105,7 +3096,7 @@ module.exports = {
|
||||
}
|
||||
// When processing a reference, schema.type could also be undefined
|
||||
else if (schema && schema.type) {
|
||||
if (typeof schemaTypeToJsValidator[schema.type] === 'function') {
|
||||
if (isKnownType(schema)) {
|
||||
let isCorrectType;
|
||||
|
||||
// Treat unresolved postman collection/environment variable as correct type
|
||||
@@ -3113,7 +3104,7 @@ module.exports = {
|
||||
isCorrectType = true;
|
||||
}
|
||||
else {
|
||||
isCorrectType = schemaTypeToJsValidator[schema.type](valueToUse);
|
||||
isCorrectType = checkIsCorrectType(valueToUse, schema);
|
||||
}
|
||||
|
||||
if (!isCorrectType) {
|
||||
|
||||
32
test/data/31CollectionTransactions/479.yaml
Normal file
32
test/data/31CollectionTransactions/479.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
openapi: "3.1.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets/anyOf:
|
||||
post:
|
||||
summary: issue 479
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/example"
|
||||
responses:
|
||||
default:
|
||||
description: ok
|
||||
components:
|
||||
schemas:
|
||||
example:
|
||||
type:
|
||||
- object
|
||||
properties:
|
||||
id:
|
||||
type:
|
||||
- integer
|
||||
hasPet:
|
||||
type:
|
||||
- boolean
|
||||
105
test/data/31CollectionTransactions/479col.json
Normal file
105
test/data/31CollectionTransactions/479col.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"item": [
|
||||
{
|
||||
"id": "c3a2f66d-f91e-45ec-9116-4ce926acb630",
|
||||
"name": "pets",
|
||||
"item": [
|
||||
{
|
||||
"id": "25758366-55ed-4370-90fd-1e1be8536b0b",
|
||||
"name": "issue 479",
|
||||
"request": {
|
||||
"name": "composite schema with anyOf keyword",
|
||||
"description": {},
|
||||
"url": {
|
||||
"path": [
|
||||
"pets",
|
||||
"anyOf"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": []
|
||||
},
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"method": "POST",
|
||||
"auth": null,
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{ \"id\": \"<integer>\", \"hasPet\": \"<boolean>\" }",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"id": "f4f6ddf5-d259-45b7-89fe-086cc22a6549",
|
||||
"name": "ok",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets",
|
||||
"anyOf"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": []
|
||||
},
|
||||
"method": "POST",
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{ \"id\": \"<integer>\", \"hasPet\": \"<boolean>\" }",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": "Internal Server Error",
|
||||
"code": 500,
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "text/plain"
|
||||
}
|
||||
],
|
||||
"body": "",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "text"
|
||||
}
|
||||
],
|
||||
"event": []
|
||||
}
|
||||
],
|
||||
"event": []
|
||||
}
|
||||
],
|
||||
"event": [],
|
||||
"variable": [
|
||||
{
|
||||
"type": "string",
|
||||
"value": "http://petstore.swagger.io/v1",
|
||||
"key": "baseUrl"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"_postman_id": "b498d8c3-e6e5-4a72-92de-e5c455786a8e",
|
||||
"name": "Swagger Petstore",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"description": {
|
||||
"content": "",
|
||||
"type": "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
openapi: "3.1.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: https://postman-echo.com/get
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
operationId: createPets
|
||||
tags:
|
||||
- pets
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
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
|
||||
format: date
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
type: object
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string`
|
||||
@@ -113,6 +113,12 @@ components:
|
||||
items:
|
||||
type:
|
||||
- string
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
entityId:
|
||||
type: string
|
||||
maxLength: 5
|
||||
isFavorite:
|
||||
type:
|
||||
- boolean
|
||||
|
||||
97
test/data/valid_openapi/issue#479.yml
Normal file
97
test/data/valid_openapi/issue#479.yml
Normal file
@@ -0,0 +1,97 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: header-1
|
||||
in: header
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
/pets2/{pathVar}:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: pathVar
|
||||
in: path
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
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
|
||||
108
test/data/valid_openapi/issue#479_2.yaml
Normal file
108
test/data/valid_openapi/issue#479_2.yaml
Normal file
@@ -0,0 +1,108 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
version: 1
|
||||
title: test for types
|
||||
servers:
|
||||
- url: 'http://localhost:3000'
|
||||
paths:
|
||||
/user:
|
||||
post:
|
||||
summary: 'Sample endpoint: Returns details about a particular user'
|
||||
operationId: listUser
|
||||
tags:
|
||||
- user
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
description: ID of the user
|
||||
required: true
|
||||
schema:
|
||||
type:
|
||||
- integer
|
||||
format: int32
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type:
|
||||
- object
|
||||
properties:
|
||||
data:
|
||||
type:
|
||||
- array
|
||||
items:
|
||||
$ref: '#/components/schemas/Entity'
|
||||
responses:
|
||||
'200':
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
components:
|
||||
schemas:
|
||||
Entity:
|
||||
type:
|
||||
- object
|
||||
title: Entity
|
||||
description: A single and unique entity linked to a user
|
||||
properties:
|
||||
entityId:
|
||||
type:
|
||||
- string
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
age:
|
||||
type: integer
|
||||
format: int32
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
isFavorite:
|
||||
type: integer
|
||||
format: int32
|
||||
needThis:
|
||||
type:
|
||||
- string
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
birthday:
|
||||
type: string
|
||||
format: date
|
||||
floatField:
|
||||
type: number
|
||||
format: float
|
||||
doubleField:
|
||||
type: number
|
||||
format: double
|
||||
content:
|
||||
format: byte
|
||||
type: string
|
||||
file:
|
||||
type: string
|
||||
format: binary
|
||||
root_pass:
|
||||
type: string
|
||||
format: password
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
@@ -37,7 +37,7 @@
|
||||
},
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"data\": [\n {\n \"entityId\": \"5e5792b234d88e12b8511b92\",\n \"accountNumber\": \"1YNykgIi3T2NDeElON0IqcPOpPI\",\n \"entityName\": \"Farmer Freddy's Veg\",\n \"entityPhone\": \"+4420832132132\",\n \"incType\": \"sole\",\n \"companyNumber\": 10000,\n \"needThisNot\": \"hello\",\n \"website\": \"https://farmer-freddy.null\",\n \"turnover\": 10000,\n \"description\": \"def\",\n \"status\": \"tradingAccepted\",\n \"wants\": [\n \"carpentry\",\n \"beer\",\n \"beer\"\n ],\n \"isFavorite\": true\n }\n ],\n \"meta\": {\n \"notNeeded\": 1,\n \"numberOfResults\": 1,\n \"totalPages\": 1\n }\n}"
|
||||
"raw": "{\n \"data\": [\n {\n \"entityId\": \"5e5792b234d88e12b8511b92\",\n \"accountNumber\": \"1YNykgIi3T2NDeElON0IqcPOpPI\",\n \"entityName\": \"Farmer Freddy's Veg\",\n \"entityPhone\": \"+4420832132132\",\n \"incType\": \"sole\",\n \"companyNumber\": 10000,\n \"needThisNot\": \"hello\",\n \"website\": \"https://farmer-freddy.null\",\n \"turnover\": 10000,\n \"description\": \"def\",\n \"status\": \"tradingAccepted\",\n \"wants\": [\n \"carpentry\",\n \"beer\",\n \"beer\"\n ],\n \"user\": {\"entityId\": \"5e5792b234d88e12b8511b92\"},\n \"isFavorite\": true\n }\n ],\n \"meta\": {\n \"notNeeded\": 1,\n \"numberOfResults\": 1,\n \"totalPages\": 1\n }\n}"
|
||||
}
|
||||
},
|
||||
"response": [
|
||||
|
||||
@@ -94,6 +94,12 @@ components:
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
entityId:
|
||||
type: string
|
||||
maxLength: 5
|
||||
isFavorite:
|
||||
type: boolean
|
||||
needThis:
|
||||
|
||||
375
test/data/validationData/invalidTypeProperty.json
Normal file
375
test/data/validationData/invalidTypeProperty.json
Normal file
@@ -0,0 +1,375 @@
|
||||
{
|
||||
"item": [
|
||||
{
|
||||
"id": "ec09078b-8861-4367-9e9e-22f8c3d31f82",
|
||||
"name": "pets",
|
||||
"description": {
|
||||
"content": "",
|
||||
"type": "text/plain"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"id": "2c8762c9-54bc-4981-8d2c-09b71fadcebc",
|
||||
"name": "List all pets",
|
||||
"request": {
|
||||
"name": "List all pets",
|
||||
"description": {},
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"disabled": false,
|
||||
"key": "limit",
|
||||
"value": "82526723",
|
||||
"description": "How many items to return at one time (max 100)"
|
||||
}
|
||||
],
|
||||
"variable": []
|
||||
},
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"method": "GET",
|
||||
"auth": null
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"id": "2d0c2488-0d26-4029-9294-fbc5c9b8363f",
|
||||
"name": "A paged array of pets",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "limit",
|
||||
"value": "82526723"
|
||||
}
|
||||
],
|
||||
"variable": []
|
||||
},
|
||||
"method": "GET",
|
||||
"body": {}
|
||||
},
|
||||
"status": "OK",
|
||||
"code": 200,
|
||||
"header": [
|
||||
{
|
||||
"disabled": false,
|
||||
"description": "A link to the next page of responses",
|
||||
"key": "x-next",
|
||||
"value": "in nulla Lorem ex"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": "[\n {\n \"id\": 41014273,\n \"name\": \"dolor eu minim in\",\n \"tag\": \"urn:uuid:94b326e4-ed11-bd40-c87d-1a1524b6bc2f\"\n },\n {\n \"id\": -74291521,\n \"name\": \"pariatur dolor e\",\n \"tag\": \"urn:uuid:092c825a-7a1d-1adc-71da-b9dbe24c2da6\"\n }\n]",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "json"
|
||||
},
|
||||
{
|
||||
"id": "eb93bc02-1380-433a-9a6e-acd8875a8334",
|
||||
"name": "unexpected error",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "limit",
|
||||
"value": "82526723"
|
||||
}
|
||||
],
|
||||
"variable": []
|
||||
},
|
||||
"method": "GET",
|
||||
"body": {}
|
||||
},
|
||||
"status": "Internal Server Error",
|
||||
"code": 500,
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": "{\n \"code\": -57418069,\n \"message\": \"non quis proident\"\n}",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "json"
|
||||
}
|
||||
],
|
||||
"event": []
|
||||
},
|
||||
{
|
||||
"id": "87611012-e59c-40e1-90f2-24a50fbbff1d",
|
||||
"name": "Create a pet",
|
||||
"request": {
|
||||
"name": "Create a pet",
|
||||
"description": {},
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": []
|
||||
},
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"method": "POST",
|
||||
"auth": null,
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"id\": -56104459,\n \"name\": \"dolore incididunt pariatur occaecat\",\n \"tag\": \"9e6b59af-239e-b38b-74a7-f3110c87227e\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"id": "813809b9-3290-43e3-8c43-f939db815d2c",
|
||||
"name": "Null response",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": []
|
||||
},
|
||||
"method": "POST",
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"id\": -56104459,\n \"name\": \"dolore incididunt pariatur occaecat\",\n \"tag\": \"9e6b59af-239e-b38b-74a7-f3110c87227e\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": "Created",
|
||||
"code": 201,
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "text/plain"
|
||||
}
|
||||
],
|
||||
"body": "",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "text"
|
||||
},
|
||||
{
|
||||
"id": "436ebb0e-5c7a-4cba-883e-f36089ccd5e2",
|
||||
"name": "unexpected error",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": []
|
||||
},
|
||||
"method": "POST",
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"id\": -56104459,\n \"name\": \"dolore incididunt pariatur occaecat\",\n \"tag\": \"9e6b59af-239e-b38b-74a7-f3110c87227e\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": "Internal Server Error",
|
||||
"code": 500,
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": "{\n \"code\": -57418069,\n \"message\": \"non quis proident\"\n}",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "json"
|
||||
}
|
||||
],
|
||||
"event": [],
|
||||
"protocolProfileBehavior": {
|
||||
"disableBodyPruning": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ab623305-0ccf-4edc-9210-c3ed68d4e1dc",
|
||||
"name": "Info for a specific pet",
|
||||
"request": {
|
||||
"name": "Info for a specific pet",
|
||||
"description": {},
|
||||
"url": {
|
||||
"path": [
|
||||
"pets",
|
||||
":petId"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": [
|
||||
{
|
||||
"disabled": false,
|
||||
"type": "any",
|
||||
"value": "in nulla Lorem ex",
|
||||
"key": "petId",
|
||||
"description": "(Required) The id of the pet to retrieve"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"method": "GET",
|
||||
"auth": null
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"id": "6de63e43-7e59-4713-8893-53bdbddeddef",
|
||||
"name": "Expected response to a valid request",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets",
|
||||
":petId"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": [
|
||||
{
|
||||
"disabled": false,
|
||||
"type": "any",
|
||||
"value": "in nulla Lorem ex",
|
||||
"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\": -56104459,\n \"name\": \"dolore incididunt pariatur occaecat\",\n \"tag\": \"9e6b59af-239e-b38b-74a7-f3110c87227e\"\n}",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "json"
|
||||
},
|
||||
{
|
||||
"id": "d221e68f-af12-4042-935e-ae2709ef52e7",
|
||||
"name": "unexpected error",
|
||||
"originalRequest": {
|
||||
"url": {
|
||||
"path": [
|
||||
"pets",
|
||||
":petId"
|
||||
],
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"query": [],
|
||||
"variable": [
|
||||
{
|
||||
"disabled": false,
|
||||
"type": "any",
|
||||
"value": "in nulla Lorem ex",
|
||||
"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\": -57418069,\n \"message\": \"non quis proident\"\n}",
|
||||
"cookie": [],
|
||||
"_postman_previewlanguage": "json"
|
||||
}
|
||||
],
|
||||
"event": []
|
||||
}
|
||||
],
|
||||
"event": []
|
||||
}
|
||||
],
|
||||
"event": [],
|
||||
"variable": [
|
||||
{
|
||||
"type": "string",
|
||||
"value": "https://postman-echo.com/get",
|
||||
"key": "baseUrl"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"_postman_id": "5baba942-df02-45da-9e3d-540db4667bc4",
|
||||
"name": "Swagger Petstore",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"description": {
|
||||
"content": "",
|
||||
"type": "text/plain"
|
||||
}
|
||||
}
|
||||
}
|
||||
118
test/data/validationData/invalidTypeProperty.yaml
Normal file
118
test/data/validationData/invalidTypeProperty.yaml
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: https://postman-echo.com/get
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
operationId: createPets
|
||||
tags:
|
||||
- pets
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
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
|
||||
format: date
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
type: object
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string`
|
||||
@@ -132,13 +132,13 @@ describe('DEREF FUNCTION TESTS ', function() {
|
||||
|
||||
expect(output).to.deep.include({ type: 'object',
|
||||
required: ['id'],
|
||||
properties: { id: { default: '<long>', type: 'integer' } } });
|
||||
properties: { id: { default: '<long>', format: 'int64', type: 'integer' } } });
|
||||
|
||||
expect(output_validation).to.deep.include({ anyOf: [
|
||||
{ type: 'object',
|
||||
required: ['id'],
|
||||
description: 'Schema 2',
|
||||
properties: { id: { type: 'integer' } }
|
||||
properties: { id: { format: 'int64', type: 'integer' } }
|
||||
}, {
|
||||
type: 'object',
|
||||
properties: { emailField: { type: 'string', format: 'email' } }
|
||||
@@ -147,7 +147,7 @@ describe('DEREF FUNCTION TESTS ', function() {
|
||||
|
||||
expect(output_withdot).to.deep.include({ type: 'object',
|
||||
required: ['id'],
|
||||
properties: { id: { default: '<long>', type: 'integer' } } });
|
||||
properties: { id: { default: '<long>', format: 'int64', type: 'integer' } } });
|
||||
|
||||
expect(output_customFormat).to.deep.include({ type: 'object',
|
||||
properties: { emailField: { default: '<email>', format: 'email', type: 'string' } } });
|
||||
@@ -156,7 +156,7 @@ describe('DEREF FUNCTION TESTS ', function() {
|
||||
type: 'object',
|
||||
description: 'Schema 2',
|
||||
properties: {
|
||||
id: { default: '<long>', type: 'integer' },
|
||||
id: { default: '<long>', format: 'int64', type: 'integer' },
|
||||
test_prop: { default: '<string>', type: 'string' }
|
||||
}
|
||||
});
|
||||
@@ -201,9 +201,6 @@ describe('DEREF FUNCTION TESTS ', function() {
|
||||
],
|
||||
nonSupportedFormats = [
|
||||
{ type: 'integer', format: 'int32' },
|
||||
{ type: 'integer', format: 'int64' },
|
||||
{ type: 'number', format: 'float' },
|
||||
{ type: 'number', format: 'double' },
|
||||
{ type: 'string', format: 'byte' },
|
||||
{ type: 'string', format: 'binary' },
|
||||
{ type: 'string', format: 'password' },
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const schemaUtilsCommon = require('../../lib/common/schemaUtilsCommon');
|
||||
const { formatDataPath } = require('../../lib/common/schemaUtilsCommon'),
|
||||
const schemaUtilsCommon = require('../../lib/common/schemaUtilsCommon'),
|
||||
{ formatDataPath,
|
||||
formatSchemaPathFromAJVErrorToConvertToDataPath,
|
||||
isTypeValue } = require('../../lib/common/schemaUtilsCommon'),
|
||||
expect = require('chai').expect;
|
||||
|
||||
describe('formatData method', function() {
|
||||
@@ -31,6 +33,14 @@ describe('formatData method', function() {
|
||||
expect(formattedDataPath).to.be.equal(expectedDataPath);
|
||||
});
|
||||
|
||||
it('Should return "properties.automatic.items.properties.configs.items"' +
|
||||
' when input is "#/properties/automatic/items/properties/configs/items/type"', function() {
|
||||
const input = 'properties/automatic/items/properties/configs/items',
|
||||
expectedDataPath = 'properties.automatic.items.properties.configs.items',
|
||||
formattedDataPath = formatDataPath(input);
|
||||
expect(formattedDataPath).to.be.equal(expectedDataPath);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('handleExclusiveMaximum method', function() {
|
||||
@@ -149,4 +159,139 @@ describe('handleExclusiveMinimum method', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatSchemaPathFromAJVErrorToConvertToDataPath method', function () {
|
||||
it('should return properties/automatic/items/properties/configs/items ' +
|
||||
'when entry is #/properties/automatic/items/properties/configs/items/type', function () {
|
||||
const result =
|
||||
formatSchemaPathFromAJVErrorToConvertToDataPath('#/properties/automatic/items/properties/configs/items/type');
|
||||
expect(result).to.equal('properties/automatic/items/properties/configs/items');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isTypeValue method', function () {
|
||||
it('should return true when value is <integer> and type is integer', function () {
|
||||
const result = isTypeValue('<integer>', {
|
||||
type: [
|
||||
'integer'
|
||||
]
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when input is <long> type integer and format int64', function () {
|
||||
const result = isTypeValue('<long>', {
|
||||
format: 'int64',
|
||||
type: ['integer']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <uuid> type is string format is uuid', function () {
|
||||
const result = isTypeValue('<uuid>', {
|
||||
format: 'uuid',
|
||||
type: ['string']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
|
||||
it('should return true when value is <otherType> type is otherType and there is not format', function () {
|
||||
const result = isTypeValue('<otherType>', {
|
||||
type: ['otherType']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true value is <otherType-otherFormat> type is otherType and format is otherFormat', function () {
|
||||
const result = isTypeValue('<otherType-otherFormat>', {
|
||||
format: 'otherFormat',
|
||||
type: ['otherType']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return false when value is <integer> and type is boolean', function () {
|
||||
const result = isTypeValue('<integer>', {
|
||||
type: ['boolean']
|
||||
});
|
||||
expect(result).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true when value is <string> and type is string', function () {
|
||||
const result = isTypeValue('<string>', {
|
||||
type: ['string']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <integer> and type is ["boolean", "integer"]', function () {
|
||||
const result = isTypeValue('<integer>', {
|
||||
type: ['boolean', 'integer']
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <integer> and type is integer not array', function () {
|
||||
const result = isTypeValue('<integer>', {
|
||||
type: 'integer'
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <integer> and type is integer not array format int64', function () {
|
||||
const result = isTypeValue('<long>', {
|
||||
format: 'int64',
|
||||
type: 'integer'
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <long> and type is integer, format not present default is <long>', function () {
|
||||
const result = isTypeValue('<long>', {
|
||||
default: '<long>',
|
||||
type: 'integer'
|
||||
});
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return false when value is <long> and type is integer,' +
|
||||
' there is no format default is <nlong>', function () {
|
||||
const result = isTypeValue('<nlong>', {
|
||||
default: '<long>',
|
||||
type: 'integer'
|
||||
});
|
||||
expect(result).to.be.false;
|
||||
});
|
||||
|
||||
|
||||
it('should return true when value is <dateTime> and type is string,' +
|
||||
' and format is date-time', function () {
|
||||
const result = isTypeValue('<dateTime>', { type: 'string', format: 'date-time' });
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <date> and type is string,' +
|
||||
' and format is date', function () {
|
||||
const result = isTypeValue('<date>', { type: 'string', format: 'date' });
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <float> and type is number,' +
|
||||
' and format is float', function () {
|
||||
const result = isTypeValue('<float>', { type: 'number', format: 'float' });
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <double> and type is number,' +
|
||||
' and format is double', function () {
|
||||
const result = isTypeValue('<double>', { type: 'number', format: 'double' });
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true when value is <double> and type is number,' +
|
||||
' and format is double', function () {
|
||||
const result = isTypeValue('<double>', { type: 'number', format: 'double' });
|
||||
expect(result).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -63,6 +63,197 @@ function getFoldersByVersion(folder30Path, folder31Path) {
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
describe('Validation with different resolution parameters options', function () {
|
||||
it('Should validate correctly with request and example parameters as Schema', function () {
|
||||
let fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_FOLDER_PATH,
|
||||
'/issue#479_2.yaml'), 'utf8'),
|
||||
expectedRequestBody =
|
||||
'{"data":[{"entityId":"<string>","user":{"id":"<long>","age":"<integer>","created_at":"<dateTime>"},' +
|
||||
'"isFavorite":"<integer>","needThis":"<string>"},' +
|
||||
'{"entityId":"<string>","user":{"id":"<long>","age":"<integer>","created_at":"<dateTime>"},' +
|
||||
'"isFavorite":"<integer>","needThis":"<string>"}]}',
|
||||
expectedResponseBody =
|
||||
'[{"id":"<long>","name":"<string>","tag":"<string>","created_at":"<dateTime>","birthday":"<date>"' +
|
||||
',"floatField":"<float>","doubleField":"<double>","content":"<byte>","file":"<binary>",' +
|
||||
'"root_pass":"<password>"},' +
|
||||
'{"id":"<long>","name":"<string>","tag":"<string>","created_at":"<dateTime>","birthday":"<date>"' +
|
||||
',"floatField":"<float>","doubleField":"<double>","content":"<byte>","file":"<binary>",' +
|
||||
'"root_pass":"<password>"}]',
|
||||
options = {
|
||||
requestParametersResolution: 'Schema',
|
||||
exampleParametersResolution: 'Schema',
|
||||
showMissingInSchemaErrors: true,
|
||||
strictRequestMatching: true,
|
||||
ignoreUnresolvedVariables: true,
|
||||
validateMetadata: true,
|
||||
suggestAvailableFixes: true,
|
||||
detailedBlobValidation: true
|
||||
},
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: fileData }, options);
|
||||
schemaPack.convert((err, conversionResult) => {
|
||||
expect(err).to.be.null;
|
||||
expect(conversionResult.result).to.equal(true);
|
||||
|
||||
let historyRequest = [];
|
||||
|
||||
getAllTransactions(conversionResult.output[0].data, historyRequest);
|
||||
|
||||
const fixedResponseBody = historyRequest[0].response[0].body.replace(/\s/g, ''),
|
||||
fixedRequestBody = historyRequest[0].request.body.raw.replace(/\s/g, '');
|
||||
expect(fixedResponseBody).to.equal(expectedResponseBody);
|
||||
expect(fixedRequestBody).to.equal(expectedRequestBody);
|
||||
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
expect(err).to.be.null;
|
||||
expect(result).to.be.an('object');
|
||||
let requestIds = Object.keys(result.requests);
|
||||
expect(err).to.be.null;
|
||||
requestIds.forEach((requestId) => {
|
||||
expect(result.requests[requestId].endpoints[0].matched).to.be.true;
|
||||
const responsesIds = Object.keys(result.requests[requestId].endpoints[0].responses);
|
||||
responsesIds.forEach((responseId) => {
|
||||
expect(result.requests[requestId].endpoints[0].responses[responseId].matched).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should validate correctly with request as schema and example parameters as Example', function () {
|
||||
let fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_FOLDER_PATH,
|
||||
'/issue#479_2.yaml'), 'utf8'),
|
||||
expectedBody =
|
||||
'{"data":[{"entityId":"<string>","user":{"id":"<long>","age":"<integer>","created_at":"<dateTime>"},' +
|
||||
'"isFavorite":"<integer>","needThis":"<string>"},' +
|
||||
'{"entityId":"<string>","user":{"id":"<long>","age":"<integer>","created_at":"<dateTime>"},' +
|
||||
'"isFavorite":"<integer>","needThis":"<string>"}]}',
|
||||
options = {
|
||||
requestParametersResolution: 'Schema',
|
||||
exampleParametersResolution: 'Example',
|
||||
showMissingInSchemaErrors: true,
|
||||
strictRequestMatching: true,
|
||||
ignoreUnresolvedVariables: true,
|
||||
validateMetadata: true,
|
||||
suggestAvailableFixes: true,
|
||||
detailedBlobValidation: true
|
||||
},
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: fileData }, options);
|
||||
schemaPack.convert((err, conversionResult) => {
|
||||
expect(err).to.be.null;
|
||||
expect(conversionResult.result).to.equal(true);
|
||||
|
||||
let historyRequest = [];
|
||||
|
||||
getAllTransactions(conversionResult.output[0].data, historyRequest);
|
||||
|
||||
const fixedBody = historyRequest[0].request.body.raw.replace(/\s/g, '');
|
||||
expect(fixedBody).to.equal(expectedBody);
|
||||
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
expect(err).to.be.null;
|
||||
expect(result).to.be.an('object');
|
||||
let requestIds = Object.keys(result.requests);
|
||||
expect(err).to.be.null;
|
||||
requestIds.forEach((requestId) => {
|
||||
expect(result.requests[requestId].endpoints[0].matched).to.be.true;
|
||||
const responsesIds = Object.keys(result.requests[requestId].endpoints[0].responses);
|
||||
responsesIds.forEach((responseId) => {
|
||||
expect(result.requests[requestId].endpoints[0].responses[responseId].matched).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should validate correctly with request as Example and example parameters as Schema', function () {
|
||||
let fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_FOLDER_PATH,
|
||||
'/issue#479_2.yaml'), 'utf8'),
|
||||
expectedResponseBody =
|
||||
'[{"id":"<long>","name":"<string>","tag":"<string>","created_at":"<dateTime>","birthday":"<date>"' +
|
||||
',"floatField":"<float>","doubleField":"<double>","content":"<byte>","file":"<binary>",' +
|
||||
'"root_pass":"<password>"},' +
|
||||
'{"id":"<long>","name":"<string>","tag":"<string>","created_at":"<dateTime>","birthday":"<date>"' +
|
||||
',"floatField":"<float>","doubleField":"<double>","content":"<byte>","file":"<binary>",' +
|
||||
'"root_pass":"<password>"}]',
|
||||
options = {
|
||||
requestParametersResolution: 'Example',
|
||||
exampleParametersResolution: 'Schema',
|
||||
showMissingInSchemaErrors: true,
|
||||
strictRequestMatching: true,
|
||||
ignoreUnresolvedVariables: true,
|
||||
validateMetadata: true,
|
||||
suggestAvailableFixes: true,
|
||||
detailedBlobValidation: true
|
||||
},
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: fileData }, options);
|
||||
schemaPack.convert((err, conversionResult) => {
|
||||
expect(err).to.be.null;
|
||||
expect(conversionResult.result).to.equal(true);
|
||||
|
||||
let historyRequest = [];
|
||||
|
||||
getAllTransactions(conversionResult.output[0].data, historyRequest);
|
||||
|
||||
const fixedResponseBody = historyRequest[0].response[0].body.replace(/\s/g, '');
|
||||
expect(fixedResponseBody).to.equal(expectedResponseBody);
|
||||
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
expect(err).to.be.null;
|
||||
expect(result).to.be.an('object');
|
||||
let requestIds = Object.keys(result.requests);
|
||||
expect(err).to.be.null;
|
||||
requestIds.forEach((requestId) => {
|
||||
expect(result.requests[requestId].endpoints[0].matched).to.be.true;
|
||||
const responsesIds = Object.keys(result.requests[requestId].endpoints[0].responses);
|
||||
responsesIds.forEach((responseId) => {
|
||||
expect(result.requests[requestId].endpoints[0].responses[responseId].matched).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should validate correctly with request and example parameters as Example', function () {
|
||||
let fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_FOLDER_PATH,
|
||||
'/issue#479_2.yaml'), 'utf8'),
|
||||
options = {
|
||||
requestParametersResolution: 'Example',
|
||||
exampleParametersResolution: 'Example',
|
||||
showMissingInSchemaErrors: true,
|
||||
strictRequestMatching: true,
|
||||
ignoreUnresolvedVariables: true,
|
||||
validateMetadata: true,
|
||||
suggestAvailableFixes: true,
|
||||
detailedBlobValidation: true
|
||||
},
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: fileData }, options);
|
||||
schemaPack.convert((err, conversionResult) => {
|
||||
expect(err).to.be.null;
|
||||
expect(conversionResult.result).to.equal(true);
|
||||
|
||||
let historyRequest = [];
|
||||
|
||||
getAllTransactions(conversionResult.output[0].data, historyRequest);
|
||||
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
expect(err).to.be.null;
|
||||
expect(result).to.be.an('object');
|
||||
let requestIds = Object.keys(result.requests);
|
||||
expect(err).to.be.null;
|
||||
requestIds.forEach((requestId) => {
|
||||
expect(result.requests[requestId].endpoints[0].matched).to.be.true;
|
||||
const responsesIds = Object.keys(result.requests[requestId].endpoints[0].responses);
|
||||
responsesIds.forEach((responseId) => {
|
||||
expect(result.requests[requestId].endpoints[0].responses[responseId].matched).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
describe('The validator must validate generated collection from schema against schema itself', function () {
|
||||
var validOpenapiFolder = fs.readdirSync(path.join(__dirname, VALID_OPENAPI_FOLDER_PATH)),
|
||||
suggestedFixProps = ['key', 'actualValue', 'suggestedValue'],
|
||||
@@ -391,21 +582,22 @@ describe('The Validation option', function () {
|
||||
{ detailedBlobValidation: true }),
|
||||
historyRequest = [],
|
||||
resultObj,
|
||||
violatedKeywords = [
|
||||
'data.items.minProperties',
|
||||
'data.items.required',
|
||||
'data.items.properties.entityId.maxLength',
|
||||
'data.items.properties.accountNumber.minLength',
|
||||
'data.items.properties.entityName.format',
|
||||
'data.items.properties.incType.enum',
|
||||
'data.items.properties.companyNumber.exclusiveMinimum',
|
||||
'data.items.properties.website.type',
|
||||
'data.items.properties.turnover.multipleOf',
|
||||
'data.items.properties.description.pattern',
|
||||
'data.items.properties.wants.uniqueItems',
|
||||
'meta.maxProperties',
|
||||
'meta.additionalProperties'
|
||||
];
|
||||
violatedKeywords = {
|
||||
'data.items.minProperties': '$.request.body.data[0]',
|
||||
'data.items.required': '$.request.body.data[0]',
|
||||
'data.items.properties.entityId.maxLength': '$.request.body.data[0].entityId',
|
||||
'data.items.properties.accountNumber.minLength': '$.request.body.data[0].accountNumber',
|
||||
'data.items.properties.entityName.format': '$.request.body.data[0].entityName',
|
||||
'data.items.properties.incType.enum': '$.request.body.data[0].incType',
|
||||
'data.items.properties.companyNumber.exclusiveMinimum': '$.request.body.data[0].companyNumber',
|
||||
'data.items.properties.website.type': '$.request.body.data[0].website',
|
||||
'data.items.properties.turnover.multipleOf': '$.request.body.data[0].turnover',
|
||||
'data.items.properties.description.pattern': '$.request.body.data[0].description',
|
||||
'data.items.properties.wants.uniqueItems': '$.request.body.data[0].wants',
|
||||
'data.items.properties.user.properties.entityId.maxLength': '$.request.body.data[0].user.entityId',
|
||||
'meta.maxProperties': '$.request.body.meta',
|
||||
'meta.additionalProperties': '$.request.body.meta'
|
||||
};
|
||||
|
||||
getAllTransactions(JSON.parse(collection), historyRequest);
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
@@ -416,7 +608,8 @@ describe('The Validation option', function () {
|
||||
_.forEach(resultObj.mismatches, (mismatch) => {
|
||||
// remove starting string '$.paths[/user].post.requestBody.content[application/json].schema.properties.'
|
||||
let localJsonPath = mismatch.schemaJsonPath.slice(76);
|
||||
expect(_.includes(violatedKeywords, localJsonPath)).to.eql(true);
|
||||
expect(_.includes(_.keys(violatedKeywords), localJsonPath)).to.eql(true);
|
||||
expect(_.includes(_.values(violatedKeywords), mismatch.transactionJsonPath)).to.eql(true);
|
||||
|
||||
// mark matched path as empty to ensure repetition does'n occur
|
||||
violatedKeywords[_.indexOf(violatedKeywords, localJsonPath)] = '';
|
||||
@@ -506,6 +699,13 @@ describe('VALIDATE FUNCTION TESTS ', function () {
|
||||
VALIDATION_DATA_SCENARIOS_FOLDER_31_PATH
|
||||
),
|
||||
'/compositeSchemaSpec.yaml'
|
||||
),
|
||||
invalidTypeProperty = getSpecsPathByVersion(
|
||||
getFoldersByVersion(
|
||||
VALIDATION_DATA_FOLDER_PATH,
|
||||
VALIDATION_DATA_SCENARIOS_FOLDER_31_PATH
|
||||
),
|
||||
'/invalidTypeProperty.yaml'
|
||||
);
|
||||
|
||||
emptyParameterSpecs.forEach((specData) => {
|
||||
@@ -749,7 +949,7 @@ describe('VALIDATE FUNCTION TESTS ', function () {
|
||||
ignoreUnresolvedVariables: true,
|
||||
validateMetadata: true,
|
||||
suggestAvailableFixes: true,
|
||||
detailedBlobValidation: false
|
||||
detailedBlobValidation: true
|
||||
},
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: primitiveDataTypeBodySpec }, options);
|
||||
|
||||
@@ -762,11 +962,13 @@ describe('VALIDATE FUNCTION TESTS ', function () {
|
||||
// request body is boolean
|
||||
resultObj = result.requests[historyRequest[0].id].endpoints[0];
|
||||
expect(resultObj.mismatches).to.have.lengthOf(0);
|
||||
|
||||
const responseId = _.keys(resultObj.responses)[0];
|
||||
// request body is integer
|
||||
responseObj = resultObj.responses[_.keys(resultObj.responses)[0]];
|
||||
responseObj = resultObj.responses[responseId];
|
||||
expect(responseObj.mismatches).to.have.lengthOf(1);
|
||||
expect(responseObj.mismatches[0].suggestedFix.suggestedValue).to.be.within(5, 10);
|
||||
expect(responseObj.mismatches[0].transactionJsonPath).to
|
||||
.equal(`$.responses[${responseId}].body`);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -961,6 +1163,36 @@ describe('VALIDATE FUNCTION TESTS ', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
invalidTypeProperty.forEach((specData) => {
|
||||
it('Should correctly suggest value and report transactionJsonPath on a body property with incorrect value ' +
|
||||
specData.version, function (done) {
|
||||
let invalidTypePropertySpec = fs.readFileSync(specData.path, 'utf-8'),
|
||||
invalidTypePropertyCollection = fs.readFileSync(path.join(__dirname, VALIDATION_DATA_FOLDER_PATH +
|
||||
'/invalidTypeProperty.json'), 'utf-8'),
|
||||
options = { suggestAvailableFixes: true, detailedBlobValidation: true },
|
||||
resultObj,
|
||||
historyRequest = [],
|
||||
schemaPack = new Converter.SchemaPack({ type: 'string', data: invalidTypePropertySpec }, options);
|
||||
|
||||
getAllTransactions(JSON.parse(invalidTypePropertyCollection), historyRequest);
|
||||
|
||||
schemaPack.validateTransaction(historyRequest, (err, result) => {
|
||||
expect(err).to.be.null;
|
||||
expect(result).to.be.an('object');
|
||||
resultObj = result.requests[historyRequest[0].id].endpoints[0];
|
||||
const responseId = _.keys(resultObj.responses)[0],
|
||||
responseMissmatches = resultObj.responses[responseId].mismatches;
|
||||
expect(responseMissmatches).to.have.lengthOf(2);
|
||||
expect(responseMissmatches[0].transactionJsonPath)
|
||||
.to.equal(`$.responses[${responseId}].body[0].tag`);
|
||||
expect(responseMissmatches[0].suggestedFix.key).to.equal('tag');
|
||||
expect(responseMissmatches[1].transactionJsonPath)
|
||||
.to.equal(`$.responses[${responseId}].body[1].tag`);
|
||||
expect(responseMissmatches[1].suggestedFix.key).to.equal('tag');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPostmanUrlSuffixSchemaScore function', function () {
|
||||
|
||||
@@ -145,6 +145,27 @@ describe('Openapi 3.1 schema pack validateTransactions', function() {
|
||||
});
|
||||
}
|
||||
|
||||
it('Fix for GITHUB#479: Should accept values like <integer> in validation', function() {
|
||||
const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/479col.json'),
|
||||
collectionData = fs.readFileSync(collectionSource, 'utf8'),
|
||||
schemaSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/479.yaml'),
|
||||
schemaData = fs.readFileSync(schemaSource, 'utf8'),
|
||||
validator = new SchemaPack({
|
||||
type: 'string',
|
||||
data: schemaData
|
||||
});
|
||||
let transactions = [];
|
||||
getAllTransactions(JSON.parse(collectionData), transactions);
|
||||
|
||||
validator.validateTransaction(transactions, (err, result) => {
|
||||
let requestIds = Object.keys(result.requests);
|
||||
expect(err).to.be.null;
|
||||
requestIds.forEach((requestId) => {
|
||||
expect(result.requests[requestId].endpoints[0].matched).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not generate any mismatch with a correct file', function() {
|
||||
const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/compositeSchemaCollection.json'),
|
||||
collectionData = fs.readFileSync(collectionSource, 'utf8'),
|
||||
|
||||
@@ -302,6 +302,112 @@ describe('validateSchema', function () {
|
||||
result = validateSchemaAJVDraft04(null, valueToUse);
|
||||
expect(result.filteredValidationError).to.be.undefined;
|
||||
});
|
||||
|
||||
it('Fix for GITHUB#479: should validate as correct input <integer> for type integer', function () {
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: [
|
||||
'integer',
|
||||
'boolean'
|
||||
],
|
||||
examples: [
|
||||
111111
|
||||
]
|
||||
},
|
||||
hasPet: {
|
||||
type: [
|
||||
'boolean'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
valueToUse = {
|
||||
'id': '<integer>',
|
||||
'hasPet': '<boolean>'
|
||||
},
|
||||
result = validateSchema(schema, valueToUse);
|
||||
expect(result).to.be.empty;
|
||||
});
|
||||
|
||||
it('Fix for GITHUB#479: should validate as incorrect input <boolean> for type integer', function () {
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: [
|
||||
'integer'
|
||||
],
|
||||
examples: [
|
||||
111111
|
||||
]
|
||||
},
|
||||
hasPet: {
|
||||
type: [
|
||||
'boolean'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
valueToUse = {
|
||||
'id': '<boolean>',
|
||||
'hasPet': '<boolean>'
|
||||
},
|
||||
result = validateSchema(schema, valueToUse);
|
||||
expect(result[0].instancePath).equal('/id');
|
||||
});
|
||||
|
||||
it('Fix for GITHUB#479: should validate as correct input <long> for type integer format int64', function () {
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: [
|
||||
'integer'
|
||||
],
|
||||
format: 'int64'
|
||||
},
|
||||
hasPet: {
|
||||
type: [
|
||||
'boolean'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
valueToUse = {
|
||||
'id': '<long>',
|
||||
'hasPet': '<boolean>'
|
||||
},
|
||||
result = validateSchema(schema, valueToUse);
|
||||
expect(result).to.be.empty;
|
||||
});
|
||||
|
||||
it('Fix for GITHUB#479: should validate as correct input <long> for type integer boolean format int64', function () {
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: [
|
||||
'integer',
|
||||
'boolean'
|
||||
],
|
||||
format: 'int64'
|
||||
},
|
||||
hasPet: {
|
||||
type: [
|
||||
'boolean'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
valueToUse = {
|
||||
'id': '<long>',
|
||||
'hasPet': '<boolean>'
|
||||
},
|
||||
result = validateSchema(schema, valueToUse);
|
||||
expect(result).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDraftToUse', function() {
|
||||
|
||||
Reference in New Issue
Block a user