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