mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
125e311eda
Signed-off-by: dusan <borovcanindusan1@gmail.com>
289 lines
7.3 KiB
Go
289 lines
7.3 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package cache_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/absmach/magistrala/auth"
|
|
"github.com/absmach/magistrala/auth/cache"
|
|
"github.com/absmach/magistrala/internal/testsutil"
|
|
"github.com/absmach/magistrala/pkg/errors"
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var (
|
|
storeClient *redis.Client
|
|
storeURL string
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
code := testsutil.RunRedisTest(m, &storeClient, &storeURL)
|
|
os.Exit(code)
|
|
}
|
|
|
|
func setupRedisTokensClient() auth.UserActiveTokensCache {
|
|
tc, err := cache.NewUserActiveTokensCache(storeClient)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return tc
|
|
}
|
|
|
|
func TestTokenSave(t *testing.T) {
|
|
storeClient.FlushAll(context.Background())
|
|
tokensCache := setupRedisTokensClient()
|
|
|
|
userID := testsutil.GenerateUUID(t)
|
|
tokenID := testsutil.GenerateUUID(t)
|
|
|
|
cases := []struct {
|
|
desc string
|
|
userID string
|
|
tokenID string
|
|
description string
|
|
expiry time.Time
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Save active token",
|
|
userID: userID,
|
|
tokenID: tokenID,
|
|
description: "Test token",
|
|
expiry: time.Now().Add(10 * time.Minute),
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save already cached token",
|
|
userID: userID,
|
|
tokenID: tokenID,
|
|
description: "Updated token",
|
|
expiry: time.Now().Add(10 * time.Minute),
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save another token for same user",
|
|
userID: userID,
|
|
tokenID: testsutil.GenerateUUID(t),
|
|
description: "Another token",
|
|
expiry: time.Now().Add(10 * time.Minute),
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save token with empty id",
|
|
userID: userID,
|
|
tokenID: "",
|
|
description: "Empty ID token",
|
|
expiry: time.Now().Add(10 * time.Minute),
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Save token with empty description",
|
|
userID: userID,
|
|
tokenID: testsutil.GenerateUUID(t),
|
|
description: "",
|
|
expiry: time.Now().Add(10 * time.Minute),
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
err := tokensCache.SaveActive(context.Background(), tc.userID, tc.tokenID, tc.description, tc.expiry)
|
|
if err == nil {
|
|
ok, err := tokensCache.IsActive(context.Background(), tc.tokenID)
|
|
assert.NoError(t, err)
|
|
assert.True(t, ok)
|
|
}
|
|
assert.True(t, errors.Contains(err, tc.err))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTokenContains(t *testing.T) {
|
|
storeClient.FlushAll(context.Background())
|
|
tokensCache := setupRedisTokensClient()
|
|
|
|
userID := testsutil.GenerateUUID(t)
|
|
tokenID := testsutil.GenerateUUID(t)
|
|
|
|
err := tokensCache.SaveActive(context.Background(), userID, tokenID, "Test token", time.Now().Add(10*time.Minute))
|
|
assert.Nil(t, err, fmt.Sprintf("Unexpected error while trying to save: %s", err))
|
|
|
|
cases := []struct {
|
|
desc string
|
|
userID string
|
|
tokenID string
|
|
ok bool
|
|
}{
|
|
{
|
|
desc: "IsActive for existing token",
|
|
userID: userID,
|
|
tokenID: tokenID,
|
|
ok: true,
|
|
},
|
|
{
|
|
desc: "IsActive for non existing token",
|
|
userID: userID,
|
|
tokenID: testsutil.GenerateUUID(t),
|
|
},
|
|
{
|
|
desc: "IsActive with empty token id",
|
|
userID: userID,
|
|
tokenID: "",
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
ok, err := tokensCache.IsActive(context.Background(), tc.tokenID)
|
|
if tc.ok {
|
|
assert.NoError(t, err)
|
|
}
|
|
assert.Equal(t, tc.ok, ok)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTokenRemove(t *testing.T) {
|
|
storeClient.FlushAll(context.Background())
|
|
tokensCache := setupRedisTokensClient()
|
|
|
|
userID := testsutil.GenerateUUID(t)
|
|
num := 10
|
|
var tokenIDs []string
|
|
for i := range num {
|
|
tokenID := testsutil.GenerateUUID(t)
|
|
err := tokensCache.SaveActive(context.Background(), userID, tokenID, fmt.Sprintf("Token %d", i), time.Now().Add(10*time.Minute))
|
|
assert.Nil(t, err, fmt.Sprintf("Unexpected error while trying to save: %s", err))
|
|
tokenIDs = append(tokenIDs, tokenID)
|
|
}
|
|
|
|
cases := []struct {
|
|
desc string
|
|
userID string
|
|
tokenID string
|
|
err error
|
|
}{
|
|
{
|
|
desc: "Remove an existing token from cache",
|
|
userID: userID,
|
|
tokenID: tokenIDs[0],
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Remove token with empty id from cache",
|
|
userID: userID,
|
|
tokenID: "",
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "Remove non existing id from cache",
|
|
userID: userID,
|
|
tokenID: testsutil.GenerateUUID(t),
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
err := tokensCache.RemoveActive(context.Background(), tc.userID, tc.tokenID)
|
|
assert.True(t, errors.Contains(err, tc.err))
|
|
if err == nil {
|
|
ok, err := tokensCache.IsActive(context.Background(), tc.tokenID)
|
|
assert.NoError(t, err)
|
|
assert.False(t, ok)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestListUserTokens(t *testing.T) {
|
|
storeClient.FlushAll(context.Background())
|
|
tokensCache := setupRedisTokensClient()
|
|
|
|
userID := testsutil.GenerateUUID(t)
|
|
userID2 := testsutil.GenerateUUID(t)
|
|
num := 5
|
|
var expectedTokens []auth.TokenInfo
|
|
|
|
for i := range num {
|
|
tokenID := testsutil.GenerateUUID(t)
|
|
description := fmt.Sprintf("Token %d", i)
|
|
err := tokensCache.SaveActive(context.Background(), userID, tokenID, description, time.Now().Add(10*time.Minute))
|
|
assert.Nil(t, err, fmt.Sprintf("Unexpected error while trying to save: %s", err))
|
|
expectedTokens = append(expectedTokens, auth.TokenInfo{
|
|
ID: tokenID,
|
|
Description: description,
|
|
})
|
|
}
|
|
|
|
tokenID2 := testsutil.GenerateUUID(t)
|
|
desc2 := "User 2 token"
|
|
err := tokensCache.SaveActive(context.Background(), userID2, tokenID2, desc2, time.Now().Add(10*time.Minute))
|
|
assert.Nil(t, err, fmt.Sprintf("Unexpected error while trying to save: %s", err))
|
|
|
|
cases := []struct {
|
|
desc string
|
|
userID string
|
|
expectedCount int
|
|
expectedTokens []auth.TokenInfo
|
|
err error
|
|
}{
|
|
{
|
|
desc: "List all tokens for user with multiple tokens",
|
|
userID: userID,
|
|
expectedCount: num,
|
|
expectedTokens: expectedTokens,
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "List tokens for user with single token",
|
|
userID: userID2,
|
|
expectedCount: 1,
|
|
expectedTokens: []auth.TokenInfo{{ID: tokenID2, Description: desc2}},
|
|
err: nil,
|
|
},
|
|
{
|
|
desc: "List tokens for user with no tokens",
|
|
userID: testsutil.GenerateUUID(t),
|
|
expectedCount: 0,
|
|
expectedTokens: nil,
|
|
err: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
tokens, err := tokensCache.ListUserTokens(context.Background(), tc.userID)
|
|
assert.True(t, errors.Contains(err, tc.err))
|
|
assert.Equal(t, tc.expectedCount, len(tokens))
|
|
if tc.expectedTokens != nil {
|
|
assert.ElementsMatch(t, tc.expectedTokens, tokens)
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("Cleanup expired tokens from list", func(t *testing.T) {
|
|
// Remove one token directly from Redis to simulate expiration
|
|
err := tokensCache.RemoveActive(context.Background(), userID, expectedTokens[0].ID)
|
|
assert.NoError(t, err)
|
|
|
|
// List should now return only valid tokens
|
|
tokens, err := tokensCache.ListUserTokens(context.Background(), userID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, num-1, len(tokens))
|
|
|
|
// Check that the removed token is not in the list
|
|
for _, token := range tokens {
|
|
assert.NotEqual(t, expectedTokens[0].ID, token.ID)
|
|
}
|
|
})
|
|
}
|