|
| 1 | + |
| 2 | +import { describe, it, expect } from 'vitest'; |
| 3 | +import { render, screen, waitFor } from '@testing-library/react'; |
| 4 | +import '@testing-library/jest-dom'; |
| 5 | +import { ObjectForm } from '@object-ui/plugin-form'; |
| 6 | +import type { DataSource } from '@object-ui/types'; |
| 7 | + |
| 8 | +// Mock DataSource that returns a schema with varied types |
| 9 | +class TypeMappingDataSource implements DataSource { |
| 10 | + private mockSchema = { |
| 11 | + name: 'test_types', |
| 12 | + fields: { |
| 13 | + text_field: { name: 'text_field', label: 'Text Field', type: 'text' }, |
| 14 | + email_field: { name: 'email_field', label: 'Email Field', type: 'email' }, |
| 15 | + number_field: { name: 'number_field', label: 'Number Field', type: 'number' }, |
| 16 | + boolean_field: { name: 'boolean_field', label: 'Boolean Field', type: 'boolean' }, |
| 17 | + date_field: { name: 'date_field', label: 'Date Field', type: 'date' }, |
| 18 | + select_field: { name: 'select_field', label: 'Select Field', type: 'select', options: [{label: 'A', value: 'a'}] }, |
| 19 | + textarea_field: { name: 'textarea_field', label: 'TextArea Field', type: 'textarea' }, |
| 20 | + } |
| 21 | + }; |
| 22 | + |
| 23 | + async getObjectSchema(_objectName: string): Promise<any> { |
| 24 | + return this.mockSchema; |
| 25 | + } |
| 26 | + |
| 27 | + async findOne(_objectName: string, _id: string): Promise<any> { |
| 28 | + return {}; |
| 29 | + } |
| 30 | + async create(_objectName: string, data: any): Promise<any> { return data; } |
| 31 | + async update(_objectName: string, _id: string, data: any): Promise<any> { return data; } |
| 32 | + async delete(_objectName: string, _id: string): Promise<boolean> { return true; } |
| 33 | + async find(_objectName: string, _options?: any): Promise<any> { return { data: [] }; } |
| 34 | +} |
| 35 | + |
| 36 | +describe('ObjectForm Field Type Mapping', () => { |
| 37 | + |
| 38 | + it('should render correct widgets for all standard field types', async () => { |
| 39 | + const dataSource = new TypeMappingDataSource(); |
| 40 | + const { container } = render( |
| 41 | + <ObjectForm |
| 42 | + schema={{ |
| 43 | + type: 'object-form', |
| 44 | + objectName: 'test_types', |
| 45 | + mode: 'create', |
| 46 | + fields: [ |
| 47 | + 'text_field', |
| 48 | + 'email_field', |
| 49 | + 'number_field', |
| 50 | + 'boolean_field', |
| 51 | + 'textarea_field', |
| 52 | + 'select_field' |
| 53 | + ] |
| 54 | + }} |
| 55 | + dataSource={dataSource} |
| 56 | + /> |
| 57 | + ); |
| 58 | + |
| 59 | + // Wait for schema to load and render |
| 60 | + await waitFor(() => { |
| 61 | + expect(screen.getByLabelText(/Text Field/i)).toBeInTheDocument(); |
| 62 | + }); |
| 63 | + |
| 64 | + // 1. Check Text Field (Input) |
| 65 | + const textInput = container.querySelector('input[name="text_field"]'); |
| 66 | + expect(textInput).toBeInTheDocument(); |
| 67 | + |
| 68 | + // 2. Check Number Field (Input) |
| 69 | + // Note: Specific type="number" check depends on the exact implementation of the field widget |
| 70 | + const numberInput = container.querySelector('input[name="number_field"]'); |
| 71 | + expect(numberInput).toBeInTheDocument(); |
| 72 | + |
| 73 | + // 3. Check TextArea |
| 74 | + const textarea = container.querySelector('textarea[name="textarea_field"]'); |
| 75 | + expect(textarea).toBeInTheDocument(); |
| 76 | + |
| 77 | + // 4. Check Boolean (Switch) |
| 78 | + // Radix UI switch usually has role="switch" |
| 79 | + const switchControl = screen.getByRole('switch', { name: /Boolean Field/i }); |
| 80 | + expect(switchControl).toBeInTheDocument(); |
| 81 | + |
| 82 | + // 5. Check Select Field |
| 83 | + // Radix UI Select trigger might not have the ID matching the label in this test environment |
| 84 | + // So we search for the role, and verify one exists. |
| 85 | + const selectTriggers = screen.getAllByRole('combobox'); |
| 86 | + expect(selectTriggers.length).toBeGreaterThan(0); |
| 87 | + |
| 88 | + // Optional: verify one of them is related to our field |
| 89 | + // We can assume the last one is ours or check context |
| 90 | + const selectWrapper = screen.getByText(/Select Field/i).closest('div'); |
| 91 | + const selectInWrapper = selectWrapper?.querySelector('button[role="combobox"]'); |
| 92 | + expect(selectInWrapper).toBeInTheDocument(); |
| 93 | + }); |
| 94 | +}); |
0 commit comments