1+ import { In , Not } from "typeorm" ;
12import { beforeEach , describe , expect , it , vi } from "vitest" ;
23import type { StorageProvider } from "../../database/entities/storage-provider.entity.js" ;
34import type { PDPProviderEx } from "../../wallet-sdk/wallet-sdk.types.js" ;
@@ -326,12 +327,17 @@ describe("StorageProviderRepository", () => {
326327 } ) ;
327328
328329 describe ( "upsertFromRegistry" , ( ) => {
329- let repo : { create : ReturnType < typeof vi . fn > ; upsert : ReturnType < typeof vi . fn > } ;
330+ let repo : { create : ReturnType < typeof vi . fn > ; manager : { transaction : ReturnType < typeof vi . fn > } } ;
331+ let txRepo : { upsert : ReturnType < typeof vi . fn > ; update : ReturnType < typeof vi . fn > } ;
330332 let service : StorageProviderRepository ;
331333 let loggerMock : { warn : ReturnType < typeof vi . fn > ; error : ReturnType < typeof vi . fn > } ;
332334
333335 beforeEach ( ( ) => {
334- repo = { create : vi . fn ( ( data ) => data ) , upsert : vi . fn ( ) } ;
336+ txRepo = { upsert : vi . fn ( ) , update : vi . fn ( ) } ;
337+ repo = {
338+ create : vi . fn ( ( data ) => data ) ,
339+ manager : { transaction : vi . fn ( ( runInTransaction ) => runInTransaction ( { getRepository : ( ) => txRepo } ) ) } ,
340+ } ;
335341 service = new StorageProviderRepository ( repo as any , { } as any ) ;
336342 loggerMock = { warn : vi . fn ( ) , error : vi . fn ( ) } ;
337343 ( service as any ) . logger = loggerMock ;
@@ -357,7 +363,7 @@ describe("StorageProviderRepository", () => {
357363 ) ;
358364 expect ( loggerMock . error ) . not . toHaveBeenCalled ( ) ;
359365
360- const [ entities , options ] = repo . upsert . mock . calls [ 0 ] ;
366+ const [ entities , options ] = txRepo . upsert . mock . calls [ 0 ] ;
361367 expect ( options ) . toEqual ( expect . objectContaining ( { conflictPaths : [ "address" , "network" ] } ) ) ;
362368 expect ( entities ) . toEqual (
363369 expect . arrayContaining ( [
@@ -374,7 +380,7 @@ describe("StorageProviderRepository", () => {
374380 await service . upsertFromRegistry ( [ active , inactive ] , "calibration" ) ;
375381
376382 expect ( loggerMock . error ) . not . toHaveBeenCalled ( ) ;
377- const [ entities ] = repo . upsert . mock . calls [ 0 ] ;
383+ const [ entities ] = txRepo . upsert . mock . calls [ 0 ] ;
378384 expect ( entities ) . toEqual (
379385 expect . arrayContaining ( [
380386 expect . objectContaining ( { address : "0xdup2" , network : "calibration" , providerId : 30n , name : "active" } ) ,
@@ -391,12 +397,47 @@ describe("StorageProviderRepository", () => {
391397 expect ( loggerMock . error ) . toHaveBeenCalledWith (
392398 expect . objectContaining ( { event : "duplicate_provider_addresses_unresolved" } ) ,
393399 ) ;
394- const [ entities ] = repo . upsert . mock . calls [ 0 ] ;
400+ const [ entities ] = txRepo . upsert . mock . calls [ 0 ] ;
395401 expect ( entities ) . toEqual (
396402 expect . arrayContaining ( [
397403 expect . objectContaining ( { address : "0xdup3" , network : "calibration" , providerId : 41n , name : "second" } ) ,
398404 ] ) ,
399405 ) ;
400406 } ) ;
407+
408+ it ( "deactivates rows whose address is absent from the registry snapshot" , async ( ) => {
409+ const stillPresent = makeProvider ( { id : 50n , serviceProvider : "0xstill" , isActive : true } ) ;
410+
411+ await service . upsertFromRegistry ( [ stillPresent ] , "calibration" ) ;
412+
413+ expect ( txRepo . update ) . toHaveBeenCalledWith (
414+ { network : "calibration" , isActive : true , address : Not ( In ( [ "0xstill" ] ) ) } ,
415+ { isActive : false } ,
416+ ) ;
417+ } ) ;
418+
419+ it ( "deactivates within the same transaction as the upsert, after it" , async ( ) => {
420+ const provider = makeProvider ( { id : 51n , serviceProvider : "0xa" } ) ;
421+ const callOrder : string [ ] = [ ] ;
422+ txRepo . upsert . mockImplementation ( ( ) => {
423+ callOrder . push ( "upsert" ) ;
424+ return Promise . resolve ( ) ;
425+ } ) ;
426+ txRepo . update . mockImplementation ( ( ) => {
427+ callOrder . push ( "update" ) ;
428+ return Promise . resolve ( ) ;
429+ } ) ;
430+
431+ await service . upsertFromRegistry ( [ provider ] , "calibration" ) ;
432+
433+ expect ( repo . manager . transaction ) . toHaveBeenCalledTimes ( 1 ) ;
434+ expect ( callOrder ) . toEqual ( [ "upsert" , "update" ] ) ;
435+ } ) ;
436+
437+ it ( "clears the address filter (deactivating every row for the network) when the registry snapshot is empty" , async ( ) => {
438+ await service . upsertFromRegistry ( [ ] , "calibration" ) ;
439+
440+ expect ( txRepo . update ) . toHaveBeenCalledWith ( { network : "calibration" , isActive : true } , { isActive : false } ) ;
441+ } ) ;
401442 } ) ;
402443} ) ;
0 commit comments