From d060108afe0902a8c6df8d765dbed15dd584afe7 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 5 Nov 2020 14:13:41 -0800 Subject: [PATCH] Added a custom transformation for models to implement specific logic. --- .../__tests__/custom-transformation.spec.ts | 26 +++++++ .../transformations/custom-transformation.ts | 75 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tests/e2e/api/src/framework/transformations/__tests__/custom-transformation.spec.ts create mode 100644 tests/e2e/api/src/framework/transformations/custom-transformation.ts diff --git a/tests/e2e/api/src/framework/transformations/__tests__/custom-transformation.spec.ts b/tests/e2e/api/src/framework/transformations/__tests__/custom-transformation.spec.ts new file mode 100644 index 00000000000..1384ae47fe2 --- /dev/null +++ b/tests/e2e/api/src/framework/transformations/__tests__/custom-transformation.spec.ts @@ -0,0 +1,26 @@ +import { CustomTransformation } from '../custom-transformation'; + +describe( 'CustomTransformation', () => { + it( 'should do nothing without hooks', () => { + const transformation = new CustomTransformation( 0, null, null ); + + const expected = { test: 'Test' }; + + expect( transformation.toModel( expected ) ).toMatchObject( expected ); + expect( transformation.fromModel( expected ) ).toMatchObject( expected ); + } ); + + it( 'should execute hooks', () => { + const toHook = jest.fn(); + toHook.mockReturnValue( { toModel: 'Test' } ); + const fromHook = jest.fn(); + fromHook.mockReturnValue( { fromModel: 'Test' } ); + + const transformation = new CustomTransformation( 0, toHook, fromHook ); + + expect( transformation.toModel( { test: 'Test' } ) ).toMatchObject( { toModel: 'Test' } ); + expect( toHook ).toHaveBeenCalledWith( { test: 'Test' } ); + expect( transformation.fromModel( { test: 'Test' } ) ).toMatchObject( { fromModel: 'Test' } ); + expect( fromHook ).toHaveBeenCalledWith( { test: 'Test' } ); + } ); +} ); diff --git a/tests/e2e/api/src/framework/transformations/custom-transformation.ts b/tests/e2e/api/src/framework/transformations/custom-transformation.ts new file mode 100644 index 00000000000..511670fbf1e --- /dev/null +++ b/tests/e2e/api/src/framework/transformations/custom-transformation.ts @@ -0,0 +1,75 @@ +import { ModelTransformation } from '../model-transformer'; + +/** + * A callback for transforming model properties. + * + * @callback TransformationCallback + * @param {*} properties The properties to transform. + * @return {*} The transformed properties. + */ +type TransformationCallback = ( properties: any ) => any; + +export class CustomTransformation implements ModelTransformation { + public readonly order: number; + + /** + * The hook to run for toModel. + * + * @type {TransformationCallback|null} + * @private + */ + private readonly toHook: TransformationCallback | null; + + /** + * The hook to run for fromModel. + * + * @type {TransformationCallback|null} + * @private + */ + private readonly fromHook: TransformationCallback | null; + + /** + * Creates a new transformation. + * + * @param {number} order The order for the transformation. Higher numbers are executed later. + * @param {TransformationCallback|null} toHook The hook to run for toModel. + * @param {TransformationCallback|null} fromHook The hook to run for fromModel. + */ + public constructor( + order: number, + toHook: TransformationCallback | null, + fromHook: TransformationCallback | null, + ) { + this.order = order; + this.toHook = toHook; + this.fromHook = fromHook; + } + + /** + * Performs a transformation from model properties to raw properties. + * + * @param {*} properties The properties to transform. + * @return {*} The transformed properties. + */ + public fromModel( properties: any ): any { + if ( ! this.fromHook ) { + return properties; + } + + return this.fromHook( properties ); + } + + /** + * Performs a transformation from raw properties to model properties. + * + * @param {*} properties The properties to transform. + * @return {*} The transformed properties. + */ + public toModel( properties: any ): any { + if ( ! this.toHook ) { + return properties; + } + + return this.toHook( properties ); + } +}