Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 26m ago 4b8c9e1d
history blame raw 2.1 KiB
1package metadata
2
3import (
4 "strings"
5 "testing"
6 "time"
7
8 "rodent.software/vole/core/git"
9)
10
11func TestLoadIssueAtReadsOnlyTheTarget(t *testing.T) {
12 t.Parallel()
13 root := t.TempDir()
14 if err := git.InitBare(root, "main"); err != nil {
15 t.Fatal(err)
16 }
17 g := git.Open(root)
18 tree, err := g.MkTree(nil)
19 if err != nil {
20 t.Fatal(err)
21 }
22 seed, err := g.CommitTree(tree, "", "seed")
23 if err != nil {
24 t.Fatal(err)
25 }
26 if err := g.UpdateRef(Ref, seed); err != nil {
27 t.Fatal(err)
28 }
29
30 now := time.Date(2026, 10, 30, 12, 0, 0, 0, time.UTC)
31 target, err := NewIssue("Target", "target body", "keenan", []string{"bug"}, nil, now)
32 if err != nil {
33 t.Fatal(err)
34 }
35 if err := CreateIssue(g, target, "keenan"); err != nil {
36 t.Fatal(err)
37 }
38 other, err := NewIssue("Other", "other body", "keenan", nil, nil, now.Add(time.Minute))
39 if err != nil {
40 t.Fatal(err)
41 }
42 if err := CreateIssue(g, other, "keenan"); err != nil {
43 t.Fatal(err)
44 }
45 c, err := NewIssueComment("One comment", "wilbur", now.Add(2*time.Minute))
46 if err != nil {
47 t.Fatal(err)
48 }
49 if err := AddIssueComment(g, target.ID, c, "wilbur"); err != nil {
50 t.Fatal(err)
51 }
52
53 got, found, err := LoadIssueAt(g, Ref, target.ID)
54 if err != nil {
55 t.Fatal(err)
56 }
57 if !found {
58 t.Fatal("target issue was not found")
59 }
60 if got.ID != target.ID || got.Title != "Target" || got.Description != "target body\n" {
61 t.Fatalf("loaded %+v, want the target issue", got)
62 }
63 if len(got.Comments) != 1 || strings.TrimSpace(got.Comments[0].Body) != "One comment" {
64 t.Fatalf("comments = %+v, want the one comment", got.Comments)
65 }
66 if got.ID == other.ID {
67 t.Fatal("LoadIssueAt returned the wrong issue")
68 }
69
70 _, found, err = LoadIssueAt(g, Ref, "01M5JR2JK29KKMAA1T9MDNTPB0")
71 if err != nil {
72 t.Fatal(err)
73 }
74 if found {
75 t.Fatal("a missing issue was reported as found")
76 }
77 // An id is used as a path segment, so anything that is not a ULID is simply
78 // not an issue rather than a chance to read outside issues/.
79 _, found, err = LoadIssueAt(g, Ref, "../../etc/passwd")
80 if err != nil {
81 t.Fatal(err)
82 }
83 if found {
84 t.Fatal("a non-ULID was read as an issue")
85 }
86}
87