amis2/packages/amis/__tests__/renderers/Form/autoFill.test.tsx

402 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 功能名称autoFill 自动填充
* 单测内容:
* 01. 字段填充
* 02. 字段填充 & 提交表单
* 03. 字段填充的表单项name为对象路径格式
* 04. 字段填充(多选模式)
* 05. 字段填充后正常触发表单项校验 & validateOnChange正常触发
*/
import React from 'react';
import {
render,
cleanup,
screen,
fireEvent,
waitFor
} from '@testing-library/react';
import '../../../src';
import {render as amisRender} from '../../../src';
import {makeEnv, wait} from '../../helper';
import {clearStoresCache} from '../../../src';
afterEach(() => {
cleanup();
clearStoresCache();
});
const optisons = [
{label: 'OptionA', value: 'a'},
{label: 'OptionB', value: 'b'}
];
test('Form:options:autoFill', async () => {
const {container, getByText} = render(
amisRender(
{
type: 'form',
title: 'The form',
body: [
{
type: 'radios',
name: 'a',
autoFill: {
aValue: '${value}',
aLabel: '${label}',
aId: '${id}'
},
options: [
{
label: 'OptionA',
value: 'a',
id: 233
},
{
label: 'OptionB',
value: 'b'
}
]
},
{
type: 'input-text',
name: 'a'
},
{
type: 'input-text',
name: 'aValue'
},
{
type: 'input-text',
name: 'aLabel'
},
{
type: 'input-text',
name: 'aId'
}
],
submitText: null,
actions: []
},
{},
makeEnv()
)
);
// expect(container).toMatchSnapshot();
fireEvent.click(getByText(/OptionA/));
await wait(500);
expect(container.querySelector('input[name=a]')?.getAttribute('value')).toBe(
'a'
);
expect(
container.querySelector('input[name=aValue]')?.getAttribute('value')
).toBe('a');
expect(
container.querySelector('input[name=aLabel]')?.getAttribute('value')
).toBe('OptionA');
expect(
container.querySelector('input[name=aId]')?.getAttribute('value')
).toBe('233');
fireEvent.click(getByText(/OptionB/));
await wait(1000);
expect(container.querySelector('input[name=a]')?.getAttribute('value')).toBe(
'b'
);
expect(
container.querySelector('input[name=aValue]')?.getAttribute('value')
).toBe('b');
expect(
container.querySelector('input[name=aLabel]')?.getAttribute('value')
).toBe('OptionB');
expect(
container.querySelector('input[name=aId]')?.getAttribute('value')
).toBe('');
});
test('Form:options:autoFill:data', async () => {
const onSubmit = jest.fn();
const {debug, container, getByText, findByText} = render(
amisRender(
{
type: 'form',
title: 'The form',
controls: [
{
type: 'radios',
name: 'a',
autoFill: {
aValue: '${value}',
aLabel: '${label}',
aId: '${id}'
},
options: [
{
label: 'OptionA',
value: 'a',
id: 233
},
{
label: 'OptionB',
value: 'b'
}
]
}
],
submitText: 'Submit'
},
{
onSubmit: onSubmit
},
makeEnv()
)
);
fireEvent.click(await findByText(/OptionA/));
await wait(500);
fireEvent.click(getByText(/Submit/));
await wait(200);
expect(onSubmit).toBeCalled();
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
fireEvent.click(getByText(/OptionB/));
await wait(500);
fireEvent.click(getByText(/Submit/));
await wait(200);
expect(onSubmit).toBeCalledTimes(2);
expect(onSubmit.mock.calls[1][0]).toMatchSnapshot();
});
test('Form:options:autoFill:keyWithPath', async () => {
const {container} = render(
amisRender(
{
type: 'form',
body: [
{
type: 'radios',
label: 'trigger',
name: 'trigger',
autoFill: {
'receiver.target1': '${value}',
'receiver.target2': '${value}'
},
options: [
{label: 'OptionA', value: 'a'},
{label: 'OptionB', value: 'b'}
]
},
{
type: 'input-text',
name: 'receiver.target1',
label: 'receiver.target1'
},
{
type: 'input-text',
name: 'receiver.target2',
label: 'receiver.target2'
},
{
type: 'input-text',
name: 'standalone',
label: 'standalone',
value: 'abc'
}
]
},
{},
makeEnv()
)
);
const triggerA = await screen.findByText(/OptionA/);
const triggerB = await screen.findByText(/OptionB/);
const target1 = container.querySelector(
'input[name=receiver\\.target1]'
) as HTMLInputElement;
const target2 = container.querySelector(
'input[name=receiver\\.target2]'
) as HTMLInputElement;
const standalone = container.querySelector(
'input[name=standalone]'
) as HTMLInputElement;
fireEvent.click(triggerA);
await wait(1000);
expect(target1.getAttribute('value')).toEqual('a');
expect(target2.getAttribute('value')).toEqual('a');
expect(standalone.getAttribute('value')).toEqual('abc');
fireEvent.click(triggerB);
await wait(1000);
expect(target1.getAttribute('value')).toEqual('b');
expect(target2.getAttribute('value')).toEqual('b');
expect(standalone.getAttribute('value')).toEqual('abc');
});
test('Form:options:autoFill:multiple:data', async () => {
const onSubmit = jest.fn();
const {container, getByText, findByText} = render(
amisRender(
{
type: 'form',
title: 'The form',
controls: [
{
type: 'radios',
name: 'a',
multiple: true,
autoFill: {
aValues: '${items|pick:value}',
aLabels: '${items|pick:label}',
aIds: '${items|pick:id}'
},
options: [
{
label: 'OptionA',
value: 'a',
id: 233
},
{
label: 'OptionB',
value: 'b'
}
]
}
],
submitText: 'Submit'
},
{
onSubmit: onSubmit
},
makeEnv()
)
);
fireEvent.click(await findByText(/OptionA/));
await wait(500);
fireEvent.click(getByText(/Submit/));
await wait(200);
expect(onSubmit).toBeCalled();
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
fireEvent.click(getByText(/OptionB/));
await wait(500);
fireEvent.click(getByText(/Submit/));
await wait(200);
expect(onSubmit).toBeCalledTimes(2);
expect(onSubmit.mock.calls[1][0]).toMatchSnapshot();
});
test('Form:options:autoFill:validation', async () => {
const onSubmitFn = jest.fn();
const submitText = 'Submit';
const validationMsg1 = '选项1校验失败数据必须为Option B';
const validationMsg2 = '选项2校验失败数据必须为Option B';
const {container} = render(
amisRender(
{
type: 'form',
submitText,
body: [
{
type: 'select',
label: '选项',
name: 'select',
placeholder: 'SelectCompt',
autoFill: {
instantValidate: '${label}',
submitValidate: '${label}'
},
clearable: true,
options: [
{label: 'OptionA', value: 'a'},
{label: 'OptionB', value: 'b'}
]
},
{
type: 'input-text',
name: 'instantValidate',
label: '选项1',
placeholder: '选项1',
description: '填充后立即校验',
required: true,
validateOnChange: true,
validations: {
equals: 'OptionB'
},
validationErrors: {
equals: validationMsg1
}
},
{
type: 'input-text',
name: 'submitValidate',
label: '选项2',
placeholder: '选项2',
description: '填充后提交表单时才校验',
required: true,
validations: {
equals: 'OptionB'
},
validationErrors: {
equals: validationMsg2
}
}
]
},
{onSubmit: onSubmitFn},
makeEnv({})
)
);
const select = container.querySelector(
'span[class*=Select-arrow]'
) as HTMLDivElement;
const option1 = container.querySelector(
'input[name=instantValidate]'
) as HTMLInputElement;
const option2 = container.querySelector(
'input[name=submitValidate]'
) as HTMLInputElement;
const submitBtn = screen.getByRole('button', {name: submitText});
// 自动填充触发后生成校验信息
fireEvent.click(select);
await wait(300);
fireEvent.click(screen.getByText(/OptionA/));
await wait(1000);
expect(option1.getAttribute('value')).toEqual('OptionA');
expect(option2.getAttribute('value')).toEqual('OptionA');
expect(screen.queryByText(validationMsg1)).toBeInTheDocument();
// 提交后校验选项2
fireEvent.click(submitBtn);
await wait(500);
expect(screen.queryByText(validationMsg2)).toBeInTheDocument();
// 自动填充再次触发后validateOnChange的选项消除校验信息
fireEvent.click(select);
await wait(300);
fireEvent.click(screen.getByText(/OptionB/));
await wait(1000);
expect(option1.getAttribute('value')).toEqual('OptionB');
expect(option1.getAttribute('value')).toEqual('OptionB');
expect(screen.queryByText(validationMsg1)).not.toBeInTheDocument();
expect(screen.queryByText(validationMsg2)).not.toBeInTheDocument();
// 提交后校验信息全部消除
fireEvent.click(submitBtn);
await wait(500);
expect(screen.queryByText(validationMsg1)).not.toBeInTheDocument();
expect(screen.queryByText(validationMsg2)).not.toBeInTheDocument();
});