test(trail): cover url wire-compat (old/new cli × old/new api) · Entire
test(trail): cover url wire-compat (old/new cli × old/new api)
4bef6a1→main·
toothbrush·3w ago·1 file·+42 added/-1 removed
Decode test proves a new server payload carrying url decodes into the
new TrailResource (new cli + new api) and is ignored by a struct without
the field (old cli + new api). new cli + old api is covered by
trailDisplayURL's fallback test.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
6d7d67ae97b1View transcript
[?
Add Web URLs to Trail CommandsClaude Code·Opus 4.8[1m]·1 step](/content/gh/entireio/cli/session/18a97739-bf62-4c0b-9cf2-9a1673f59583#timeline-6d7d67ae97b1/index.html)
Changes
1
cmd/entire/cli/api
Mtrail_types_test.go+42/-1
1
2
3
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package api
import "testing"
import (
"encoding/json"
"testing"
)
// TestTrailResourceDecodesServerURL covers the wire-compatibility matrix for the
// `url` field the API added:
// - new cli + new api: the field decodes into TrailResource.URL and is used.
// - old cli + new api: a client struct predating the field ignores the extra
// key without error (Go's json.Unmarshal drops unknown fields), so an older
// CLI keeps working against a newer server.
//
// (new cli + old api is exercised by trailDisplayURL's fallback in the cli pkg.)
func TestTrailResourceDecodesServerURL(t *testing.T) {
t.Parallel()
// Shape a newer server would emit: includes `url`.
payload := []byte(`{"id":"t1","number":640,"url":"https://entire.io/gh/o/r/trails/640/slug","branch":"feat/x","title":"T"}`)
// new cli + new api: URL is captured and available to display.
var newClient TrailResource
if err := json.Unmarshal(payload, &newClient); err != nil {
t.Fatalf("new client failed to decode new payload: %v", err)
}
if newClient.URL != "https://entire.io/gh/o/r/trails/640/slug" {
t.Fatalf("URL = %q, want server-provided url", newClient.URL)
}
// old cli + new api: a struct without a URL field must not choke on the
// extra key, and still decodes the fields it knows about.
var oldClient struct {
ID string `json:"id"`
Number int `json:"number"`
Title string `json:"title"`
}
if err := json.Unmarshal(payload, &oldClient); err != nil {
t.Fatalf("old client rejected new payload with extra url field: %v", err)
}
if oldClient.Number != 640 || oldClient.Title != "T" {
t.Fatalf("old client decoded wrong values: %+v", oldClient)
}
}
func TestTrailResourceToMetadataUsesID(t *testing.T) {
t.Parallel()
Mcmd/entire/cli/api/trail_types_test.go+42/-1