@@ -1828,6 +1828,10 @@ module.exports = {
1828
1828
bodyData = this . convertToPmBodyData ( contentObj [ FORM_DATA ] , requestType , FORM_DATA ,
1829
1829
PARAMETER_SOURCE . REQUEST , options . indentCharacter , components , options , schemaCache ) ;
1830
1830
encoding = contentObj [ FORM_DATA ] . encoding ? contentObj [ FORM_DATA ] . encoding : { } ;
1831
+
1832
+ if ( contentObj [ FORM_DATA ] . hasOwnProperty ( 'schema' ) && contentObj [ FORM_DATA ] . schema . hasOwnProperty ( '$ref' ) ) {
1833
+ contentObj [ FORM_DATA ] . schema = this . getRefObject ( contentObj [ FORM_DATA ] . schema . $ref , components , options ) ;
1834
+ }
1831
1835
// create the form parameters and add it to the request body object
1832
1836
_ . forOwn ( bodyData , ( value , key ) => {
1833
1837
@@ -2626,11 +2630,15 @@ module.exports = {
2626
2630
matchedPath ,
2627
2631
matchedPathJsonPath ,
2628
2632
schemaPathItems = schema . paths ,
2633
+ pathToMatchServer ,
2629
2634
filteredPathItemsArray = [ ] ;
2630
2635
2631
2636
// Return no matches for invalid url (if unable to decode parsed url)
2632
2637
try {
2633
2638
pathToMatch = decodeURI ( parsedUrl . pathname ) ;
2639
+ if ( ! _ . isNil ( parsedUrl . hash ) ) {
2640
+ pathToMatch += parsedUrl . hash ;
2641
+ }
2634
2642
}
2635
2643
catch ( e ) {
2636
2644
console . warn (
@@ -2669,9 +2677,16 @@ module.exports = {
2669
2677
}
2670
2678
return accumulator ;
2671
2679
} , [ ] ) ;
2672
-
2680
+ let schemaMatchResult = { match : false } ;
2673
2681
// check if path and pathToMatch match (non-null)
2674
- let schemaMatchResult = this . getPostmanUrlSchemaMatchScore ( pathToMatch , path , options ) ;
2682
+ // check in explicit (local defined) servers
2683
+ if ( pathItemObject [ method . toLowerCase ( ) ] . servers ) {
2684
+ pathToMatchServer = this . handleExplicitServersPathToMatch ( pathToMatch , path ) ;
2685
+ schemaMatchResult = this . getPostmanUrlSchemaMatchScore ( pathToMatchServer , path , options ) ;
2686
+ }
2687
+ else {
2688
+ schemaMatchResult = this . getPostmanUrlSchemaMatchScore ( pathToMatch , path , options ) ;
2689
+ }
2675
2690
if ( ! schemaMatchResult . match ) {
2676
2691
// there was no reasonable match b/w the postman path and this schema path
2677
2692
return true ;
@@ -3337,7 +3352,7 @@ module.exports = {
3337
3352
3338
3353
/**
3339
3354
*
3340
- * @param {* } determinedPathVariables the key/determined-value pairs of the path variables (from Postman)
3355
+ * @param {* } matchedPathData the matchedPath data
3341
3356
* @param {* } transactionPathPrefix the jsonpath for this validation (will be prepended to all identified mismatches)
3342
3357
* @param {* } schemaPath the applicable pathItem defined at the schema level
3343
3358
* @param {* } components the components + paths from the OAS spec that need to be used to resolve $refs
@@ -3348,7 +3363,7 @@ module.exports = {
3348
3363
* @returns {array } mismatches (in the callback)
3349
3364
*/
3350
3365
checkPathVariables : function (
3351
- determinedPathVariables ,
3366
+ matchedPathData ,
3352
3367
transactionPathPrefix ,
3353
3368
schemaPath ,
3354
3369
components ,
@@ -3362,7 +3377,9 @@ module.exports = {
3362
3377
var mismatchProperty = 'PATHVARIABLE' ,
3363
3378
// all path variables defined in this path. acc. to the spec, all path params are required
3364
3379
schemaPathVariables ,
3365
- pmPathVariables ;
3380
+ pmPathVariables ,
3381
+ determinedPathVariables = matchedPathData . pathVariables ,
3382
+ unmatchedVariablesFromTransaction = matchedPathData . unmatchedVariablesFromTransaction ;
3366
3383
3367
3384
if ( options . validationPropertiesToIgnore . includes ( mismatchProperty ) ) {
3368
3385
return callback ( null , [ ] ) ;
@@ -3428,17 +3445,41 @@ module.exports = {
3428
3445
} , ( err , res ) => {
3429
3446
let mismatches = [ ] ,
3430
3447
mismatchObj ;
3448
+ const unmatchedSchemaVariableNames = determinedPathVariables . filter ( ( pathVariable ) => {
3449
+ return ! pathVariable . _varMatched ;
3450
+ } ) . map ( ( schemaPathVar ) => {
3451
+ return schemaPathVar . key ;
3452
+ } ) ;
3431
3453
3432
3454
if ( err ) {
3433
3455
return callback ( err ) ;
3434
3456
}
3435
3457
3436
3458
// go through required schemaPathVariables, and params that aren't found in the given transaction are errors
3437
- _ . each ( schemaPathVariables , ( pathVar ) => {
3459
+ _ . each ( schemaPathVariables , ( pathVar , index ) => {
3438
3460
if ( ! _ . find ( determinedPathVariables , ( param ) => {
3439
3461
// only consider variable matching if url path variables is not allowed
3440
3462
return param . key === pathVar . name && ( options . allowUrlPathVarMatching || param . _varMatched ) ;
3441
3463
} ) ) {
3464
+ let reasonCode = 'MISSING_IN_REQUEST' ,
3465
+ reason ,
3466
+ actualValue ,
3467
+ currentUnmatchedVariableInTransaction = unmatchedVariablesFromTransaction [ index ] ,
3468
+ isInvalidValue = currentUnmatchedVariableInTransaction !== undefined ;
3469
+
3470
+ if ( unmatchedSchemaVariableNames . length > 0 && isInvalidValue ) {
3471
+ reason = `The ${ currentUnmatchedVariableInTransaction . key } path variable does not match with ` +
3472
+ `path variable expected (${ unmatchedSchemaVariableNames [ index ] } ) in the schema at this position` ;
3473
+ actualValue = {
3474
+ key : currentUnmatchedVariableInTransaction . key ,
3475
+ description : this . getParameterDescription ( currentUnmatchedVariableInTransaction ) ,
3476
+ value : currentUnmatchedVariableInTransaction . value
3477
+ } ;
3478
+ }
3479
+ else {
3480
+ reason = `The required path variable "${ pathVar . name } " was not found in the transaction` ;
3481
+ actualValue = null ;
3482
+ }
3442
3483
3443
3484
// assign parameter example(s) as schema examples;
3444
3485
this . assignParameterExamples ( pathVar ) ;
@@ -3447,14 +3488,14 @@ module.exports = {
3447
3488
property : mismatchProperty ,
3448
3489
transactionJsonPath : transactionPathPrefix ,
3449
3490
schemaJsonPath : pathVar . pathPrefix ,
3450
- reasonCode : 'MISSING_IN_REQUEST' ,
3451
- reason : `The required path variable " ${ pathVar . name } " was not found in the transaction`
3491
+ reasonCode,
3492
+ reason
3452
3493
} ;
3453
3494
3454
3495
if ( options . suggestAvailableFixes ) {
3455
3496
mismatchObj . suggestedFix = {
3456
3497
key : pathVar . name ,
3457
- actualValue : null ,
3498
+ actualValue,
3458
3499
suggestedValue : {
3459
3500
key : pathVar . name ,
3460
3501
value : safeSchemaFaker ( pathVar . schema || { } , 'example' , PROCESSING_TYPE . VALIDATION ,
@@ -4454,6 +4495,32 @@ module.exports = {
4454
4495
} ) ;
4455
4496
} ,
4456
4497
4498
+ /**
4499
+ * Takes in the postman path and the schema path
4500
+ * takes from the path the number of segments present in the schema path
4501
+ * and returns the last segments from the path to match in an string format
4502
+ *
4503
+ * @param {string } pathToMatch - parsed path (exclude host and params) from the Postman request
4504
+ * @param {string } schemaPath - schema path from the OAS spec (exclude servers object)
4505
+ * @returns {string } only the selected segments from the pathToMatch
4506
+ */
4507
+ handleExplicitServersPathToMatch : function ( pathToMatch , schemaPath ) {
4508
+ let pathTMatchSlice ,
4509
+ schemaPathArr = _ . reject ( schemaPath . split ( '/' ) , ( segment ) => {
4510
+ return segment === '' ;
4511
+ } ) ,
4512
+ schemaPathSegments = schemaPathArr . length ,
4513
+ pathToMatchArr = _ . reject ( pathToMatch . split ( '/' ) , ( segment ) => {
4514
+ return segment === '' ;
4515
+ } ) ,
4516
+ pathToMatchSegments = pathToMatchArr . length ;
4517
+ if ( pathToMatchSegments < schemaPathSegments ) {
4518
+ return pathToMatch ;
4519
+ }
4520
+ pathTMatchSlice = pathToMatchArr . slice ( pathToMatchArr . length - schemaPathSegments , pathToMatchArr . length ) ;
4521
+ return pathTMatchSlice . join ( '/' ) ;
4522
+ } ,
4523
+
4457
4524
/**
4458
4525
* @param {string } postmanPath - parsed path (exclude host and params) from the Postman request
4459
4526
* @param {string } schemaPath - schema path from the OAS spec (exclude servers object)
0 commit comments