@@ -267,3 +267,148 @@ func Test_BundleValidatorCallsAllValidationFnsInOrder(t *testing.T) {
267267 require .NoError (t , val .Validate (nil ))
268268 require .Equal (t , "hi" , actual )
269269}
270+
271+ func Test_WithBundleConfig (t * testing.T ) {
272+ config := & render.BundleConfig {
273+ WatchNamespace : "test-namespace" ,
274+ }
275+ opts := & render.Options {}
276+ render .WithBundleConfig (config )(opts )
277+ require .Equal (t , config , opts .BundleConfig )
278+ }
279+
280+ func Test_BundleRenderer_ValidatesBundleConfig (t * testing.T ) {
281+ for _ , tc := range []struct {
282+ name string
283+ installModes []v1alpha1.InstallModeType
284+ config * render.BundleConfig
285+ expectedErr string
286+ }{
287+ {
288+ name : "AllNamespaces only - rejects watchNamespace" ,
289+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeAllNamespaces },
290+ config : & render.BundleConfig {
291+ WatchNamespace : "test-namespace" ,
292+ },
293+ expectedErr : "watchNamespace configuration parameter is not supported for bundles that only support AllNamespaces install mode" ,
294+ },
295+ {
296+ name : "AllNamespaces only - accepts empty watchNamespace" ,
297+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeAllNamespaces },
298+ config : & render.BundleConfig {
299+ WatchNamespace : "" ,
300+ },
301+ expectedErr : "" ,
302+ },
303+ {
304+ name : "AllNamespaces and SingleNamespace - accepts any watchNamespace" ,
305+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeAllNamespaces , v1alpha1 .InstallModeTypeSingleNamespace },
306+ config : & render.BundleConfig {
307+ WatchNamespace : "test-namespace" ,
308+ },
309+ expectedErr : "" ,
310+ },
311+ {
312+ name : "AllNamespaces and OwnNamespace - accepts matching watchNamespace" ,
313+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeAllNamespaces , v1alpha1 .InstallModeTypeOwnNamespace },
314+ config : & render.BundleConfig {
315+ WatchNamespace : "install-namespace" ,
316+ },
317+ expectedErr : "" ,
318+ },
319+ {
320+ name : "AllNamespaces and OwnNamespace - rejects non-matching watchNamespace" ,
321+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeAllNamespaces , v1alpha1 .InstallModeTypeOwnNamespace },
322+ config : & render.BundleConfig {
323+ WatchNamespace : "different-namespace" ,
324+ },
325+ expectedErr : "watchNamespace must equal install namespace (install-namespace) when set for bundles supporting AllNamespaces and OwnNamespace install modes" ,
326+ },
327+ {
328+ name : "SingleNamespace only - requires watchNamespace" ,
329+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeSingleNamespace },
330+ config : & render.BundleConfig {
331+ WatchNamespace : "" ,
332+ },
333+ expectedErr : "watchNamespace configuration parameter is required for bundles that only support SingleNamespace install mode" ,
334+ },
335+ {
336+ name : "SingleNamespace only - accepts watchNamespace" ,
337+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeSingleNamespace },
338+ config : & render.BundleConfig {
339+ WatchNamespace : "test-namespace" ,
340+ },
341+ expectedErr : "" ,
342+ },
343+ {
344+ name : "SingleNamespace and OwnNamespace - requires watchNamespace" ,
345+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeSingleNamespace , v1alpha1 .InstallModeTypeOwnNamespace },
346+ config : & render.BundleConfig {
347+ WatchNamespace : "" ,
348+ },
349+ expectedErr : "watchNamespace configuration parameter is required for bundles supporting SingleNamespace and OwnNamespace install modes" ,
350+ },
351+ {
352+ name : "OwnNamespace only - rejects watchNamespace" ,
353+ installModes : []v1alpha1.InstallModeType {v1alpha1 .InstallModeTypeOwnNamespace },
354+ config : & render.BundleConfig {
355+ WatchNamespace : "test-namespace" ,
356+ },
357+ expectedErr : "watchNamespace configuration parameter is not supported for bundles that only support OwnNamespace install mode" ,
358+ },
359+ {
360+ name : "No install modes - invalid bundle" ,
361+ installModes : []v1alpha1.InstallModeType {},
362+ config : & render.BundleConfig {
363+ WatchNamespace : "test-namespace" ,
364+ },
365+ expectedErr : "invalid bundle: no supported install modes" ,
366+ },
367+ } {
368+ t .Run (tc .name , func (t * testing.T ) {
369+ renderer := render.BundleRenderer {}
370+ _ , err := renderer .Render (
371+ bundle.RegistryV1 {
372+ CSV : MakeCSV (WithInstallModeSupportFor (tc .installModes ... )),
373+ },
374+ "install-namespace" ,
375+ render .WithBundleConfig (tc .config ),
376+ )
377+
378+ if tc .expectedErr == "" {
379+ require .NoError (t , err )
380+ } else {
381+ require .Error (t , err )
382+ require .Contains (t , err .Error (), tc .expectedErr )
383+ }
384+ })
385+ }
386+ }
387+
388+ func Test_BundleRenderer_DerivesTargetNamespacesFromConfig (t * testing.T ) {
389+ expectedWatchNamespace := "test-watch-namespace"
390+
391+ renderer := render.BundleRenderer {
392+ ResourceGenerators : []render.ResourceGenerator {
393+ func (rv1 * bundle.RegistryV1 , opts render.Options ) ([]client.Object , error ) {
394+ // Verify that target namespaces are derived from bundle config
395+ require .Equal (t , []string {expectedWatchNamespace }, opts .TargetNamespaces )
396+ return nil , nil
397+ },
398+ },
399+ }
400+
401+ config := & render.BundleConfig {
402+ WatchNamespace : expectedWatchNamespace ,
403+ }
404+
405+ _ , err := renderer .Render (
406+ bundle.RegistryV1 {
407+ CSV : MakeCSV (WithInstallModeSupportFor (v1alpha1 .InstallModeTypeSingleNamespace )),
408+ },
409+ "install-namespace" ,
410+ render .WithBundleConfig (config ),
411+ )
412+
413+ require .NoError (t , err )
414+ }
0 commit comments