diff --git a/Makefile b/Makefile index e2cf4bb..2a700c1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ build: go build -o ./bin/app ./cmd/main.go test: - go test ./... + go test -v ./... run: go run ./cmd/main.go diff --git a/README.md b/README.md index eed9361..3830185 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # feature-tag How manage feature tags with go? + + +## Use case + +- Retorna todas as tags ativas. +- Verifica se {tag} está ativa? diff --git a/go.mod b/go.mod index c8e7690..5d6d8f8 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,11 @@ module github.com/mist-gopher/feature-tag go 1.22.0 + +require github.com/stretchr/testify v1.9.0 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..60ce688 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/client/client.go b/internal/client/client.go new file mode 100644 index 0000000..b8a4241 --- /dev/null +++ b/internal/client/client.go @@ -0,0 +1,11 @@ +package client + +type Client struct { + Id string + Keys []ClientKey +} + +type ClientKey struct { + Name string + Value string +} diff --git a/internal/repository/memory_repo/tag.go b/internal/repository/memory_repo/tag.go new file mode 100644 index 0000000..b3470b9 --- /dev/null +++ b/internal/repository/memory_repo/tag.go @@ -0,0 +1,31 @@ +package memory_repo + +import ( + "github.com/mist-gopher/feature-tag/internal/tag" +) + +type Tag struct { + Data map[string]tag.Tag + Err error +} + +func NewTagRepositoryInMemory() Tag { + return Tag{ + Data: map[string]tag.Tag{}, + Err: nil, + } +} + +func (repo *Tag) GetByName(name string) (*tag.Tag, error) { + if repo.Err != nil { + return nil, repo.Err + } + + value, exist := repo.Data[name] + + if !exist { + return nil, nil + } + + return &value, nil +} diff --git a/internal/tag/tag.go b/internal/tag/tag.go new file mode 100644 index 0000000..d4e8ce8 --- /dev/null +++ b/internal/tag/tag.go @@ -0,0 +1,20 @@ +package tag + +type Tag struct { + Id string + Name string + Value bool +} + +func New(clientId, name string, value bool) Tag { + return Tag{ + Id: MakeId(name, clientId), + Name: name, + Value: value, + } +} + +func MakeId(name, clientId string) string { + return "tag:" + clientId + ":" + name +} + diff --git a/internal/tag/tag_test.go b/internal/tag/tag_test.go new file mode 100644 index 0000000..a13c4c1 --- /dev/null +++ b/internal/tag/tag_test.go @@ -0,0 +1,16 @@ +package tag_test + +import ( + "testing" + + "github.com/mist-gopher/feature-tag/internal/tag" + "github.com/stretchr/testify/assert" +) + +func TestNewTag(t *testing.T){ + ntag := tag.New("clientid", "tagname", false) + assert.Equal(t, "tag:clientid:tagname", ntag.Id) + assert.Equal(t, "tagname", ntag.Name) + assert.False(t, ntag.Value) +} + diff --git a/internal/usecase/get_tag_status.go b/internal/usecase/get_tag_status.go new file mode 100644 index 0000000..b1d3719 --- /dev/null +++ b/internal/usecase/get_tag_status.go @@ -0,0 +1,34 @@ +package usecase + +import ( + "github.com/mist-gopher/feature-tag/internal/tag" +) + +type GetTagStatusInput struct { + AppId string + ApiKey string + TagName string +} + +type GetTagStatusOutput struct { + Active bool +} + +type GetTagByNameRepository interface { + GetByName(name string) (*tag.Tag, error) +} + +func GetTagStatus(input GetTagStatusInput, repo GetTagByNameRepository) (GetTagStatusOutput, error) { + output := GetTagStatusOutput{Active: false} + tag, err := repo.GetByName(tag.MakeId(input.TagName, input.AppId)) + + if err != nil { + return output, err + } + + if tag != nil { + output.Active = tag.Value + } + + return output, nil +} diff --git a/internal/usecase/get_tag_status_test.go b/internal/usecase/get_tag_status_test.go new file mode 100644 index 0000000..b895cd1 --- /dev/null +++ b/internal/usecase/get_tag_status_test.go @@ -0,0 +1,57 @@ +package usecase_test + +import ( + "testing" + + "github.com/mist-gopher/feature-tag/internal/repository/memory_repo" + "github.com/mist-gopher/feature-tag/internal/tag" + "github.com/mist-gopher/feature-tag/internal/usecase" + "github.com/stretchr/testify/assert" +) + +func MockTagData() map[string]tag.Tag { + activeTag := tag.New("valid key", "tagname", true) + return map[string]tag.Tag{ + activeTag.Id: activeTag, + } +} + +func TestGetTagStatus(t *testing.T) { + type TestCase struct { + input usecase.GetTagStatusInput + resultValue bool + resultError error + } + + cases := map[string]TestCase{ + "with valid input for active tag": { + input: usecase.GetTagStatusInput{ + AppId: "valid key", + ApiKey: "valid id", + TagName: "tagname", + }, + resultValue: true, + resultError: nil, + }, + "unknown tag": { + input: usecase.GetTagStatusInput{ + AppId: "valid key", + ApiKey: "valid id", + TagName: "not a created tag", + }, + resultValue: false, + resultError: nil, + }, + } + + repo := memory_repo.NewTagRepositoryInMemory() + repo.Data = MockTagData() + + for testName, testCase := range cases { + t.Run(testName, func(t *testing.T) { + result, err := usecase.GetTagStatus(testCase.input, &repo) + assert.Equal(t, nil, err) + assert.Equal(t, testCase.resultValue, result.Active) + }) + } +}