@@ -62,6 +62,55 @@ func TestIgnoreMapper_AfterRemoteOperation_Variables(t *testing.T) {
6262 }, state .All ())
6363}
6464
65+ func TestIgnoreMapper_AfterRemoteOperation_Variables_SharedByMultipleConsumers (t * testing.T ) {
66+ t .Parallel ()
67+ state , d := createStateWithMapper (t )
68+ logger := d .DebugLogger ()
69+
70+ // Consumer 1
71+ consumer1Key := model.ConfigKey {BranchID : 1 , ComponentID : "ex-generic-v2" , ID : "1" }
72+ consumer1 := & model.ConfigState {
73+ ConfigManifest : & model.ConfigManifest {ConfigKey : consumer1Key },
74+ Remote : & model.Config {ConfigKey : consumer1Key },
75+ }
76+ require .NoError (t , state .Set (consumer1 ))
77+
78+ // Consumer 2
79+ consumer2Key := model.ConfigKey {BranchID : 1 , ComponentID : "ex-generic-v2" , ID : "2" }
80+ consumer2 := & model.ConfigState {
81+ ConfigManifest : & model.ConfigManifest {ConfigKey : consumer2Key },
82+ Remote : & model.Config {ConfigKey : consumer2Key },
83+ }
84+ require .NoError (t , state .Set (consumer2 ))
85+
86+ // Shared variables config with two VariablesForRelation entries — simulates the case
87+ // where the relations mapper's two-pass dedup did not run for this config (it was absent
88+ // from the loaded batch when consumer relations were linked).
89+ sharedVarsKey := model.ConfigKey {BranchID : 1 , ComponentID : keboola .VariablesComponentID , ID : "3" }
90+ sharedVars := & model.ConfigState {
91+ ConfigManifest : & model.ConfigManifest {ConfigKey : sharedVarsKey },
92+ Remote : & model.Config {
93+ ConfigKey : sharedVarsKey ,
94+ Relations : model.Relations {
95+ & model.VariablesForRelation {ComponentID : consumer1Key .ComponentID , ConfigID : consumer1Key .ID },
96+ & model.VariablesForRelation {ComponentID : consumer2Key .ComponentID , ConfigID : consumer2Key .ID },
97+ },
98+ },
99+ }
100+ require .NoError (t , state .Set (sharedVars ))
101+
102+ // Invoke
103+ changes := model .NewRemoteChanges ()
104+ changes .AddLoaded (consumer1 )
105+ changes .AddLoaded (consumer2 )
106+ changes .AddLoaded (sharedVars )
107+ require .NoError (t , state .Mapper ().AfterRemoteOperation (t .Context (), changes ))
108+ logger .AssertJSONMessages (t , `{"level":"debug","message":"Ignored config \"branch:1/component:keboola.variables/config:3\" shared by 2 consumers"}` )
109+
110+ // Shared variables config is removed; consumers remain
111+ assert .Equal (t , []model.ObjectState {consumer1 , consumer2 }, state .All ())
112+ }
113+
65114func TestIgnoreMapper_AfterRemoteOperation_Scheduler (t * testing.T ) {
66115 t .Parallel ()
67116 state , d := createStateWithMapper (t )
0 commit comments