222 lines
6.8 KiB
Go
222 lines
6.8 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadSessionWithOptionsRejectsCompactPlaceholder(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: "{{session_id}}"
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
_, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{SessionID: "2026-04-04"})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
assertConcreteSessionTemplateError(t, err, "session_id")
|
|
}
|
|
|
|
func TestLoadSessionWithOptionsRejectsSpacedPlaceholder(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: "{{ session_id }}"
|
|
previous_session_id: "{{ previous_session_id }}"
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
_, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{
|
|
SessionID: "2026-04-04",
|
|
PreviousSessionID: "2026-03-28",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
assertConcreteSessionTemplateError(t, err, "session_id", "previous_session_id")
|
|
}
|
|
|
|
func TestLoadSessionWithOptionsMismatchFails(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: 2026-05-03
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
_, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{SessionID: "2026-04-04"})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "session_id mismatch") {
|
|
t.Fatalf("error = %q, want mismatch context", err.Error())
|
|
}
|
|
if strings.Contains(err.Error(), "rendered") {
|
|
t.Fatalf("error = %q, should not mention rendered session", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestLoadSessionWithOptionsPreviousSessionMismatchFails(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: 2026-05-03
|
|
previous_session_id: 2026-04-26
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
_, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{
|
|
SessionID: "2026-05-03",
|
|
PreviousSessionID: "2026-04-25",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "previous_session_id mismatch") {
|
|
t.Fatalf("error = %q, want mismatch context", err.Error())
|
|
}
|
|
if strings.Contains(err.Error(), "rendered") {
|
|
t.Fatalf("error = %q, should not mention rendered session", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestLoadSessionWithOptionsUnknownFieldStillRejected(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: 2026-04-04
|
|
campaign: sample-campaign
|
|
unknown_field: true
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
_, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{SessionID: "2026-04-04"})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "strict decode failed") {
|
|
t.Fatalf("error = %q, want strict-decode context", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestLoadSessionWithOptionsConcreteSessionStillLoads(t *testing.T) {
|
|
dir := t.TempDir()
|
|
sessionPath := filepath.Join(dir, "session.yml")
|
|
sessionYAML := `session_id: 2026-05-03
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_dir: ./audio
|
|
speakers_file: ./speakers.yml
|
|
autocorrect_file: ./autocorrect.yml
|
|
glossary_file: ./glossary.yml
|
|
`
|
|
if err := os.WriteFile(sessionPath, []byte(sessionYAML), 0o644); err != nil {
|
|
t.Fatalf("write session.yml: %v", err)
|
|
}
|
|
|
|
cfg, err := LoadSessionWithOptions(sessionPath, SessionLoadOptions{})
|
|
if err != nil {
|
|
t.Fatalf("LoadSessionWithOptions() error = %v", err)
|
|
}
|
|
if cfg.SessionID != "2026-05-03" {
|
|
t.Fatalf("SessionID = %q, want 2026-05-03", cfg.SessionID)
|
|
}
|
|
}
|
|
|
|
func TestLoadSessionBytesWithOptionsRejectsPlaceholder(t *testing.T) {
|
|
sessionYAML := []byte(`session_id: "{{ session_id }}"
|
|
campaign: sample-campaign
|
|
inputs:
|
|
audio_s3:
|
|
prefix: audio/
|
|
`)
|
|
|
|
_, err := LoadSessionBytesWithOptions("s3://bucket/session.yml", sessionYAML, SessionLoadOptions{SessionID: "2026-05-03"})
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
assertConcreteSessionTemplateError(t, err, "session_id")
|
|
}
|
|
|
|
func TestLoadSessionBytesWithOptionsStrictDecode(t *testing.T) {
|
|
cfg, err := LoadSessionBytesWithOptions("s3://bucket/session.yml", []byte("session_id: 2026-05-03\n"), SessionLoadOptions{})
|
|
if err != nil {
|
|
t.Fatalf("LoadSessionBytesWithOptions() error = %v", err)
|
|
}
|
|
if cfg.SessionID != "2026-05-03" {
|
|
t.Fatalf("SessionID = %q, want 2026-05-03", cfg.SessionID)
|
|
}
|
|
|
|
_, err = LoadSessionBytesWithOptions("s3://bucket/session.yml", []byte("session_id: 2026-05-03\nunknown: true\n"), SessionLoadOptions{})
|
|
if err == nil {
|
|
t.Fatal("expected strict decode error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "strict decode failed") {
|
|
t.Fatalf("error = %q, want strict decode context", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestLoadSessionBytesWithOptionsMismatchFails(t *testing.T) {
|
|
_, err := LoadSessionBytesWithOptions("s3://bucket/session.yml", []byte("session_id: 2026-05-03\n"), SessionLoadOptions{SessionID: "2026-04-04"})
|
|
if err == nil {
|
|
t.Fatal("expected mismatch error, got nil")
|
|
}
|
|
if !strings.Contains(err.Error(), "session_id mismatch") {
|
|
t.Fatalf("error = %q, want mismatch context", err.Error())
|
|
}
|
|
}
|
|
|
|
func assertConcreteSessionTemplateError(t *testing.T, err error, vars ...string) {
|
|
t.Helper()
|
|
if !strings.Contains(err.Error(), "session.yml must be concrete") {
|
|
t.Fatalf("error = %q, want concrete session guidance", err.Error())
|
|
}
|
|
if !strings.Contains(err.Error(), "run narratio session init") {
|
|
t.Fatalf("error = %q, want session init guidance", err.Error())
|
|
}
|
|
for _, name := range vars {
|
|
if !strings.Contains(err.Error(), name) {
|
|
t.Fatalf("error = %q, want variable %q", err.Error(), name)
|
|
}
|
|
}
|
|
}
|