/** * 功能名称: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(); });