diff --git a/tools/spectral/ipa/__tests__/IPA110CollectionsRequestHasItemsPerPageQueryParam.test.js b/tools/spectral/ipa/__tests__/IPA110CollectionsRequestHasItemsPerPageQueryParam.test.js index 5e47272e41..1c31e4d374 100644 --- a/tools/spectral/ipa/__tests__/IPA110CollectionsRequestHasItemsPerPageQueryParam.test.js +++ b/tools/spectral/ipa/__tests__/IPA110CollectionsRequestHasItemsPerPageQueryParam.test.js @@ -61,6 +61,56 @@ testRule('xgen-IPA-110-collections-request-has-itemsPerPage-query-param', [ }, errors: [], }, + { + name: 'valid - non-100 default value greater than 1', + document: { + paths: { + '/resources': { + get: { + parameters: [ + { + name: 'itemsPerPage', + in: 'query', + schema: { + type: 'integer', + default: 50, + }, + }, + ], + }, + }, + 'resources/{resourceId}': { + get: {}, + }, + }, + }, + errors: [], + }, + { + name: 'valid - minimum allowed default value of 2', + document: { + paths: { + '/resources': { + get: { + parameters: [ + { + name: 'itemsPerPage', + in: 'query', + schema: { + type: 'integer', + default: 2, + }, + }, + ], + }, + }, + 'resources/{resourceId}': { + get: {}, + }, + }, + }, + errors: [], + }, { name: 'invalid - missing parameters', document: { @@ -195,7 +245,7 @@ testRule('xgen-IPA-110-collections-request-has-itemsPerPage-query-param', [ ], }, { - name: 'invalid - wrong default value', + name: 'invalid - default value of 0', document: { paths: { '/resources': { @@ -220,7 +270,39 @@ testRule('xgen-IPA-110-collections-request-has-itemsPerPage-query-param', [ errors: [ { code: 'xgen-IPA-110-collections-request-has-itemsPerPage-query-param', - message: 'itemsPerPage query parameter of List method must have a default value of 100.', + message: 'itemsPerPage query parameter of List method must have a default value greater than 1.', + path: ['paths', '/resources', 'get'], + severity: DiagnosticSeverity.Error, + }, + ], + }, + { + name: 'invalid - default value of 1', + document: { + paths: { + '/resources': { + get: { + parameters: [ + { + name: 'itemsPerPage', + in: 'query', + schema: { + type: 'integer', + default: 1, + }, + }, + ], + }, + }, + 'resources/{resourceId}': { + get: {}, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-110-collections-request-has-itemsPerPage-query-param', + message: 'itemsPerPage query parameter of List method must have a default value greater than 1.', path: ['paths', '/resources', 'get'], severity: DiagnosticSeverity.Error, }, diff --git a/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasItemsPerPageQueryParam.js b/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasItemsPerPageQueryParam.js index 6e3eb2d5b8..34c79721e9 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasItemsPerPageQueryParam.js +++ b/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasItemsPerPageQueryParam.js @@ -18,6 +18,6 @@ export default (input, _, { path, documentInventory, rule }) => { return; } - const errors = checkPaginationQueryParameterAndReturnErrors(input, path, 'itemsPerPage', 100, ruleName); + const errors = checkPaginationQueryParameterAndReturnErrors(input, path, 'itemsPerPage', { min: 1 }, ruleName); return evaluateAndCollectAdoptionStatus(errors, ruleName, input, path); }; diff --git a/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasPageNumQueryParam.js b/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasPageNumQueryParam.js index 218f1014b9..0e8cef95b1 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasPageNumQueryParam.js +++ b/tools/spectral/ipa/rulesets/functions/IPA110CollectionsRequestHasPageNumQueryParam.js @@ -18,6 +18,6 @@ export default (input, _, { path, documentInventory, rule }) => { return; } - const errors = checkPaginationQueryParameterAndReturnErrors(input, path, 'pageNum', 1, ruleName); + const errors = checkPaginationQueryParameterAndReturnErrors(input, path, 'pageNum', { value: 1 }, ruleName); return evaluateAndCollectAdoptionStatus(errors, ruleName, input, path); }; diff --git a/tools/spectral/ipa/rulesets/functions/utils/validations/checkPaginationQueryParameterAndReturnErrors.js b/tools/spectral/ipa/rulesets/functions/utils/validations/checkPaginationQueryParameterAndReturnErrors.js index aef35a5ef4..9c9c6df13b 100644 --- a/tools/spectral/ipa/rulesets/functions/utils/validations/checkPaginationQueryParameterAndReturnErrors.js +++ b/tools/spectral/ipa/rulesets/functions/utils/validations/checkPaginationQueryParameterAndReturnErrors.js @@ -6,11 +6,11 @@ import { handleInternalError } from '../collectionUtils.js'; * @param {Object} operation - The OpenAPI operation object to check * @param {string[]} path - The path to the operation * @param {string} paramName - The name of the parameter to check ('pageNum' or 'itemsPerPage') - * @param {number} defaultValue - The expected default value (1 for pageNum, 100 for itemsPerPage) + * @param {{value: number}|{min?: number, max?: number}} constraint - Either `{ value: N }` for an exact match, or `{ min: N, max: N }` for a range check (min and max are both optional) * @param {string} ruleName - The rule name for error handling * @returns {Array} - Array of error objects or empty array if no errors */ -export function checkPaginationQueryParameterAndReturnErrors(operation, path, paramName, defaultValue, ruleName) { +export function checkPaginationQueryParameterAndReturnErrors(operation, path, paramName, constraint, ruleName) { try { const parameters = operation.parameters; @@ -54,13 +54,35 @@ export function checkPaginationQueryParameterAndReturnErrors(operation, path, pa ]; } - if (param.schema.default !== defaultValue) { - return [ - { - path, - message: `${paramName} query parameter of List method must have a default value of ${defaultValue}.`, - }, - ]; + if ('value' in constraint) { + if (param.schema.default !== constraint.value) { + return [ + { + path, + message: `${paramName} query parameter of List method must have a default value of ${constraint.value}.`, + }, + ]; + } + } else { + if (!('min' in constraint) && !('max' in constraint)) { + throw new Error(`constraint must have either 'value', 'min', or 'max'`); + } + if ('min' in constraint && param.schema.default <= constraint.min) { + return [ + { + path, + message: `${paramName} query parameter of List method must have a default value greater than ${constraint.min}.`, + }, + ]; + } + if ('max' in constraint && param.schema.default > constraint.max) { + return [ + { + path, + message: `${paramName} query parameter of List method must have a default value less than or equal to ${constraint.max}.`, + }, + ]; + } } return [];