github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/promote/promote_test.go (about)

     1  // +build unit
     2  
     3  package promote_test
     4  
     5  import (
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/olli-ai/jx/v2/pkg/tests"
    10  
    11  	v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1"
    12  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    13  	"github.com/olli-ai/jx/v2/pkg/cmd/promote"
    14  	"github.com/olli-ai/jx/v2/pkg/gits"
    15  	"github.com/stretchr/testify/assert"
    16  
    17  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    18  )
    19  
    20  func fakeSearchForChart(f string) (string, error) {
    21  	return "mySearchedApp", nil
    22  }
    23  
    24  func fakeDiscoverAppName() (string, error) {
    25  	return "myDiscoveredApp", nil
    26  }
    27  
    28  func TestEnsureApplicationNameIsDefinedWithoutApplicationFlagWithArgs(t *testing.T) {
    29  	promoteOptions := &promote.PromoteOptions{
    30  		Environment: "production", // --env production
    31  	}
    32  
    33  	commonOpts := &opts.CommonOptions{}
    34  	promoteOptions.CommonOptions = commonOpts // Factory and other mocks initialized by cmd.ConfigureTestOptionsWithResources
    35  	commonOpts.Args = []string{"myArgumentApp"}
    36  
    37  	err := promoteOptions.EnsureApplicationNameIsDefined(fakeSearchForChart, fakeDiscoverAppName)
    38  	assert.NoError(t, err)
    39  
    40  	assert.Equal(t, "myArgumentApp", promoteOptions.Application)
    41  }
    42  
    43  func TestEnsureApplicationNameIsDefinedWithoutApplicationFlagWithFilterFlag(t *testing.T) {
    44  	promoteOptions := &promote.PromoteOptions{
    45  		Environment: "production", // --env production
    46  		Filter:      "something",
    47  	}
    48  
    49  	commonOpts := &opts.CommonOptions{}
    50  	promoteOptions.CommonOptions = commonOpts // Factory and other mocks initialized by cmd.ConfigureTestOptionsWithResources
    51  
    52  	err := promoteOptions.EnsureApplicationNameIsDefined(fakeSearchForChart, fakeDiscoverAppName)
    53  	assert.NoError(t, err)
    54  
    55  	assert.Equal(t, "mySearchedApp", promoteOptions.Application)
    56  }
    57  
    58  func TestEnsureApplicationNameIsDefinedWithoutApplicationFlagWithBatchFlag(t *testing.T) {
    59  	promoteOptions := &promote.PromoteOptions{
    60  		Environment: "production", // --env production
    61  	}
    62  
    63  	commonOpts := &opts.CommonOptions{}
    64  	promoteOptions.CommonOptions = commonOpts // Factory and other mocks initialized by cmd.ConfigureTestOptionsWithResources
    65  	promoteOptions.BatchMode = true           // --batch-mode
    66  
    67  	err := promoteOptions.EnsureApplicationNameIsDefined(fakeSearchForChart, fakeDiscoverAppName)
    68  	assert.NoError(t, err)
    69  
    70  	assert.Equal(t, "myDiscoveredApp", promoteOptions.Application)
    71  }
    72  
    73  func TestEnsureApplicationNameIsDefinedWithoutApplicationFlag(t *testing.T) {
    74  	tests.SkipForWindows(t, "go-expect does not work on windows")
    75  
    76  	console := tests.NewTerminal(t, nil)
    77  	defer console.Cleanup()
    78  
    79  	promoteOptions := &promote.PromoteOptions{
    80  		Environment: "production", // --env production
    81  	}
    82  
    83  	commonOpts := &opts.CommonOptions{}
    84  	promoteOptions.CommonOptions = commonOpts // Factory and other mocks initialized by cmd.ConfigureTestOptionsWithResources
    85  	promoteOptions.Out = console.Out
    86  	promoteOptions.In = console.In
    87  
    88  	donec := make(chan struct{})
    89  	go func() {
    90  		defer close(donec)
    91  		// Test boolean type
    92  		console.ExpectString("Are you sure you want to promote the application named: myDiscoveredApp?")
    93  		console.SendLine("Y")
    94  		console.ExpectEOF()
    95  	}()
    96  
    97  	err := promoteOptions.EnsureApplicationNameIsDefined(fakeSearchForChart, fakeDiscoverAppName)
    98  
    99  	console.Close()
   100  	<-donec
   101  
   102  	assert.NoError(t, err)
   103  	assert.Equal(t, "myDiscoveredApp", promoteOptions.Application)
   104  }
   105  
   106  func TestEnsureApplicationNameIsDefinedWithoutApplicationFlagUserSaysNo(t *testing.T) {
   107  	tests.SkipForWindows(t, "go-expect does not work on windows")
   108  
   109  	console := tests.NewTerminal(t, nil)
   110  	defer console.Cleanup()
   111  
   112  	promoteOptions := &promote.PromoteOptions{
   113  		Environment: "production", // --env production
   114  	}
   115  
   116  	commonOpts := &opts.CommonOptions{}
   117  	promoteOptions.CommonOptions = commonOpts // Factory and other mocks initialized by cmd.ConfigureTestOptionsWithResources
   118  	promoteOptions.Out = console.Out
   119  	promoteOptions.In = console.In
   120  
   121  	donec := make(chan struct{})
   122  	go func() {
   123  		defer close(donec)
   124  		// Test boolean type
   125  		console.ExpectString("Are you sure you want to promote the application named: myDiscoveredApp?")
   126  		console.SendLine("N")
   127  		console.ExpectEOF()
   128  	}()
   129  
   130  	err := promoteOptions.EnsureApplicationNameIsDefined(fakeSearchForChart, fakeDiscoverAppName)
   131  
   132  	console.Close()
   133  	<-donec
   134  
   135  	assert.Error(t, err)
   136  	assert.Equal(t, "", promoteOptions.Application)
   137  }
   138  
   139  func TestGetEnvChartValues(t *testing.T) {
   140  	tests := []struct {
   141  		ns           string
   142  		env          v1.Environment
   143  		values       []string
   144  		valueStrings []string
   145  	}{{
   146  		"jx-test-preview-pr-6",
   147  		v1.Environment{
   148  			ObjectMeta: metav1.ObjectMeta{
   149  				Name: "test-preview",
   150  			},
   151  			Spec: v1.EnvironmentSpec{
   152  				Namespace:         "jx-test-preview-pr-6",
   153  				Label:             "Test preview",
   154  				Kind:              v1.EnvironmentKindTypePreview,
   155  				PromotionStrategy: v1.PromotionStrategyTypeAutomatic,
   156  				PullRequestURL:    "https://github.com/my-project/my-app/pull/6",
   157  				Order:             999,
   158  				Source: v1.EnvironmentRepository{
   159  					Kind: v1.EnvironmentRepositoryTypeGit,
   160  					URL:  "https://github.com/my-project/my-app",
   161  					Ref:  "my-branch",
   162  				},
   163  				PreviewGitSpec: v1.PreviewGitSpec{
   164  					ApplicationName: "my-app",
   165  					Name:            "6",
   166  					URL:             "https://github.com/my-project/my-app/pull/6",
   167  				},
   168  			},
   169  		},
   170  		[]string{
   171  			"tags.jx-preview=true",
   172  			"tags.jx-env-test-preview=true",
   173  			"tags.jx-ns-jx-test-preview-pr-6=true",
   174  			"global.jxPreview=true",
   175  			"global.jxEnvTestPreview=true",
   176  			"global.jxNsJxTestPreviewPr6=true",
   177  		},
   178  		[]string{
   179  			"global.jxTypeEnv=preview",
   180  			"global.jxEnv=test-preview",
   181  			"global.jxNs=jx-test-preview-pr-6",
   182  			"global.jxPreviewApp=my-app",
   183  			"global.jxPreviewPr=6",
   184  		},
   185  	}, {
   186  		"jx-custom-env",
   187  		v1.Environment{
   188  			ObjectMeta: metav1.ObjectMeta{
   189  				Name: "custom-env",
   190  			},
   191  			Spec: v1.EnvironmentSpec{
   192  				Namespace:         "jx-custom-env",
   193  				Label:             "Custom environment",
   194  				Kind:              v1.EnvironmentKindTypePermanent,
   195  				PromotionStrategy: v1.PromotionStrategyTypeManual,
   196  				Order:             5,
   197  				Source: v1.EnvironmentRepository{
   198  					Kind: v1.EnvironmentRepositoryTypeGit,
   199  					URL:  "https://github.com/my-project/jx-environment-custom-env",
   200  					Ref:  "master",
   201  				},
   202  			},
   203  		},
   204  		[]string{
   205  			"tags.jx-permanent=true",
   206  			"tags.jx-env-custom-env=true",
   207  			"tags.jx-ns-jx-custom-env=true",
   208  			"global.jxPermanent=true",
   209  			"global.jxEnvCustomEnv=true",
   210  			"global.jxNsJxCustomEnv=true",
   211  		},
   212  		[]string{
   213  			"global.jxTypeEnv=permanent",
   214  			"global.jxEnv=custom-env",
   215  			"global.jxNs=jx-custom-env",
   216  		},
   217  	}, {
   218  		"ns-rand",
   219  		v1.Environment{
   220  			ObjectMeta: metav1.ObjectMeta{
   221  				Name: "random-env",
   222  			},
   223  			Spec: v1.EnvironmentSpec{
   224  				Namespace:         "ns-other",
   225  				Label:             "Random environment",
   226  				Kind:              v1.EnvironmentKindTypeEdit,
   227  				PromotionStrategy: v1.PromotionStrategyTypeNever,
   228  				Order:             666,
   229  				Source: v1.EnvironmentRepository{
   230  					Kind: v1.EnvironmentRepositoryTypeGit,
   231  					URL:  "https://github.com/my-project/random",
   232  					Ref:  "master",
   233  				},
   234  				PreviewGitSpec: v1.PreviewGitSpec{
   235  					ApplicationName: "random",
   236  					Name:            "2",
   237  					URL:             "https://github.com/my-project/random/pull/6",
   238  				},
   239  			},
   240  		},
   241  		[]string{
   242  			"tags.jx-edit=true",
   243  			"tags.jx-env-random-env=true",
   244  			"tags.jx-ns-ns-rand=true",
   245  			"global.jxEdit=true",
   246  			"global.jxEnvRandomEnv=true",
   247  			"global.jxNsNsRand=true",
   248  		},
   249  		[]string{
   250  			"global.jxTypeEnv=edit",
   251  			"global.jxEnv=random-env",
   252  			"global.jxNs=ns-rand",
   253  		},
   254  	}}
   255  
   256  	for _, test := range tests {
   257  		promoteOptions := &promote.PromoteOptions{}
   258  		values, valueStrings := promoteOptions.GetEnvChartValues(test.ns, &test.env)
   259  		sort.Strings(values)
   260  		sort.Strings(test.values)
   261  		assert.Equal(t, values, test.values)
   262  		sort.Strings(valueStrings)
   263  		sort.Strings(test.valueStrings)
   264  		assert.Equal(t, valueStrings, test.valueStrings)
   265  	}
   266  }
   267  
   268  // Contains all useful data from the test environment initialized by `prepareInitialPromotionEnv`
   269  type TestEnv struct {
   270  	Activity        *v1.PipelineActivity
   271  	CommonOptions   *opts.CommonOptions
   272  	FakeGitProvider *gits.FakeProvider
   273  	DevRepo         *gits.FakeRepository
   274  	StagingRepo     *gits.FakeRepository
   275  	ProdRepo        *gits.FakeRepository
   276  }