@@ -17,6 +17,7 @@ import {
1717 MetadataManagerConfigSchema ,
1818 MetadataFallbackStrategySchema ,
1919 MetadataSourceSchema ,
20+ PackagePublishResultSchema ,
2021} from './metadata-persistence.zod' ;
2122
2223describe ( 'MetadataScopeSchema' , ( ) => {
@@ -100,6 +101,35 @@ describe('MetadataRecordSchema', () => {
100101 expect ( record . tags ) . toEqual ( [ 'crm' , 'custom' ] ) ;
101102 } ) ;
102103
104+ it ( 'should accept publishing fields' , ( ) => {
105+ const record = MetadataRecordSchema . parse ( {
106+ id : 'abc-123' ,
107+ name : 'account_list_view' ,
108+ type : 'view' ,
109+ metadata : { columns : [ 'name' ] } ,
110+ publishedDefinition : { columns : [ 'name' , 'email' ] } ,
111+ publishedAt : '2025-06-01T12:00:00Z' ,
112+ publishedBy : 'admin-user' ,
113+ } ) ;
114+
115+ expect ( record . publishedDefinition ) . toEqual ( { columns : [ 'name' , 'email' ] } ) ;
116+ expect ( record . publishedAt ) . toBe ( '2025-06-01T12:00:00Z' ) ;
117+ expect ( record . publishedBy ) . toBe ( 'admin-user' ) ;
118+ } ) ;
119+
120+ it ( 'should allow omitting publishing fields (backward compatible)' , ( ) => {
121+ const record = MetadataRecordSchema . parse ( {
122+ id : 'abc-123' ,
123+ name : 'test' ,
124+ type : 'object' ,
125+ metadata : { } ,
126+ } ) ;
127+
128+ expect ( record . publishedDefinition ) . toBeUndefined ( ) ;
129+ expect ( record . publishedAt ) . toBeUndefined ( ) ;
130+ expect ( record . publishedBy ) . toBeUndefined ( ) ;
131+ } ) ;
132+
103133 it ( 'should default version to 1' , ( ) => {
104134 const record = MetadataRecordSchema . parse ( {
105135 id : 'x' , name : 'y' , type : 'z' , metadata : { } ,
@@ -518,3 +548,44 @@ describe('MetadataSourceSchema', () => {
518548 expect ( ( ) => MetadataSourceSchema . parse ( 'unknown' ) ) . toThrow ( ) ;
519549 } ) ;
520550} ) ;
551+
552+ describe ( 'PackagePublishResultSchema' , ( ) => {
553+ it ( 'should accept a successful publish result' , ( ) => {
554+ const result = PackagePublishResultSchema . parse ( {
555+ success : true ,
556+ packageId : 'com.acme.crm' ,
557+ version : 2 ,
558+ publishedAt : '2025-06-01T12:00:00Z' ,
559+ itemsPublished : 5 ,
560+ } ) ;
561+
562+ expect ( result . success ) . toBe ( true ) ;
563+ expect ( result . packageId ) . toBe ( 'com.acme.crm' ) ;
564+ expect ( result . version ) . toBe ( 2 ) ;
565+ expect ( result . publishedAt ) . toBe ( '2025-06-01T12:00:00Z' ) ;
566+ expect ( result . itemsPublished ) . toBe ( 5 ) ;
567+ expect ( result . validationErrors ) . toBeUndefined ( ) ;
568+ } ) ;
569+
570+ it ( 'should accept a failed publish result with validation errors' , ( ) => {
571+ const result = PackagePublishResultSchema . parse ( {
572+ success : false ,
573+ packageId : 'com.acme.crm' ,
574+ version : 1 ,
575+ publishedAt : '2025-06-01T12:00:00Z' ,
576+ itemsPublished : 0 ,
577+ validationErrors : [
578+ { type : 'view' , name : 'missing_view' , message : 'Referenced object not found' } ,
579+ ] ,
580+ } ) ;
581+
582+ expect ( result . success ) . toBe ( false ) ;
583+ expect ( result . validationErrors ) . toHaveLength ( 1 ) ;
584+ expect ( result . validationErrors ! [ 0 ] . type ) . toBe ( 'view' ) ;
585+ } ) ;
586+
587+ it ( 'should reject missing required fields' , ( ) => {
588+ expect ( ( ) => PackagePublishResultSchema . parse ( { } ) ) . toThrow ( ) ;
589+ expect ( ( ) => PackagePublishResultSchema . parse ( { success : true } ) ) . toThrow ( ) ;
590+ } ) ;
591+ } ) ;
0 commit comments