DigitalConsumer.ISS/playwright-tests/impl/utils/PropertyUtils.ts
chase-safelite 5d3ab0ef59
Added playwright tests into repo (#923)
* Initial import of playwright tests

* Pipeline changes for automated tests

* Modified pipeline for testing

* Attempt #2

* Attempt #3

* Added missing paren

* Removed debug stuff from pipeline

* Changes from playwright repo

* Changed pipeline for debugging

* Fix for ServiceLocationPage playwright locators

* Change pipeline to run with TEST APIs

* Moved more of Siraj's changes to this repo

* Changed where updating env occurs

* Changed location of env update again

* Escaped double quotes

* Added visible report in Azure

* Moved changes into main pipeline

* Made it so dotenv only runs config in local
2025-02-14 09:54:11 -05:00

111 lines
No EOL
4.4 KiB
TypeScript

import { ValidationResult } from "@business-logic/types/RuleEngine";
import EnumUtils from "./EnumUtils";
export type ExtractName<T> = { [K in keyof T]: () => K; };
type GetValueOptions = {
isRequired: boolean;
};
function isNullOrWhiteSpace(input: unknown): boolean {
if (typeof input !== "string")
return input == null;
return input.trim().length === 0;
}
// Matches: '() => _Enums.*****', e.g.: '() => _Enums.ModificationTypes'
// Matches: '() => *****', e.g.: '() => ModificationTypes'
// Returns: EnumName, e.g.: 'ModificationTypes'
function getEnumName(propertySelector: () => object): string {
const functionString = propertySelector.toString();
const match = functionString.match(/\(\s*\)\s*=>\s*(?:_?[A-Z]\w*\.)?(\w+)(?::)?/);
return match ? match[1] : "Unknown";
}
// Matches: 'x => x.*****', e.g.: 'x => x.name', 'x => x.tags'
// Returns: PropertyName, e.g.: 'name', 'tags'
function getNameof<T>(propertySelector: (obj: T) => any): string {
const propertyString = propertySelector.toString();
const match = propertyString.match(/(?:=>|return)\s*([\w\s.]+)/);
if (match && match[1]) {
const parts = match[1].split('.');
return parts[parts.length - 1].trim();
}
throw new Error(`Invalid property selector: ${propertyString}`);
}
function getValueOrNull<T>(json: any, propertySelector: (obj: T) => any): any | null {
if (json == null)
return null;
const property = getNameof(propertySelector);
if (json.hasOwnProperty(property))
return json[property];
return null;
}
function getValue<T>(json: any, typeName: string, validationResults: ValidationResult[], options: GetValueOptions, propertySelector: (obj: T) => any): any | null {
const retval = getValueOrNull(json, propertySelector);
if (retval == null)
validationResults.push(options.isRequired ? ValidationResult.FromFailure(`Value for ${typeName}.${getNameof(propertySelector)} is null but is required!`) : ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} is null but is NOT required.`));
else {
if (isNullOrWhiteSpace(retval))
validationResults.push(ValidationResult.FromFailure(`Value for ${typeName}.${getNameof(propertySelector)} is empty!`));
else
validationResults.push(ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} is valid.`));
}
return retval;
}
function hasProperty<T>(json: any, typeName: string, validationResults: ValidationResult[], options: GetValueOptions, propertySelector: (obj: ExtractName<T>) => () => keyof T): boolean {
const retval = json.hasOwnProperty(getNameof(propertySelector));
if (retval)
validationResults.push(ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} is valid.`));
else
validationResults.push(options.isRequired ? ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} is not defined but is required!`) : ValidationResult.FromFailure(`Value for ${typeName}.${getNameof(propertySelector)} is not defined but is NOT required!`));
return retval;
}
function getEnumValueOrNull<T>(json: any, enumType: object, propertySelector: (obj: T) => any): any | null {
if (json == null)
return null;
const property = getNameof(propertySelector);
const retval = EnumUtils.validateEnumProperty(json, property, enumType);
if (retval != null)
return retval;
else if (Object.values(enumType).includes(json[property]))
return json[property];
return null;
}
function getEnumValue<T>(json: any, typeName: string, validationResults: ValidationResult[], enumType: object, enumTypeInstance: () => object, options: GetValueOptions, propertySelector: (obj: T) => any): any | null {
const retval = getEnumValueOrNull(json, enumType, propertySelector);
if (retval == null)
validationResults.push(options.isRequired ? ValidationResult.FromFailure(`Value for ${typeName}.${getNameof(propertySelector)} [${getEnumName(enumTypeInstance)}] is null but is required!`) : ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} [${getEnumName(enumTypeInstance)}] is null but is NOT required.`));
else
validationResults.push(ValidationResult.FromSuccess(retval, `Value for ${typeName}.${getNameof(propertySelector)} is valid.`));
return retval;
}
export { getEnumName, getEnumValueOrNull, getNameof, getValueOrNull };
const PropertyUtils = {
hasProperty,
getValue,
getEnumValue
};
export default PropertyUtils;