mirror of https://github.com/usememos/memos.git
658 lines
19 KiB
Go
658 lines
19 KiB
Go
package test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
storepb "github.com/usememos/memos/proto/gen/store"
|
|
"github.com/usememos/memos/store"
|
|
)
|
|
|
|
func TestUserSettingStore(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
Value: &storepb.UserSetting_General{General: &storepb.GeneralUserSetting{Locale: "en"}},
|
|
})
|
|
require.NoError(t, err)
|
|
list, err := ts.ListUserSettings(ctx, &store.FindUserSetting{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(list))
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetByUserID(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create setting
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
Value: &storepb.UserSetting_General{General: &storepb.GeneralUserSetting{Locale: "zh"}},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Get by user ID
|
|
setting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{
|
|
UserID: &user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, setting)
|
|
require.Equal(t, "zh", setting.GetGeneral().Locale)
|
|
|
|
// Get non-existent key
|
|
nonExistentSetting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{
|
|
UserID: &user.ID,
|
|
Key: storepb.UserSetting_SHORTCUTS,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Nil(t, nonExistentSetting)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingUpsertUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create initial setting
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
Value: &storepb.UserSetting_General{General: &storepb.GeneralUserSetting{Locale: "en"}},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Update setting
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
Value: &storepb.UserSetting_General{General: &storepb.GeneralUserSetting{Locale: "fr"}},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Verify update
|
|
setting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{
|
|
UserID: &user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
})
|
|
require.NoError(t, err)
|
|
require.Equal(t, "fr", setting.GetGeneral().Locale)
|
|
|
|
// Verify only one setting exists
|
|
list, err := ts.ListUserSettings(ctx, &store.FindUserSetting{UserID: &user.ID})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(list))
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingRefreshTokens(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Initially no tokens
|
|
tokens, err := ts.GetUserRefreshTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Empty(t, tokens)
|
|
|
|
// Add a refresh token
|
|
token1 := &storepb.RefreshTokensUserSetting_RefreshToken{
|
|
TokenId: "token-1",
|
|
Description: "Chrome browser session",
|
|
}
|
|
err = ts.AddUserRefreshToken(ctx, user.ID, token1)
|
|
require.NoError(t, err)
|
|
|
|
// Verify token was added
|
|
tokens, err = ts.GetUserRefreshTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokens, 1)
|
|
require.Equal(t, "token-1", tokens[0].TokenId)
|
|
|
|
// Add another token
|
|
token2 := &storepb.RefreshTokensUserSetting_RefreshToken{
|
|
TokenId: "token-2",
|
|
Description: "Firefox browser session",
|
|
}
|
|
err = ts.AddUserRefreshToken(ctx, user.ID, token2)
|
|
require.NoError(t, err)
|
|
|
|
tokens, err = ts.GetUserRefreshTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokens, 2)
|
|
|
|
// Get specific token by ID
|
|
foundToken, err := ts.GetUserRefreshTokenByID(ctx, user.ID, "token-1")
|
|
require.NoError(t, err)
|
|
require.NotNil(t, foundToken)
|
|
require.Equal(t, "Chrome browser session", foundToken.Description)
|
|
|
|
// Get non-existent token
|
|
notFound, err := ts.GetUserRefreshTokenByID(ctx, user.ID, "non-existent")
|
|
require.NoError(t, err)
|
|
require.Nil(t, notFound)
|
|
|
|
// Remove token
|
|
err = ts.RemoveUserRefreshToken(ctx, user.ID, "token-1")
|
|
require.NoError(t, err)
|
|
|
|
tokens, err = ts.GetUserRefreshTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, tokens, 1)
|
|
require.Equal(t, "token-2", tokens[0].TokenId)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingPersonalAccessTokens(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Initially no PATs
|
|
pats, err := ts.GetUserPersonalAccessTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Empty(t, pats)
|
|
|
|
// Add a PAT
|
|
pat1 := &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-1",
|
|
TokenHash: "pat-hash-1",
|
|
Description: "API Token for external access",
|
|
}
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, pat1)
|
|
require.NoError(t, err)
|
|
|
|
// Verify PAT was added
|
|
pats, err = ts.GetUserPersonalAccessTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, pats, 1)
|
|
require.Equal(t, "API Token for external access", pats[0].Description)
|
|
|
|
// Add another PAT
|
|
pat2 := &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-2",
|
|
TokenHash: "pat-hash-2",
|
|
Description: "CI Token",
|
|
}
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, pat2)
|
|
require.NoError(t, err)
|
|
|
|
pats, err = ts.GetUserPersonalAccessTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, pats, 2)
|
|
|
|
// Remove PAT
|
|
err = ts.RemoveUserPersonalAccessToken(ctx, user.ID, "pat-1")
|
|
require.NoError(t, err)
|
|
|
|
pats, err = ts.GetUserPersonalAccessTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, pats, 1)
|
|
require.Equal(t, "pat-2", pats[0].TokenId)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingWebhooks(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Initially no webhooks
|
|
webhooks, err := ts.GetUserWebhooks(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Empty(t, webhooks)
|
|
|
|
// Add a webhook
|
|
webhook1 := &storepb.WebhooksUserSetting_Webhook{
|
|
Id: "webhook-1",
|
|
Title: "Deploy Hook",
|
|
Url: "https://example.com/webhook",
|
|
}
|
|
err = ts.AddUserWebhook(ctx, user.ID, webhook1)
|
|
require.NoError(t, err)
|
|
|
|
// Verify webhook was added
|
|
webhooks, err = ts.GetUserWebhooks(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, webhooks, 1)
|
|
require.Equal(t, "Deploy Hook", webhooks[0].Title)
|
|
|
|
// Update webhook
|
|
webhook1Updated := &storepb.WebhooksUserSetting_Webhook{
|
|
Id: "webhook-1",
|
|
Title: "Updated Deploy Hook",
|
|
Url: "https://example.com/webhook/v2",
|
|
}
|
|
err = ts.UpdateUserWebhook(ctx, user.ID, webhook1Updated)
|
|
require.NoError(t, err)
|
|
|
|
webhooks, err = ts.GetUserWebhooks(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, webhooks, 1)
|
|
require.Equal(t, "Updated Deploy Hook", webhooks[0].Title)
|
|
require.Equal(t, "https://example.com/webhook/v2", webhooks[0].Url)
|
|
|
|
// Add another webhook
|
|
webhook2 := &storepb.WebhooksUserSetting_Webhook{
|
|
Id: "webhook-2",
|
|
Title: "Notification Hook",
|
|
Url: "https://slack.example.com/webhook",
|
|
}
|
|
err = ts.AddUserWebhook(ctx, user.ID, webhook2)
|
|
require.NoError(t, err)
|
|
|
|
webhooks, err = ts.GetUserWebhooks(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, webhooks, 2)
|
|
|
|
// Remove webhook
|
|
err = ts.RemoveUserWebhook(ctx, user.ID, "webhook-1")
|
|
require.NoError(t, err)
|
|
|
|
webhooks, err = ts.GetUserWebhooks(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, webhooks, 1)
|
|
require.Equal(t, "webhook-2", webhooks[0].Id)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingShortcuts(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create shortcuts setting
|
|
shortcuts := &storepb.ShortcutsUserSetting{
|
|
Shortcuts: []*storepb.ShortcutsUserSetting_Shortcut{
|
|
{Id: "shortcut-1", Title: "Work Notes", Filter: "tag:work"},
|
|
{Id: "shortcut-2", Title: "Personal", Filter: "tag:personal"},
|
|
},
|
|
}
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_SHORTCUTS,
|
|
Value: &storepb.UserSetting_Shortcuts{Shortcuts: shortcuts},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Retrieve and verify
|
|
setting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{
|
|
UserID: &user.ID,
|
|
Key: storepb.UserSetting_SHORTCUTS,
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, setting)
|
|
require.Len(t, setting.GetShortcuts().Shortcuts, 2)
|
|
require.Equal(t, "Work Notes", setting.GetShortcuts().Shortcuts[0].Title)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHash(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create a PAT with a known hash
|
|
patHash := "test-pat-hash-12345"
|
|
pat := &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-test-1",
|
|
TokenHash: patHash,
|
|
Description: "Test PAT for lookup",
|
|
}
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, pat)
|
|
require.NoError(t, err)
|
|
|
|
// Lookup user by PAT hash
|
|
result, err := ts.GetUserByPATHash(ctx, patHash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Equal(t, user.ID, result.UserID)
|
|
require.NotNil(t, result.User)
|
|
require.Equal(t, user.Username, result.User.Username)
|
|
require.NotNil(t, result.PAT)
|
|
require.Equal(t, "pat-test-1", result.PAT.TokenId)
|
|
require.Equal(t, "Test PAT for lookup", result.PAT.Description)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashNotFound(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
_, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Lookup non-existent PAT hash
|
|
result, err := ts.GetUserByPATHash(ctx, "non-existent-hash")
|
|
require.Error(t, err)
|
|
require.Nil(t, result)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashMultipleUsers(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user1, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
user2, err := createTestingUserWithRole(ctx, ts, "user2", store.RoleUser)
|
|
require.NoError(t, err)
|
|
|
|
// Create PATs for both users
|
|
pat1Hash := "user1-pat-hash"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user1.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-user1",
|
|
TokenHash: pat1Hash,
|
|
Description: "User 1 PAT",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pat2Hash := "user2-pat-hash"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user2.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-user2",
|
|
TokenHash: pat2Hash,
|
|
Description: "User 2 PAT",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Lookup user1's PAT
|
|
result1, err := ts.GetUserByPATHash(ctx, pat1Hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, user1.ID, result1.UserID)
|
|
require.Equal(t, user1.Username, result1.User.Username)
|
|
|
|
// Lookup user2's PAT
|
|
result2, err := ts.GetUserByPATHash(ctx, pat2Hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, user2.ID, result2.UserID)
|
|
require.Equal(t, user2.Username, result2.User.Username)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashMultiplePATsSameUser(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create multiple PATs for the same user
|
|
pat1Hash := "first-pat-hash"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-1",
|
|
TokenHash: pat1Hash,
|
|
Description: "First PAT",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pat2Hash := "second-pat-hash"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-2",
|
|
TokenHash: pat2Hash,
|
|
Description: "Second PAT",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Both PATs should resolve to the same user
|
|
result1, err := ts.GetUserByPATHash(ctx, pat1Hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, user.ID, result1.UserID)
|
|
require.Equal(t, "pat-1", result1.PAT.TokenId)
|
|
|
|
result2, err := ts.GetUserByPATHash(ctx, pat2Hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, user.ID, result2.UserID)
|
|
require.Equal(t, "pat-2", result2.PAT.TokenId)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingUpdatePATLastUsed(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create a PAT
|
|
patHash := "pat-hash-for-update"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-update-test",
|
|
TokenHash: patHash,
|
|
Description: "PAT for update test",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Update last used timestamp
|
|
now := timestamppb.Now()
|
|
err = ts.UpdatePATLastUsed(ctx, user.ID, "pat-update-test", now)
|
|
require.NoError(t, err)
|
|
|
|
// Verify the update
|
|
pats, err := ts.GetUserPersonalAccessTokens(ctx, user.ID)
|
|
require.NoError(t, err)
|
|
require.Len(t, pats, 1)
|
|
require.NotNil(t, pats[0].LastUsedAt)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashWithExpiredToken(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create a PAT with expiration info
|
|
patHash := "pat-hash-with-expiry"
|
|
expiresAt := timestamppb.Now()
|
|
pat := &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-expiry-test",
|
|
TokenHash: patHash,
|
|
Description: "PAT with expiry",
|
|
ExpiresAt: expiresAt,
|
|
}
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, pat)
|
|
require.NoError(t, err)
|
|
|
|
// Should still be able to look up by hash (expiry check is done at auth level)
|
|
result, err := ts.GetUserByPATHash(ctx, patHash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Equal(t, user.ID, result.UserID)
|
|
require.NotNil(t, result.PAT.ExpiresAt)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashAfterRemoval(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create a PAT
|
|
patHash := "pat-hash-to-remove"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-remove-test",
|
|
TokenHash: patHash,
|
|
Description: "PAT to be removed",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Verify it exists
|
|
result, err := ts.GetUserByPATHash(ctx, patHash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
|
|
// Remove the PAT
|
|
err = ts.RemoveUserPersonalAccessToken(ctx, user.ID, "pat-remove-test")
|
|
require.NoError(t, err)
|
|
|
|
// Should no longer be found
|
|
result, err = ts.GetUserByPATHash(ctx, patHash)
|
|
require.Error(t, err)
|
|
require.Nil(t, result)
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashSpecialCharacters(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create PATs with special characters in hash (simulating real hash values)
|
|
testCases := []struct {
|
|
tokenID string
|
|
tokenHash string
|
|
}{
|
|
{"pat-special-1", "abc123+/=XYZ"},
|
|
{"pat-special-2", "sha256:abcdef1234567890"},
|
|
{"pat-special-3", "$2a$10$N9qo8uLOickgx2ZMRZoMy"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: tc.tokenID,
|
|
TokenHash: tc.tokenHash,
|
|
Description: "PAT with special chars",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Verify lookup works with special characters
|
|
result, err := ts.GetUserByPATHash(ctx, tc.tokenHash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Equal(t, tc.tokenID, result.PAT.TokenId)
|
|
}
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingGetUserByPATHashLargeTokenCount(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create many PATs for the same user
|
|
tokenCount := 10
|
|
hashes := make([]string, tokenCount)
|
|
for i := 0; i < tokenCount; i++ {
|
|
hashes[i] = "pat-hash-" + string(rune('A'+i)) + "-large-test"
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-large-" + string(rune('A'+i)),
|
|
TokenHash: hashes[i],
|
|
Description: "PAT for large count test",
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// Verify each hash can be looked up
|
|
for i, hash := range hashes {
|
|
result, err := ts.GetUserByPATHash(ctx, hash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Equal(t, user.ID, result.UserID)
|
|
require.Equal(t, "pat-large-"+string(rune('A'+i)), result.PAT.TokenId)
|
|
}
|
|
|
|
ts.Close()
|
|
}
|
|
|
|
func TestUserSettingMultipleSettingTypes(t *testing.T) {
|
|
t.Parallel()
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
user, err := createTestingHostUser(ctx, ts)
|
|
require.NoError(t, err)
|
|
|
|
// Create GENERAL setting
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_GENERAL,
|
|
Value: &storepb.UserSetting_General{General: &storepb.GeneralUserSetting{Locale: "ja"}},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create SHORTCUTS setting
|
|
_, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
|
UserId: user.ID,
|
|
Key: storepb.UserSetting_SHORTCUTS,
|
|
Value: &storepb.UserSetting_Shortcuts{Shortcuts: &storepb.ShortcutsUserSetting{
|
|
Shortcuts: []*storepb.ShortcutsUserSetting_Shortcut{
|
|
{Id: "s1", Title: "Shortcut 1"},
|
|
},
|
|
}},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Add a PAT
|
|
err = ts.AddUserPersonalAccessToken(ctx, user.ID, &storepb.PersonalAccessTokensUserSetting_PersonalAccessToken{
|
|
TokenId: "pat-multi",
|
|
TokenHash: "hash-multi",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// List all settings for user
|
|
settings, err := ts.ListUserSettings(ctx, &store.FindUserSetting{UserID: &user.ID})
|
|
require.NoError(t, err)
|
|
require.Len(t, settings, 3)
|
|
|
|
// Verify each setting type
|
|
generalSetting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{UserID: &user.ID, Key: storepb.UserSetting_GENERAL})
|
|
require.NoError(t, err)
|
|
require.Equal(t, "ja", generalSetting.GetGeneral().Locale)
|
|
|
|
shortcutsSetting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{UserID: &user.ID, Key: storepb.UserSetting_SHORTCUTS})
|
|
require.NoError(t, err)
|
|
require.Len(t, shortcutsSetting.GetShortcuts().Shortcuts, 1)
|
|
|
|
patsSetting, err := ts.GetUserSetting(ctx, &store.FindUserSetting{UserID: &user.ID, Key: storepb.UserSetting_PERSONAL_ACCESS_TOKENS})
|
|
require.NoError(t, err)
|
|
require.Len(t, patsSetting.GetPersonalAccessTokens().Tokens, 1)
|
|
|
|
ts.Close()
|
|
}
|