返回 DeepSeek-Reasonix
remote_transcript_path_foreground_test.go
根目录 / desktop / remote_transcript_path_foreground_test.go
1 package main
2
3 import (
4 "context"
5 "net/http/httptest"
6 "path/filepath"
7 "testing"
8 "time"
9
10 "reasonix/internal/agent"
11 "reasonix/internal/config"
12 "reasonix/internal/control"
13 "reasonix/internal/provider"
14 "reasonix/internal/serve"
15 "reasonix/internal/transcript"
16 )
17
18 // A Serve whose foreground is a path-backed session (the controller POST
19 // /resume installs for a historical .jsonl) still serves Follow v2 through the
20 // legacy projection, so the handshake a desktop attaches with must say so.
21 func TestRemoteFollowAttachesToServeWithPathBackedForeground(t *testing.T) {
22 dir := t.TempDir()
23 path := filepath.Join(dir, "session.jsonl")
24 sess := agent.NewSession("system")
25 sess.Add(provider.Message{Role: provider.RoleUser, Content: "question"})
26 sess.Add(provider.Message{Role: provider.RoleAssistant, Content: "answer"})
27 if err := sess.Save(path); err != nil {
28 t.Fatal(err)
29 }
30 bc := serve.NewBroadcaster()
31 ctrl := control.New(control.Options{Executor: agent.New(nil, nil, sess, agent.Options{}, bc), SessionDir: dir, SessionPath: path, Sink: bc})
32 defer ctrl.Close()
33 if ctrl.UsesExclusiveSession() {
34 t.Fatal("fixture must put a path-backed session in the foreground")
35 }
36 server := httptest.NewServer(serve.New(ctrl, bc, config.ServeConfig{AuthMode: "token", Token: "fixture-token"}).Handler())
37 defer server.Close()
38
39 client, err := newServeHTTPClient(server.URL)
40 if err != nil {
41 t.Fatal(err)
42 }
43 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
44 defer cancel()
45 capabilities, err := serveHandshakeCapabilities(ctx, client, server.URL, "fixture-token")
46 if err != nil {
47 t.Fatal(err)
48 }
49 tab := &remoteTab{id: "remote", state: "ready", client: client, base: server.URL, gen: 1,
50 routing: remoteTabSessionRouting{currentPath: path}, capabilities: map[string]bool{}}
51 for _, capability := range capabilities {
52 tab.capabilities[capability] = true
53 }
54 app := &App{remoteTabs: map[string]*remoteTab{tab.id: tab}}
55
56 followed, err := app.RemoteTranscriptFollowForTab(tab.id, transcript.FollowRequest{})
57 if err != nil {
58 t.Fatalf("follow against a path-backed foreground (capabilities %v): %v", capabilities, err)
59 }
60 if followed.ProtocolVersion != transcript.FollowProtocolVersion || followed.Snapshot == nil || followed.Subscription == "" || followed.StorageBackend != "legacy" {
61 t.Fatalf("follow = %+v", followed)
62 }
63 if len(followed.Snapshot.Records) != 2 {
64 t.Fatalf("follow snapshot records = %d, want 2", len(followed.Snapshot.Records))
65 }
66 if _, err := app.RemoteTranscriptFollowForTab(tab.id, transcript.FollowRequest{Subscription: followed.Subscription, Close: true}); err != nil {
67 t.Fatalf("close follow: %v", err)
68 }
69 }
70
70 lines GO