# test(mirror): command-level test for `repo mirror list --show-available`

`f388237`→[main](/content/gh/entireio/cli/commits/main/index.html)·

toothbrush·3w ago·3 files·+147 added/-5 removed

Add a test seam (activeCoreClient) so `repo mirror list` can run end-to-end
against an httptest core, and lock in the --show-available routing: endpoint
selection, columns, banner, and --owner/--cluster/--provider flag behavior.
Also correct the availableMirror column doc to use full command names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

f4db3e97fed1View transcript

## Changes

3

- cmd/entire/cli

- Mcorecmd.go+7/-1
  
  - Mrepo_mirror.go+5/-4
  
  - Mrepo_mirror_test.go+135

```
241 unmodified lines

```

// activeCoreClient builds the control-plane client for active-context
// commands. A package-level seam (production wiring is coreapi.New) so
// command-level tests can point the whole command tree at an httptest server
// without standing up the auth/context/TLS stack.
var activeCoreClient = func(context.Context) (*coreapi.Client, error) { return coreapi.New() }

// runCore is the variant for commands that don't render JSON (delete,
// revoke, remove): it runs the same preamble — silence usage, build
// client, map API errors — and leaves any success output to fn. The client
// dials the active context's core (coreapi.New); use runCoreForCluster for
// commands addressed at a specific cluster.
func runCore(cmd *cobra.Command, fn func(ctx context.Context, c *coreapi.Client) error) error {
    return runCoreClient(cmd, func(context.Context) (*coreapi.Client, error) { return coreapi.New() }, fn)
    return runCoreClient(cmd, activeCoreClient, fn)
}

// availableMirrorColumns is the view of a repo you *could* mirror: the
// scannable repo name, your effective GitHub access, and whether it's
// onboardable. STATUS is "available" (run `entire repo mirror create` to onboard),
// "mirrored" (already done — `entire repo mirror list` shows the clone URL), or
// "owner-only" (a personal repo of another user; only its owner may mirror
// it). No clone URL column: an un-onboarded repo doesn't have one yet.
var availableMirrorColumns = []string{"REPO", "ACCESS", "STATUS"}

func availableMirrorRow(m coreapi.AvailableMirror) []string {
```

```
218 unmodified lines

```

// recordedRequest captures the routing facts a command-level test asserts on:
// which endpoint the list command hit and with what query.
type recordedRequest struct {
    method string
    path   string
    query  url.Values
}

// serveMirrorList stands up a fake control-plane that records the inbound
// request and answers /mirrors and /mirrors/available with the given payloads,
// then points the active-context client seam at it for the duration of the
// test. The returned pointer is populated on each request.
func serveMirrorList(t *testing.T, mirrors []coreapi.Mirror, available []coreapi.AvailableMirror) *recordedRequest {
    t.Helper()
    var rec recordedRequest
    srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        rec.method, rec.path, rec.query = r.Method, r.URL.Path, r.URL.Query()
        w.Header().Set("Content-Type", "application/json")
        switch r.URL.Path {
        case "/api/v1/mirrors/available":
            if err := writeJSON(w, &coreapi.ListAvailableMirrorsOutputBody{Available: available}); err != nil {
                t.Errorf("encode available response: %v", err)
            }
        case "/api/v1/mirrors":
            if err := writeJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: mirrors}); err != nil {
                t.Errorf("encode mirrors response: %v", err)
            }
        default:
            t.Errorf("unexpected path %q", r.URL.Path)
            w.WriteHeader(http.StatusNotFound)
        }
    }))
    t.Cleanup(srv.Close)

prev := activeCoreClient
    activeCoreClient = func(context.Context) (*coreapi.Client, error) {
        return coreapi.NewWithBearer(srv.URL, "tok")
    }
    t.Cleanup(func() { activeCoreClient = prev })
    return &rec
}

// runMirrorList executes `repo mirror list` with args against the fake server,
// returning stdout (the table/JSON) and stderr (the routing banner).
func runMirrorList(t *testing.T, args ...string) (stdout, stderr string) {
    t.Helper()
    cmd := newRepoMirrorListCmd()
    var out, errOut bytes.Buffer
    cmd.SetOut(&out)
    cmd.SetErr(&errOut)
    cmd.SetArgs(args)
    require.NoError(t, cmd.ExecuteContext(t.Context()))
    return out.String(), errOut.String()
}

// TestRepoMirrorList_ShowAvailableRouting locks in the flag-driven branch of
// `repo mirror list`: --show-available must hit the /mirrors/available endpoint
// with the available-repo columns and its own banner, while the default lists
// existing mirrors from /mirrors. --owner flows into the query on both paths;
// --cluster/--provider apply only to the existing-mirror path. These are the
// behaviors the seam was added to pin — the per-row formatting is covered by
// TestMirrorRow / TestAvailableMirrorRow.
//
// Not parallel: swaps the package-level activeCoreClient seam.
func TestRepoMirrorList_ShowAvailableRouting(t *testing.T) {
    t.Run("--show-available routes to /mirrors/available with available columns", func(t *testing.T) {
        rec := serveMirrorList(t,
            []coreapi.Mirror{{Owner: "acme", Repo: "web", ClusterHost: "aws-us-east-2.entire.io"}},
            []coreapi.AvailableMirror{{Owner: "acme", Repo: "web", Access: "write", Status: "available"}},
        )
        stdout, stderr := runMirrorList(t, "--show-available")

require.Equal(t, http.MethodGet, rec.method)
        require.Equal(t, "/api/v1/mirrors/available", rec.path)
        require.Contains(t, stderr, "Listing repos you could mirror")
        // Available columns, not the existing-mirror "CLONE URL" view.
        require.Contains(t, stdout, "ACCESS")
        require.Contains(t, stdout, "STATUS")
        require.Contains(t, stdout, "acme/web")
        require.Contains(t, stdout, "available")
        require.NotContains(t, stdout, "CLONE URL")
    })

t.Run("default lists existing mirrors from /mirrors", func(t *testing.T) {
        rec := serveMirrorList(t,
            []coreapi.Mirror{{Owner: "acme", Repo: "web", ClusterHost: "aws-us-east-2.entire.io"}},
            nil,
        )
        stdout, stderr := runMirrorList(t)

require.Equal(t, "/api/v1/mirrors", rec.path)
        require.Contains(t, stderr, "Listing mirrors on")
        require.Contains(t, stdout, "CLONE URL")
        require.Contains(t, stdout, "entire://aws-us-east-2.entire.io/gh/acme/web")
    })

t.Run("--owner flows into the available query", func(t *testing.T) {
        rec := serveMirrorList(t, nil,
            []coreapi.AvailableMirror{{Owner: "acme", Repo: "web", Access: "write", Status: "available"}},
        )
        runMirrorList(t, "--show-available", "--owner", "acme")

require.Equal(t, "/api/v1/mirrors/available", rec.path)
        require.Equal(t, "acme", rec.query.Get("owner"))
    })

t.Run("--owner flows into the existing-mirror query", func(t *testing.T) {
        rec := serveMirrorList(t,
            []coreapi.Mirror{{Owner: "acme", Repo: "web", ClusterHost: "aws-us-east-2.entire.io"}}, nil,
        )
        runMirrorList(t, "--owner", "acme")

require.Equal(t, "/api/v1/mirrors", rec.path)
        require.Equal(t, "acme", rec.query.Get("owner"))
    })

t.Run("--cluster/--provider apply to /mirrors but are ignored by --show-available", func(t *testing.T) {
        rec := serveMirrorList(t,
            []coreapi.Mirror{{Owner: "acme", Repo: "web", ClusterHost: "aws-us-east-2.entire.io"}}, nil,
        )
        runMirrorList(t, "--cluster", "eu-west-1.entire.io", "--provider", "github")
        require.Equal(t, "/api/v1/mirrors", rec.path)
        require.Equal(t, "eu-west-1.entire.io", rec.query.Get("cluster"))
        require.Equal(t, "github", rec.query.Get("provider"))

rec = serveMirrorList(t, nil,
            []coreapi.AvailableMirror{{Owner: "acme", Repo: "web", Access: "write", Status: "available"}},
        )
        runMirrorList(t, "--show-available", "--cluster", "eu-west-1.entire.io", "--provider", "github")
        require.Equal(t, "/api/v1/mirrors/available", rec.path)
        require.Empty(t, rec.query.Get("cluster"), "show-available is cluster-agnostic; must not send --cluster")
        require.Empty(t, rec.query.Get("provider"), "show-available is GitHub-only; must not send --provider")
    })
}

// TestParseGitHubURL is ported from entiredb's cmd/entire-repo/cli
// mirror_test.go, since parseGitHubURL was carried over verbatim.
func TestParseGitHubURL(t *testing.T) {
