| index 073f54c38..da55ed25d 100644 |
| --- a/sidecars_cli_test.go |
| +++ b/sidecars_cli_test.go |
| @@ -5,12 +5,20 @@ |
| // exists in this package for os.Exit paths). What's tested directly |
| // instead is sidecarsEnable, the core PutSidecarManifest wrapper; |
| // parseArgv, the -args flag's whitespace-split helper; parseDurationSeconds, |
| -// the -idle/-max-run duration-to-seconds conversion; and the two small |
| -// render helpers `ls`'s VERSION and PLACEMENT columns go through. |
| +// the -idle/-max-run duration-to-seconds conversion; the two small render |
| +// helpers `ls`'s VERSION and PLACEMENT columns go through; and |
| +// TestSidecarsListTruncatedNotice, which drives the real runSidecarsList |
| +// against a fake console (apimode_test.go's newTestSession/loginTo/ |
| +// apiTestAccount verb-level fixtures) to pin the truncation honesty notice |
| +// added in review round 1. |
| package main |
| |
| import ( |
| "context" |
| + "encoding/json" |
| + "net/http" |
| + "net/http/httptest" |
| + "strings" |
| "testing" |
| |
| "github.com/carlosframework/platform/internal/provision" |
| @@ -147,3 +155,59 @@ func TestSidecarPlacementCell(t *testing.T) { |
| } |
| } |
| } |
| + |
| +// TestSidecarsListTruncatedNotice pins the truncation honesty rule added in |
| +// Task 14 review round 1: the console caps one `ls` answer at |
| +// sidecarListMax (500, internal/console/apisidecars.go) and reports it via |
| +// the response's `truncated` flag; a caller that prints the records and |
| +// drops that flag on the floor renders a list that quietly stops at a |
| +// prefix and says nothing — the same overclaim VERSION's "unknown" exists |
| +// to prevent, and not hypothetical for the motivating customer (Eleven: a |
| +// bot per enrolled member, so exceeding 500 is growth, not misuse). |
| +// |
| +// This drives the real runSidecarsList — not just the client method — |
| +// against a fake console built the way apimode_test.go's other verb-level |
| +// tests are (newTestSession/loginTo/apiTestAccount), asserting the notice |
| +// appears for a truncated answer and stays silent for a whole one. Those |
| +// two cases are the mutation check the brief asked for: a change that |
| +// ignores the flag entirely (always prints it, or never does) fails |
| +// exactly one of the two subtests. |
| +func TestSidecarsListTruncatedNotice(t *testing.T) { |
| + for _, tc := range []struct { |
| + name string |
| + truncated bool |
| + }{ |
| + {"truncated", true}, |
| + {"not truncated", false}, |
| + } { |
| + t.Run(tc.name, func(t *testing.T) { |
| + useTempCredentials(t) |
| + clearDeploymentEnv(t) |
| + checkNoRegistry := requireNoRegistryTouch(t) |
| + |
| + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| + json.NewEncoder(w).Encode(map[string]any{ |
| + "sidecars": []map[string]any{ |
| + {"name": "bot-acme", "host": "bot-acme.titogo.bab.sidecar.internal", "channel": "stable"}, |
| + }, |
| + "truncated": tc.truncated, |
| + }) |
| + })) |
| + defer ts.Close() |
| + loginTo(t, ts.URL, "vicky@keymail.dev") |
| + |
| + buf := captureStdout(t) |
| + runSidecarsList([]string{"-app", "titogo", "-account", apiTestAccount}) |
| + |
| + out := buf.String() |
| + const notice = "more exist" |
| + if tc.truncated && !strings.Contains(out, notice) { |
| + t.Fatalf("ls stdout = %q, want a truncation notice containing %q", out, notice) |
| + } |
| + if !tc.truncated && strings.Contains(out, notice) { |
| + t.Fatalf("ls stdout = %q, must NOT claim more exist for a whole (untruncated) answer", out) |
| + } |
| + checkNoRegistry() |
| + }) |
| + } |
| +} |