33 *
44 * Tests for the system administration Object Manager page that integrates
55 * ObjectManager and FieldDesigner from @object-ui/plugin-designer.
6+ * Covers list view, detail view with URL-based navigation, and field management.
67 */
78
89import { describe , it , expect , vi , beforeEach } from 'vitest' ;
@@ -19,6 +20,7 @@ vi.mock('../context/MetadataProvider', () => ({
1920 label : 'Accounts' ,
2021 icon : 'Building' ,
2122 description : 'Customer accounts' ,
23+ enabled : true ,
2224 fields : [
2325 { name : 'id' , type : 'text' , label : 'ID' , readonly : true } ,
2426 { name : 'name' , type : 'text' , label : 'Account Name' , required : true } ,
@@ -66,7 +68,9 @@ function renderPage(route = '/system/objects') {
6668 < MemoryRouter initialEntries = { [ route ] } >
6769 < Routes >
6870 < Route path = "/system/objects" element = { < ObjectManagerPage /> } />
71+ < Route path = "/system/objects/:objectName" element = { < ObjectManagerPage /> } />
6972 < Route path = "/apps/:appName/system/objects" element = { < ObjectManagerPage /> } />
73+ < Route path = "/apps/:appName/system/objects/:objectName" element = { < ObjectManagerPage /> } />
7074 </ Routes >
7175 </ MemoryRouter >
7276 ) ;
@@ -77,7 +81,7 @@ describe('ObjectManagerPage', () => {
7781 vi . clearAllMocks ( ) ;
7882 } ) ;
7983
80- describe ( 'Rendering ' , ( ) => {
84+ describe ( 'List View ' , ( ) => {
8185 it ( 'should render the page with Object Manager title' , ( ) => {
8286 renderPage ( ) ;
8387 const titles = screen . getAllByText ( 'Object Manager' ) ;
@@ -105,61 +109,64 @@ describe('ObjectManagerPage', () => {
105109 } ) ;
106110 } ) ;
107111
108- describe ( 'Object Selection & Field Designer' , ( ) => {
109- it ( 'should show FieldDesigner when an object row is clicked' , async ( ) => {
110- renderPage ( ) ;
112+ describe ( 'Detail View (URL-based)' , ( ) => {
113+ it ( 'should show object detail page when navigating to /system/objects/:objectName' , ( ) => {
114+ renderPage ( '/system/objects/account' ) ;
115+ expect ( screen . getByTestId ( 'object-detail-view' ) ) . toBeDefined ( ) ;
116+ const titles = screen . getAllByText ( 'Accounts' ) ;
117+ expect ( titles . length ) . toBeGreaterThanOrEqual ( 1 ) ;
118+ } ) ;
111119
112- // ObjectGrid renders data asynchronously via ValueDataSource.
113- // Once loaded, primary field values become clickable links (data-testid="primary-field-link").
114- await waitFor ( ( ) => {
115- const links = screen . queryAllByTestId ( 'primary-field-link' ) ;
116- if ( links . length > 0 ) {
117- // Click the first object's primary field link
118- fireEvent . click ( links [ 0 ] ) ;
119- }
120- } ) ;
120+ it ( 'should show object properties section' , ( ) => {
121+ renderPage ( '/system/objects/account' ) ;
122+ expect ( screen . getByTestId ( 'object-properties' ) ) . toBeDefined ( ) ;
123+ expect ( screen . getByText ( 'API Name' ) ) . toBeDefined ( ) ;
124+ expect ( screen . getByText ( 'account' ) ) . toBeDefined ( ) ;
125+ } ) ;
121126
122- // Either FieldDesigner shows (if primary-field-link was found) or ObjectManager remains
123- const fieldDesigner = screen . queryByTestId ( 'field-designer ') ;
124- const objectManager = screen . queryByTestId ( 'object-manager' ) ;
125- expect ( fieldDesigner || objectManager ) . toBeDefined ( ) ;
127+ it ( 'should show field management section with FieldDesigner' , ( ) => {
128+ renderPage ( '/system/objects/account ') ;
129+ expect ( screen . getByTestId ( 'field-management-section' ) ) . toBeDefined ( ) ;
130+ expect ( screen . getByTestId ( 'field-designer' ) ) . toBeDefined ( ) ;
126131 } ) ;
127132
128- it ( 'should show back button when a field designer is active' , async ( ) => {
129- renderPage ( ) ;
133+ it ( 'should show back button to return to object list' , ( ) => {
134+ renderPage ( '/system/objects/account' ) ;
135+ expect ( screen . getByTestId ( 'back-to-objects' ) ) . toBeDefined ( ) ;
136+ } ) ;
130137
138+ it ( 'should navigate back to object list when back button is clicked' , async ( ) => {
139+ renderPage ( '/system/objects/account' ) ;
140+ const backBtn = screen . getByTestId ( 'back-to-objects' ) ;
141+ fireEvent . click ( backBtn ) ;
131142 await waitFor ( ( ) => {
132- const links = screen . queryAllByTestId ( 'primary-field-link' ) ;
133- if ( links . length > 0 ) {
134- fireEvent . click ( links [ 0 ] ) ;
135- }
143+ expect ( screen . getByTestId ( 'object-manager' ) ) . toBeDefined ( ) ;
136144 } ) ;
145+ } ) ;
137146
138- // If field designer is active, back button should be present
139- const backBtn = screen . queryByTestId ( 'back-to-objects' ) ;
140- const fieldDesigner = screen . queryByTestId ( 'field-designer' ) ;
141- if ( fieldDesigner ) {
142- expect ( backBtn ) . toBeDefined ( ) ;
143- }
147+ it ( 'should show relationships if the object has them' , ( ) => {
148+ renderPage ( '/system/objects/account' ) ;
149+ expect ( screen . getByText ( 'Relationships' ) ) . toBeDefined ( ) ;
150+ expect ( screen . getByText ( / c o n t a c t .* o n e - t o - m a n y / ) ) . toBeDefined ( ) ;
144151 } ) ;
152+ } ) ;
145153
146- it ( 'should return to object list when back button is clicked' , async ( ) => {
154+ describe ( 'Object Selection via ObjectGrid' , ( ) => {
155+ it ( 'should navigate to detail when primary field link is clicked' , async ( ) => {
147156 renderPage ( ) ;
148157
158+ // ObjectGrid renders data asynchronously. Primary field links are auto-generated.
149159 await waitFor ( ( ) => {
150160 const links = screen . queryAllByTestId ( 'primary-field-link' ) ;
151161 if ( links . length > 0 ) {
152162 fireEvent . click ( links [ 0 ] ) ;
153163 }
154164 } ) ;
155165
156- const backBtn = screen . queryByTestId ( 'back-to-objects' ) ;
157- if ( backBtn ) {
158- fireEvent . click ( backBtn ) ;
159- await waitFor ( ( ) => {
160- expect ( screen . getByTestId ( 'object-manager' ) ) . toBeDefined ( ) ;
161- } ) ;
162- }
166+ // Either detail view shows (if link was found) or list remains
167+ const detailView = screen . queryByTestId ( 'object-detail-view' ) ;
168+ const objectManager = screen . queryByTestId ( 'object-manager' ) ;
169+ expect ( detailView || objectManager ) . toBeDefined ( ) ;
163170 } ) ;
164171 } ) ;
165172} ) ;
0 commit comments