41f3060e00
- Introduced BrandLibrarySummary type to encapsulate brand library limits and usage. - Updated Brand interface to include keyword_count and question_count fields. - Implemented brand library limits in the backend, including max brands, keywords, and questions per keyword. - Added API endpoint to retrieve brand library summary. - Enhanced BrandsView.vue to display brand library usage and limits. - Implemented computed properties to manage brand, keyword, and question limits in the UI. - Updated mutation handlers to invalidate relevant queries upon creating/updating brands, keywords, and questions. - Added visual indicators for brand, keyword, and question limits in the UI. - Enhanced error handling for exceeding brand and keyword limits during creation.
127 lines
3.3 KiB
Go
127 lines
3.3 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadPrefersEnvLLMAPIKey(t *testing.T) {
|
|
t.Setenv("LLM_API_KEY", "env-priority-key")
|
|
|
|
configPath := writeTestConfig(t, `
|
|
llm:
|
|
provider: ark
|
|
api_key: "config-file-key"
|
|
`)
|
|
|
|
cfg, err := Load(configPath)
|
|
if err != nil {
|
|
t.Fatalf("Load() error = %v", err)
|
|
}
|
|
|
|
if cfg.LLM.APIKey != "env-priority-key" {
|
|
t.Fatalf("expected env api key, got %q", cfg.LLM.APIKey)
|
|
}
|
|
}
|
|
|
|
func TestLoadFallsBackToConfigLLMAPIKey(t *testing.T) {
|
|
t.Setenv("LLM_API_KEY", "")
|
|
|
|
configPath := writeTestConfig(t, `
|
|
llm:
|
|
provider: ark
|
|
api_key: "config-file-key"
|
|
`)
|
|
|
|
cfg, err := Load(configPath)
|
|
if err != nil {
|
|
t.Fatalf("Load() error = %v", err)
|
|
}
|
|
|
|
if cfg.LLM.APIKey != "config-file-key" {
|
|
t.Fatalf("expected config api key, got %q", cfg.LLM.APIKey)
|
|
}
|
|
}
|
|
|
|
func TestLoadPrefersEnvRetrievalAndQdrantSettings(t *testing.T) {
|
|
t.Setenv("SILICONFLOW_API_KEY", "siliconflow-env-key")
|
|
t.Setenv("SILICONFLOW_EMBEDDING_MODEL", "env-embedding")
|
|
t.Setenv("SILICONFLOW_RERANKER_MODEL", "env-reranker")
|
|
t.Setenv("QDRANT_API_KEY", "qdrant-env-key")
|
|
t.Setenv("QDRANT_URL", "qdrant-env:6334")
|
|
t.Setenv("QDRANT_COLLECTION", "env_collection")
|
|
|
|
configPath := writeTestConfig(t, `
|
|
qdrant:
|
|
url: qdrant-config:6334
|
|
api_key: "qdrant-config-key"
|
|
collection: "config_collection"
|
|
retrieval:
|
|
provider: siliconflow
|
|
api_key: "retrieval-config-key"
|
|
embedding_model: "config-embedding"
|
|
reranker_model: "config-reranker"
|
|
`)
|
|
|
|
cfg, err := Load(configPath)
|
|
if err != nil {
|
|
t.Fatalf("Load() error = %v", err)
|
|
}
|
|
|
|
if cfg.Retrieval.APIKey != "siliconflow-env-key" {
|
|
t.Fatalf("expected env retrieval api key, got %q", cfg.Retrieval.APIKey)
|
|
}
|
|
if cfg.Retrieval.EmbeddingModel != "env-embedding" {
|
|
t.Fatalf("expected env embedding model, got %q", cfg.Retrieval.EmbeddingModel)
|
|
}
|
|
if cfg.Retrieval.RerankerModel != "env-reranker" {
|
|
t.Fatalf("expected env reranker model, got %q", cfg.Retrieval.RerankerModel)
|
|
}
|
|
if cfg.Qdrant.APIKey != "qdrant-env-key" {
|
|
t.Fatalf("expected env qdrant api key, got %q", cfg.Qdrant.APIKey)
|
|
}
|
|
if cfg.Qdrant.URL != "qdrant-env:6334" {
|
|
t.Fatalf("expected env qdrant url, got %q", cfg.Qdrant.URL)
|
|
}
|
|
if cfg.Qdrant.Collection != "env_collection" {
|
|
t.Fatalf("expected env qdrant collection, got %q", cfg.Qdrant.Collection)
|
|
}
|
|
}
|
|
|
|
func TestLoadAppliesBrandLibraryDefaults(t *testing.T) {
|
|
configPath := writeTestConfig(t, `
|
|
brand_library: {}
|
|
`)
|
|
|
|
cfg, err := Load(configPath)
|
|
if err != nil {
|
|
t.Fatalf("Load() error = %v", err)
|
|
}
|
|
|
|
if cfg.BrandLibrary.FreeBrandLimit != 1 {
|
|
t.Fatalf("expected default free brand limit 1, got %d", cfg.BrandLibrary.FreeBrandLimit)
|
|
}
|
|
if cfg.BrandLibrary.PaidBrandLimit != 2 {
|
|
t.Fatalf("expected default paid brand limit 2, got %d", cfg.BrandLibrary.PaidBrandLimit)
|
|
}
|
|
if cfg.BrandLibrary.MaxKeywords != 5 {
|
|
t.Fatalf("expected default max keywords 5, got %d", cfg.BrandLibrary.MaxKeywords)
|
|
}
|
|
if cfg.BrandLibrary.MaxQuestionsPerKeyword != 5 {
|
|
t.Fatalf("expected default max questions per keyword 5, got %d", cfg.BrandLibrary.MaxQuestionsPerKeyword)
|
|
}
|
|
}
|
|
|
|
func writeTestConfig(t *testing.T, body string) string {
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "config.yaml")
|
|
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
|
|
t.Fatalf("write config: %v", err)
|
|
}
|
|
|
|
return path
|
|
}
|