11import { describe , it , expect } from 'vitest' ;
22import {
33 InterfaceSchema ,
4- InterfacePageSchema ,
5- InterfacePageTypeSchema ,
64 InterfaceBrandingSchema ,
7- RecordReviewConfigSchema ,
85 defineInterface ,
96 type Interface ,
10- type InterfacePage ,
11- type RecordReviewConfig ,
127} from './interface.zod' ;
138import {
9+ PageSchema ,
10+ PageTypeSchema ,
1411 PageComponentSchema ,
12+ RecordReviewConfigSchema ,
1513 ElementDataSourceSchema ,
14+ type Page ,
1615 type ElementDataSource ,
16+ type RecordReviewConfig ,
1717} from './page.zod' ;
1818import {
1919 ElementTextPropsSchema ,
@@ -23,22 +23,29 @@ import {
2323} from './component.zod' ;
2424
2525// ---------------------------------------------------------------------------
26- // InterfacePageTypeSchema
26+ // PageTypeSchema — unified page types (platform + interface)
2727// ---------------------------------------------------------------------------
28- describe ( 'InterfacePageTypeSchema' , ( ) => {
29- it ( 'should accept all valid page types' , ( ) => {
28+ describe ( 'PageTypeSchema' , ( ) => {
29+ it ( 'should accept all platform page types' , ( ) => {
30+ const types = [ 'record' , 'home' , 'app' , 'utility' ] ;
31+ types . forEach ( type => {
32+ expect ( ( ) => PageTypeSchema . parse ( type ) ) . not . toThrow ( ) ;
33+ } ) ;
34+ } ) ;
35+
36+ it ( 'should accept all interface page types' , ( ) => {
3037 const types = [
3138 'dashboard' , 'grid' , 'list' , 'gallery' , 'kanban' , 'calendar' ,
3239 'timeline' , 'form' , 'record_detail' , 'record_review' , 'overview' , 'blank' ,
3340 ] ;
3441
3542 types . forEach ( type => {
36- expect ( ( ) => InterfacePageTypeSchema . parse ( type ) ) . not . toThrow ( ) ;
43+ expect ( ( ) => PageTypeSchema . parse ( type ) ) . not . toThrow ( ) ;
3744 } ) ;
3845 } ) ;
3946
4047 it ( 'should reject invalid page type' , ( ) => {
41- expect ( ( ) => InterfacePageTypeSchema . parse ( 'invalid' ) ) . toThrow ( ) ;
48+ expect ( ( ) => PageTypeSchema . parse ( 'invalid' ) ) . toThrow ( ) ;
4249 } ) ;
4350} ) ;
4451
@@ -141,24 +148,25 @@ describe('InterfaceBrandingSchema', () => {
141148} ) ;
142149
143150// ---------------------------------------------------------------------------
144- // InterfacePageSchema
151+ // PageSchema — interface page types (merged from InterfacePageSchema)
145152// ---------------------------------------------------------------------------
146- describe ( 'InterfacePageSchema ' , ( ) => {
147- it ( 'should accept minimal page' , ( ) => {
148- const page : InterfacePage = InterfacePageSchema . parse ( {
149- id : 'page_overview' ,
153+ describe ( 'PageSchema with interface page types ' , ( ) => {
154+ it ( 'should accept minimal interface-style page' , ( ) => {
155+ const page : Page = PageSchema . parse ( {
156+ name : 'page_overview' ,
150157 label : 'Overview' ,
158+ type : 'blank' ,
151159 regions : [ ] ,
152160 } ) ;
153161
154- expect ( page . id ) . toBe ( 'page_overview' ) ;
162+ expect ( page . name ) . toBe ( 'page_overview' ) ;
155163 expect ( page . type ) . toBe ( 'blank' ) ;
156164 expect ( page . template ) . toBe ( 'default' ) ;
157165 } ) ;
158166
159167 it ( 'should accept dashboard page' , ( ) => {
160- const page = InterfacePageSchema . parse ( {
161- id : 'page_dashboard' ,
168+ const page = PageSchema . parse ( {
169+ name : 'page_dashboard' ,
162170 label : 'Dashboard' ,
163171 type : 'dashboard' ,
164172 regions : [
@@ -176,8 +184,8 @@ describe('InterfacePageSchema', () => {
176184 } ) ;
177185
178186 it ( 'should accept record_review page with config' , ( ) => {
179- const page = InterfacePageSchema . parse ( {
180- id : 'page_review' ,
187+ const page = PageSchema . parse ( {
188+ name : 'page_review' ,
181189 label : 'Review Queue' ,
182190 type : 'record_review' ,
183191 object : 'order' ,
@@ -196,8 +204,8 @@ describe('InterfacePageSchema', () => {
196204 } ) ;
197205
198206 it ( 'should accept page with variables' , ( ) => {
199- const page = InterfacePageSchema . parse ( {
200- id : 'page_filtered' ,
207+ const page = PageSchema . parse ( {
208+ name : 'page_filtered' ,
201209 label : 'Filtered View' ,
202210 type : 'blank' ,
203211 variables : [
@@ -210,33 +218,45 @@ describe('InterfacePageSchema', () => {
210218 expect ( page . variables ) . toHaveLength ( 2 ) ;
211219 } ) ;
212220
213- it ( 'should accept all page types' , ( ) => {
221+ it ( 'should accept all interface page types' , ( ) => {
214222 const types = [
215223 'dashboard' , 'grid' , 'list' , 'gallery' , 'kanban' , 'calendar' ,
216224 'timeline' , 'form' , 'record_detail' , 'record_review' , 'overview' , 'blank' ,
217225 ] ;
218226
219227 types . forEach ( type => {
220- expect ( ( ) => InterfacePageSchema . parse ( {
221- id : 'test_page' ,
228+ expect ( ( ) => PageSchema . parse ( {
229+ name : 'test_page' ,
222230 label : 'Test' ,
223231 type,
224232 regions : [ ] ,
225233 } ) ) . not . toThrow ( ) ;
226234 } ) ;
227235 } ) ;
228236
237+ it ( 'should accept page with icon' , ( ) => {
238+ const page = PageSchema . parse ( {
239+ name : 'page_with_icon' ,
240+ label : 'Dashboard' ,
241+ type : 'dashboard' ,
242+ icon : 'bar-chart' ,
243+ regions : [ ] ,
244+ } ) ;
245+
246+ expect ( page . icon ) . toBe ( 'bar-chart' ) ;
247+ } ) ;
248+
229249 it ( 'should accept page with i18n label' , ( ) => {
230- expect ( ( ) => InterfacePageSchema . parse ( {
231- id : 'i18n_page' ,
250+ expect ( ( ) => PageSchema . parse ( {
251+ name : 'i18n_page' ,
232252 label : { key : 'interface.pages.overview' , defaultValue : 'Overview' } ,
233253 regions : [ ] ,
234254 } ) ) . not . toThrow ( ) ;
235255 } ) ;
236256
237257 it ( 'should accept page with ARIA attributes' , ( ) => {
238- expect ( ( ) => InterfacePageSchema . parse ( {
239- id : 'accessible_page' ,
258+ expect ( ( ) => PageSchema . parse ( {
259+ name : 'accessible_page' ,
240260 label : 'Accessible Page' ,
241261 regions : [ ] ,
242262 aria : { ariaLabel : 'Interface overview page' , role : 'main' } ,
@@ -268,13 +288,13 @@ describe('InterfaceSchema', () => {
268288 object : 'opportunity' ,
269289 pages : [
270290 {
271- id : 'page_dashboard' ,
291+ name : 'page_dashboard' ,
272292 label : 'Dashboard' ,
273293 type : 'dashboard' ,
274294 regions : [ ] ,
275295 } ,
276296 {
277- id : 'page_pipeline' ,
297+ name : 'page_pipeline' ,
278298 label : 'Pipeline' ,
279299 type : 'kanban' ,
280300 object : 'opportunity' ,
@@ -362,7 +382,7 @@ describe('defineInterface', () => {
362382 label : 'HR Portal' ,
363383 pages : [
364384 {
365- id : 'page_onboarding' ,
385+ name : 'page_onboarding' ,
366386 label : 'Onboarding' ,
367387 type : 'overview' ,
368388 regions : [ ] ,
@@ -653,7 +673,7 @@ describe('Interface end-to-end', () => {
653673 object : 'order' ,
654674 pages : [
655675 {
656- id : 'page_overview' ,
676+ name : 'page_overview' ,
657677 label : 'Overview' ,
658678 type : 'dashboard' ,
659679 regions : [
@@ -687,7 +707,7 @@ describe('Interface end-to-end', () => {
687707 ] ,
688708 } ,
689709 {
690- id : 'page_review' ,
710+ name : 'page_review' ,
691711 label : 'Review Queue' ,
692712 type : 'record_review' ,
693713 object : 'order' ,
@@ -707,7 +727,7 @@ describe('Interface end-to-end', () => {
707727 regions : [ ] ,
708728 } ,
709729 {
710- id : 'page_grid' ,
730+ name : 'page_grid' ,
711731 label : 'All Orders' ,
712732 type : 'grid' ,
713733 object : 'order' ,
0 commit comments