@@ -468,6 +468,54 @@ defmodule Realtime.Extensions.PostgresCdcRls.ReplicationPollerTest do
468468
469469 assert_receive { :DOWN , ^ ref , :process , ^ pid , { :shutdown , :drop_replication_slot_failed } } , 1000
470470 end
471+
472+ test "refreshes oids without touching the slot when the publication stays non-empty" , % { args: args } do
473+ tenant_id = args [ "id" ]
474+
475+ # While the publication keeps having tables the slot must never be dropped
476+ # or recreated; :check_oids only refreshes the oid map in place.
477+ reject ( & Replications . drop_replication_slot / 2 )
478+
479+ pid = start_link_supervised! ( { Poller , args } )
480+
481+ # First poll happens with the default non-empty stub.
482+ assert_receive { :telemetry , [ :realtime , :replication , :poller , :query , :stop ] , _ , % { tenant: ^ tenant_id } } , 500
483+
484+ # Publication still has tables but the oid set changed (e.g. a table was added).
485+ new_oids = % { { "public" , "test" } => [ 1234 ] , { "public" , "other" } => [ 5678 ] }
486+ expect ( Subscriptions , :fetch_publication_tables , fn _ , _ -> new_oids end )
487+
488+ send ( pid , :check_oids )
489+
490+ # oids map is refreshed in place and the periodic check stays armed.
491+ state = :sys . get_state ( pid )
492+ assert state . oids == new_oids
493+ assert is_reference ( state . check_oid_ref )
494+ end
495+
496+ test "arms the periodic :check_oids timer when polling starts" , % { args: args } do
497+ tenant_id = args [ "id" ]
498+
499+ pid = start_link_supervised! ( { Poller , args } )
500+
501+ assert_receive { :telemetry , [ :realtime , :replication , :poller , :query , :stop ] , _ , % { tenant: ^ tenant_id } } , 500
502+
503+ assert is_reference ( :sys . get_state ( pid ) . check_oid_ref )
504+ end
505+
506+ test "arms the periodic :check_oids timer even when the publication is empty" , % { args: args } do
507+ tenant_id = args [ "id" ]
508+
509+ expect ( Subscriptions , :fetch_publication_tables , fn _ , _ -> % { } end )
510+ reject ( & Replications . list_changes / 5 )
511+
512+ pid = start_link_supervised! ( { Poller , args } )
513+
514+ refute_receive { :telemetry , [ :realtime , :replication , :poller , :query , :stop ] , _ , % { tenant: ^ tenant_id } } , 200
515+
516+ # Even idle (no slot), the poller must keep checking for tables to appear.
517+ assert is_reference ( :sys . get_state ( pid ) . check_oid_ref )
518+ end
471519 end
472520
473521 @ columns [
0 commit comments