1package modes
2
3import (
4 "context"
5 "errors"
6 "testing"
7
8 "github.com/patriceckhart/zot/packages/core"
9 "github.com/patriceckhart/zot/packages/provider"
10)
11
12func TestNewSessionUnavailableWithoutPersistence(t *testing.T) {
13 i := NewInteractive(InteractiveConfig{})
14 if i.slashCancelsActiveTurn("/new") {
15 t.Fatal("unavailable /new would cancel the active turn")
16 }
17 i.runSlash(context.Background(), "/new")
18
19 if i.statusErr != "sessions are disabled by --no-session" {
20 t.Fatalf("status error = %q", i.statusErr)
21 }
22}
23
24func TestNewSessionResetsConversationView(t *testing.T) {
25 ag := core.NewAgent(nil, "model", "", nil)
26 ag.SetMessages([]provider.Message{{
27 Role: provider.RoleUser,
28 Content: []provider.Content{provider.TextBlock{Text: "old conversation"}},
29 }})
30 calls := 0
31 var gotProvider, gotModel string
32 gate := core.NewConfirmGate(nil)
33 gate.AllowAll()
34 i := NewInteractive(InteractiveConfig{
35 Agent: ag,
36 Provider: "test-provider",
37 Model: "active-model",
38 ConfirmGate: gate,
39 NewSession: func(providerName, model string) error {
40 calls++
41 gotProvider, gotModel = providerName, model
42 ag.SetMessages(nil)
43 return nil
44 },
45 })
46 i.cumUsage = provider.Usage{InputTokens: 10}
47 i.lastCtxInput = 10
48 i.extNotes = []string{"old notice"}
49
50 i.runSlash(context.Background(), "/new")
51
52 if calls != 1 {
53 t.Fatalf("NewSession calls = %d, want 1", calls)
54 }
55 if gotProvider != "test-provider" || gotModel != "active-model" {
56 t.Fatalf("NewSession model = %q/%q", gotProvider, gotModel)
57 }
58 if len(ag.Messages()) != 0 || len(i.view.Messages) != 0 {
59 t.Fatal("new session retained the previous transcript")
60 }
61 if i.cumUsage != (provider.Usage{}) || i.lastCtxInput != 0 {
62 t.Fatalf("usage was not reset: cumulative=%+v context=%d", i.cumUsage, i.lastCtxInput)
63 }
64 if len(i.extNotes) != 0 {
65 t.Fatalf("extension notices were not cleared: %v", i.extNotes)
66 }
67 if decision := gate.DecideToolCall(core.ToolCallConfirmation{Name: "bash"}); decision.Allow {
68 t.Fatal("new session retained session-scoped confirmation approval")
69 }
70 if i.statusOK != "started new session" || i.statusErr != "" {
71 t.Fatalf("status = %q, %q", i.statusOK, i.statusErr)
72 }
73}
74
75func TestNewSessionFailureKeepsConversationView(t *testing.T) {
76 ag := core.NewAgent(nil, "model", "", nil)
77 messages := []provider.Message{{
78 Role: provider.RoleUser,
79 Content: []provider.Content{provider.TextBlock{Text: "still active"}},
80 }}
81 ag.SetMessages(messages)
82 i := NewInteractive(InteractiveConfig{
83 Agent: ag,
84 NewSession: func(string, string) error { return errors.New("disk full") },
85 })
86
87 i.runSlash(context.Background(), "/new")
88
89 if len(ag.Messages()) != 1 || len(i.view.Messages) != 1 {
90 t.Fatal("failed session creation cleared the current transcript")
91 }
92 if i.statusErr != "start new session: disk full" {
93 t.Fatalf("status error = %q", i.statusErr)
94 }
95}