Skip to content

Commit

Permalink
Update test and query validation
Browse files Browse the repository at this point in the history
Add schema validator to have a cache for body and a separate cache for query parameters.
Add conditions to avoid using ALLOW_OVERPOSTING if we are validating a query parameter schema.
Update unit and integration tests.
  • Loading branch information
jleiva-gap committed Nov 6, 2023
1 parent 3dbe56b commit c798e2c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ export type ResourceSchemaValidators = {
queryValidator: ValidateFunction;
};

function initializeAjv(): Ajv {
const removeAdditional = getBooleanFromEnvironment('ALLOW_OVERPOSTING', false);
function initializeAjv(isQueryParameterValidator: boolean): Ajv {
// A query parameter validator cannot have additional properties
const removeAdditional = isQueryParameterValidator ? false : getBooleanFromEnvironment('ALLOW_OVERPOSTING', false);
const coerceTypes = getBooleanFromEnvironment('ALLOW_TYPE_COERCION', false);

const ajv = new Ajv({ allErrors: true, coerceTypes, removeAdditional });
Expand All @@ -38,14 +39,19 @@ let ajv;
// simple cache implementation, see: https://rewind.io/blog/simple-caching-in-aws-lambda-functions/
/** This is a cache mapping MetaEd model objects to compiled ajv JSON Schema validators for the API resource */
const validatorCache: Map<TopLevelEntity, ResourceSchemaValidators> = new Map();
const queryValidatorCache: Map<TopLevelEntity, ResourceSchemaValidators> = new Map();

/**
* Returns the API resource JSON Schema validator functions for the given MetaEd model. Caches results.
*/
function getSchemaValidatorsFor(metaEdModel: TopLevelEntity): ResourceSchemaValidators {
const cachedValidators: ResourceSchemaValidators | undefined = validatorCache.get(metaEdModel);
function getSchemaValidatorsFor(
metaEdModel: TopLevelEntity,
isQueryParameterValidator: boolean = false,
): ResourceSchemaValidators {
const validatorCacheObject = isQueryParameterValidator ? queryValidatorCache : validatorCache;
const cachedValidators: ResourceSchemaValidators | undefined = validatorCacheObject.get(metaEdModel);
if (cachedValidators != null) return cachedValidators;
ajv = initializeAjv();
ajv = initializeAjv(isQueryParameterValidator);
const resourceValidators: ResourceSchemaValidators = {
insertValidator: ajv.compile(metaEdModel.data.edfiApiSchema.jsonSchemaForInsert),
updateValidator: ajv.compile(metaEdModel.data.edfiApiSchema.jsonSchemaForUpdate),
Expand All @@ -55,7 +61,7 @@ function getSchemaValidatorsFor(metaEdModel: TopLevelEntity): ResourceSchemaVali
required: [],
}),
};
validatorCache.set(metaEdModel, resourceValidators);
validatorCacheObject.set(metaEdModel, resourceValidators);
return resourceValidators;
}

Expand All @@ -64,6 +70,7 @@ function getSchemaValidatorsFor(metaEdModel: TopLevelEntity): ResourceSchemaVali
*/
export function clearAllValidatorCache(): void {
validatorCache.clear();
queryValidatorCache.clear();
}
/**
* Creates a new empty ResourceMatchResult object
Expand Down Expand Up @@ -138,7 +145,7 @@ export function validateQueryParametersAgainstSchema(
metaEdModel: TopLevelEntity,
queryParameters: FrontendQueryParameters,
): string[] {
const { queryValidator } = getSchemaValidatorsFor(metaEdModel);
const { queryValidator } = getSchemaValidatorsFor(metaEdModel, true);

let errors: string[] = [];

Expand Down
Loading

0 comments on commit c798e2c

Please sign in to comment.