diff --git a/src/lib/unstable/__tests__/helpers.test.ts b/src/lib/unstable/__tests__/helpers.test.ts new file mode 100644 index 00000000..597f6160 --- /dev/null +++ b/src/lib/unstable/__tests__/helpers.test.ts @@ -0,0 +1,201 @@ +import {JsonSchemaType, SchemaRendererMode} from '../core/constants'; +import type { + IndependentView, + JsonSchema, + JsonSchemaArray, + JsonSchemaBoolean, + JsonSchemaNumber, + JsonSchemaObject, + JsonSchemaString, + SchemaRendererConfig, + SimpleView, + Wrapper, +} from '../core/types'; + +export const MockArrayFormComponent: SimpleView = () => null; +export const MockBooleanFormComponent: SimpleView = () => null; +export const MockNumberFormComponent: SimpleView = () => null; +export const MockObjectFormComponent: SimpleView = () => null; +export const MockStringFormComponent: SimpleView = () => null; + +export const MockArrayOverviewComponent: SimpleView = () => null; +export const MockBooleanOverviewComponent: SimpleView = () => null; +export const MockNumberOverviewComponent: SimpleView = () => null; +export const MockObjectOverviewComponent: SimpleView = () => null; +export const MockStringOverviewComponent: SimpleView = () => null; + +export const MockIndependentArrayFormComponent: IndependentView = () => null; +export const MockIndependentBooleanFormComponent: IndependentView = () => null; +export const MockIndependentNumberFormComponent: IndependentView = () => null; +export const MockIndependentObjectFormComponent: IndependentView = () => null; +export const MockIndependentStringFormComponent: IndependentView = () => null; + +export const MockIndependentArrayOverviewComponent: IndependentView = () => null; +export const MockIndependentBooleanOverviewComponent: IndependentView = () => + null; +export const MockIndependentNumberOverviewComponent: IndependentView = () => null; +export const MockIndependentObjectOverviewComponent: IndependentView = () => null; +export const MockIndependentStringOverviewComponent: IndependentView = () => null; + +export const MockArrayWrapper: Wrapper = () => null; +export const MockBooleanWrapper: Wrapper = () => null; +export const MockNumberWrapper: Wrapper = () => null; +export const MockObjectWrapper: Wrapper = () => null; +export const MockStringWrapper: Wrapper = () => null; + +export const mockSchemaRendererConfig: SchemaRendererConfig = { + [JsonSchemaType.Array]: { + views: { + base: { + [SchemaRendererMode.Form]: { + Component: MockArrayFormComponent, + }, + [SchemaRendererMode.Overview]: { + Component: MockArrayOverviewComponent, + }, + }, + custom: { + [SchemaRendererMode.Form]: { + Component: MockIndependentArrayFormComponent, + independent: true, + }, + [SchemaRendererMode.Overview]: { + Component: MockIndependentArrayOverviewComponent, + independent: true, + }, + }, + }, + wrappers: { + default: MockArrayWrapper, + }, + validators: {}, + }, + [JsonSchemaType.Boolean]: { + views: { + base: { + [SchemaRendererMode.Form]: { + Component: MockBooleanFormComponent, + }, + [SchemaRendererMode.Overview]: { + Component: MockBooleanOverviewComponent, + }, + }, + custom: { + [SchemaRendererMode.Form]: { + Component: MockIndependentBooleanFormComponent, + independent: true, + }, + [SchemaRendererMode.Overview]: { + Component: MockIndependentBooleanOverviewComponent, + independent: true, + }, + }, + }, + wrappers: { + default: MockBooleanWrapper, + }, + validators: {}, + }, + [JsonSchemaType.Number]: { + views: { + base: { + [SchemaRendererMode.Form]: { + Component: MockNumberFormComponent, + }, + [SchemaRendererMode.Overview]: { + Component: MockNumberOverviewComponent, + }, + }, + custom: { + [SchemaRendererMode.Form]: { + Component: MockIndependentNumberFormComponent, + independent: true, + }, + [SchemaRendererMode.Overview]: { + Component: MockIndependentNumberOverviewComponent, + independent: true, + }, + }, + }, + wrappers: { + default: MockNumberWrapper, + }, + validators: {}, + }, + [JsonSchemaType.Object]: { + views: { + base: { + [SchemaRendererMode.Form]: { + Component: MockObjectFormComponent, + }, + [SchemaRendererMode.Overview]: { + Component: MockObjectOverviewComponent, + }, + }, + custom: { + [SchemaRendererMode.Form]: { + Component: MockIndependentObjectFormComponent, + independent: true, + }, + [SchemaRendererMode.Overview]: { + Component: MockIndependentObjectOverviewComponent, + independent: true, + }, + }, + }, + wrappers: { + default: MockObjectWrapper, + }, + validators: {}, + }, + [JsonSchemaType.String]: { + views: { + base: { + [SchemaRendererMode.Form]: { + Component: MockStringFormComponent, + }, + [SchemaRendererMode.Overview]: { + Component: MockStringOverviewComponent, + }, + }, + custom: { + [SchemaRendererMode.Form]: { + Component: MockIndependentStringFormComponent, + independent: true, + }, + [SchemaRendererMode.Overview]: { + Component: MockIndependentStringOverviewComponent, + independent: true, + }, + }, + }, + wrappers: { + default: MockStringWrapper, + }, + validators: {}, + }, +}; + +export function createMockSchema( + type: JsonSchemaType, + viewType = 'base', + wrapperType = 'default', + viewProps: Record = {}, + wrapperProps: Record = {}, +): T { + return { + type, + entityParameters: { + viewType, + wrapperType, + viewProps, + wrapperProps, + }, + } as T; +} + +describe('helpers', () => { + test('just empty test', () => { + expect(true).toBe(true); + }); +}); diff --git a/src/lib/unstable/core/Entity/__tests__/utils.test.ts b/src/lib/unstable/core/Entity/__tests__/utils.test.ts new file mode 100644 index 00000000..dd9480f8 --- /dev/null +++ b/src/lib/unstable/core/Entity/__tests__/utils.test.ts @@ -0,0 +1,279 @@ +import { + MockIndependentStringFormComponent, + MockIndependentStringOverviewComponent, + MockObjectFormComponent, + MockObjectWrapper, + MockStringFormComponent, + MockStringOverviewComponent, + MockStringWrapper, + createMockSchema, + mockSchemaRendererConfig, +} from '../../../__tests__/helpers.test'; +import {JsonSchemaType, SchemaRendererMode} from '../../constants'; +import type {JsonSchema, JsonSchemaString} from '../../types'; +import {getRenderKit} from '../utils'; + +describe('Entity/utils', () => { + describe('getRenderKit', () => { + test('should return render kit with simple string form component', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'base', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: MockStringFormComponent, + viewProps: {viewProp: 'viewProp'}, + Wrapper: MockStringWrapper, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + + test('should return render kit with simple string overview component', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'base', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Overview, + schema, + }); + + expect(result).toEqual({ + View: MockStringOverviewComponent, + viewProps: {viewProp: 'viewProp'}, + Wrapper: MockStringWrapper, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + + test('should return render kit with simple object form component', () => { + const schema = createMockSchema( + JsonSchemaType.Object, + 'base', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: MockObjectFormComponent, + viewProps: {viewProp: 'viewProp'}, + Wrapper: MockObjectWrapper, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + + test('should return render kit with independent string form component', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'custom', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: MockIndependentStringFormComponent, + viewProps: {viewProp: 'viewProp'}, + Wrapper: MockStringWrapper, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: true, + }); + }); + + test('should return render kit with independent string overview component', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'custom', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Overview, + schema, + }); + + expect(result).toEqual({ + View: MockIndependentStringOverviewComponent, + viewProps: {viewProp: 'viewProp'}, + Wrapper: MockStringWrapper, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: true, + }); + }); + + test('should return render kit with undefined components when viewType/wrapperType are missing', () => { + const schema: JsonSchema = { + type: JsonSchemaType.String, + entityParameters: { + viewProps: {viewProp: 'viewProp'}, + wrapperProps: {wrapperProp: 'wrapperProp'}, + }, + }; + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: undefined, + viewProps: {viewProp: 'viewProp'}, + Wrapper: undefined, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + + test('should return render kit with undefined components when viewType/wrapperType are unknown', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'unknown', + 'unknown', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: undefined, + viewProps: {viewProp: 'viewProp'}, + Wrapper: undefined, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + + test('should return render kit with undefined components when entityParameters is empty', () => { + const schema: JsonSchema = { + type: JsonSchemaType.String, + }; + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: undefined, + viewProps: {}, + Wrapper: undefined, + wrapperProps: {}, + independent: undefined, + }); + }); + + test('should return render kit with undefined components when entityParameters is null', () => { + const schema: JsonSchema = { + type: JsonSchemaType.String, + entityParameters: null as any, + }; + + const result = getRenderKit({ + config: mockSchemaRendererConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: undefined, + viewProps: {}, + Wrapper: undefined, + wrapperProps: {}, + independent: undefined, + }); + }); + + test('should return render kit with undefined components when config is empty', () => { + const schema = createMockSchema( + JsonSchemaType.String, + 'base', + 'default', + {viewProp: 'viewProp'}, + {wrapperProp: 'wrapperProp'}, + ); + + const emptyConfig = { + [JsonSchemaType.String]: { + views: {}, + wrappers: {}, + validators: {}, + }, + [JsonSchemaType.Array]: { + views: {}, + wrappers: {}, + validators: {}, + }, + [JsonSchemaType.Boolean]: { + views: {}, + wrappers: {}, + validators: {}, + }, + [JsonSchemaType.Number]: { + views: {}, + wrappers: {}, + validators: {}, + }, + [JsonSchemaType.Object]: { + views: {}, + wrappers: {}, + validators: {}, + }, + }; + + const result = getRenderKit({ + config: emptyConfig, + mode: SchemaRendererMode.Form, + schema, + }); + + expect(result).toEqual({ + View: undefined, + viewProps: {viewProp: 'viewProp'}, + Wrapper: undefined, + wrapperProps: {wrapperProp: 'wrapperProp'}, + independent: undefined, + }); + }); + }); +}); diff --git a/src/lib/unstable/core/Entity/utils.ts b/src/lib/unstable/core/Entity/utils.ts index eff211f3..72f6984d 100644 --- a/src/lib/unstable/core/Entity/utils.ts +++ b/src/lib/unstable/core/Entity/utils.ts @@ -11,24 +11,23 @@ export const getRenderKit = ({ schema, }: GetRenderKitParams): GetRenderKitReturn => { const viewType: string | undefined = get(schema, 'entityParameters.viewType'); - const wrapperType: string | undefined = get(schema, 'entityParameters.wrapperType'); - - const viewProps = get(schema, 'entityParameters.viewProps', EMPTY_OBJECT); - const wrapperProps = get(schema, 'entityParameters.wrapperProps', EMPTY_OBJECT); - const ViewComponent: View | undefined = get( config, `${schema.type}.views.${viewType}.${mode}.Component`, ); - const WrapperComponent: Wrapper | undefined = get( - config, - `${schema.type}.wrappers.${wrapperType}`, - ); + const viewProps = get(schema, 'entityParameters.viewProps', EMPTY_OBJECT); const independent: boolean | undefined = get( config, `${schema.type}.views.${viewType}.${mode}.independent`, ); + const wrapperType: string | undefined = get(schema, 'entityParameters.wrapperType'); + const WrapperComponent: Wrapper | undefined = get( + config, + `${schema.type}.wrappers.${wrapperType}`, + ); + const wrapperProps = get(schema, 'entityParameters.wrapperProps', EMPTY_OBJECT); + return { View: ViewComponent, viewProps, diff --git a/src/lib/unstable/core/types/helpers.ts b/src/lib/unstable/core/types/helpers.ts index be7de6b5..45827639 100644 --- a/src/lib/unstable/core/types/helpers.ts +++ b/src/lib/unstable/core/types/helpers.ts @@ -57,16 +57,16 @@ type ExtractViewProps = ViewConfig extends { } ? FormViewComponentProps extends {viewProps: infer ViewComponentProps} ? ViewComponentProps - : {} - : {}) & + : Record + : Record) & (OverviewComponentConfig extends { Component: React.ComponentType; } ? OverivewViewComponentProps extends {viewProps: infer ViewComponentProps} ? ViewComponentProps - : {} - : {}) - : {}; + : Record + : Record) + : Record; export type ViewComponentPropsByConfig = { [Key in keyof Config['views']]: ExtractViewProps; @@ -75,8 +75,8 @@ export type ViewComponentPropsByConfig = Wrapper extends React.ComponentType ? WrapperProps extends {wrapperProps: infer WrapperComponentProps} ? WrapperComponentProps - : {} - : {}; + : Record + : Record; export type WrapperComponentPropsByConfig = { [Key in keyof Config['wrappers']]: ExtractWrapperProps;