@@ -207,6 +207,107 @@ describe('api-publisher', () => {
207207 expect ( calls [ 0 ] [ 3 ] . nameParts [ 0 ] ) . toBe ( 'orders-api;rev=1' ) ;
208208 expect ( calls [ 1 ] [ 3 ] . nameParts [ 0 ] ) . toBe ( 'orders-api;rev=2' ) ;
209209 expect ( calls [ 2 ] [ 3 ] . nameParts [ 0 ] ) . toBe ( 'orders-api;rev=3' ) ;
210+
211+ // Root API is only replayed when source marks it current (isCurrent=true).
212+ // Default mock root payload has no isCurrent flag, so only the initial PUT runs.
213+ expect ( client . putResource ) . toHaveBeenCalledTimes ( 1 ) ;
214+ } ) ;
215+
216+ it ( 'should replay root API without re-importing specification after revisions' , async ( ) => {
217+ const client = createMockClient ( ) ;
218+ const revisions = [ { type : ResourceType . Api , nameParts : [ 'orders-api;rev=2' ] } ] ;
219+ const store = createMockStore ( revisions ) ;
220+ store . readResource . mockResolvedValue ( {
221+ name : 'orders-api' ,
222+ properties : { path : 'orders' , isCurrent : true } ,
223+ } ) ;
224+ store . readContent . mockResolvedValue ( {
225+ content : 'openapi: "3.0.0"' ,
226+ format : 'yaml' ,
227+ } ) ;
228+
229+ const apiDescriptor : ResourceDescriptor = {
230+ type : ResourceType . Api ,
231+ nameParts : [ 'orders-api' ] ,
232+ } ;
233+
234+ await publishApi ( client , store , testContext , apiDescriptor , testConfig ) ;
235+
236+ // Spec is only read/injected on the first root publish.
237+ expect ( store . readContent ) . toHaveBeenCalledTimes ( 1 ) ;
238+ expect ( client . putResource ) . toHaveBeenCalledTimes ( 2 ) ;
239+
240+ const firstPayload = client . putResource . mock . calls [ 0 ] [ 2 ] as Record < string , unknown > ;
241+ const secondPayload = client . putResource . mock . calls [ 1 ] [ 2 ] as Record < string , unknown > ;
242+ const firstProps = firstPayload . properties as Record < string , unknown > ;
243+ const secondProps = secondPayload . properties as Record < string , unknown > ;
244+
245+ expect ( firstProps ) . toHaveProperty ( 'format' , 'openapi' ) ;
246+ expect ( firstProps ) . toHaveProperty ( 'value' , 'openapi: "3.0.0"' ) ;
247+ expect ( secondProps ) . not . toHaveProperty ( 'format' ) ;
248+ expect ( secondProps ) . not . toHaveProperty ( 'value' ) ;
249+ } ) ;
250+
251+ it ( 'should not replay root API when source root is not current' , async ( ) => {
252+ const client = createMockClient ( ) ;
253+ const revisions = [ { type : ResourceType . Api , nameParts : [ 'orders-api;rev=2' ] } ] ;
254+ const store = createMockStore ( revisions ) ;
255+ store . readResource . mockResolvedValue ( {
256+ name : 'orders-api' ,
257+ properties : {
258+ isCurrent : false ,
259+ apiRevision : '2' ,
260+ serviceUrl : 'https://src-revisioned-backend-v2.example.com/api' ,
261+ } ,
262+ } ) ;
263+
264+ const apiDescriptor : ResourceDescriptor = {
265+ type : ResourceType . Api ,
266+ nameParts : [ 'orders-api' ] ,
267+ } ;
268+
269+ await publishApi ( client , store , testContext , apiDescriptor , testConfig ) ;
270+
271+ // Root is not current in source, so no root alignment replay is performed.
272+ expect ( client . putResource ) . toHaveBeenCalledTimes ( 1 ) ;
273+ const alignedPayload = client . putResource . mock . calls [ 0 ] [ 2 ] as Record < string , unknown > ;
274+ const alignedProps = alignedPayload . properties as Record < string , unknown > ;
275+
276+ expect ( alignedProps ) . toHaveProperty ( 'apiRevision' , '2' ) ;
277+ expect ( alignedProps ) . toHaveProperty ( 'serviceUrl' , 'https://src-revisioned-backend-v2.example.com/api' ) ;
278+ expect ( alignedProps ) . not . toHaveProperty ( 'format' ) ;
279+ expect ( alignedProps ) . not . toHaveProperty ( 'value' ) ;
280+ } ) ;
281+
282+ it ( 'should align active revision from source when active revision is 1' , async ( ) => {
283+ const client = createMockClient ( ) ;
284+ const revisions = [ { type : ResourceType . Api , nameParts : [ 'orders-api;rev=2' ] } ] ;
285+ const store = createMockStore ( revisions ) ;
286+ store . readResource . mockResolvedValue ( {
287+ name : 'orders-api' ,
288+ properties : {
289+ isCurrent : true ,
290+ apiRevision : '1' ,
291+ serviceUrl : 'https://src-revisioned-backend.example.com/api' ,
292+ } ,
293+ } ) ;
294+
295+ const apiDescriptor : ResourceDescriptor = {
296+ type : ResourceType . Api ,
297+ nameParts : [ 'orders-api' ] ,
298+ } ;
299+
300+ await publishApi ( client , store , testContext , apiDescriptor , testConfig ) ;
301+
302+ // Second root PUT is the explicit active-revision alignment pass.
303+ expect ( client . putResource ) . toHaveBeenCalledTimes ( 2 ) ;
304+ const alignedPayload = client . putResource . mock . calls [ 1 ] [ 2 ] as Record < string , unknown > ;
305+ const alignedProps = alignedPayload . properties as Record < string , unknown > ;
306+
307+ expect ( alignedProps ) . toHaveProperty ( 'apiRevision' , '1' ) ;
308+ expect ( alignedProps ) . toHaveProperty ( 'serviceUrl' , 'https://src-revisioned-backend.example.com/api' ) ;
309+ expect ( alignedProps ) . not . toHaveProperty ( 'format' ) ;
310+ expect ( alignedProps ) . not . toHaveProperty ( 'value' ) ;
210311 } ) ;
211312
212313 it ( 'should skip non-matching revisions when filtering by API name' , async ( ) => {
0 commit comments