diff --git a/pkg/client/configs_test.go b/pkg/client/configs_test.go new file mode 100644 index 00000000..a247586f --- /dev/null +++ b/pkg/client/configs_test.go @@ -0,0 +1,89 @@ +package client + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetConfigNameAndVersion(t *testing.T) { + tests := []struct { + name string + fullName string + stackName string + expected string + expectedVer string + expectError bool + }{ + { + name: "valid config with version", + fullName: "myapp_database_v2", + stackName: "myapp", + expected: "database", + expectedVer: "v2", + expectError: false, + }, + { + name: "valid config with numeric version", + fullName: "myapp_redis_1", + stackName: "myapp", + expected: "redis", + expectedVer: "1", + expectError: false, + }, + { + name: "config without underscore in name", + fullName: "myapp_db_v1", + stackName: "myapp", + expected: "db", + expectedVer: "v1", + expectError: false, + }, + { + name: "config with multiple underscores", + fullName: "myapp_my_database_v3", + stackName: "myapp", + expected: "my_database", + expectedVer: "v3", + expectError: false, + }, + { + name: "invalid config - no version", + fullName: "myapp_database", + stackName: "myapp", + expectError: true, + }, + { + name: "empty config name", + fullName: "myapp__v1", + stackName: "myapp", + expected: "", + expectedVer: "v1", + expectError: false, + }, + { + name: "wrong stack prefix", + fullName: "otherapp_database_v1", + stackName: "myapp", + expected: "otherapp_database", + expectedVer: "v1", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + name, version, err := GetConfigNameAndVersion(tt.fullName, tt.stackName) + + if tt.expectError { + assert.Error(t, err) + assert.Empty(t, name) + assert.Empty(t, version) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expected, name) + assert.Equal(t, tt.expectedVer, version) + } + }) + } +} \ No newline at end of file diff --git a/pkg/client/secret_test.go b/pkg/client/secret_test.go new file mode 100644 index 00000000..b466d151 --- /dev/null +++ b/pkg/client/secret_test.go @@ -0,0 +1,58 @@ +package client + +import ( + "testing" + + "github.com/docker/docker/api/types/swarm" + "github.com/stretchr/testify/assert" +) + +func TestGetSecretNames(t *testing.T) { + tests := []struct { + name string + secrets []swarm.Secret + expected []string + description string + }{ + { + name: "empty secrets list", + secrets: []swarm.Secret{}, + expected: nil, + description: "should return nil for empty input", + }, + { + name: "single secret", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "database_password"}}}, + }, + expected: []string{"database_password"}, + description: "should return single secret name", + }, + { + name: "multiple secrets", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "db_password"}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "api_key"}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "ssl_cert"}}}, + }, + expected: []string{"db_password", "api_key", "ssl_cert"}, + description: "should return all secret names in order", + }, + { + name: "secrets with empty names", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: ""}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "valid_name"}}}, + }, + expected: []string{"", "valid_name"}, + description: "should include empty names if present", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := GetSecretNames(tt.secrets) + assert.Equal(t, tt.expected, result, tt.description) + }) + } +} \ No newline at end of file diff --git a/pkg/deploy/utils_test.go b/pkg/deploy/utils_test.go new file mode 100644 index 00000000..f9e80c55 --- /dev/null +++ b/pkg/deploy/utils_test.go @@ -0,0 +1,88 @@ +package deploy + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetImageNameAndTag(t *testing.T) { + tests := []struct { + name string + imageName string + expectedName string + expectedTag string + expectError bool + description string + }{ + { + name: "standard image with tag", + imageName: "nginx:1.23", + expectedName: "nginx", + expectedTag: "1.23", + expectError: false, + description: "should parse standard image name with tag", + }, + { + name: "image with digest", + imageName: "nginx:1.23@sha256:abc123", + expectedName: "nginx", + expectedTag: "1.23", + expectError: false, + description: "should parse image with digest, ignoring digest part", + }, + { + name: "image with latest tag", + imageName: "redis:latest", + expectedName: "redis", + expectedTag: "latest", + expectError: false, + description: "should parse image with latest tag", + }, + { + name: "image with numeric tag", + imageName: "postgres:14", + expectedName: "postgres", + expectedTag: "14", + expectError: false, + description: "should parse image with numeric tag", + }, + { + name: "image with complex name", + imageName: "registry.example.com/myapp/api:v1.2.3", + expectedName: "registry.example.com/myapp/api", + expectedTag: "v1.2.3", + expectError: false, + description: "should parse image with registry prefix and complex name", + }, + { + name: "image without tag", + imageName: "nginx", + expectError: true, + description: "should error when no tag present", + }, + { + name: "empty image name", + imageName: "", + expectError: true, + description: "should error on empty image name", + }, + + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + name, tag, err := GetImageNameAndTag(tt.imageName) + + if tt.expectError { + assert.Error(t, err) + assert.Empty(t, name) + assert.Empty(t, tag) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedName, name) + assert.Equal(t, tt.expectedTag, tag) + } + }) + } +} \ No newline at end of file