diff --git a/pkg/odo/cli/application/delete_test.go b/pkg/odo/cli/application/delete_test.go index cc871aa39d6..4c2360e3dd1 100644 --- a/pkg/odo/cli/application/delete_test.go +++ b/pkg/odo/cli/application/delete_test.go @@ -163,6 +163,7 @@ func TestDelete(t *testing.T) { err := opts.Complete("delete", cmdline, tt.args) if err != nil { + t.Errorf("Expected nil error, got %s", err) return } if opts.appName != tt.wantAppName { diff --git a/pkg/odo/cli/project/create_test.go b/pkg/odo/cli/project/create_test.go new file mode 100644 index 00000000000..c4268a71fcd --- /dev/null +++ b/pkg/odo/cli/project/create_test.go @@ -0,0 +1,119 @@ +package project + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/golang/mock/gomock" + + "github.com/redhat-developer/odo/pkg/envinfo" + "github.com/redhat-developer/odo/pkg/kclient" + "github.com/redhat-developer/odo/pkg/odo/cmdline" + "github.com/redhat-developer/odo/pkg/project" + "github.com/redhat-developer/odo/pkg/testingutil/filesystem" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestCreate(t *testing.T) { + + prefixDir, err := os.MkdirTemp(os.TempDir(), "unittests-") + if err != nil { + t.Errorf("Error creating temp directory for tests") + return + } + workingDir := filepath.Join(prefixDir, "myapp") + + tests := []struct { + name string + populateWorkingDir func(fs filesystem.Filesystem) + args []string + // existingApps []string + wantProjectName string + //wantErrValidate string + }{ + { + name: "project from args", + populateWorkingDir: func(fs filesystem.Filesystem) { + _ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755) + env, er := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp")) + if er != nil { + return + } + _ = env.SetComponentSettings(envinfo.ComponentSettings{ + Name: "a-name", + Project: "a-project", + AppName: "an-app-name", + }) + }, + args: []string{"project-name-to-create"}, + wantProjectName: "project-name-to-create", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // the first one is to cleanup the directory before execution (in case there are remaining files from a previous execution) + os.RemoveAll(prefixDir) + // the second one to cleanup after execution + defer os.RemoveAll(prefixDir) + + // Fake Cobra + ctrl := gomock.NewController(t) + defer ctrl.Finish() + cmdline := cmdline.NewMockCmdline(ctrl) + cmdline.EXPECT().GetWorkingDirectory().Return(workingDir, nil).AnyTimes() + cmdline.EXPECT().FlagValueIfSet("project").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("app").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("component").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("o").Return("").AnyTimes() + cmdline.EXPECT().CheckIfConfigurationNeeded().Return(false, nil).AnyTimes() + cmdline.EXPECT().Context().Return(context.Background()).AnyTimes() + + // Fake odo Kube client + kclient := kclient.NewMockClientInterface(ctrl) + cmdline.EXPECT().GetKubeClient().Return(kclient, nil).AnyTimes() + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "a-project", + }, + } + kclient.EXPECT().GetNamespaceNormal("a-project").Return(ns, nil).AnyTimes() + kclient.EXPECT().SetNamespace("a-project").AnyTimes() + + tt.populateWorkingDir(filesystem.DefaultFs{}) + + /* Mocks for Complete */ + prjClient := project.NewMockClient(ctrl) + opts := NewProjectCreateOptions(prjClient) + + /* COMPLETE */ + err = opts.Complete("create", cmdline, tt.args) + + if err != nil { + t.Errorf("Expected nil error, got %s", err) + return + } + if opts.projectName != tt.wantProjectName { + t.Errorf("Got appName %q, expected %q", opts.projectName, tt.wantProjectName) + } + + /* VALIDATE */ + err = opts.Validate() + if err != nil { + return + } + + /* Mocks for Run */ + prjClient.EXPECT().Create(tt.wantProjectName, false).Times(1) + prjClient.EXPECT().SetCurrent(tt.wantProjectName).Times(1) + + /* RUN */ + err = opts.Run() + }) + } +} diff --git a/pkg/odo/cli/project/delete_test.go b/pkg/odo/cli/project/delete_test.go new file mode 100644 index 00000000000..c51559fcd29 --- /dev/null +++ b/pkg/odo/cli/project/delete_test.go @@ -0,0 +1,155 @@ +package project + +import ( + "context" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/golang/mock/gomock" + + "github.com/redhat-developer/odo/pkg/envinfo" + "github.com/redhat-developer/odo/pkg/kclient" + "github.com/redhat-developer/odo/pkg/odo/cmdline" + "github.com/redhat-developer/odo/pkg/project" + "github.com/redhat-developer/odo/pkg/testingutil/filesystem" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestDelete(t *testing.T) { + + prefixDir, err := os.MkdirTemp(os.TempDir(), "unittests-") + if err != nil { + t.Errorf("Error creating temp directory for tests") + return + } + workingDir := filepath.Join(prefixDir, "myapp") + + tests := []struct { + name string + populateWorkingDir func(fs filesystem.Filesystem) + args []string + projectExists bool + wantProjectName string + wantErrValidate string + }{ + { + name: "project from args", + populateWorkingDir: func(fs filesystem.Filesystem) { + _ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755) + env, er := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp")) + if er != nil { + return + } + _ = env.SetComponentSettings(envinfo.ComponentSettings{ + Name: "a-name", + Project: "a-project", + AppName: "an-app-name", + }) + }, + args: []string{"project-name-to-delete"}, + projectExists: true, + wantProjectName: "project-name-to-delete", + }, { + name: "project from args not existing", + populateWorkingDir: func(fs filesystem.Filesystem) { + _ = fs.MkdirAll(filepath.Join(prefixDir, "myapp", ".odo", "env"), 0755) + env, er := envinfo.NewEnvSpecificInfo(filepath.Join(prefixDir, "myapp")) + if er != nil { + return + } + _ = env.SetComponentSettings(envinfo.ComponentSettings{ + Name: "a-name", + Project: "a-project", + AppName: "an-app-name", + }) + }, + args: []string{"project-name-to-delete"}, + projectExists: false, + wantProjectName: "project-name-to-delete", + wantErrValidate: `The project "project-name-to-delete" does not exist`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // the first one is to cleanup the directory before execution (in case there are remaining files from a previous execution) + os.RemoveAll(prefixDir) + // the second one to cleanup after execution + defer os.RemoveAll(prefixDir) + + // Fake Cobra + ctrl := gomock.NewController(t) + defer ctrl.Finish() + cmdline := cmdline.NewMockCmdline(ctrl) + cmdline.EXPECT().GetWorkingDirectory().Return(workingDir, nil).AnyTimes() + cmdline.EXPECT().FlagValueIfSet("project").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("app").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("component").Return("").AnyTimes() + cmdline.EXPECT().FlagValueIfSet("o").Return("").AnyTimes() + cmdline.EXPECT().CheckIfConfigurationNeeded().Return(false, nil).AnyTimes() + cmdline.EXPECT().Context().Return(context.Background()).AnyTimes() + + // Fake odo Kube client + kclient := kclient.NewMockClientInterface(ctrl) + cmdline.EXPECT().GetKubeClient().Return(kclient, nil).AnyTimes() + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "a-project", + }, + } + kclient.EXPECT().GetNamespaceNormal("a-project").Return(ns, nil).AnyTimes() + kclient.EXPECT().SetNamespace("a-project").AnyTimes() + + tt.populateWorkingDir(filesystem.DefaultFs{}) + + /* Mocks for Complete */ + prjClient := project.NewMockClient(ctrl) + opts := NewProjectDeleteOptions(prjClient) + opts.forceFlag = true + + /* COMPLETE */ + err = opts.Complete("delete", cmdline, tt.args) + + if err != nil { + t.Errorf("Expected nil error, got %s", err) + return + } + if opts.projectName != tt.wantProjectName { + t.Errorf("Got appName %q, expected %q", opts.projectName, tt.wantProjectName) + } + + /* Mocks for Validate */ + prjClient.EXPECT().Exists(tt.wantProjectName).Return(tt.projectExists, nil).Times(1) + + /* VALIDATE */ + err = opts.Validate() + + if err == nil && tt.wantErrValidate != "" { + t.Errorf("Expected %v, got no error", tt.wantErrValidate) + return + } + if err != nil && tt.wantErrValidate == "" { + t.Errorf("Expected no error, got %v", err.Error()) + return + } + if err != nil && tt.wantErrValidate != "" && !strings.Contains(err.Error(), tt.wantErrValidate) { + t.Errorf("Expected error %v, got %v", tt.wantErrValidate, err.Error()) + return + } + if err != nil { + return + } + /* Mocks for Run */ + prjClient.EXPECT().SetCurrent(tt.wantProjectName).Times(1) + prjClient.EXPECT().Delete(tt.wantProjectName, false).Times(1) + + /* RUN */ + err = opts.Run() + }) + } +} diff --git a/pkg/project/mock.go b/pkg/project/mock.go new file mode 100644 index 00000000000..164b5f6a65c --- /dev/null +++ b/pkg/project/mock.go @@ -0,0 +1,106 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/project/project.go + +// Package project is a generated GoMock package. +package project + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockClient is a mock of Client interface. +type MockClient struct { + ctrl *gomock.Controller + recorder *MockClientMockRecorder +} + +// MockClientMockRecorder is the mock recorder for MockClient. +type MockClientMockRecorder struct { + mock *MockClient +} + +// NewMockClient creates a new mock instance. +func NewMockClient(ctrl *gomock.Controller) *MockClient { + mock := &MockClient{ctrl: ctrl} + mock.recorder = &MockClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClient) EXPECT() *MockClientMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockClient) Create(projectName string, wait bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", projectName, wait) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockClientMockRecorder) Create(projectName, wait interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClient)(nil).Create), projectName, wait) +} + +// Delete mocks base method. +func (m *MockClient) Delete(projectName string, wait bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", projectName, wait) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClientMockRecorder) Delete(projectName, wait interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), projectName, wait) +} + +// Exists mocks base method. +func (m *MockClient) Exists(projectName string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Exists", projectName) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Exists indicates an expected call of Exists. +func (mr *MockClientMockRecorder) Exists(projectName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockClient)(nil).Exists), projectName) +} + +// List mocks base method. +func (m *MockClient) List() (ProjectList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List") + ret0, _ := ret[0].(ProjectList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClientMockRecorder) List() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClient)(nil).List)) +} + +// SetCurrent mocks base method. +func (m *MockClient) SetCurrent(projectName string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetCurrent", projectName) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetCurrent indicates an expected call of SetCurrent. +func (mr *MockClientMockRecorder) SetCurrent(projectName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrent", reflect.TypeOf((*MockClient)(nil).SetCurrent), projectName) +} diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index 9a8204540de..7ce58dd538f 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -30,3 +30,7 @@ mockgen -source=pkg/odo/cmdline/cmdline.go \ mockgen -source=pkg/application/application.go \ -package application \ -destination pkg/application/mock.go + +mockgen -source=pkg/project/project.go \ + -package project \ + -destination pkg/project/mock.go