ms-auth/internal/users/repository/valkey_repository_test.go
Vyacheslav1557 3b03447d2f feat(user):
2024-12-30 20:04:26 +05:00

268 lines
7.3 KiB
Go

package repository
import (
"context"
"fmt"
"git.sch9.ru/new_gate/ms-auth/internal/models"
"git.sch9.ru/new_gate/ms-auth/pkg"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/valkey-io/valkey-go"
"github.com/valkey-io/valkey-go/mock"
"go.uber.org/mock/gomock"
"strings"
"testing"
)
var (
matcherAny = mock.MatchFn(func(cmd []string) bool { return true })
)
func TestValkeyRepository_CreateSession(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewClient(ctrl)
sessionRepo := NewValkeyRepository(client)
var userId int32 = 1
matcher := mock.MatchFn(func(cmd []string) bool {
if cmd[0] != "SET" {
return false
}
if !strings.HasPrefix(cmd[1], fmt.Sprintf("userid:%d:sessionid:", userId)) {
return false
}
if cmd[3] != "EX" {
return false
}
if cmd[4] != "2400" {
return false
}
return true
})
t.Run("valid session creation", func(t *testing.T) {
ctx := context.Background()
client.EXPECT().Do(ctx, matcher)
sessionId, err := sessionRepo.CreateSession(context.Background(), userId, models.RoleAdmin)
require.NoError(t, err)
require.NotEmpty(t, sessionId)
})
t.Run("invalid session creation 1", func(t *testing.T) {
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.ErrorResult(valkey.Nil))
sessionId, err := sessionRepo.CreateSession(context.Background(), userId, models.RoleAdmin)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.ErrorIs(t, err, valkey.Nil)
require.Empty(t, sessionId)
})
t.Run("invalid session creation 2 (invalid userid)", func(t *testing.T) {
sessionId, err := sessionRepo.CreateSession(context.Background(), 0, models.RoleAdmin)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.Empty(t, sessionId)
})
t.Run("invalid session creation 3 (invalid role)", func(t *testing.T) {
sessionId, err := sessionRepo.CreateSession(context.Background(), userId, 123)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.Empty(t, sessionId)
})
}
func TestValkeyRepository_ReadSession(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewClient(ctrl)
sessionRepo := NewValkeyRepository(client)
matcher := mock.MatchFn(func(cmd []string) bool {
if cmd[0] != "EVALSHA" {
return false
}
if cmd[2] != "0" {
return false
}
if !strings.HasPrefix(cmd[3], "userid:*:sessionid:") {
return false
}
return true
})
t.Run("valid session read", func(t *testing.T) {
data, id, err := models.NewSession(1, models.RoleAdmin)
require.NoError(t, err)
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyString(data)))
res, err := sessionRepo.ReadSession(context.Background(), id)
require.NoError(t, err)
require.Equal(t, int32(1), res.UserId)
require.Equal(t, id, res.Id)
require.Equal(t, models.RoleAdmin, res.Role)
})
t.Run("invalid session read 1 (not found)", func(t *testing.T) {
_, id, err := models.NewSession(1, models.RoleAdmin)
require.NoError(t, err)
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.ErrorResult(valkey.Nil))
res, err := sessionRepo.ReadSession(context.Background(), id)
require.ErrorIs(t, err, pkg.ErrNotFound)
require.ErrorIs(t, err, valkey.Nil)
require.Empty(t, res)
})
t.Run("invalid session read 2 (corrupted session storage)", func(t *testing.T) {
_, id, err := models.NewSession(1, models.RoleAdmin)
require.NoError(t, err)
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyInt64(123)))
res, err := sessionRepo.ReadSession(context.Background(), id)
require.ErrorIs(t, err, pkg.ErrInternal)
require.True(t, valkey.IsParseErr(err))
require.Empty(t, res)
})
t.Run("invalid session read 3 (bad sessionid)", func(t *testing.T) {
res, err := sessionRepo.ReadSession(context.Background(), "123")
require.ErrorIs(t, err, pkg.ErrBadInput)
require.Empty(t, res)
})
}
func TestValkeyRepository_UpdateSession(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewClient(ctrl)
sessionRepo := NewValkeyRepository(client)
matcher := mock.MatchFn(func(cmd []string) bool {
if cmd[0] != "EVALSHA" {
return false
}
if cmd[2] != "0" {
return false
}
if !strings.HasPrefix(cmd[3], "userid:*:sessionid:") {
return false
}
return true
})
t.Run("valid session update", func(t *testing.T) {
id := uuid.NewString()
ctx := context.Background()
client.EXPECT().Do(ctx, matcher)
err := sessionRepo.UpdateSession(context.Background(), id)
require.NoError(t, err)
})
t.Run("invalid session update 1 (nil response)", func(t *testing.T) {
id := uuid.NewString()
ctx := context.Background()
client.EXPECT().Do(ctx, matcherAny).Return(mock.ErrorResult(valkey.Nil))
err := sessionRepo.UpdateSession(context.Background(), id)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.ErrorIs(t, err, valkey.Nil)
})
t.Run("invalid session update 2 (bad sessionid)", func(t *testing.T) {
err := sessionRepo.UpdateSession(context.Background(), "123")
require.ErrorIs(t, err, pkg.ErrBadInput)
})
}
func TestValkeyRepository_DeleteSession(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewClient(ctrl)
sessionRepo := NewValkeyRepository(client)
matcher := mock.MatchFn(func(cmd []string) bool {
if cmd[0] != "EVALSHA" {
return false
}
if cmd[2] != "0" {
return false
}
if !strings.HasPrefix(cmd[3], "userid:*:sessionid:") {
return false
}
return true
})
t.Run("valid session delete", func(t *testing.T) {
id := uuid.NewString()
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyInt64(1)))
err := sessionRepo.DeleteSession(context.Background(), id)
require.NoError(t, err)
})
t.Run("invalid session delete 1", func(t *testing.T) {
id := uuid.NewString()
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyNil()))
err := sessionRepo.DeleteSession(context.Background(), id)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.ErrorIs(t, err, valkey.Nil)
})
t.Run("invalid session delete 2 (bad sessionid)", func(t *testing.T) {
err := sessionRepo.DeleteSession(context.Background(), "123")
require.ErrorIs(t, err, pkg.ErrBadInput)
})
}
func TestValkeyRepository_DeleteAllSessions(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := mock.NewClient(ctrl)
sessionRepo := NewValkeyRepository(client)
matcher := mock.MatchFn(func(cmd []string) bool {
if cmd[0] != "EVALSHA" {
return false
}
if cmd[2] != "0" {
return false
}
if !strings.HasPrefix(cmd[3], "userid:1:sessionid:*") {
return false
}
return true
})
t.Run("valid all sessions deletion", func(t *testing.T) {
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyInt64(1)))
err := sessionRepo.DeleteAllSessions(context.Background(), 1)
require.NoError(t, err)
})
t.Run("invalid all sessions deletion 1 (nil response)", func(t *testing.T) {
ctx := context.Background()
client.EXPECT().Do(ctx, matcher).Return(mock.Result(mock.ValkeyNil()))
err := sessionRepo.DeleteAllSessions(context.Background(), 1)
require.ErrorIs(t, err, pkg.ErrBadInput)
require.ErrorIs(t, err, valkey.Nil)
})
}