github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/internal/commands/status_test.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	_ "embed"
     6  	"github.com/aws/aws-sdk-go/aws"
     7  	"github.com/aws/aws-sdk-go/service/iam"
     8  	"github.com/aws/aws-sdk-go/service/sts"
     9  	"github.com/golang/mock/gomock"
    10  	_ "github.com/golang/mock/mockgen/model"
    11  	"github.com/hazelops/ize/internal/config"
    12  	"github.com/hazelops/ize/pkg/mocks"
    13  	"github.com/pterm/pterm"
    14  	"github.com/spf13/pflag"
    15  	"github.com/spf13/viper"
    16  	"os"
    17  	"path/filepath"
    18  	"strings"
    19  	"testing"
    20  )
    21  
    22  //go:generate mockgen -package=mocks -destination ../../pkg/mocks/mock_aim.go github.com/aws/aws-sdk-go/service/iam/iamiface IAMAPI
    23  //go:generate mockgen -package=mocks -destination ../../pkg/mocks/mock_sts.go github.com/aws/aws-sdk-go/service/sts/stsiface STSAPI
    24  
    25  //go:embed testdata/status_valid.toml
    26  var statusToml string
    27  
    28  func TestStatus(t *testing.T) {
    29  	mockIAMClient := func(m *mocks.MockIAMAPI) {
    30  		m.EXPECT().ListUserTags(gomock.Any()).Return(&iam.ListUserTagsOutput{
    31  			IsTruncated: nil,
    32  			Marker:      nil,
    33  			Tags:        []*iam.Tag{{Key: aws.String("devEnvironmentName"), Value: aws.String("test")}},
    34  		}, nil).Times(1)
    35  		m.EXPECT().GetUser(gomock.Any()).Return(&iam.GetUserOutput{
    36  			User: &iam.User{
    37  				UserName: aws.String("test"),
    38  			},
    39  		}, nil).Times(1)
    40  	}
    41  	mockSTSClient := func(m *mocks.MockSTSAPI) {
    42  		m.EXPECT().GetCallerIdentity(gomock.Any()).Return(&sts.GetCallerIdentityOutput{
    43  			Account: aws.String("0"),
    44  		}, nil).Times(1)
    45  	}
    46  
    47  	pterm.DisableStyling()
    48  	tests := []struct {
    49  		name           string
    50  		args           []string
    51  		wantErr        bool
    52  		env            map[string]string
    53  		withConfigFile bool
    54  		contains       []string
    55  		mockIAMClient  func(m *mocks.MockIAMAPI)
    56  		mockSTSClient  func(m *mocks.MockSTSAPI)
    57  	}{
    58  		{
    59  			name:           "success (only config)",
    60  			args:           []string{"status"},
    61  			env:            map[string]string{"ENV": "test", "AWS_PROFILE": "test"},
    62  			withConfigFile: true,
    63  			wantErr:        false,
    64  			mockIAMClient:  mockIAMClient,
    65  			mockSTSClient:  mockSTSClient,
    66  			contains: []string{
    67  				"ENV            | test",
    68  				"NAMESPACE      | testnut",
    69  				"TAG            | test",
    70  				"TERRAFORM_VERSION | 1.2.6",
    71  				"AWS PROFILE | test",
    72  				"AWS USER    | test",
    73  				"AWS ACCOUNT | 0",
    74  				"AWS_DEV_ENV_NAME | test",
    75  			},
    76  		},
    77  		{
    78  			name:           "success (config and flags)",
    79  			args:           []string{"-e=test", "-r=us-east-1", "-p=test", "-n=test", "--terraform-version=1.1.3", "status"},
    80  			withConfigFile: true,
    81  			wantErr:        false,
    82  			mockIAMClient:  mockIAMClient,
    83  			mockSTSClient:  mockSTSClient,
    84  			contains: []string{
    85  				"ENV            | test",
    86  				"NAMESPACE      | test",
    87  				"TAG            | test",
    88  				"TERRAFORM_VERSION | 1.1.3",
    89  				"AWS PROFILE | test",
    90  				"AWS USER    | test",
    91  				"AWS ACCOUNT | 0",
    92  				"AWS_DEV_ENV_NAME | test",
    93  			},
    94  		},
    95  		{
    96  			name:           "success (config and env and flags)",
    97  			args:           []string{"-p=testnut", "-r=us-east-1", "--terraform-version=1.1.5", "status"},
    98  			env:            map[string]string{"IZE_TERRAFORM_VERSION": "1.1.7", "ENV": "test", "AWS_PROFILE": "test"},
    99  			withConfigFile: true,
   100  			wantErr:        false,
   101  			mockIAMClient:  mockIAMClient,
   102  			mockSTSClient:  mockSTSClient,
   103  			contains: []string{
   104  				"ENV            | test",
   105  				"NAMESPACE      | test",
   106  				"TAG            | test",
   107  				"TERRAFORM_VERSION | 1.1.5",
   108  				"AWS PROFILE | testnut",
   109  				"AWS USER    | test",
   110  				"AWS ACCOUNT | 0",
   111  				"AWS_DEV_ENV_NAME | test",
   112  			},
   113  		},
   114  		{
   115  			name:          "success (env and flags)",
   116  			args:          []string{"--namespace", "test", "-r=us-west-2", "--terraform-version=1.1.7", "status"},
   117  			env:           map[string]string{"IZE_TERRAFORM_VERSION": "1.1.3", "ENV": "test", "AWS_PROFILE": "test"},
   118  			wantErr:       false,
   119  			mockIAMClient: mockIAMClient,
   120  			mockSTSClient: mockSTSClient,
   121  			contains: []string{
   122  				"ENV            | test",
   123  				"NAMESPACE      | test",
   124  				"TAG            | test",
   125  				"TERRAFORM_VERSION | 1.1.7",
   126  				"AWS PROFILE | test",
   127  				"AWS USER    | test",
   128  				"AWS ACCOUNT | 0",
   129  				"AWS_DEV_ENV_NAME | test",
   130  			},
   131  		},
   132  		{
   133  			name:          "success (flags)",
   134  			args:          []string{"-e=test", "-r=us-east-1", "-p=test", "-n=testnut", "--terraform-version=1.1.7", "status"},
   135  			wantErr:       false,
   136  			mockIAMClient: mockIAMClient,
   137  			mockSTSClient: mockSTSClient,
   138  			contains: []string{
   139  				"ENV            | test",
   140  				"NAMESPACE      | testnut",
   141  				"TAG            | test",
   142  				"TERRAFORM_VERSION | 1.1.7",
   143  				"AWS PROFILE | test",
   144  				"AWS USER    | test",
   145  				"AWS ACCOUNT | 0",
   146  				"AWS_DEV_ENV_NAME | test",
   147  			},
   148  		},
   149  		{
   150  			name:          "success (env)",
   151  			wantErr:       false,
   152  			args:          []string{"status"},
   153  			env:           map[string]string{"IZE_TERRAFORM_VERSION": "1.1.5", "ENV": "test", "AWS_PROFILE": "test", "AWS_REGION": "us-east-1", "NAMESPACE": "dev-test"},
   154  			mockIAMClient: mockIAMClient,
   155  			mockSTSClient: mockSTSClient,
   156  			contains: []string{
   157  				"ENV            | test",
   158  				"NAMESPACE      | dev-test",
   159  				"TAG            | test",
   160  				"TERRAFORM_VERSION | 1.1.5",
   161  				"AWS PROFILE | test",
   162  				"AWS USER    | test",
   163  				"AWS ACCOUNT | 0",
   164  				"AWS_DEV_ENV_NAME | test",
   165  			},
   166  		},
   167  	}
   168  	for _, tt := range tests {
   169  		t.Run(tt.name, func(t *testing.T) {
   170  			defer resetEnv(os.Environ())
   171  			viper.Reset()
   172  			os.Unsetenv("IZE_CONFIG_FILE")
   173  			// Set env
   174  			for k, v := range tt.env {
   175  				t.Setenv(k, v)
   176  			}
   177  
   178  			temp, err := os.MkdirTemp("", "test")
   179  			if err != nil {
   180  				t.Error(err)
   181  				return
   182  			}
   183  			err = os.Chdir(temp)
   184  			if err != nil {
   185  				t.Error(err)
   186  				return
   187  			}
   188  
   189  			err = os.MkdirAll(filepath.Join(temp, ".ize", "env", "test"), 0777)
   190  			if err != nil {
   191  				t.Error(err)
   192  				return
   193  			}
   194  
   195  			if tt.withConfigFile {
   196  				setConfigFile(filepath.Join(temp, "ize.toml"), terraformToml, t)
   197  			}
   198  			t.Setenv("HOME", temp)
   199  
   200  			ctrl := gomock.NewController(t)
   201  			defer ctrl.Finish()
   202  
   203  			mockIAMAPI := mocks.NewMockIAMAPI(ctrl)
   204  			tt.mockIAMClient(mockIAMAPI)
   205  
   206  			mockSTSAPI := mocks.NewMockSTSAPI(ctrl)
   207  			tt.mockSTSClient(mockSTSAPI)
   208  
   209  			cfg := new(config.Project)
   210  			cmd := newRootCmd(cfg)
   211  
   212  			cmd.SetArgs(tt.args)
   213  			buf := new(bytes.Buffer)
   214  			pterm.SetDefaultOutput(buf)
   215  			cmd.SetOut(buf)
   216  			cmd.SetErr(buf)
   217  			cmd.PersistentFlags().ParseErrorsWhitelist.UnknownFlags = true
   218  			err = cmd.PersistentFlags().Parse(tt.args)
   219  			if err != nil {
   220  				t.Error(err)
   221  				return
   222  			}
   223  
   224  			cmd.PersistentFlags().VisitAll(func(f *pflag.Flag) {
   225  				if len(f.Value.String()) != 0 {
   226  					_ = viper.BindPFlag(strings.ReplaceAll(f.Name, "-", "_"), cmd.PersistentFlags().Lookup(f.Name))
   227  				}
   228  			})
   229  
   230  			config.InitConfig()
   231  
   232  			err = cfg.GetTestConfig()
   233  			if err != nil {
   234  				t.Errorf("get config error = %v, wantErr %v", err, tt.wantErr)
   235  				os.Exit(1)
   236  			}
   237  
   238  			cfg.AWSClient = config.NewAWSClient(
   239  				config.WithIAMClient(mockIAMAPI),
   240  				config.WithSTSClient(mockSTSAPI),
   241  			)
   242  
   243  			cfg.Session = getSession(false)
   244  			err = cmd.Execute()
   245  			if (err != nil) != tt.wantErr {
   246  				t.Errorf("ize terraform error = %v, wantErr %v", err, tt.wantErr)
   247  				return
   248  			}
   249  
   250  			for _, contain := range tt.contains {
   251  				if !strings.Contains(buf.String(), contain) {
   252  					t.Errorf("output = %v, want %v", buf.String(), contain)
   253  					return
   254  				}
   255  			}
   256  
   257  			// Unset env
   258  			for k, _ := range tt.env {
   259  				os.Unsetenv(k)
   260  			}
   261  		})
   262  	}
   263  }