@@ -21,8 +21,10 @@ import (
2121 "testing"
2222 "time"
2323
24+ configapi "github.com/kptdev/porch/api/porchconfig/v1alpha1"
2425 "github.com/stretchr/testify/assert"
2526 "github.com/stretchr/testify/require"
27+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628 "sigs.k8s.io/controller-runtime/pkg/client"
2729 "sigs.k8s.io/controller-runtime/pkg/client/fake"
2830 "sigs.k8s.io/controller-runtime/pkg/healthz"
@@ -308,11 +310,20 @@ func TestValidateConfig(t *testing.T) {
308310 }
309311}
310312
313+ // fakeFieldIndexer is a minimal field.Indexer for testing that stores index functions but doesn't actually index.
314+ type fakeFieldIndexer struct {}
315+
316+ func (f * fakeFieldIndexer ) IndexField (ctx context.Context , obj client.Object , field string , fn client.IndexerFunc ) error {
317+ // No-op for testing - just accept the index function registration
318+ return nil
319+ }
320+
311321// fakeManager is a minimal manager.Manager for unit testing Init().
312- // Only GetClient(), GetAPIReader(), and GetWebhookServer () are implemented; all other methods will panic if called.
322+ // Only GetClient(), GetAPIReader(), GetWebhookServer(), and GetFieldIndexer () are implemented; all other methods will panic if called.
313323type fakeManager struct {
314324 manager.Manager
315- client client.Client
325+ client client.Client
326+ indexer * fakeFieldIndexer
316327}
317328
318329func (f * fakeManager ) GetClient () client.Client {
@@ -327,6 +338,10 @@ func (f *fakeManager) GetWebhookServer() webhook.Server {
327338 return & fakeWebhookServer {}
328339}
329340
341+ func (f * fakeManager ) GetFieldIndexer () client.FieldIndexer {
342+ return f .indexer
343+ }
344+
330345// fakeWebhookServer is a minimal webhook.Server for testing.
331346type fakeWebhookServer struct {}
332347
@@ -365,7 +380,10 @@ func TestInit(t *testing.T) {
365380 for _ , tt := range tests {
366381 t .Run (tt .name , func (t * testing.T ) {
367382 reconciler := & RepositoryReconciler {}
368- mgr := & fakeManager {client : fake .NewClientBuilder ().Build ()}
383+ mgr := & fakeManager {
384+ client : fake .NewClientBuilder ().Build (),
385+ indexer : & fakeFieldIndexer {},
386+ }
369387
370388 err := reconciler .Init (mgr )
371389
@@ -377,3 +395,153 @@ func TestInit(t *testing.T) {
377395 })
378396 }
379397}
398+
399+ // TestGitRepoIndexingFunction tests the git.repo index function used in Init
400+ func TestGitRepoIndexingFunction (t * testing.T ) {
401+ indexFunc := func (o client.Object ) []string {
402+ repository := o .(* configapi.Repository )
403+ if repository .Spec .Git == nil || repository .Spec .Git .Repo == "" {
404+ return nil
405+ }
406+ return []string {repository .Spec .Git .Repo }
407+ }
408+
409+ tests := []struct {
410+ name string
411+ repo * configapi.Repository
412+ expected []string
413+ }{
414+ {
415+ name : "git repository with valid URL" ,
416+ repo : & configapi.Repository {
417+ ObjectMeta : metav1.ObjectMeta {Name : "repo1" , Namespace : "default" },
418+ Spec : configapi.RepositorySpec {
419+ Git : & configapi.GitRepository {
420+ Repo : "http://gitea.local/org/repo.git" ,
421+ },
422+ },
423+ },
424+ expected : []string {"http://gitea.local/org/repo.git" },
425+ },
426+ {
427+ name : "OCI repository (nil Git)" ,
428+ repo : & configapi.Repository {
429+ ObjectMeta : metav1.ObjectMeta {Name : "repo-oci" , Namespace : "default" },
430+ Spec : configapi.RepositorySpec {
431+ Type : configapi .RepositoryTypeOCI ,
432+ },
433+ },
434+ expected : nil ,
435+ },
436+ {
437+ name : "git repository with empty URL" ,
438+ repo : & configapi.Repository {
439+ ObjectMeta : metav1.ObjectMeta {Name : "repo2" , Namespace : "default" },
440+ Spec : configapi.RepositorySpec {
441+ Git : & configapi.GitRepository {Repo : "" },
442+ },
443+ },
444+ expected : nil ,
445+ },
446+ {
447+ name : "repository with git spec but empty URL" ,
448+ repo : & configapi.Repository {
449+ ObjectMeta : metav1.ObjectMeta {Name : "repo3" , Namespace : "default" },
450+ Spec : configapi.RepositorySpec {
451+ Git : & configapi.GitRepository {
452+ Repo : "https://github.com/example/pkg.git" ,
453+ },
454+ },
455+ },
456+ expected : []string {"https://github.com/example/pkg.git" },
457+ },
458+ }
459+
460+ for _ , tc := range tests {
461+ t .Run (tc .name , func (t * testing.T ) {
462+ result := indexFunc (tc .repo )
463+ assert .Equal (t , tc .expected , result )
464+ })
465+ }
466+ }
467+
468+ // TestGitBranchIndexingFunction tests the git.branch index function used in Init
469+ func TestGitBranchIndexingFunction (t * testing.T ) {
470+ indexFunc := func (o client.Object ) []string {
471+ repository := o .(* configapi.Repository )
472+ if repository .Spec .Git == nil || repository .Spec .Git .Branch == "" {
473+ return nil
474+ }
475+ return []string {repository .Spec .Git .Branch }
476+ }
477+
478+ tests := []struct {
479+ name string
480+ repo * configapi.Repository
481+ expected []string
482+ }{
483+ {
484+ name : "repository with main branch" ,
485+ repo : & configapi.Repository {
486+ ObjectMeta : metav1.ObjectMeta {Name : "repo1" , Namespace : "default" },
487+ Spec : configapi.RepositorySpec {
488+ Git : & configapi.GitRepository {
489+ Branch : "main" ,
490+ },
491+ },
492+ },
493+ expected : []string {"main" },
494+ },
495+ {
496+ name : "repository with develop branch" ,
497+ repo : & configapi.Repository {
498+ ObjectMeta : metav1.ObjectMeta {Name : "repo2" , Namespace : "default" },
499+ Spec : configapi.RepositorySpec {
500+ Git : & configapi.GitRepository {
501+ Branch : "develop" ,
502+ },
503+ },
504+ },
505+ expected : []string {"develop" },
506+ },
507+ {
508+ name : "OCI repository (nil Git)" ,
509+ repo : & configapi.Repository {
510+ ObjectMeta : metav1.ObjectMeta {Name : "repo-oci" , Namespace : "default" },
511+ Spec : configapi.RepositorySpec {},
512+ },
513+ expected : nil ,
514+ },
515+ {
516+ name : "repository with release branch" ,
517+ repo : & configapi.Repository {
518+ ObjectMeta : metav1.ObjectMeta {Name : "repo3" , Namespace : "prod" },
519+ Spec : configapi.RepositorySpec {
520+ Git : & configapi.GitRepository {
521+ Branch : "release-v1.0" ,
522+ },
523+ },
524+ },
525+ expected : []string {"release-v1.0" },
526+ },
527+ {
528+ name : "repository with feature branch" ,
529+ repo : & configapi.Repository {
530+ ObjectMeta : metav1.ObjectMeta {Name : "repo4" , Namespace : "staging" },
531+ Spec : configapi.RepositorySpec {
532+ Git : & configapi.GitRepository {
533+ Branch : "feature/new-feature" ,
534+ },
535+ },
536+ },
537+ expected : []string {"feature/new-feature" },
538+ },
539+ }
540+
541+ for _ , tc := range tests {
542+ t .Run (tc .name , func (t * testing.T ) {
543+ result := indexFunc (tc .repo )
544+ assert .Equal (t , tc .expected , result )
545+ })
546+ }
547+ }
0 commit comments