test(trail): cover link request and branch cleanup · Entire

test(trail): cover link request and branch cleanup

985b5e2→main·

dipree·4w ago·2 files·+133 added/-9 removed

Add regression coverage for branch_action=link on trail create requests and cleanupCreatedTrailBranch local/remote cleanup permutations, including the checked-out local branch guard that prevents remote deletion.

Sessions

43250240f4aaView transcript

Changes

2

672 unmodified lines

673
674
675
676
677
678
679
680
681
682
683
684
676
677
678
679
40 unmodified lines

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

672 unmodified lines

fmt.Fprintf(w, "Pushed branch %s to origin\n", branch)
}

createReq := api.TrailCreateRequest{
    Title:      title,
    Body:       body,
    BranchName: branch,
    // Branch already pushed above; link it instead of backfilling at base.
    BranchAction: "link",
    Base:         base,
    Status:       statusStr,
}
createReq := newTrailCreateRequest(title, body, branch, base, statusStr)

var createResp api.TrailCreateResponse
resp, err := client.Post(ctx, trailsBasePath(forge, owner, repoName), createReq)
40 unmodified lines

return nil
}

func newTrailCreateRequest(title, body, branch, base, statusStr string) api.TrailCreateRequest {
    return api.TrailCreateRequest{
        Title:        title,
        Body:         body,
        BranchName:   branch,
        BranchAction: "link",
        Base:         base,
        Status:       statusStr,
    }
}

func newTrailUpdateCmd() *cobra.Command {
    var statusStr, title, body, branch string
    var labelAdd, labelRemove []string

Mcmd/entire/cli/trail_cmd.go+12/-9

7 unmodified lines

8
9
10
11
12
13
14
9 unmodified lines

24
25
26
27
28
29
30
31
32
1 unmodified line

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

7 unmodified lines

"io"
    "net/http"
    "net/http/httptest"
    "os"
    "os/exec"
    "path/filepath"
    "strconv"
9 unmodified lines

"github.com/entireio/cli/internal/entireclient/clusterdiscovery"
    "github.com/entireio/cli/internal/entireclient/contexts"
    "github.com/entireio/cli/internal/entireclient/tokenstore"
    "github.com/go-git/go-git/v6"
    "github.com/spf13/cobra"
    "github.com/stretchr/testify/require"
)

const (
1 unmodified line

trailListTestAuthorBob   = "bob"
)

func TestNewTrailCreateRequestUsesLinkBranchAction(t *testing.T) {
    req := newTrailCreateRequest("title", "body", "feature/x", "main", "open")

require.Equal(t, api.TrailCreateRequest{
        Title:        "title",
        Body:         "body",
        BranchName:   "feature/x",
        BranchAction: "link",
        Base:         "main",
        Status:       "open",
    }, req)
}

func TestCleanupCreatedTrailBranch(t *testing.T) {
    cases := []struct {
        name             string
        localCreated     bool
        remotePushed     bool
        checkoutBranch   bool
        wantLocalBranch  bool
        wantRemoteBranch bool
    }{
        {
            name:             "removes local branch only",
            localCreated:     true,
            remotePushed:     false,
            wantLocalBranch:  false,
            wantRemoteBranch: false,
        },
        {
            name:             "removes local and pushed remote branch",
            localCreated:     true,
            remotePushed:     true,
            wantLocalBranch:  false,
            wantRemoteBranch: false,
        },
        {
            name:             "does not delete remote when checked out branch cannot be removed locally",
            localCreated:     true,
            remotePushed:     true,
            checkoutBranch:   true,
            wantLocalBranch:  true,
            wantRemoteBranch: true,
        },
        {
            name:             "deletes remote when local was not created by cleanup owner",
            localCreated:     false,
            remotePushed:     true,
            wantLocalBranch:  true,
            wantRemoteBranch: false,
        },
    }

for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            branch := "cleanup-test"
            localDir, originDir, repo := initTrailCleanupRepo(t)
            defer repo.Close()
            t.Chdir(localDir)

runGitTrailTest(t, localDir, "branch", branch)
            if tc.remotePushed {
                runGitTrailTest(t, localDir, "push", "origin", branch)
            }
            if tc.checkoutBranch {
                runGitTrailTest(t, localDir, "checkout", branch)
            }

var errBuf bytes.Buffer
            cleanupCreatedTrailBranch(repo, branch, tc.localCreated, tc.remotePushed, &errBuf)

require.Equal(t, tc.wantLocalBranch, gitBranchExistsTrailTest(t, localDir, branch), "local branch mismatch; stderr: %s", errBuf.String())
            require.Equal(t, tc.wantRemoteBranch, gitBranchExistsTrailTest(t, originDir, branch), "remote branch mismatch; stderr: %s", errBuf.String())
            if tc.checkoutBranch {
                require.Contains(t, errBuf.String(), "not deleting remote branch")
            }
        })
    }
}

func initTrailCleanupRepo(t *testing.T) (localDir, originDir string, repo *git.Repository) {
    t.Helper()

tmp := t.TempDir()
    localDir = filepath.Join(tmp, "local")
    originDir = filepath.Join(tmp, "origin.git")
    require.NoError(t, os.MkdirAll(localDir, 0o755))
    runGitTrailTest(t, tmp, "init", "--bare", originDir)
    repo = initOpenedTestRepo(t, localDir)

testutil.WriteFile(t, localDir, "README.md", "test\n")
    runGitTrailTest(t, localDir, "add", "README.md")
    runGitTrailTest(t, localDir, "commit", "-m", "initial")
    runGitTrailTest(t, localDir, "remote", "add", "origin", originDir)
    return localDir, originDir, repo
}

func runGitTrailTest(t *testing.T, dir string, args ...string) {
    t.Helper()
    cmd := exec.CommandContext(context.Background(), "git", args...)
    cmd.Dir = dir
    output, err := cmd.CombinedOutput()
    require.NoError(t, err, "git %s failed: %s", strings.Join(args, " "), strings.TrimSpace(string(output)))
}

func gitBranchExistsTrailTest(t *testing.T, repoDir, branch string) bool {
    t.Helper()
    cmd := exec.CommandContext(context.Background(), "git", "show-ref", "--verify", "--quiet", "refs/heads/"+branch)
    cmd.Dir = repoDir
    err := cmd.Run()
    if err == nil {
        return true
    }
    var exitErr *exec.ExitError
    require.ErrorAs(t, err, &exitErr)
    require.Equal(t, 1, exitErr.ExitCode())
    return false
}

func TestRunTrailListAll_PrintsLoginHintWhenNotLoggedIn(t *testing.T) {
    // No t.Parallel: SetResolveContextForAPIForTest and
    // tokenstore.UseFileBackendForTesting mutate package-level state.