Infra ADR-0004 renamed the Gitea host. Bulk replace across go.mod and all .go import paths. Build and tests pass unchanged. Closes #20 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dt6aHEDWRjkK14Voi6HnGh
110 lines
4.0 KiB
Go
110 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.d-ma.be/mathias/tapir/internal/config"
|
|
)
|
|
|
|
// TestBuildProcessorNilOnIncompleteConfig asserts the queue-only fallback: when a
|
|
// required input is missing, buildProcessor returns (nil, nil) — never an error —
|
|
// so the web UI degrades to queue-only instead of failing to start.
|
|
func TestBuildProcessorNilOnIncompleteConfig(t *testing.T) {
|
|
// A complete config (the fields buildProcessor gates on). The store is nil:
|
|
// buildProcessor must not touch it on the incomplete paths, and the complete
|
|
// path only stores the pointer (no connection), so nil is fine for this test.
|
|
complete := config.Config{
|
|
GatewayURL: "http://gw/v1",
|
|
YTClientID: "id",
|
|
YTClientSecret: "secret",
|
|
SecretsFile: "/tmp/secrets.json",
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
mutate func(config.Config) config.Config
|
|
wantNil bool
|
|
}{
|
|
{"complete", func(c config.Config) config.Config { return c }, false},
|
|
{"no gateway url", func(c config.Config) config.Config { c.GatewayURL = ""; return c }, true},
|
|
{"no yt client id", func(c config.Config) config.Config { c.YTClientID = ""; return c }, true},
|
|
{"no yt client secret", func(c config.Config) config.Config { c.YTClientSecret = ""; return c }, true},
|
|
{"no secrets file", func(c config.Config) config.Config { c.SecretsFile = ""; return c }, true},
|
|
{"empty config", func(config.Config) config.Config { return config.Config{} }, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
engine, err := buildProcessor(tt.mutate(complete), nil)
|
|
if err != nil {
|
|
t.Fatalf("buildProcessor returned an error, want nil: %v", err)
|
|
}
|
|
if (engine == nil) != tt.wantNil {
|
|
t.Fatalf("engine == nil is %v, want %v", engine == nil, tt.wantNil)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestBurstChainModelsLeadsWithOnboardModel: the onboarding burst chain (ADR-028)
|
|
// leads with the stronger onboard model, then falls back through the standard
|
|
// ADR-022 chain (primary -> local fallback -> cloud), deduped.
|
|
func TestBurstChainModelsLeadsWithOnboardModel(t *testing.T) {
|
|
got := burstChainModels(config.Config{
|
|
OnboardSummarizerModel: "iguana/gemma4-26b",
|
|
SummarizerModel: "koala/phi4-mini",
|
|
FallbackModel: "iguana/gemma4-26b", // also the onboard model -> dedup
|
|
CloudFallbackModel: "berget/mistral-small",
|
|
})
|
|
want := []string{"iguana/gemma4-26b", "koala/phi4-mini", "berget/mistral-small"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("burstChainModels = %v, want %v", got, want)
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("burstChainModels = %v, want %v", got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestBurstChainModelsCloudAbsentWhenDisabled: the NDA lever holds for the burst
|
|
// too — empty cloud fallback keeps the burst chain fully local.
|
|
func TestBurstChainModelsCloudAbsentWhenDisabled(t *testing.T) {
|
|
got := burstChainModels(config.Config{
|
|
OnboardSummarizerModel: "iguana/gemma4-26b",
|
|
SummarizerModel: "koala/phi4-mini",
|
|
CloudFallbackModel: "",
|
|
})
|
|
for _, m := range got {
|
|
if m == "" || m == "berget/mistral-small" {
|
|
t.Fatalf("cloud model leaked into burst chain: %v", got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestBuildBurstProcessorNilWhenCollapsed: an empty or primary-equal onboard model
|
|
// collapses the burst onto the shared processor (buildBurstProcessor returns nil).
|
|
func TestBuildBurstProcessorNilWhenCollapsed(t *testing.T) {
|
|
base := config.Config{
|
|
GatewayURL: "http://gw/v1",
|
|
YTClientID: "id",
|
|
YTClientSecret: "secret",
|
|
SecretsFile: "/tmp/secrets.json",
|
|
SummarizerModel: "koala/phi4-mini",
|
|
}
|
|
t.Run("empty onboard model", func(t *testing.T) {
|
|
base.OnboardSummarizerModel = ""
|
|
eng, err := buildBurstProcessor(base, nil)
|
|
if err != nil || eng != nil {
|
|
t.Fatalf("buildBurstProcessor = (%v, %v), want (nil, nil)", eng, err)
|
|
}
|
|
})
|
|
t.Run("onboard model equals primary", func(t *testing.T) {
|
|
base.OnboardSummarizerModel = "koala/phi4-mini"
|
|
eng, err := buildBurstProcessor(base, nil)
|
|
if err != nil || eng != nil {
|
|
t.Fatalf("buildBurstProcessor = (%v, %v), want (nil, nil)", eng, err)
|
|
}
|
|
})
|
|
}
|