Skip to content

Commit

Permalink
test: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Enki Pontvianne committed Sep 12, 2024
1 parent 7ccb8f6 commit e50894e
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 29 deletions.
3 changes: 0 additions & 3 deletions packages/_example/src/forest/customizations/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export default (collection: CardCustomizer) =>
// {
// type: 'Layout',
// component: 'Separator',
// if: ctx => ctx.formValues.first_name === 'test',
// },
// {
// type: 'Layout',
Expand All @@ -121,7 +120,6 @@ export default (collection: CardCustomizer) =>
// {
// type: 'Layout',
// component: 'Page',
// // "if_": lambda ctx: ctx.form_values.get("Number of children") != 0,
// elements: [
{ type: 'Number', label: 'Number of children' },
// {
Expand All @@ -140,7 +138,6 @@ export default (collection: CardCustomizer) =>
// {
// type: 'Layout',
// component: 'Page',
// // "if_": lambda ctx: ctx.form_values.get("Are they wise") is False,
// elements: [
// {
// type: 'Layout',
Expand Down
12 changes: 4 additions & 8 deletions packages/agent/src/routes/modification/action/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,10 @@ export default class ActionRoute extends CollectionRoute {
includeHiddenFields: false,
});

const { fields, layout } = SchemaGeneratorActions.extractFieldsAndLayout(form);

context.response.body = {
fields: fields.map(field =>
SchemaGeneratorActions.buildFieldSchema(this.collection.dataSource, field),
),
layout: layout.map(layoutElement => SchemaGeneratorActions.buildLayoutSchema(layoutElement)),
};
context.response.body = SchemaGeneratorActions.buildFieldsAndLayout(
this.collection.dataSource,
form,
);
}

private async middlewareCustomActionApprovalRequestData(context: Context, next: Next) {
Expand Down
36 changes: 20 additions & 16 deletions packages/agent/src/utils/forest-schema/generator-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,13 @@ export default class SchemaGeneratorActions {

// Generate url-safe friendly name (which won't be unique, but that's OK).
const slug = SchemaGeneratorActions.getActionSlug(name);
const form: {
fields: ForestServerActionField[];
layout?: ForestServerActionFormLayoutElement[];
} = {
fields: SchemaGeneratorActions.defaultFields,
};
let fields = SchemaGeneratorActions.defaultFields;

if (schema.staticForm) {
const rawForm = await collection.getForm(null, name, null, null);
const fieldsAndLayout = SchemaGeneratorActions.extractFieldsAndLayout(rawForm);

form.fields = fieldsAndLayout.fields.map(field => {
const newField = SchemaGeneratorActions.buildFieldSchema(collection.dataSource, field);
newField.defaultValue = newField.value;
delete newField.value;
fields = SchemaGeneratorActions.buildFieldsAndLayout(collection.dataSource, rawForm).fields;

return newField;
});
SchemaGeneratorActions.setFieldsDefaultValue(fields);
}

return {
Expand All @@ -80,16 +69,31 @@ export default class SchemaGeneratorActions {
httpMethod: 'POST',
redirect: null, // frontend ignores this attribute
download: Boolean(schema.generateFile),
...form,
fields,
hooks: {
load: !schema.staticForm,

// Always registering the change hook has no consequences, even if we don't use it.
change: ['changeHook'],
},
};
}

static buildFieldsAndLayout(dataSource: DataSource, form: ActionFormElement[]) {
const { fields, layout } = SchemaGeneratorActions.extractFieldsAndLayout(form);

return {
fields: fields.map(field => SchemaGeneratorActions.buildFieldSchema(dataSource, field)),
layout: layout.map(layoutElement => SchemaGeneratorActions.buildLayoutSchema(layoutElement)),
};
}

static setFieldsDefaultValue(fields: ForestServerActionField[]) {
fields.forEach(field => {
field.defaultValue = field.value;
delete field.value;
});
}

/** Build schema for given field */
static buildFieldSchema(dataSource: DataSource, field: ActionField): ForestServerActionField {
const { label, description, isRequired, isReadOnly, watchChanges, type } = field;
Expand Down
17 changes: 17 additions & 0 deletions packages/agent/test/routes/modification/action/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,23 @@ describe('ActionRoute', () => {
});
});

test('handleHook should generate a form with layout if some layout elements are present', async () => {
const context = createMockContext(baseContext);

dataSource.getCollection('books').getForm = jest.fn().mockResolvedValue([
{ type: 'String', label: 'firstname' },
{ type: 'Layout', component: 'Separator' },
]);

// @ts-expect-error: test private method
await route.handleHook(context);

expect(context.response.body).toEqual({
fields: [{ field: 'firstname', type: 'String' }],
layout: [{ component: 'input', fieldId: 'firstname' }, { component: 'separator' }],
});
});

test('handleHook should generate the form if called with changehook params', async () => {
const context = createMockContext({
...baseContext,
Expand Down
62 changes: 62 additions & 0 deletions packages/agent/test/utils/forest-schema/generator-actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ describe('SchemaGeneratorActions', () => {
test('should include a reference to the change hook', async () => {
const schema = await SchemaGeneratorActions.buildSchema(collection, 'Send email');
expect(schema.fields[0].hook).toEqual('changeHook');
expect(schema.layout).toEqual(undefined);
});
});

Expand Down Expand Up @@ -132,6 +133,10 @@ describe('SchemaGeneratorActions', () => {
value: null,
watchChanges: false,
},
{
type: 'Layout',
component: 'Separator',
},
{
label: 'inclusive gender',
description: 'Choose None, Male, Female or Both',
Expand Down Expand Up @@ -177,6 +182,9 @@ describe('SchemaGeneratorActions', () => {
type: ['Enum'],
enums: ['Male', 'Female'],
});

// no layout in schema, only in hooks response
expect(schema.layout).toEqual(undefined);
});
});

Expand Down Expand Up @@ -269,4 +277,58 @@ describe('SchemaGeneratorActions', () => {
});
});
});

describe('buildFieldsAndLayout', () => {
it('should compute the schema of layout elements', async () => {
const dataSource = factories.dataSource.buildWithCollections([
factories.collection.buildWithAction(
'Update title',
{
scope: 'Single',
generateFile: false,
staticForm: true,
},
[
{
label: 'title',
description: 'updated title',
type: 'String',
isRequired: true,
isReadOnly: false,
value: null,
watchChanges: false,
},
{
type: 'Layout',
component: 'Separator',
},
{
label: 'description',
type: 'String',
watchChanges: false,
},
],
),
]);

const collection = dataSource.getCollection('books');

const form = await collection.getForm(null, 'Update title');

const schema = SchemaGeneratorActions.buildFieldsAndLayout(collection.dataSource, form);

expect(schema.fields.length).toEqual(2);
expect(schema.layout).toEqual([
{
component: 'input',
fieldId: 'title',
},
{ component: 'separator' },
{
component: 'input',
fieldId: 'description',
},
]);
});
});
});
8 changes: 6 additions & 2 deletions packages/datasource-toolkit/test/__factories__/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
import { Factory } from 'fishery';

import collectionSchemaFactory from './schema/collection-schema';
import { ActionField } from '../../src/interfaces/action';
import { ActionFormElement } from '../../src/interfaces/action';
import { Collection } from '../../src/interfaces/collection';
import { ActionSchema } from '../../src/interfaces/schema';

export class CollectionFactory extends Factory<Collection> {
buildWithAction(name: string, schema: ActionSchema, fields: ActionField[] = null): Collection {
buildWithAction(
name: string,
schema: ActionSchema,
fields: ActionFormElement[] = null,
): Collection {
return this.build({
name: 'books',
schema: collectionSchemaFactory.build({
Expand Down

0 comments on commit e50894e

Please sign in to comment.