main 81ede3b

issue_test.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package api_test
4
5import (
6	"testing"
7
8	"bnema.dev/ermite-api/gen/ermite"
9	"bnema.dev/ermite-api/gen/ermite/ermiteconnect"
10	"google.golang.org/protobuf/proto"
11	"google.golang.org/protobuf/reflect/protoreflect"
12)
13
14func TestIssueProcedures(t *testing.T) {
15	tests := map[string]string{
16		ermiteconnect.IssueServiceCreateIssueProcedure:       "CreateIssue",
17		ermiteconnect.IssueServiceListIssuesProcedure:        "ListIssues",
18		ermiteconnect.IssueServiceGetIssueProcedure:          "GetIssue",
19		ermiteconnect.IssueServiceAddIssueCommentProcedure:   "AddIssueComment",
20		ermiteconnect.IssueServiceCloseIssueProcedure:        "CloseIssue",
21		ermiteconnect.IssueServiceReopenIssueProcedure:       "ReopenIssue",
22		ermiteconnect.IssueServiceResolveIssueProcedure:      "ResolveIssue",
23		ermiteconnect.IssueServiceListPendingIssuesProcedure: "ListPendingIssues",
24		ermiteconnect.IssueServiceApproveIssueProcedure:      "ApproveIssue",
25		ermiteconnect.IssueServiceRejectIssueProcedure:       "RejectIssue",
26	}
27	for got, name := range tests {
28		if want := "/ermite.IssueService/" + name; got != want {
29			t.Errorf("procedure = %q, want %q", got, want)
30		}
31	}
32}
33
34func TestIssueContract(t *testing.T) {
35	for _, tt := range []struct {
36		msg    proto.Message
37		fields map[string]int
38	}{
39		{&ermite.Issue{}, map[string]int{"repo": 1, "number": 2, "title": 3, "body": 4, "state": 5, "author": 6, "created_at": 7, "updated_at": 8, "comment_count": 9}},
40		{&ermite.IssueComment{}, map[string]int{"id": 1, "author": 2, "text": 3, "created_at": 4}},
41		{&ermite.RepoSettings{}, map[string]int{"issues": 3}},
42		{&ermite.UpdateRepoRequest{}, map[string]int{"issues": 8}},
43		{&ermite.Event{}, map[string]int{"issue_opened": 17, "issue_closed": 18, "issue_reopened": 19, "issue_commented": 20, "issue_submitted": 21}},
44		{&ermite.IssueSubmitted{}, map[string]int{"repo": 1, "id": 2}},
45		{&ermite.PendingIssue{}, map[string]int{"id": 1, "repo": 2, "title": 3, "body": 4, "author": 5, "created_at": 6}},
46		{&ermite.ListPendingIssuesRequest{}, map[string]int{"repo": 1, "page_size": 2, "page_token": 3}},
47		{&ermite.ListPendingIssuesResponse{}, map[string]int{"issues": 1, "next_page_token": 2}},
48		{&ermite.ApproveIssueRequest{}, map[string]int{"repo": 1, "id": 2}},
49		{&ermite.ApproveIssueResponse{}, map[string]int{"issue": 1}},
50		{&ermite.RejectIssueRequest{}, map[string]int{"repo": 1, "id": 2, "ban": 3}},
51	} {
52		md := tt.msg.ProtoReflect().Descriptor()
53		for name, num := range tt.fields {
54			if fd := md.Fields().ByName(protoreflect.Name(name)); fd == nil || int(fd.Number()) != num {
55				t.Errorf("%s.%s = %v, want %d", md.Name(), name, fd, num)
56			}
57		}
58	}
59	if ermite.Scope_SCOPE_ISSUE_WRITE != 11 {
60		t.Fatal("issue:write scope number changed")
61	}
62	for name, want := range map[string]int32{"ISSUE_STATE_UNSPECIFIED": 0, "ISSUE_STATE_OPEN": 1, "ISSUE_STATE_CLOSED": 2, "ISSUE_STATE_PENDING": 3, "ISSUE_STATE_RESOLVED": 4} {
63		if got := ermite.IssueState_value[name]; got != want {
64			t.Errorf("%s = %d, want %d", name, got, want)
65		}
66	}
67	for name, want := range map[string]int32{"ISSUES_MODE_UNSPECIFIED": 0, "ISSUES_MODE_OFF": 1, "ISSUES_MODE_OWNER": 2, "ISSUES_MODE_PUBLIC": 3} {
68		if got := ermite.IssuesMode_value[name]; got != want {
69			t.Errorf("%s = %d, want %d", name, got, want)
70		}
71	}
72	mode := ermite.IssuesMode_ISSUES_MODE_OFF
73	for _, in := range []proto.Message{
74		&ermite.UpdateRepoRequest{Repo: "r", Issues: &mode},
75		&ermite.Event{Kind: &ermite.Event_IssueOpened{IssueOpened: &ermite.IssueOpened{Issue: &ermite.Issue{Repo: "r", Number: 1}}}},
76		&ermite.Event{Kind: &ermite.Event_IssueClosed{IssueClosed: &ermite.IssueClosed{Issue: &ermite.Issue{Repo: "r", Number: 1}}}},
77		&ermite.Event{Kind: &ermite.Event_IssueReopened{IssueReopened: &ermite.IssueReopened{Issue: &ermite.Issue{Repo: "r", Number: 1}}}},
78		&ermite.Event{Kind: &ermite.Event_IssueSubmitted{IssueSubmitted: &ermite.IssueSubmitted{Repo: "r", Id: "p1"}}},
79		&ermite.PendingIssue{Id: "p1", Repo: "r", Title: "t", Author: "anon"},
80		&ermite.RejectIssueRequest{Repo: "r", Id: "p1", Ban: true},
81		&ermite.Event{Kind: &ermite.Event_IssueCommented{IssueCommented: &ermite.IssueCommented{Repo: "r", Number: 1, Comment: &ermite.IssueComment{Id: "c", Text: "hi"}}}},
82	} {
83		b, err := proto.Marshal(in)
84		if err != nil {
85			t.Fatal(err)
86		}
87		out := in.ProtoReflect().New().Interface()
88		if err := proto.Unmarshal(b, out); err != nil {
89			t.Fatal(err)
90		}
91		if !proto.Equal(in, out) {
92			t.Errorf("%T: round trip mismatch", in)
93		}
94	}
95	fd := (&ermite.UpdateRepoRequest{}).ProtoReflect().Descriptor().Fields().ByName("issues")
96	if !fd.HasOptionalKeyword() {
97		t.Fatal("UpdateRepoRequest.issues must be optional")
98	}
99}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close