-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Implement unit tests for core/app using mock adapters
* test: Add cacher and redirection_repo mocks * refactor: Change redirection key data type to string instead of url * fix: Set cache after cache miss * refactor: Change byte array data type which used in cacher port to string for convenience
- Loading branch information
1 parent
d8657ea
commit 7236bbd
Showing
8 changed files
with
221 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
module github.com/mehmetumit/dexus | ||
|
||
go 1.21.3 | ||
|
||
require ( | ||
github.com/cespare/xxhash/v2 v2.2.0 // indirect | ||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect | ||
github.com/go-chi/chi/v5 v5.0.10 // indirect | ||
github.com/go-chi/cors v1.2.1 // indirect | ||
github.com/google/uuid v1.4.0 // indirect | ||
github.com/redis/go-redis/v9 v9.2.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= | ||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= | ||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= | ||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= | ||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= | ||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= | ||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= | ||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= | ||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg= | ||
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package app | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/mehmetumit/dexus/internal/core/ports" | ||
"github.com/mehmetumit/dexus/internal/mocks" | ||
) | ||
|
||
func newTestApp(t testing.TB) *App { | ||
t.Helper() | ||
mockLogger := mocks.NewMockLogger() | ||
mockRedirectionRepo := mocks.NewMockRedirectionRepo() | ||
mockCacher := mocks.NewMockCacher() | ||
mockLogger.SetDebugLevel(true) | ||
return NewApp( | ||
AppConfig{ | ||
Logger: mockLogger, | ||
RedirectionRepo: mockRedirectionRepo, | ||
Cacher: mockCacher, | ||
}, | ||
) | ||
} | ||
|
||
func TestApp_FindRedirect(t *testing.T) { | ||
redirectionMap := mocks.MockRedirectionMap{ | ||
"test1": "https://test1.com", | ||
"test2": "https://test2.com", | ||
"test3": "https://test3.com", | ||
} | ||
notFoundKeys := []string{"not-found", "not/found", ""} | ||
t.Run("Find Redirect From Repo", func(t *testing.T) { | ||
app := newTestApp(t) | ||
ctx := context.Background() | ||
app.RedirectionRepo.(*mocks.MockRedirectionRepo).SetMockRedirectionMap(redirectionMap) | ||
for k, v := range redirectionMap { | ||
u, err := app.FindRedirect(ctx, k) | ||
if err != nil { | ||
t.Errorf("Expected err nil, got %v", err) | ||
} | ||
|
||
if u.String() != v { | ||
t.Errorf("Expected redirection %v, got %v", v, u.String()) | ||
|
||
} | ||
} | ||
}) | ||
t.Run("Find Not Found Redirect From Repo", func(t *testing.T) { | ||
app := newTestApp(t) | ||
app.RedirectionRepo.(*mocks.MockRedirectionRepo).SetMockRedirectionMap(redirectionMap) | ||
for _, v := range notFoundKeys { | ||
_, err := app.FindRedirect(context.Background(), v) | ||
if err != ports.ErrRedirectionNotFound { | ||
t.Errorf("Expected err %v, got %v", ports.ErrRedirectionNotFound, err) | ||
} | ||
} | ||
}) | ||
t.Run("Find Redirect From Cache", func(t *testing.T) { | ||
app := newTestApp(t) | ||
app.RedirectionRepo.(*mocks.MockRedirectionRepo).SetMockRedirectionMap(redirectionMap) | ||
ctx := context.Background() | ||
for k := range redirectionMap { | ||
app.FindRedirect(ctx, k) | ||
} | ||
for k, v := range redirectionMap { | ||
keyHash, err := app.Cacher.GenKey(ctx, k) | ||
if err != nil { | ||
t.Errorf("Expected err nil, got %v", err) | ||
} | ||
gotVal, err := app.Cacher.Get(ctx, keyHash) | ||
if err != nil { | ||
t.Errorf("Expected err nil, got %v", err) | ||
} | ||
if gotVal != v { | ||
t.Errorf("Expected cache val %v, got %v", v, gotVal) | ||
} | ||
_, err = app.FindRedirect(ctx, k) | ||
if err != nil { | ||
t.Errorf("Expected err nil, got %v", err) | ||
} | ||
} | ||
|
||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package mocks | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
"github.com/mehmetumit/dexus/internal/core/ports" | ||
) | ||
|
||
type MockCacheMap map[string]string | ||
type MockCacher struct { | ||
sync.RWMutex //Useful for concurrent nonblocking reads | ||
cacheMap MockCacheMap | ||
} | ||
|
||
func NewMockCacher() *MockCacher { | ||
return &MockCacher{ | ||
cacheMap: make(MockCacheMap), | ||
} | ||
} | ||
|
||
func (mc *MockCacher) expireAfter(key string, ttl time.Duration) { | ||
time.AfterFunc(ttl, func() { | ||
mc.Lock() | ||
defer mc.Unlock() | ||
delete(mc.cacheMap, key) | ||
}) | ||
} | ||
func (mc *MockCacher) GenKey(ctx context.Context, s string) (string, error) { | ||
hashKey := uuid.NewSHA1(uuid.NameSpaceOID, []byte(s)).String() | ||
return hashKey, nil | ||
|
||
} | ||
func (mc *MockCacher) Get(ctx context.Context, key string) (string, error) { | ||
mc.RLock() | ||
defer mc.RUnlock() | ||
val, ok := mc.cacheMap[key] | ||
if !ok { | ||
return "", ports.ErrKeyNotFound | ||
} | ||
return val, nil | ||
|
||
} | ||
func (mc *MockCacher) Set(ctx context.Context, key string, val string, ttl time.Duration) error { | ||
mc.Lock() | ||
defer mc.Unlock() | ||
mc.cacheMap[key] = val | ||
mc.expireAfter(key, ttl) | ||
return nil | ||
} | ||
func (mc *MockCacher) Delete(ctx context.Context, key string) error { | ||
mc.Lock() | ||
defer mc.Unlock() | ||
delete(mc.cacheMap, key) | ||
return nil | ||
} | ||
func (mc *MockCacher) Flush(ctx context.Context) error { | ||
mc.Lock() | ||
defer mc.Unlock() | ||
clear(mc.cacheMap) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package mocks | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/mehmetumit/dexus/internal/core/ports" | ||
) | ||
|
||
type MockRedirectionRepo struct { | ||
redirectionMap MockRedirectionMap | ||
} | ||
|
||
type MockRedirectionMap map[string]string | ||
|
||
func NewMockRedirectionRepo(p ...MockRedirectionMap) *MockRedirectionRepo { | ||
return &MockRedirectionRepo{} | ||
|
||
} | ||
func (mr *MockRedirectionRepo) Get(ctx context.Context, from string) (string, error) { | ||
to, ok := mr.redirectionMap[from] | ||
if !ok { | ||
return "", ports.ErrRedirectionNotFound | ||
} | ||
return to, nil | ||
} | ||
func (mr *MockRedirectionRepo) SetMockRedirectionMap(m MockRedirectionMap) { | ||
mr.redirectionMap = m | ||
} |