@@ -79,6 +79,26 @@ func TestHandleRespSecrets(t *testing.T) {
7979 input : Map {"k" : Map {"type" : "password" , "value" : Map {"isSecretRef" : true , "id" : "unknown-secret" }}},
8080 want : Map {"k" : Map {"isSecretRef" : true , "id" : "unknown-secret" }},
8181 },
82+ {
83+ name : "converts list secret" ,
84+ input : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"known-secret" }}},
85+ want : Map {"k" : []any {"secret" }},
86+ },
87+ {
88+ name : "converts multiple list secrets" ,
89+ input : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"known-secret" , "known-secret" }}},
90+ want : Map {"k" : []any {"secret" , "secret" }},
91+ },
92+ {
93+ name : "converts mixed list secrets" ,
94+ input : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"known-secret" , "unknown-secret" }}},
95+ want : Map {"k" : []any {"secret" }},
96+ },
97+ {
98+ name : "converts wrapped list secret" ,
99+ input : Map {"k" : Map {"type" : "array" , "value" : Map {"isSecretRef" : true , "ids" : []any {"known-secret" }}}},
100+ want : Map {"k" : []any {"secret" }},
101+ },
82102 }
83103
84104 for _ , tt := range tests {
@@ -184,6 +204,30 @@ func TestHandleReqRespSecrets(t *testing.T) {
184204 respInput : Map {"k" : Map {"type" : "password" , "value" : Map {"isSecretRef" : true , "id" : "unknown-secret" }}},
185205 want : Map {"k" : Map {"isSecretRef" : true , "id" : "unknown-secret" }},
186206 },
207+ {
208+ name : "converts list secret" ,
209+ reqInput : Map {"k" : []any {"secret1" , "secret2" }},
210+ respInput : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"ref1" , "ref2" }}},
211+ want : Map {"k" : []any {"secret1" , "secret2" }},
212+ },
213+ {
214+ name : "converts wrapped list secret" ,
215+ reqInput : Map {"k" : []any {"secret1" , "secret2" }},
216+ respInput : Map {"k" : Map {"type" : "array" , "value" : Map {"isSecretRef" : true , "ids" : []any {"ref1" , "ref2" }}}},
217+ want : Map {"k" : []any {"secret1" , "secret2" }},
218+ },
219+ {
220+ name : "converts partial list secret" ,
221+ reqInput : Map {"k" : []any {"secret1" }},
222+ respInput : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"ref1" , "ref2" }}},
223+ want : Map {"k" : []any {"secret1" }},
224+ },
225+ {
226+ name : "converts empty list secret" ,
227+ reqInput : Map {"k" : []any {}},
228+ respInput : Map {"k" : Map {"isSecretRef" : true , "ids" : []any {"ref1" }}},
229+ want : Map {"k" : []any {}},
230+ },
187231 }
188232
189233 for _ , tt := range tests {
@@ -236,13 +280,209 @@ func TestHandleReqRespSecrets(t *testing.T) {
236280 want = * (* wants .Inputs ["input1" ].Streams )["stream1" ].Vars
237281 require .Equal (t , want , got )
238282
239- if v , ok := (* req .Vars )["k" ]; ok && v == "secret" {
283+ // Check private data expectations based on test case
284+ switch tt .name {
285+ case "converts secret" , "converts wrapped secret" :
240286 privateWants := privateData {"secrets" : `{"known-secret":"secret"}` }
241287 require .Equal (t , privateWants , private )
242- } else {
288+ case "converts list secret" , "converts wrapped list secret" :
289+ privateWants := privateData {"secrets" : `{"ref1":"secret1","ref2":"secret2"}` }
290+ require .Equal (t , privateWants , private )
291+ case "converts partial list secret" :
292+ privateWants := privateData {"secrets" : `{"ref1":"secret1"}` }
293+ require .Equal (t , privateWants , private )
294+ case "converts empty list secret" :
295+ privateWants := privateData {"secrets" : `{}` }
296+ require .Equal (t , privateWants , private )
297+ default :
243298 privateWants := privateData {"secrets" : `{}` }
244299 require .Equal (t , privateWants , private )
245300 }
246301 })
247302 }
248303}
304+
305+ func TestEdgeCases (t * testing.T ) {
306+ t .Parallel ()
307+
308+ ctx := context .Background ()
309+
310+ t .Run ("handles deeply nested secret references" , func (t * testing.T ) {
311+ private := privateData {"secrets" : `{"nested-ref":"nested-secret"}` }
312+
313+ resp := & kbapi.PackagePolicy {
314+ SecretReferences : & []kbapi.PackagePolicySecretRef {{Id : "nested-ref" }},
315+ Vars : & map [string ]any {
316+ "level1" : map [string ]any {
317+ "type" : "object" ,
318+ "value" : map [string ]any {
319+ "level2" : map [string ]any {
320+ "isSecretRef" : true ,
321+ "id" : "nested-ref" ,
322+ },
323+ },
324+ },
325+ },
326+ }
327+
328+ diags := integration_policy .HandleRespSecrets (ctx , resp , & private )
329+ require .Empty (t , diags )
330+
331+ expected := map [string ]any {
332+ "level1" : map [string ]any {
333+ "level2" : "nested-secret" ,
334+ },
335+ }
336+ require .Equal (t , expected , * resp .Vars )
337+ })
338+
339+ t .Run ("handles multiple input streams" , func (t * testing.T ) {
340+ private := privateData {"secrets" : `{"stream1-ref":"stream1-secret","stream2-ref":"stream2-secret"}` }
341+
342+ resp := & kbapi.PackagePolicy {
343+ SecretReferences : & []kbapi.PackagePolicySecretRef {
344+ {Id : "stream1-ref" }, {Id : "stream2-ref" },
345+ },
346+ Inputs : map [string ]kbapi.PackagePolicyInput {
347+ "input1" : {
348+ Streams : & map [string ]kbapi.PackagePolicyInputStream {
349+ "stream1" : {
350+ Vars : & map [string ]any {
351+ "secret1" : map [string ]any {"isSecretRef" : true , "id" : "stream1-ref" },
352+ },
353+ },
354+ "stream2" : {
355+ Vars : & map [string ]any {
356+ "secret2" : map [string ]any {"isSecretRef" : true , "id" : "stream2-ref" },
357+ },
358+ },
359+ },
360+ },
361+ },
362+ }
363+
364+ diags := integration_policy .HandleRespSecrets (ctx , resp , & private )
365+ require .Empty (t , diags )
366+
367+ streams := * resp .Inputs ["input1" ].Streams
368+ require .Equal (t , "stream1-secret" , (* streams ["stream1" ].Vars )["secret1" ])
369+ require .Equal (t , "stream2-secret" , (* streams ["stream2" ].Vars )["secret2" ])
370+ })
371+
372+ t .Run ("handles invalid JSON in private data" , func (t * testing.T ) {
373+ private := privateData {"secrets" : `{"invalid": json}` }
374+
375+ resp := & kbapi.PackagePolicy {
376+ SecretReferences : & []kbapi.PackagePolicySecretRef {},
377+ Vars : & map [string ]any {},
378+ }
379+
380+ diags := integration_policy .HandleRespSecrets (ctx , resp , & private )
381+ require .True (t , diags .HasError (), "Expected error diagnostics" )
382+ })
383+ }
384+
385+ func TestMigrationScenarios (t * testing.T ) {
386+ t .Parallel ()
387+
388+ // Test pre-0.11.7 migration scenarios mentioned in HandleReqRespSecrets
389+ ctx := context .Background ()
390+
391+ t .Run ("handles importing existing secret refs" , func (t * testing.T ) {
392+ // Simulate importing a resource that already has secret refs in request
393+ req := kbapi.PackagePolicyRequest {
394+ Vars : & map [string ]any {
395+ "existing_secret" : map [string ]any {
396+ "isSecretRef" : true ,
397+ "id" : "existing-ref" ,
398+ },
399+ },
400+ }
401+
402+ resp := & kbapi.PackagePolicy {
403+ SecretReferences : & []kbapi.PackagePolicySecretRef {{Id : "new-ref" }},
404+ Vars : & map [string ]any {
405+ "existing_secret" : map [string ]any {
406+ "isSecretRef" : true ,
407+ "id" : "new-ref" ,
408+ },
409+ },
410+ }
411+
412+ private := privateData {}
413+ diags := integration_policy .HandleReqRespSecrets (ctx , req , resp , & private )
414+ require .Empty (t , diags )
415+
416+ // Should preserve the original secret ref structure since original is also a secret ref
417+ expected := map [string ]any {
418+ "existing_secret" : map [string ]any {
419+ "isSecretRef" : true ,
420+ "id" : "existing-ref" ,
421+ },
422+ }
423+ require .Equal (t , expected , * resp .Vars )
424+ })
425+
426+ t .Run ("handles migration from plain text to secret ref" , func (t * testing.T ) {
427+ // Simulate migration where plain text becomes secret ref
428+ req := kbapi.PackagePolicyRequest {
429+ Vars : & map [string ]any {
430+ "password" : "plain-text-password" ,
431+ },
432+ }
433+
434+ resp := & kbapi.PackagePolicy {
435+ SecretReferences : & []kbapi.PackagePolicySecretRef {{Id : "password-ref" }},
436+ Vars : & map [string ]any {
437+ "password" : map [string ]any {
438+ "isSecretRef" : true ,
439+ "id" : "password-ref" ,
440+ },
441+ },
442+ }
443+
444+ private := privateData {}
445+ diags := integration_policy .HandleReqRespSecrets (ctx , req , resp , & private )
446+ require .Empty (t , diags )
447+
448+ // Should replace secret ref with original plain text
449+ expected := map [string ]any {"password" : "plain-text-password" }
450+ require .Equal (t , expected , * resp .Vars )
451+
452+ // Should save the mapping for future use
453+ expectedPrivate := `{"password-ref":"plain-text-password"}`
454+ require .Equal (t , expectedPrivate , private ["secrets" ])
455+ })
456+
457+ t .Run ("handles list migration scenarios" , func (t * testing.T ) {
458+ req := kbapi.PackagePolicyRequest {
459+ Vars : & map [string ]any {
460+ "hosts" : []any {"host1.example.com" , "host2.example.com" , "host3.example.com" },
461+ },
462+ }
463+
464+ resp := & kbapi.PackagePolicy {
465+ SecretReferences : & []kbapi.PackagePolicySecretRef {
466+ {Id : "host-ref-1" }, {Id : "host-ref-2" }, {Id : "host-ref-3" },
467+ },
468+ Vars : & map [string ]any {
469+ "hosts" : map [string ]any {
470+ "isSecretRef" : true ,
471+ "ids" : []any {"host-ref-1" , "host-ref-2" , "host-ref-3" },
472+ },
473+ },
474+ }
475+
476+ private := privateData {}
477+ diags := integration_policy .HandleReqRespSecrets (ctx , req , resp , & private )
478+ require .Empty (t , diags )
479+
480+ // Should replace list secret refs with original array
481+ expected := map [string ]any {"hosts" : []any {"host1.example.com" , "host2.example.com" , "host3.example.com" }}
482+ require .Equal (t , expected , * resp .Vars )
483+
484+ // Should save individual mappings
485+ expectedPrivate := `{"host-ref-1":"host1.example.com","host-ref-2":"host2.example.com","host-ref-3":"host3.example.com"}`
486+ require .Equal (t , expectedPrivate , private ["secrets" ])
487+ })
488+ }
0 commit comments