@@ -217,6 +217,79 @@ describe('Console Application Simulation', () => {
217217 expect ( screen . getAllByText ( '5000' ) . length ) . toBeGreaterThan ( 0 ) ;
218218 } ) ;
219219
220+ // -----------------------------------------------------------------------------
221+ // SIMPLIFIED FORM INTEGRATION TESTS
222+ // -----------------------------------------------------------------------------
223+ it ( 'Form Scenario B: Metadata-Driven Form Generation' , async ( ) => {
224+ vi . spyOn ( mocks . MockDataSource . prototype , 'getObjectSchema' ) . mockResolvedValue ( {
225+ name : 'kitchen_sink' ,
226+ fields : {
227+ name : { type : 'text' , label : 'Name Field' } ,
228+ amount : { type : 'number' , label : 'Amount Field' }
229+ }
230+ } ) ;
231+
232+ renderApp ( '/kitchen_sink' ) ;
233+ await waitFor ( ( ) => {
234+ expect ( screen . getByRole ( 'heading' , { name : / K i t c h e n S i n k / i } ) ) . toBeInTheDocument ( ) ;
235+ } ) ;
236+
237+ // Verify the form can be opened (showing metadata was loaded)
238+ const newButton = screen . getByRole ( 'button' , { name : / N e w K i t c h e n S i n k / i } ) ;
239+ fireEvent . click ( newButton ) ;
240+
241+ // Verify form loaded with schema-based fields
242+ await waitFor ( ( ) => {
243+ expect ( screen . getByRole ( 'dialog' ) ) . toBeInTheDocument ( ) ;
244+ } ) ;
245+
246+ // Form should render based on mocked schema
247+ // The actual field labels might differ based on implementation
248+ // but the form should render without errors
249+ expect ( screen . queryByText ( / e r r o r / i) ) . not . toBeInTheDocument ( ) ;
250+ } ) ;
251+
252+ // -----------------------------------------------------------------------------
253+ // SIMPLIFIED GRID INTEGRATION TESTS
254+ // -----------------------------------------------------------------------------
255+ it ( 'Grid Scenario A: Grid Rendering and Actions' , async ( ) => {
256+ renderApp ( '/kitchen_sink' ) ;
257+
258+ await waitFor ( ( ) => {
259+ expect ( screen . getByRole ( 'heading' , { name : / K i t c h e n S i n k / i } ) ) . toBeInTheDocument ( ) ;
260+ } ) ;
261+
262+ const newButton = screen . getByRole ( 'button' , { name : / N e w K i t c h e n S i n k / i } ) ;
263+ expect ( newButton ) . toBeInTheDocument ( ) ;
264+ } ) ;
265+
266+ it ( 'Grid Scenario B: Grid Data Loading' , async ( ) => {
267+ const seedData = [
268+ { id : '1' , name : 'Item 1' , amount : 100 } ,
269+ { id : '2' , name : 'Item 2' , amount : 200 }
270+ ] ;
271+
272+ const findSpy = vi . spyOn ( mocks . MockDataSource . prototype , 'find' )
273+ . mockResolvedValue ( { data : seedData } ) ;
274+
275+ renderApp ( '/kitchen_sink' ) ;
276+
277+ await waitFor ( ( ) => {
278+ expect ( screen . getByRole ( 'heading' , { name : / K i t c h e n S i n k / i } ) ) . toBeInTheDocument ( ) ;
279+ } ) ;
280+
281+ // Verify data source was called to load grid data
282+ await waitFor ( ( ) => {
283+ expect ( findSpy ) . toHaveBeenCalledWith ( 'kitchen_sink' , expect . any ( Object ) ) ;
284+ } ) ;
285+
286+ // Verify grid displays the loaded data
287+ await waitFor ( ( ) => {
288+ expect ( screen . getByText ( 'Item 1' ) ) . toBeInTheDocument ( ) ;
289+ } ) ;
290+ expect ( screen . getByText ( 'Item 2' ) ) . toBeInTheDocument ( ) ;
291+ } ) ;
292+
220293} ) ;
221294
222295// -----------------------------------------------------------------------------
@@ -664,3 +737,87 @@ describe('Kanban Integration', () => {
664737 expect ( findSpy ) . toHaveBeenCalledWith ( 'project_task' , expect . any ( Object ) ) ;
665738 } ) ;
666739} ) ;
740+
741+
742+ // -----------------------------------------------------------------------------
743+ // FIELDS INTEGRATION TESTS
744+ // -----------------------------------------------------------------------------
745+ describe ( 'Fields Integration' , ( ) => {
746+ it ( 'Scenario A: Field Type Mapping' , async ( ) => {
747+ const { mapFieldTypeToFormType } = await import ( '@object-ui/fields' ) ;
748+
749+ expect ( mapFieldTypeToFormType ( 'text' ) ) . toBe ( 'field:text' ) ;
750+ expect ( mapFieldTypeToFormType ( 'email' ) ) . toBe ( 'field:email' ) ;
751+ expect ( mapFieldTypeToFormType ( 'number' ) ) . toBe ( 'field:number' ) ;
752+ expect ( mapFieldTypeToFormType ( 'boolean' ) ) . toBe ( 'field:boolean' ) ;
753+ expect ( mapFieldTypeToFormType ( 'select' ) ) . toBe ( 'field:select' ) ;
754+ } ) ;
755+
756+ it ( 'Scenario A.2: Unknown Field Type Fallback in Form' , async ( ) => {
757+ const { mapFieldTypeToFormType } = await import ( '@object-ui/fields' ) ;
758+
759+ // Verify unknown types fallback to text
760+ expect ( mapFieldTypeToFormType ( 'unknown_type' ) ) . toBe ( 'field:text' ) ;
761+ expect ( mapFieldTypeToFormType ( 'custom_widget' ) ) . toBe ( 'field:text' ) ;
762+
763+ // This ensures forms don't break when encountering unknown field types
764+ // The actual rendering is tested via the full form integration tests
765+ } ) ;
766+
767+ it ( 'Scenario B: Field Formatting Utilities' , async ( ) => {
768+ const { formatCurrency, formatDate, formatPercent } = await import ( '@object-ui/fields' ) ;
769+
770+ const formatted = formatCurrency ( 1234.56 ) ;
771+ expect ( formatted ) . toContain ( '1,234.56' ) ;
772+
773+ const dateStr = formatDate ( new Date ( '2024-01-15' ) ) ;
774+ expect ( dateStr ) . toContain ( '2024' ) ;
775+
776+ const percent = formatPercent ( 0.1234 ) ;
777+ expect ( percent ) . toBe ( '12.34%' ) ;
778+ } ) ;
779+ } ) ;
780+
781+ // -----------------------------------------------------------------------------
782+ // DASHBOARD INTEGRATION TESTS
783+ // -----------------------------------------------------------------------------
784+ describe ( 'Dashboard Integration' , ( ) => {
785+ const renderApp = ( initialRoute : string ) => {
786+ return render (
787+ < MemoryRouter initialEntries = { [ initialRoute ] } >
788+ < AppContent />
789+ </ MemoryRouter >
790+ ) ;
791+ } ;
792+
793+ it ( 'Scenario A: Dashboard Page Rendering' , async ( ) => {
794+ renderApp ( '/dashboard/sales_dashboard' ) ;
795+
796+ await waitFor ( ( ) => {
797+ expect ( screen . getByText ( / S a l e s O v e r v i e w / i) ) . toBeInTheDocument ( ) ;
798+ } ) ;
799+
800+ expect ( screen . getByText ( / S a l e s b y R e g i o n / i) ) . toBeInTheDocument ( ) ;
801+ } ) ;
802+
803+ it ( 'Scenario B: Report Page Rendering' , async ( ) => {
804+ renderApp ( '/page/report_page' ) ;
805+
806+ await waitFor ( ( ) => {
807+ expect ( screen . getByText ( / S a l e s P e r f o r m a n c e R e p o r t / i) ) . toBeInTheDocument ( ) ;
808+ } ) ;
809+
810+ expect ( screen . getByText ( 'Region' ) ) . toBeInTheDocument ( ) ;
811+ expect ( screen . getByText ( 'North' ) ) . toBeInTheDocument ( ) ;
812+ } ) ;
813+
814+ it ( 'Scenario C: Component Registry Check' , async ( ) => {
815+ const { ComponentRegistry } = await import ( '@object-ui/core' ) ;
816+
817+ const dashboardRenderer = ComponentRegistry . get ( 'dashboard' ) ;
818+ expect ( dashboardRenderer ) . toBeDefined ( ) ;
819+
820+ const reportRenderer = ComponentRegistry . get ( 'report' ) ;
821+ expect ( reportRenderer ) . toBeDefined ( ) ;
822+ } ) ;
823+ } ) ;
0 commit comments