/ internal / client / gateway_sync_test.go
gateway_sync_test.go
 1  package client
 2  
 3  import (
 4  	"context"
 5  	"encoding/json"
 6  	"io"
 7  	"net/http"
 8  	"net/http/httptest"
 9  	"strings"
10  	"testing"
11  	"time"
12  )
13  
14  func TestGatewayClient_SyncSessions_HappyPath(t *testing.T) {
15  	var capturedAuth string
16  	var capturedBody []byte
17  	var capturedPath string
18  
19  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
20  		capturedAuth = r.Header.Get("X-API-Key")
21  		capturedPath = r.URL.Path
22  		capturedBody, _ = io.ReadAll(r.Body)
23  		w.Header().Set("Content-Type", "application/json")
24  		w.WriteHeader(200)
25  		_, _ = w.Write([]byte(`{"accepted":["s1"],"rejected":[]}`))
26  	}))
27  	defer srv.Close()
28  
29  	c := NewGatewayClient(srv.URL, "TEST_KEY")
30  	resp, err := c.SyncSessions(context.Background(), SyncBatchRequest{
31  		ClientVersion: "shanclaw/test",
32  		SyncAt:        time.Date(2026, 4, 19, 3, 0, 0, 0, time.UTC),
33  		Sessions: []SessionEnvelope{
34  			{AgentName: "ops-bot", Session: json.RawMessage(`{"id":"s1"}`)},
35  		},
36  	})
37  	if err != nil {
38  		t.Fatalf("SyncSessions: %v", err)
39  	}
40  	if len(resp.Accepted) != 1 || resp.Accepted[0] != "s1" {
41  		t.Errorf("accepted: got %v, want [s1]", resp.Accepted)
42  	}
43  	if capturedAuth != "TEST_KEY" {
44  		t.Errorf("X-API-Key header: got %q, want TEST_KEY", capturedAuth)
45  	}
46  	if capturedPath != "/api/v1/sessions/sync" {
47  		t.Errorf("path: got %q, want /api/v1/sessions/sync", capturedPath)
48  	}
49  	if !strings.Contains(string(capturedBody), `"agent_name":"ops-bot"`) {
50  		t.Errorf("body should include agent_name=ops-bot; got: %s", capturedBody)
51  	}
52  	if !strings.Contains(string(capturedBody), `"session":{"id":"s1"}`) {
53  		t.Errorf("body should embed session JSON verbatim; got: %s", capturedBody)
54  	}
55  }
56  
57  func TestGatewayClient_SyncSessions_ServerError(t *testing.T) {
58  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
59  		w.WriteHeader(503)
60  	}))
61  	defer srv.Close()
62  
63  	c := NewGatewayClient(srv.URL, "K")
64  	_, err := c.SyncSessions(context.Background(), SyncBatchRequest{})
65  	if err == nil {
66  		t.Fatalf("expected error on 503")
67  	}
68  }