axonhub-chat / internal /server /backup /backup_apikey_test.go
llzai's picture
Upload 1793 files
9853396 verified
package backup
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/looplj/axonhub/internal/ent"
"github.com/looplj/axonhub/internal/ent/apikey"
"github.com/looplj/axonhub/internal/objects"
)
func TestBackupService_Backup_WithAPIKeys(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
user, _ := client.User.Query().First(ctx)
require.NotNil(t, user)
proj1 := createBackupTestProject(t, client, ctx, "Project1", "Test Project 1")
proj2 := createBackupTestProject(t, client, ctx, "Project2", "Test Project 2")
ak1 := createBackupTestAPIKey(t, client, ctx, user, proj1, "API Key 1", "sk-test-key-1")
ak2 := createBackupTestAPIKey(t, client, ctx, user, proj2, "API Key 2", "sk-test-key-2")
data, err := service.Backup(ctx, BackupOptions{
IncludeAPIKeys: true,
})
require.NoError(t, err)
require.NotNil(t, data)
var backupData BackupData
err = json.Unmarshal(data, &backupData)
require.NoError(t, err)
require.Equal(t, BackupVersion, backupData.Version)
require.Len(t, backupData.APIKeys, 2)
require.Equal(t, ak1.Name, backupData.APIKeys[0].Name)
require.Equal(t, ak1.Key, backupData.APIKeys[0].Key)
require.Equal(t, "Project1", backupData.APIKeys[0].ProjectName)
require.Equal(t, ak2.Name, backupData.APIKeys[1].Name)
require.Equal(t, ak2.Key, backupData.APIKeys[1].Key)
require.Equal(t, "Project2", backupData.APIKeys[1].ProjectName)
}
func TestBackupService_Restore_APIKeys_NewKeys(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
proj1 := createBackupTestProject(t, client, ctx, "TestProject", "Test Project")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-new-key-1",
Name: "New API Key 1",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "TestProject",
},
{
APIKey: ent.APIKey{
Key: "sk-new-key-2",
Name: "New API Key 2",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "TestProject",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyOverwrite,
})
require.NoError(t, err)
apiKeys, err := client.APIKey.Query().WithProject().All(ctx)
require.NoError(t, err)
require.Len(t, apiKeys, 2)
ak1, err := client.APIKey.Query().
Where(apikey.Key("sk-new-key-1")).
WithProject().
First(ctx)
require.NoError(t, err)
require.Equal(t, "New API Key 1", ak1.Name)
require.Equal(t, proj1.ID, ak1.Edges.Project.ID)
require.Equal(t, "TestProject", ak1.Edges.Project.Name)
ak2, err := client.APIKey.Query().
Where(apikey.Key("sk-new-key-2")).
WithProject().
First(ctx)
require.NoError(t, err)
require.Equal(t, "New API Key 2", ak2.Name)
require.Equal(t, proj1.ID, ak2.Edges.Project.ID)
}
func TestBackupService_Restore_APIKeys_DefaultProject(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
createBackupTestProject(t, client, ctx, "Default", "Default Project")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-default-key",
Name: "Default API Key",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyOverwrite,
})
require.NoError(t, err)
ak, err := client.APIKey.Query().
Where(apikey.Key("sk-default-key")).
WithProject().
First(ctx)
require.NoError(t, err)
require.Equal(t, "Default API Key", ak.Name)
require.Equal(t, "Default", ak.Edges.Project.Name)
}
func TestBackupService_Restore_APIKeys_ProjectNotFound(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-orphan-key",
Name: "Orphan API Key",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "NonExistentProject",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyOverwrite,
})
require.NoError(t, err)
count, err := client.APIKey.Query().Count(ctx)
require.NoError(t, err)
require.Equal(t, 0, count)
}
func TestBackupService_Restore_APIKeys_ConflictSkip(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
user, _ := client.User.Query().First(ctx)
proj := createBackupTestProject(t, client, ctx, "TestProject", "Test Project")
createBackupTestAPIKey(t, client, ctx, user, proj, "Existing Key", "sk-existing-key")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-existing-key",
Name: "Updated Key Name",
Type: "service_account",
Status: "disabled",
Scopes: []string{"chat", "embedding"},
Profiles: profiles,
},
ProjectName: "TestProject",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategySkip,
})
require.NoError(t, err)
ak, err := client.APIKey.Query().
Where(apikey.Key("sk-existing-key")).
First(ctx)
require.NoError(t, err)
require.Equal(t, "Existing Key", ak.Name)
require.Equal(t, apikey.TypeUser, ak.Type)
require.Equal(t, apikey.StatusEnabled, ak.Status)
}
func TestBackupService_Restore_APIKeys_ConflictOverwrite(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
user, _ := client.User.Query().First(ctx)
proj := createBackupTestProject(t, client, ctx, "TestProject", "Test Project")
createBackupTestAPIKey(t, client, ctx, user, proj, "Existing Key", "sk-existing-key")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "production",
Profiles: []objects.APIKeyProfile{
{
Name: "production",
ModelIDs: []string{"gpt-4", "claude-3"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-existing-key",
Name: "Updated Key Name",
Type: "service_account",
Status: "disabled",
Scopes: []string{"chat", "embedding"},
Profiles: profiles,
},
ProjectName: "TestProject",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyOverwrite,
})
require.NoError(t, err)
ak, err := client.APIKey.Query().
Where(apikey.Key("sk-existing-key")).
First(ctx)
require.NoError(t, err)
require.Equal(t, "Updated Key Name", ak.Name)
require.Equal(t, apikey.TypeServiceAccount, ak.Type)
require.Equal(t, apikey.StatusDisabled, ak.Status)
require.Equal(t, []string{"chat", "embedding"}, ak.Scopes)
require.Equal(t, "production", ak.Profiles.ActiveProfile)
}
func TestBackupService_Restore_APIKeys_ConflictError(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
user, _ := client.User.Query().First(ctx)
proj := createBackupTestProject(t, client, ctx, "TestProject", "Test Project")
createBackupTestAPIKey(t, client, ctx, user, proj, "Existing Key", "sk-existing-key")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-existing-key",
Name: "Updated Key Name",
Type: "service_account",
Status: "disabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "TestProject",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyError,
})
require.Error(t, err)
require.Contains(t, err.Error(), "already exists")
}
func TestBackupService_Restore_APIKeys_MultipleProjects(t *testing.T) {
client, service, ctx := setupBackupTest(t)
defer client.Close()
proj1 := createBackupTestProject(t, client, ctx, "Project1", "Test Project 1")
proj2 := createBackupTestProject(t, client, ctx, "Project2", "Test Project 2")
profiles := &objects.APIKeyProfiles{
ActiveProfile: "default",
Profiles: []objects.APIKeyProfile{
{
Name: "default",
ModelIDs: []string{"gpt-4"},
},
},
}
backupData := BackupData{
Version: BackupVersion,
APIKeys: []*BackupAPIKey{
{
APIKey: ent.APIKey{
Key: "sk-proj1-key",
Name: "Project 1 Key",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "Project1",
},
{
APIKey: ent.APIKey{
Key: "sk-proj2-key",
Name: "Project 2 Key",
Type: "user",
Status: "enabled",
Scopes: []string{"chat"},
Profiles: profiles,
},
ProjectName: "Project2",
},
},
}
data, err := json.MarshalIndent(backupData, "", " ")
require.NoError(t, err)
err = service.Restore(ctx, data, RestoreOptions{
IncludeAPIKeys: true,
APIKeyConflictStrategy: ConflictStrategyOverwrite,
})
require.NoError(t, err)
ak1, err := client.APIKey.Query().
Where(apikey.Key("sk-proj1-key")).
WithProject().
First(ctx)
require.NoError(t, err)
require.Equal(t, "Project 1 Key", ak1.Name)
require.Equal(t, proj1.ID, ak1.Edges.Project.ID)
ak2, err := client.APIKey.Query().
Where(apikey.Key("sk-proj2-key")).
WithProject().
First(ctx)
require.NoError(t, err)
require.Equal(t, "Project 2 Key", ak2.Name)
require.Equal(t, proj2.ID, ak2.Edges.Project.ID)
}