返回 DeepSeek-Reasonix
extension_form_http_test.go
根目录 / internal / serve / extension_form_http_test.go
1 package serve
2
3 import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "strings"
8 "testing"
9
10 "reasonix/internal/config"
11 "reasonix/internal/control"
12 "reasonix/internal/event"
13 )
14
15 type extensionFormController struct {
16 control.SessionAPI
17 pluginID, surfaceID string
18 values map[string]any
19 generation uint64
20 instanceID string
21 exactCalls int
22 sessionID string
23 }
24
25 func (c *extensionFormController) RuntimeStateSnapshot() event.RuntimeStateSnapshot {
26 return event.RuntimeStateSnapshot{SchemaVersion: 1, SessionID: c.sessionID}
27 }
28
29 func (c *extensionFormController) SubmitExtensionFormExact(_ context.Context, pluginID, surfaceID string, generation uint64, instanceID string, values map[string]any) error {
30 c.exactCalls++
31 c.pluginID, c.surfaceID, c.generation, c.instanceID, c.values = pluginID, surfaceID, generation, instanceID, values
32 return nil
33 }
34
35 func (c *extensionFormController) SubmitExtensionForm(_ context.Context, pluginID, surfaceID string, values map[string]any) error {
36 c.pluginID, c.surfaceID, c.values = pluginID, surfaceID, values
37 return nil
38 }
39
40 func TestServeExactExtensionFormChecksSessionBeforeController(t *testing.T) {
41 bc := NewBroadcaster()
42 ctrl := &extensionFormController{SessionAPI: control.New(control.Options{Sink: bc}), sessionID: "session-a"}
43 srv := httptest.NewServer(New(ctrl, bc, config.ServeConfig{}).Handler())
44 defer srv.Close()
45 post := func(sessionID string) int {
46 resp, err := http.Post(srv.URL+"/extension-form", "application/json", strings.NewReader(
47 `{"sessionId":"`+sessionID+`","pluginId":"remote-plugin","surfaceId":"setup","generation":7,"formInstanceId":"form-2","values":{"region":"sg"}}`,
48 ))
49 if err != nil {
50 t.Fatal(err)
51 }
52 defer resp.Body.Close()
53 return resp.StatusCode
54 }
55 if got := post("session-old"); got != http.StatusConflict || ctrl.exactCalls != 0 {
56 t.Fatalf("stale exact form status/calls = %d/%d", got, ctrl.exactCalls)
57 }
58 if got := post("session-a"); got != http.StatusNoContent || ctrl.exactCalls != 1 || ctrl.generation != 7 || ctrl.instanceID != "form-2" {
59 t.Fatalf("current exact form status/call = %d/%+v", got, ctrl)
60 }
61 }
62
63 func TestServeExtensionFormSubmissionRoutesToController(t *testing.T) {
64 bc := NewBroadcaster()
65 ctrl := &extensionFormController{SessionAPI: control.New(control.Options{Sink: bc})}
66 srv := httptest.NewServer(New(ctrl, bc, config.ServeConfig{}).Handler())
67 defer srv.Close()
68 resp, err := http.Post(srv.URL+"/extension-form", "application/json", strings.NewReader(
69 `{"pluginId":"remote-plugin","surfaceId":"setup","values":{"region":"us-west"}}`,
70 ))
71 if err != nil {
72 t.Fatal(err)
73 }
74 resp.Body.Close()
75 if resp.StatusCode != http.StatusNoContent {
76 t.Fatalf("status = %d, want 204", resp.StatusCode)
77 }
78 if ctrl.pluginID != "remote-plugin" || ctrl.surfaceID != "setup" || ctrl.values["region"] != "us-west" {
79 t.Fatalf("submission = %q/%q/%v", ctrl.pluginID, ctrl.surfaceID, ctrl.values)
80 }
81 }
82
82 lines GO