mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
455e2f8be5
Public config now comes from admin as a flat visibility=1 map instead of a cross-plugin query that compared an integer column to "visible". Login and register resolve CaptchaService per request so CAP is not skipped when user applies before cap.
205 lines
5.7 KiB
Go
205 lines
5.7 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package service_test
|
|
|
|
import (
|
|
"Wavelet/plugins/domain/admin/model"
|
|
"Wavelet/plugins/domain/admin/repository"
|
|
"Wavelet/plugins/domain/admin/service"
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/glebarez/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type testDBService struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func (s *testDBService) DB(ctx context.Context) *gorm.DB {
|
|
return s.db
|
|
}
|
|
|
|
func (s *testDBService) MasterDB(ctx context.Context) *gorm.DB {
|
|
return s.db
|
|
}
|
|
|
|
func (s *testDBService) GORM() *gorm.DB {
|
|
return s.db
|
|
}
|
|
|
|
func (s *testDBService) Named(_ string) *gorm.DB {
|
|
return s.db
|
|
}
|
|
|
|
func setupSystemConfigTest(t *testing.T) (*gorm.DB, func()) {
|
|
t.Helper()
|
|
|
|
sqliteDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
|
|
DisableForeignKeyConstraintWhenMigrating: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("gorm.Open(sqlite) error = %v", err)
|
|
}
|
|
if err := sqliteDB.AutoMigrate(&model.SystemConfig{}); err != nil {
|
|
t.Fatalf("AutoMigrate(SystemConfig) error = %v", err)
|
|
}
|
|
|
|
siteConfig := model.SystemConfig{
|
|
Key: model.ConfigKeySiteName,
|
|
Value: "Wavelet",
|
|
Type: "system",
|
|
Description: "系统平台的展示名称",
|
|
}
|
|
if err := sqliteDB.Create(&siteConfig).Error; err != nil {
|
|
t.Fatalf("Create(site_name) error = %v", err)
|
|
}
|
|
|
|
service.SetDBService(&testDBService{db: sqliteDB})
|
|
|
|
cleanup := func() {
|
|
repository.StopSystemConfigCacheListener()
|
|
repository.ResetSystemConfigRAMCacheForTest()
|
|
service.ResetServices()
|
|
}
|
|
|
|
return sqliteDB, cleanup
|
|
}
|
|
|
|
func TestPublicSystemConfigsExposesVisibleKeys(t *testing.T) {
|
|
dbConn, cleanup := setupSystemConfigTest(t)
|
|
defer cleanup()
|
|
repository.ResetSystemConfigRAMCacheForTest()
|
|
ctx := context.Background()
|
|
|
|
hidden := model.SystemConfig{
|
|
Key: "secret_key",
|
|
Value: "nope",
|
|
Type: "system",
|
|
Visibility: model.ConfigVisibilityHidden,
|
|
}
|
|
visible := model.SystemConfig{
|
|
Key: model.ConfigKeyCapLoginEnabled,
|
|
Value: "true",
|
|
Type: "system",
|
|
Visibility: model.ConfigVisibilityVisible,
|
|
}
|
|
if err := dbConn.Create(&hidden).Error; err != nil {
|
|
t.Fatalf("Create(hidden) error = %v", err)
|
|
}
|
|
if err := dbConn.Create(&visible).Error; err != nil {
|
|
t.Fatalf("Create(visible) error = %v", err)
|
|
}
|
|
|
|
got, err := service.PublicSystemConfigs(ctx)
|
|
if err != nil {
|
|
t.Fatalf("PublicSystemConfigs() error = %v", err)
|
|
}
|
|
if got[model.ConfigKeyCapLoginEnabled] != "true" {
|
|
t.Fatalf("PublicSystemConfigs()[%s] = %q, want %q", model.ConfigKeyCapLoginEnabled, got[model.ConfigKeyCapLoginEnabled], "true")
|
|
}
|
|
if _, ok := got["secret_key"]; ok {
|
|
t.Fatalf("PublicSystemConfigs() leaked hidden key secret_key")
|
|
}
|
|
|
|
viaProvider, err := service.PublicConfigAdapter{}.PublicConfig(ctx)
|
|
if err != nil {
|
|
t.Fatalf("PublicConfigAdapter.PublicConfig() error = %v", err)
|
|
}
|
|
if viaProvider[model.ConfigKeyCapLoginEnabled] != "true" {
|
|
t.Fatalf("PublicConfigAdapter.PublicConfig()[%s] = %q, want %q", model.ConfigKeyCapLoginEnabled, viaProvider[model.ConfigKeyCapLoginEnabled], "true")
|
|
}
|
|
}
|
|
|
|
func TestListSystemConfigsByKeys_EmptyKeys(t *testing.T) {
|
|
result, err := repository.ListSystemConfigsByKeys(context.Background(), nil)
|
|
if err != nil {
|
|
t.Fatalf("ListSystemConfigsByKeys(nil) error = %v", err)
|
|
}
|
|
if len(result) != 0 {
|
|
t.Fatalf("ListSystemConfigsByKeys(nil) = %#v, want empty map", result)
|
|
}
|
|
}
|
|
|
|
func TestListSystemConfigsByKeys_LoadsFromRAMCache(t *testing.T) {
|
|
dbConn, cleanup := setupSystemConfigTest(t)
|
|
defer cleanup()
|
|
ctx := context.Background()
|
|
|
|
repository.ResetSystemConfigRAMCacheForTest()
|
|
|
|
// Initial load
|
|
warm, err := repository.GetSystemConfigByKey(ctx, model.ConfigKeySiteName)
|
|
if err != nil {
|
|
t.Fatalf("GetSystemConfigByKey(site_name) warm error = %v", err)
|
|
}
|
|
if warm.Value != "Wavelet" {
|
|
t.Fatalf("GetSystemConfigByKey(site_name).Value = %q, want %q", warm.Value, "Wavelet")
|
|
}
|
|
|
|
// Update DB directly
|
|
if err := dbConn.Model(&model.SystemConfig{}).
|
|
Where("key = ?", model.ConfigKeySiteName).
|
|
Update("value", "db_only_value").Error; err != nil {
|
|
t.Fatalf("Update(site_name) error = %v", err)
|
|
}
|
|
|
|
// Fetch via ListSystemConfigsByKeys should serve from local store (meaning the old value "Wavelet")
|
|
configs, err := repository.ListSystemConfigsByKeys(ctx, []string{model.ConfigKeySiteName})
|
|
if err != nil {
|
|
t.Fatalf("ListSystemConfigsByKeys(site_name) error = %v", err)
|
|
}
|
|
|
|
sc, ok := configs[model.ConfigKeySiteName]
|
|
if !ok {
|
|
t.Fatal("ListSystemConfigsByKeys(site_name) missing site_name entry")
|
|
}
|
|
if sc.Value != "Wavelet" {
|
|
t.Fatalf("ListSystemConfigsByKeys(site_name).Value = %q, want cached value %q", sc.Value, "Wavelet")
|
|
}
|
|
}
|
|
|
|
func TestGetSystemConfigByGroupAndInvalidation(t *testing.T) {
|
|
dbConn, cleanup := setupSystemConfigTest(t)
|
|
defer cleanup()
|
|
ctx := context.Background()
|
|
|
|
repository.ResetSystemConfigRAMCacheForTest()
|
|
|
|
// Get via specific group/type
|
|
cfg, err := repository.GetSystemConfigByGroup(ctx, repository.ConfigCacheType, model.ConfigKeySiteName)
|
|
if err != nil {
|
|
t.Fatalf("GetSystemConfigByGroup error = %v", err)
|
|
}
|
|
if cfg.Value != "Wavelet" {
|
|
t.Fatalf("value = %q, want %q", cfg.Value, "Wavelet")
|
|
}
|
|
|
|
// Direct DB update
|
|
if err := dbConn.Model(&model.SystemConfig{}).
|
|
Where("key = ?", model.ConfigKeySiteName).
|
|
Update("value", "new_site_name").Error; err != nil {
|
|
t.Fatalf("DB Update error = %v", err)
|
|
}
|
|
|
|
// Invalidate
|
|
if err := repository.InvalidateSystemConfigCache(ctx, model.ConfigKeySiteName); err != nil {
|
|
t.Fatalf("InvalidateSystemConfigCache error = %v", err)
|
|
}
|
|
|
|
// Wait for broadcast execution
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Fetch again
|
|
updated, err := repository.GetSystemConfigByKey(ctx, model.ConfigKeySiteName)
|
|
if err != nil {
|
|
t.Fatalf("GetSystemConfigByKey error = %v", err)
|
|
}
|
|
if updated.Value != "new_site_name" {
|
|
t.Fatalf("value = %q, want %q", updated.Value, "new_site_name")
|
|
}
|
|
}
|