This repository has no description
1package pages
2
3import (
4 "bytes"
5 "io"
6 "log/slog"
7 "strings"
8 "testing"
9
10 "tangled.org/core/appview/config"
11 "tangled.org/core/appview/models"
12 "tangled.org/core/appview/pages/repoinfo"
13 "tangled.org/core/patchutil"
14 "tangled.org/core/types"
15)
16
17func TestPullComposeTemplatesParse(t *testing.T) {
18 cfg := &config.Config{}
19 p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)))
20
21 cases := []struct {
22 name string
23 stack []string
24 }{
25 {"new.html via repo base", []string{"layouts/base", "layouts/repobase", "repo/pulls/new"}},
26 {"pullComposeHost", []string{"repo/pulls/fragments/pullComposeHost"}},
27 {"pullStepSource", []string{"repo/pulls/fragments/pullStepSource"}},
28 {"pullStepReview", []string{"repo/pulls/fragments/pullStepReview"}},
29 {"pullStepDetails", []string{"repo/pulls/fragments/pullStepDetails"}},
30 {"pullCompareForks", []string{"repo/pulls/fragments/pullCompareForks"}},
31 {"pullCompareBranches", []string{"repo/pulls/fragments/pullCompareBranches"}},
32 {"pullCompareForksBranches", []string{"repo/pulls/fragments/pullCompareForksBranches"}},
33 {"pull.html via repo base", []string{"layouts/base", "layouts/repobase", "repo/pulls/pull"}},
34 {"pullComment", []string{"fragments/comment/pullComment"}},
35 }
36
37 for _, c := range cases {
38 t.Run(c.name, func(t *testing.T) {
39 if _, err := p.rawParse(c.stack...); err != nil {
40 t.Fatalf("parse %v: %v", c.stack, err)
41 }
42 })
43 }
44}
45
46func TestPullComposeHostRender(t *testing.T) {
47 cfg := &config.Config{}
48 p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)))
49
50 base := RepoNewPullParams{
51 RepoInfo: repoinfo.RepoInfo{
52 OwnerDid: "did:plc:test",
53 Name: "test-repo",
54 },
55 }
56
57 for _, source := range []Source{"", SourceBranch, SourceFork, SourcePatch} {
58 for _, stacked := range []bool{false, true} {
59 if source == SourcePatch && stacked {
60 continue
61 }
62 params := base
63 params.Source = source
64 params.IsStacked = stacked
65 name := string(source)
66 if name == "" {
67 name = "default"
68 }
69 if stacked {
70 name += "-stacked"
71 }
72 t.Run(name, func(t *testing.T) {
73 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
74 t.Fatalf("render source=%q stacked=%v: %v", source, stacked, err)
75 }
76 })
77 }
78 }
79}
80
81func TestPullComposeHostRenderWithData(t *testing.T) {
82 cfg := &config.Config{}
83 p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)))
84
85 sampleBranches := []types.Branch{
86 {Reference: types.Reference{Name: "feature"}},
87 {Reference: types.Reference{Name: "main"}, IsDefault: true},
88 }
89
90 formatPatch := `From 1111111111111111111111111111111111111111 Mon Sep 11 00:00:00 2001
91From: Test <test@best.fest>
92Date: Tue, 1 Jan 2020 00:00:00 +0000
93Subject: [PATCH] example commit
94
95---
96 a.txt | 1 +
97 1 file changed, 1 insertion(+)
98
99diff --git a/a.txt b/a.txt
100index 0000000..1111111 100644
101--- a/a.txt
102+++ b/a.txt
103@@ -0,0 +1 @@
104+hello
105`
106 patches, err := patchutil.ExtractPatches(formatPatch)
107 if err != nil {
108 t.Fatalf("extract patches: %v", err)
109 }
110 comparison := &types.RepoFormatPatchResponse{
111 FormatPatchRaw: formatPatch,
112 FormatPatch: patches,
113 }
114 diff := patchutil.AsNiceDiff(formatPatch, "main")
115
116 params := RepoNewPullParams{
117 RepoInfo: repoinfo.RepoInfo{
118 OwnerDid: "did:plc:test",
119 Name: "test-repo",
120 },
121 Branches: sampleBranches,
122 SourceBranches: []types.Branch{sampleBranches[0]},
123 ForkBranches: []types.Branch{sampleBranches[0]},
124 Source: SourceBranch,
125 SourceBranch: "feature",
126 TargetBranch: "main",
127 Comparison: comparison,
128 Diff: &diff,
129 }
130
131 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
132 t.Fatalf("render with data: %v", err)
133 }
134
135 params.IsStacked = true
136 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
137 t.Fatalf("render stacked: %v", err)
138 }
139
140 params.PrefillError = "branch not found"
141 params.Comparison = nil
142 params.Diff = nil
143 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
144 t.Fatalf("render with prefill error: %v", err)
145 }
146
147 bugDef := &models.LabelDefinition{
148 Did: "did:plc:test",
149 Rkey: "bug",
150 Name: "bug",
151 ValueType: models.ValueType{Type: models.ConcreteTypeNull},
152 Scope: []string{"sh.tangled.repo.pull"},
153 }
154 priorityDef := &models.LabelDefinition{
155 Did: "did:plc:test",
156 Rkey: "priority",
157 Name: "priority",
158 ValueType: models.ValueType{Type: models.ConcreteTypeString, Enum: []string{"low", "med", "high"}},
159 Scope: []string{"sh.tangled.repo.pull"},
160 }
161 assigneeDef := &models.LabelDefinition{
162 Did: "did:plc:test",
163 Rkey: "assignee",
164 Name: "assignee",
165 ValueType: models.ValueType{Type: models.ConcreteTypeString, Format: models.ValueTypeFormatDid},
166 Scope: []string{"sh.tangled.repo.pull"},
167 Multiple: true,
168 }
169 labelDefs := map[string]*models.LabelDefinition{
170 bugDef.AtUri().String(): bugDef,
171 priorityDef.AtUri().String(): priorityDef,
172 assigneeDef.AtUri().String(): assigneeDef,
173 }
174
175 pushRepoInfo := repoinfo.RepoInfo{
176 OwnerDid: "did:plc:test",
177 Name: "test-repo",
178 Roles: repoinfo.RolesInRepo{Roles: []string{"repo:push"}},
179 }
180 params = RepoNewPullParams{
181 RepoInfo: pushRepoInfo,
182 Branches: sampleBranches,
183 SourceBranches: []types.Branch{sampleBranches[0]},
184 Source: SourceBranch,
185 SourceBranch: "feature",
186 TargetBranch: "main",
187 Comparison: comparison,
188 Diff: &diff,
189 LabelDefs: labelDefs,
190 LabelState: models.NewLabelState(),
191 }
192 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
193 t.Fatalf("render with labels: %v", err)
194 }
195
196 params.IsStacked = true
197 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
198 t.Fatalf("render stacked with labels: %v", err)
199 }
200
201 params.StackedDiffs = []StackedDiff{{
202 Diff: &diff,
203 Opts: types.DiffOpts{Split: true, RefreshUrl: "/r", Target: "#stack-diff-x", Field: "stackSplit[x]"},
204 }}
205 if err := p.PullComposeHostFragment(io.Discard, params); err != nil {
206 t.Fatalf("render stacked with per-commit diffs: %v", err)
207 }
208}
209
210func TestPullComposeLabelStateRoundTrip(t *testing.T) {
211 cfg := &config.Config{}
212 p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)))
213
214 sampleBranches := []types.Branch{
215 {Reference: types.Reference{Name: "feature"}},
216 {Reference: types.Reference{Name: "main"}, IsDefault: true},
217 }
218
219 bugDef := &models.LabelDefinition{
220 Did: "did:plc:test", Rkey: "bug", Name: "bug",
221 ValueType: models.ValueType{Type: models.ConcreteTypeNull},
222 Scope: []string{"sh.tangled.repo.pull"},
223 }
224 priorityDef := &models.LabelDefinition{
225 Did: "did:plc:test", Rkey: "priority", Name: "priority",
226 ValueType: models.ValueType{Type: models.ConcreteTypeString, Enum: []string{"low", "med", "high"}},
227 Scope: []string{"sh.tangled.repo.pull"},
228 }
229 bugKey := bugDef.AtUri().String()
230 priorityKey := priorityDef.AtUri().String()
231 labelDefs := map[string]*models.LabelDefinition{
232 bugKey: bugDef,
233 priorityKey: priorityDef,
234 }
235
236 state := models.NewLabelState()
237 actx := &models.LabelApplicationCtx{Defs: labelDefs}
238 for _, op := range []models.LabelOp{
239 {OperandKey: bugKey, OperandValue: "null", Operation: models.LabelOperationAdd},
240 {OperandKey: priorityKey, OperandValue: "high", Operation: models.LabelOperationAdd},
241 } {
242 if err := actx.ApplyLabelOp(state, op); err != nil {
243 t.Fatalf("seed state: %v", err)
244 }
245 }
246
247 formatPatch := `From 1111111111111111111111111111111111111111 Mon Sep 11 00:00:00 2001
248From: Test <test@best.fest>
249Date: Tue, 1 Jan 2020 00:00:00 +0000
250Subject: [PATCH] example commit
251
252---
253 a.txt | 1 +
254 1 file changed, 1 insertion(+)
255
256diff --git a/a.txt b/a.txt
257index 0000000..1111111 100644
258--- a/a.txt
259+++ b/a.txt
260@@ -0,0 +1 @@
261+hello
262`
263 patches, err := patchutil.ExtractPatches(formatPatch)
264 if err != nil {
265 t.Fatalf("extract patches: %v", err)
266 }
267 comparison := &types.RepoFormatPatchResponse{
268 FormatPatchRaw: formatPatch,
269 FormatPatch: patches,
270 }
271
272 params := RepoNewPullParams{
273 RepoInfo: repoinfo.RepoInfo{
274 OwnerDid: "did:plc:test",
275 Name: "test-repo",
276 Roles: repoinfo.RolesInRepo{Roles: []string{"repo:push"}},
277 },
278 Branches: sampleBranches,
279 SourceBranches: []types.Branch{sampleBranches[0]},
280 Source: SourceBranch,
281 SourceBranch: "feature",
282 TargetBranch: "main",
283 Comparison: comparison,
284 LabelDefs: labelDefs,
285 LabelState: state,
286 }
287
288 var buf bytes.Buffer
289 if err := p.PullComposeHostFragment(&buf, params); err != nil {
290 t.Fatalf("render: %v", err)
291 }
292 out := buf.String()
293 for _, want := range []string{
294 `value="null" checked`,
295 `value="high" checked`,
296 } {
297 if !strings.Contains(out, want) {
298 t.Errorf("missing pre-selection %q", want)
299 }
300 }
301}
302
303func TestParseSource(t *testing.T) {
304 cases := []struct {
305 in string
306 want Source
307 wantOk bool
308 }{
309 {"branch", SourceBranch, true},
310 {"BRANCH", SourceBranch, true},
311 {"fork", SourceFork, true},
312 {"patch", SourcePatch, true},
313 {"", "", false},
314 {"method", "", false},
315 {"strategy", "", false},
316 {"unknown", "", false},
317 }
318 for _, c := range cases {
319 got, ok := ParseSource(c.in)
320 if got != c.want || ok != c.wantOk {
321 t.Errorf("ParseSource(%q) = %q, %v; want %q, %v", c.in, got, ok, c.want, c.wantOk)
322 }
323 }
324}