From 92549adcb8dfdd031500f6bb4d1a02f776f4028b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=9Cmit=20=C3=96zden?= Date: Sun, 5 Nov 2023 21:25:48 +0300 Subject: [PATCH] feat: Implement yaml redirect adapter * test: Add tests and test_data of yaml redirect --- internal/adapters/fileredirect/yaml.go | 65 ++++++++++++++++ internal/adapters/fileredirect/yaml_test.go | 84 +++++++++++++++++++++ test_data/faulty_formatted_redirection.yaml | 3 + test_data/redirection.yaml | 3 + 4 files changed, 155 insertions(+) create mode 100644 internal/adapters/fileredirect/yaml.go create mode 100644 internal/adapters/fileredirect/yaml_test.go create mode 100644 test_data/faulty_formatted_redirection.yaml create mode 100644 test_data/redirection.yaml diff --git a/internal/adapters/fileredirect/yaml.go b/internal/adapters/fileredirect/yaml.go new file mode 100644 index 0000000..cc28615 --- /dev/null +++ b/internal/adapters/fileredirect/yaml.go @@ -0,0 +1,65 @@ +package fileredirect + +import ( + "context" + "errors" + "os" + "sync" + + "github.com/mehmetumit/dexus/internal/core/ports" + "gopkg.in/yaml.v3" +) + +var ( + ErrStoreIsNotInitialized = errors.New("store is not initialized") + ErrUnableToOpenYamlFile = errors.New("unable to open the file") + ErrUnableToDecodeYamlFile = errors.New("unable to decode yaml file") +) + +type RedirectionStore struct { + RedirectionMap map[string]string `yaml:"redirections"` +} +type YamlRedirect struct { + sync.RWMutex + redirectionStore *RedirectionStore + logger ports.Logger +} + +func initStore(logger ports.Logger, filePath string) (*RedirectionStore, error) { + f, err := os.Open(filePath) + defer f.Close() + if err != nil { + logger.Error(ErrUnableToOpenYamlFile, err) + return nil, ErrUnableToOpenYamlFile + } + store := RedirectionStore{ + RedirectionMap: make(map[string]string), + } + if err := yaml.NewDecoder(f).Decode(&store); err != nil { + logger.Error(ErrUnableToDecodeYamlFile, err) + return nil, ErrUnableToDecodeYamlFile + } + return &store, nil + +} +func NewYamlRedirect(logger ports.Logger, filePath string) (*YamlRedirect, error) { + store, err := initStore(logger, filePath) + if err != nil { + logger.Error("failed to create yaml redirect") + } + return &YamlRedirect{ + redirectionStore: store, + }, err +} +func (yr *YamlRedirect) Get(ctx context.Context, from string) (string, error) { + yr.RLock() + defer yr.RUnlock() + if yr.redirectionStore == nil { + return "", ErrStoreIsNotInitialized + } + to, ok := yr.redirectionStore.RedirectionMap[from] + if !ok { + return "", ports.ErrRedirectionNotFound + } + return to, nil +} diff --git a/internal/adapters/fileredirect/yaml_test.go b/internal/adapters/fileredirect/yaml_test.go new file mode 100644 index 0000000..2a81a6f --- /dev/null +++ b/internal/adapters/fileredirect/yaml_test.go @@ -0,0 +1,84 @@ +package fileredirect + +import ( + "context" + "path/filepath" + "testing" + + "github.com/mehmetumit/dexus/internal/core/ports" + "github.com/mehmetumit/dexus/internal/mocks" +) + +var ( + // Make paths usable on different oses + redirectionFilePath = filepath.ToSlash("./../../../test_data/redirection.yaml") + faultyFormattedRedirectionFilePath = filepath.ToSlash("./../../../test_data/faulty_formatted_redirection.yaml") + notExistsRedirectionFilePath = filepath.ToSlash("./../../../this/path/not/exists") +) + +func newTestYamlRedirect(tb testing.TB) (*YamlRedirect, error) { + tb.Helper() + l := mocks.NewMockLogger() + return NewYamlRedirect(l, redirectionFilePath) +} + +func TestYamlRedirect_FaultyFormattedFile(t *testing.T) { + mockLogger := mocks.NewMockLogger() + + _, err := NewYamlRedirect(mockLogger, faultyFormattedRedirectionFilePath) + if err != ErrUnableToDecodeYamlFile { + t.Errorf("Expected err %v, got %v", ErrUnableToOpenYamlFile, err) + } + +} +func TestYamlRedirect_NotExistsFile(t *testing.T) { + mockLogger := mocks.NewMockLogger() + _, err := NewYamlRedirect(mockLogger, notExistsRedirectionFilePath) + if err != ErrUnableToOpenYamlFile { + t.Errorf("Expected err %v, got %v", ErrUnableToOpenYamlFile, err) + } +} +func TestYamlRedirect_CorrectFile(t *testing.T) { + mockLogger := mocks.NewMockLogger() + _, err := NewYamlRedirect(mockLogger, redirectionFilePath) + if err != nil { + t.Errorf("Expected err %v, got %v", nil, err) + } +} +func TestYamlRedirect_NotInitializedStore(t *testing.T) { + mockLogger := mocks.NewMockLogger() + hasNotInitializedStore := YamlRedirect{logger: mockLogger} + ctx := context.Background() + _, err := hasNotInitializedStore.Get(ctx, "/abc") + if err != ErrStoreIsNotInitialized { + t.Errorf("Expected err %v, got %v", ErrStoreIsNotInitialized, err) + } +} +func TestYamlRedirect_RedirectionFound(t *testing.T) { + yr, err := newTestYamlRedirect(t) + ctx := context.Background() + if err != nil { + t.Errorf("Expected err %v, got %v", nil, err) + } + for k, v := range yr.redirectionStore.RedirectionMap { + gotRedirect, err := yr.Get(ctx, k) + if err != nil { + t.Errorf("Expected err %v, got %v", nil, err) + } + if gotRedirect != v { + t.Errorf("Expected redirect %v, got %v", v, gotRedirect) + } + + } +} +func TestYamlRedirect_RedirectionNotFound(t *testing.T) { + yr, err := newTestYamlRedirect(t) + ctx := context.Background() + if err != nil { + t.Errorf("Expected err %v, got %v", nil, err) + } + _, err = yr.Get(ctx, "/this/path/not/exists") + if err != ports.ErrRedirectionNotFound { + t.Errorf("Expected err %v, got %v", ports.ErrRedirectionNotFound, err) + } +} diff --git a/test_data/faulty_formatted_redirection.yaml b/test_data/faulty_formatted_redirection.yaml new file mode 100644 index 0000000..6e3392b --- /dev/null +++ b/test_data/faulty_formatted_redirection.yaml @@ -0,0 +1,3 @@ +redirections: + - faulty + - formatted diff --git a/test_data/redirection.yaml b/test_data/redirection.yaml new file mode 100644 index 0000000..1ab9ff6 --- /dev/null +++ b/test_data/redirection.yaml @@ -0,0 +1,3 @@ +redirections: + /abc : https://google.com + /xyz : https://github.com