f88a029ecc
Client.Go-002: the Events/EventsAfter compatibility path silently dropped events when the 16-slot results channel filled — it cancelled the stream and closed the channel with no error delivered. sendEventResult now evicts an old buffered event and delivers a terminal EventResult carrying the new exported ErrEventBufferOverflow before close, so the overflow is observable. Client.Go-003: parseInt32List panicked on a malformed -item-handles token, crashing the CLI with a stack trace. It now returns an error that runUnsubscribeBulk propagates, exiting 2 with a clean message. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRunVersionJSON(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
if err := runWithIO(t.Context(), []string{"version", "-json"}, &stdout, &stderr); err != nil {
|
|
t.Fatalf("runWithIO() error = %v; stderr = %s", err, stderr.String())
|
|
}
|
|
|
|
var output versionOutput
|
|
if err := json.Unmarshal(stdout.Bytes(), &output); err != nil {
|
|
t.Fatalf("parse JSON: %v", err)
|
|
}
|
|
if output.GatewayProtocolVersion == 0 || output.WorkerProtocolVersion == 0 {
|
|
t.Fatalf("protocol versions were not populated: %+v", output)
|
|
}
|
|
}
|
|
|
|
func TestCommonOptionsRedactsAPIKey(t *testing.T) {
|
|
options, err := (&commonOptions{
|
|
Endpoint: "localhost:5000",
|
|
APIKey: "mxgw_super_secret",
|
|
Plaintext: true,
|
|
CallTimeout: "2s",
|
|
}).resolved()
|
|
if err != nil {
|
|
t.Fatalf("resolved() error = %v", err)
|
|
}
|
|
|
|
data, err := json.Marshal(options)
|
|
if err != nil {
|
|
t.Fatalf("marshal options: %v", err)
|
|
}
|
|
if strings.Contains(string(data), "super_secret") {
|
|
t.Fatalf("redacted JSON leaked API key: %s", data)
|
|
}
|
|
if !strings.Contains(string(data), "mxgw") {
|
|
t.Fatalf("redacted JSON did not preserve key shape: %s", data)
|
|
}
|
|
}
|
|
|
|
func TestParseValueBuildsTypedValue(t *testing.T) {
|
|
value, err := parseValue("int32", "123")
|
|
if err != nil {
|
|
t.Fatalf("parseValue() error = %v", err)
|
|
}
|
|
if got := value.GetInt32Value(); got != 123 {
|
|
t.Fatalf("int32 value = %d, want 123", got)
|
|
}
|
|
}
|
|
|
|
func TestParseInt32ListParsesValidTokens(t *testing.T) {
|
|
items, err := parseInt32List("1, 2 ,3")
|
|
if err != nil {
|
|
t.Fatalf("parseInt32List() error = %v", err)
|
|
}
|
|
want := []int32{1, 2, 3}
|
|
if len(items) != len(want) {
|
|
t.Fatalf("parseInt32List() = %v, want %v", items, want)
|
|
}
|
|
for i := range want {
|
|
if items[i] != want[i] {
|
|
t.Fatalf("parseInt32List()[%d] = %d, want %d", i, items[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseInt32ListReturnsErrorOnMalformedToken(t *testing.T) {
|
|
items, err := parseInt32List("1,foo")
|
|
if err == nil {
|
|
t.Fatalf("parseInt32List() error = nil, want a parse error; items = %v", items)
|
|
}
|
|
if items != nil {
|
|
t.Fatalf("parseInt32List() items = %v, want nil on error", items)
|
|
}
|
|
if !strings.Contains(err.Error(), "foo") {
|
|
t.Fatalf("parseInt32List() error = %q, want it to name the bad token", err.Error())
|
|
}
|
|
}
|