Select Git revision
caching_middleware_test.go
caching_middleware_test.go 38.92 KiB
package middleware
import (
"context"
"testing"
"time"
"git.perx.ru/perxis/perxis-go/pkg/cache"
"git.perx.ru/perxis/perxis-go/pkg/environments"
envmocks "git.perx.ru/perxis/perxis-go/pkg/environments/mocks"
"git.perx.ru/perxis/perxis-go/pkg/errors"
"git.perx.ru/perxis/perxis-go/pkg/items"
itmsmocks "git.perx.ru/perxis/perxis-go/pkg/items/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestItemsCache(t *testing.T) {
const (
colID = "colID"
spaceID = "spaceID"
envID = "envID"
envAlias = "envAlias"
itemID = "itemID"
locID = "locID"
size = 5
ttl = 20 * time.Millisecond
)
errNotFound := errors.NotFound(errors.New("not found"))
ctx := context.Background()
t.Run("Get from cache", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша, при повторном запросе.")
v3, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
assert.Same(t, v3, v2, "Ожидается получение объекта из кеша, при запросе того же объекта по alias окружения.")
require.NoError(t, err)
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("Get from cache(by Alias)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envAlias, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша, при повторном запросе.")
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
assert.Same(t, v3, v2, "Ожидается получение объекта из кеша, при запросе того же объекта по ID окружения.")
require.NoError(t, err)
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("GetPublished from cache", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша, при запросе того же объекта по alias окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("GetPublished from cache(by Alias)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша, при запросе того же объекта по ID окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("GetPublished from cache (with different locales)", func(t *testing.T) {
const (
loc1 = "loc1"
loc2 = "loc2"
)
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Twice()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1loc1, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: loc1})
require.NoError(t, err, "Ожидается получение объекта из сервиса и добавление его в кеш с loc1.")
v1loc2, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: loc2})
require.NoError(t, err, "Ожидается получение объекта из сервиса и добавление его в кеш с loc2 вместе с loc1.")
v2loc1, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: loc1})
require.NoError(t, err)
assert.Same(t, v1loc1, v2loc1, "Ожидается получение объекта c локализацией loc1 из кеша.")
v2loc2, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: loc2})
require.NoError(t, err)
assert.Same(t, v1loc2, v2loc2, "Ожидается получение объекта c локализацией loc2 из кеша.")
v3loc1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: loc1})
require.NoError(t, err)
assert.Same(t, v2loc1, v3loc1, "Ожидается получение объекта c локализацией loc1 из кеша, при запросе того же объекта по ID окружения.")
v3loc2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: loc2})
require.NoError(t, err)
assert.Same(t, v2loc2, v3loc2, "Ожидается получение объекта c локализацией loc2 из кеша, при запросе того же объекта по ID окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("Invalidate cache", func(t *testing.T) {
t.Run("After Update(Get)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d1"}}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
itms.On("Update", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Update(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d2"}})
require.NoError(t, err)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d2"}}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после обновления и получение его заново из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Archive(Get)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
itms.On("Archive", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Archive(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft})
require.NoError(t, err)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateArchived}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после архивации и получение из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Publish(Get)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
itms.On("Publish", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Publish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft})
require.NoError(t, err)
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после публикации и получение заново из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Delete", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша при повторном запросе.")
v3, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша по alias окружения.")
itms.On("Delete", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Delete(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID})
require.NoError(t, err)
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(nil, errNotFound).Once()
itms.On("Get", mock.Anything, spaceID, envAlias, colID, itemID).Return(nil, errNotFound).Once()
_, err = svc.Get(ctx, spaceID, envID, colID, itemID)
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление из кэша после удаления объекта и получение ошибки от сервиса.")
_, err = svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление из кэша после удаления объекта и получение ошибки от сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Unpublish(Get)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Unpublish", mock.Anything, mock.Anything).Return(nil).Once()
err = svc.Unpublish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished})
require.NoError(t, err)
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после снятия с публикации и получение заново из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Publish(Get by Alias)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша по alias окружения.")
itms.On("Publish", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Publish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft})
require.NoError(t, err)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envAlias, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после публикации и получение из сервиса по alias окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Update(Get by Alias)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d1"}}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша по alias окружения.")
itms.On("Update", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Update(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d2"}})
require.NoError(t, err)
itms.On("Get", mock.Anything, spaceID, envAlias, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, Data: map[string]interface{}{"f1": "d2"}}, nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша при обновлении и получение из сервиса по alias окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Unpublish(Get by Alias)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша по alias окружения.")
itms.On("Unpublish", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Unpublish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished})
require.NoError(t, err)
itms.On("Get", mock.Anything, spaceID, envAlias, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envAlias, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v3, v2, "Ожидается удаление объекта из кэша после снятия с публикации и получение из сервиса по alias окружения.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Update(GetPublished)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished, Data: map[string]interface{}{"f1": "d1"}}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша по о alias окружения.")
itms.On("Update", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Update(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished, Data: map[string]interface{}{"f1": "d2"}})
require.NoError(t, err)
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
_, err = svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по ID окружения после его обновления и получение ошибки от сервиса.")
_, err = svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по alias окружения после его обновления и получение ошибки от сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Archive(GetPublished)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша по о alias окружения.")
itms.On("Archive", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Archive(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft})
require.NoError(t, err)
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
_, err = svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по ID окружения после его архивации и получение ошибки от сервиса.")
_, err = svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по alias окружения после его архивации и получение ошибки от сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Delete(GetPublished)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша по о alias окружения.")
itms.On("Delete", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Delete(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID})
require.NoError(t, err)
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
_, err = svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша после удаления из хранилища и получение ошибки от сервиса.")
_, err = svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается очистка кеша по alias окружения после удаления объекта и получение ошибки от сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Unpublish(GetPublished)", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v2, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v2, v3, "Ожидается получение объекта из кеша по о alias окружения.")
itms.On("Unpublish", mock.Anything, mock.Anything).Return(nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
err = svc.Unpublish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished})
require.NoError(t, err)
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
_, err = svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по ID окружения после снятия с публикации и получение ошибки от сервиса.")
_, err = svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша по alias окружения после снятия с публикации и получение ошибки от сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After Unpublish by Alias", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
env.On("Get", mock.Anything, spaceID, envAlias).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envID, colID, itemID, mock.Anything).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StatePublished}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
v3, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
v4, err := svc.GetPublished(ctx, spaceID, envID, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.NoError(t, err)
assert.Same(t, v3, v4, "Ожидается получение опубликованного объекта из кеша.")
itms.On("Unpublish", mock.Anything, mock.Anything).Return(nil).Once()
err = svc.Unpublish(ctx, &items.Item{ID: itemID, SpaceID: spaceID, EnvID: envAlias, CollectionID: colID, State: items.StatePublished})
require.NoError(t, err)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
itms.On("GetPublished", mock.Anything, spaceID, envAlias, colID, itemID, mock.Anything).Return(nil, errNotFound).Once()
v5, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v5, v2, "Ожидается удаление объекта из кэша и получение заново из сервиса.")
_, err = svc.GetPublished(ctx, spaceID, envAlias, colID, itemID, &items.GetPublishedOptions{LocaleID: locID})
require.Error(t, err)
assert.EqualError(t, err, "not found", "Ожидается удаление объекта из кэша и получение ошибки от сервиса из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
t.Run("After TTL expired", func(t *testing.T) {
itms := &itmsmocks.Items{}
env := &envmocks.Environments{}
svc := CachingMiddleware(cache.NewMemoryCache(size, ttl), cache.NewMemoryCache(size, ttl), env)(itms)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v1, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
v2, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.Same(t, v1, v2, "Ожидается получение объекта из кеша.")
time.Sleep(2 * ttl)
env.On("Get", mock.Anything, spaceID, envID).Return(&environments.Environment{ID: envID, SpaceID: spaceID, Aliases: []string{envAlias}}, nil).Once()
itms.On("Get", mock.Anything, spaceID, envID, colID, itemID).Return(&items.Item{ID: itemID, SpaceID: spaceID, EnvID: envID, CollectionID: colID, State: items.StateDraft}, nil).Once()
v3, err := svc.Get(ctx, spaceID, envID, colID, itemID)
require.NoError(t, err)
assert.NotSame(t, v2, v3, "Ожидается удаление объекта из кэша и получение из сервиса.")
env.AssertExpectations(t)
itms.AssertExpectations(t)
})
})
}