Skip to content

Commit 3789dd8

Browse files
authored
Merge pull request #146 from codingpot/feat-gh-2
feat: add GitHub handler and dependency injection
2 parents ea8c87e + d2e0409 commit 3789dd8

File tree

7 files changed

+118
-24
lines changed

7 files changed

+118
-24
lines changed

k8s/kkweon-okteto/server.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ spec:
5757
value: "9000"
5858
- name: PR12ER_PROMETHEUS_PORT
5959
value: "9093"
60+
- name: GITHUB_API_KEY
61+
value: "${GITHUB_API_KEY}"
6062

6163
readinessProbe:
6264
exec:

server/cmd/server/main.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import (
44
"fmt"
55
"net"
66

7+
"github.com/codingpot/pr12er/server/internal/ghv3"
78
"github.com/codingpot/pr12er/server/middlewares/healthserver"
89
"github.com/codingpot/pr12er/server/middlewares/metrics"
910
"github.com/codingpot/pr12er/server/pkg/env"
11+
"github.com/codingpot/pr12er/server/pkg/handlers"
1012
"github.com/codingpot/pr12er/server/pkg/pr12er"
1113
"github.com/codingpot/pr12er/server/pkg/serv"
1214
grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
@@ -18,14 +20,20 @@ import (
1820
)
1921

2022
func main() {
21-
log.WithField("ServicePort", env.ServicePort).Print("gRPC server is listening")
23+
log.WithFields(
24+
log.Fields{
25+
"ServicePort": env.ServicePort,
26+
"GITHUB_API_KEY": env.GitHubAPIKey,
27+
}).Print("gRPC server is listening")
2228

2329
lis, err := net.Listen("tcp", fmt.Sprintf(":%s", env.ServicePort))
2430
if err != nil {
2531
log.WithError(err).Fatalf("failed to listen")
2632
}
2733

28-
s := serv.Server{}
34+
githubService := ghv3.New(env.GitHubAPIKey)
35+
handler := handlers.New(githubService)
36+
s := serv.New(handler)
2937

3038
logNewEntry := log.NewEntry(log.New())
3139

@@ -42,7 +50,7 @@ func main() {
4250
),
4351
)
4452

45-
pr12er.RegisterPr12ErServiceServer(grpcServer, &s)
53+
pr12er.RegisterPr12ErServiceServer(grpcServer, s)
4654
healthserver.RegisterHealthServer(grpcServer)
4755
reflection.Register(grpcServer)
4856

server/cmd/tools/tools.go

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package tools
44

55
import (
66
_ "github.com/daixiang0/gci"
7+
_ "github.com/golang/mock/mockgen"
78
_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
89
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
910
_ "mvdan.cc/gofumpt"

server/pkg/env/env.go

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ var (
1010
ServicePort = getEnvVar("PR12ER_GRPC_PORT", "9000")
1111
// PrometheusPort is the port for Prometheus metrics (/metrics).
1212
PrometheusPort = getEnvVar("PR12ER_PROMETHEUS_PORT", "9092")
13+
// GitHubAPIKey is the GitHub API Key used to create an issue.
14+
GitHubAPIKey = getEnvVar("GITHUB_API_KEY", "")
1315
)
1416

1517
func getEnvVar(key, fallbackValue string) string {

server/pkg/handlers/handlers.go

+50-16
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1+
// Package handlers provide functions used to handle gRPC.
12
package handlers
23

34
import (
5+
"errors"
46
"sort"
57

68
"github.com/codingpot/pr12er/server/internal/err"
9+
"github.com/codingpot/pr12er/server/pkg/handlers/gh"
710
"github.com/codingpot/pr12er/server/pkg/handlers/prutils"
811
"github.com/codingpot/pr12er/server/pkg/pr12er"
912
)
1013

14+
// Handler depends on gh.GitHubService interface.
15+
type Handler struct {
16+
gh gh.GitHubService
17+
}
18+
19+
func New(service gh.GitHubService) *Handler {
20+
return &Handler{gh: service}
21+
}
22+
1123
// VideosResponseFromDB converts DB proto to GetVideosResponse.
12-
func VideosResponseFromDB(db *pr12er.Database) *pr12er.GetVideosResponse {
24+
func (h *Handler) VideosResponseFromDB(db *pr12er.Database) *pr12er.GetVideosResponse {
1325
videos := make([]*pr12er.Video, len(db.GetPrIdToVideo()))
1426
i := 0
1527

@@ -38,6 +50,43 @@ func VideosResponseFromDB(db *pr12er.Database) *pr12er.GetVideosResponse {
3850
}
3951
}
4052

53+
// DetailResponseFromDB builds DetailResponse from Database.
54+
func (h *Handler) DetailResponseFromDB(prID int32, db *pr12er.Database) (*pr12er.GetDetailResponse, error) {
55+
video, ok := db.GetPrIdToVideo()[prID]
56+
if !ok {
57+
return nil, err.ErrorPrIDNotFound{PrID: prID}
58+
}
59+
60+
return &pr12er.GetDetailResponse{
61+
Detail: &pr12er.Detail{
62+
PrId: prID,
63+
Papers: video.GetPapers(),
64+
},
65+
}, nil
66+
}
67+
68+
// Report handles when a client sends a bug report or a missing PR video report.
69+
func (h *Handler) Report(in *pr12er.ReportRequest) (*pr12er.ReportResponse, error) {
70+
var issue *gh.GitHubIssue
71+
var e error
72+
73+
switch in.GetType() {
74+
case pr12er.ReportRequest_REPORT_TYPE_BUG:
75+
issue, e = h.gh.CreateIssue("버그 리포트", in.GetBody(), []string{"bug"})
76+
case pr12er.ReportRequest_REPORT_TYPE_MISSING_PR_VIDEO:
77+
issue, e = h.gh.CreateIssue("PR12 누락 동영상", in.GetBody(), []string{"data"})
78+
case pr12er.ReportRequest_REPORT_TYPE_UNSPECIFIED:
79+
issue, e = h.gh.CreateIssue("기타", in.GetBody(), nil)
80+
default:
81+
e = errors.New("this bug report type is not supported")
82+
}
83+
84+
if issue == nil || e != nil {
85+
return nil, e
86+
}
87+
return &pr12er.ReportResponse{IssueUrl: issue.URL}, e
88+
}
89+
4190
// getKeywords returns all keywords by merging each paper's methods.
4291
func getKeywords(prVideo *pr12er.PrVideo) []string {
4392
var ret []string
@@ -53,18 +102,3 @@ func getKeywords(prVideo *pr12er.PrVideo) []string {
53102
func getYouTubeLinkFromID(videoID string) string {
54103
return "https://youtu.be/" + videoID
55104
}
56-
57-
// DetailResponseFromDB builds DetailResponse from Database.
58-
func DetailResponseFromDB(prID int32, db *pr12er.Database) (*pr12er.GetDetailResponse, error) {
59-
video, ok := db.GetPrIdToVideo()[prID]
60-
if !ok {
61-
return nil, err.ErrorPrIDNotFound{PrID: prID}
62-
}
63-
64-
return &pr12er.GetDetailResponse{
65-
Detail: &pr12er.Detail{
66-
PrId: prID,
67-
Papers: video.GetPapers(),
68-
},
69-
}, nil
70-
}

server/pkg/handlers/handlers_test.go

+42-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import (
44
"testing"
55

66
"github.com/codingpot/pr12er/server/internal/data"
7+
"github.com/codingpot/pr12er/server/internal/mock_gh"
8+
"github.com/codingpot/pr12er/server/pkg/handlers/gh"
79
"github.com/codingpot/pr12er/server/pkg/pr12er"
10+
"github.com/golang/mock/gomock"
811
"github.com/google/go-cmp/cmp"
912
"github.com/stretchr/testify/assert"
1013
"google.golang.org/protobuf/testing/protocmp"
@@ -81,7 +84,8 @@ func TestConvertToGet(t *testing.T) {
8184

8285
for _, tt := range tests {
8386
t.Run(tt.name, func(t *testing.T) {
84-
got := VideosResponseFromDB(tt.args.db)
87+
h := New(nil)
88+
got := h.VideosResponseFromDB(tt.args.db)
8589
if got := cmp.Diff(tt.want, got, protocmp.Transform()); got != "" {
8690
t.Error(got)
8791
}
@@ -140,7 +144,8 @@ func TestDetailResponseFromDB(t *testing.T) {
140144
}
141145
for _, tt := range tests {
142146
t.Run(tt.name, func(t *testing.T) {
143-
got, err := DetailResponseFromDB(tt.args.prID, tt.args.db)
147+
h := New(nil)
148+
got, err := h.DetailResponseFromDB(tt.args.prID, tt.args.db)
144149
if tt.wantErr {
145150
assert.Error(t, err)
146151
} else {
@@ -156,3 +161,38 @@ func TestDetailResponseFromDB(t *testing.T) {
156161
})
157162
}
158163
}
164+
165+
func TestHandler_Report(t *testing.T) {
166+
ctrl := gomock.NewController(t)
167+
defer ctrl.Finish()
168+
169+
{
170+
// GIVEN a report
171+
in := &pr12er.ReportRequest{
172+
Type: pr12er.ReportRequest_REPORT_TYPE_BUG,
173+
Body: "Bug Bug Bug",
174+
}
175+
176+
// THEN it should create a issue with the following information.
177+
mockService := mock_gh.NewMockGitHubService(ctrl)
178+
mockService.
179+
EXPECT().
180+
CreateIssue(
181+
gomock.Eq("버그 리포트"),
182+
gomock.Eq("Bug Bug Bug"),
183+
gomock.Eq([]string{"bug"}),
184+
).
185+
Return(&gh.GitHubIssue{URL: "github-issue-url"}, nil)
186+
187+
// THEN checks the response contains the URL.
188+
want := &pr12er.ReportResponse{
189+
IssueUrl: "github-issue-url",
190+
}
191+
h := New(mockService)
192+
got, err := h.Report(in)
193+
assert.NoError(t, err)
194+
if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
195+
t.Error(diff)
196+
}
197+
}
198+
}

server/pkg/serv/serv.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,29 @@ import (
1111

1212
type Server struct {
1313
pr12er.UnsafePr12ErServiceServer
14+
h *handlers.Handler
15+
}
16+
17+
func New(handler *handlers.Handler) *Server {
18+
return &Server{
19+
h: handler,
20+
}
1421
}
1522

1623
var _ pr12er.Pr12ErServiceServer = (*Server)(nil)
1724

1825
func (s Server) GetDetail(_ context.Context, in *pr12er.GetDetailRequest) (*pr12er.GetDetailResponse, error) {
19-
return handlers.DetailResponseFromDB(in.GetPrId(), &data.DB)
26+
return s.h.DetailResponseFromDB(in.GetPrId(), &data.DB)
2027
}
2128

2229
func (s Server) GetHello(_ context.Context, in *pr12er.HelloRequest) (*pr12er.HelloResponse, error) {
2330
return &pr12er.HelloResponse{Body: fmt.Sprintf("Hello %s", in.Body)}, nil
2431
}
2532

2633
func (s Server) GetVideos(_ context.Context, _ *pr12er.GetVideosRequest) (*pr12er.GetVideosResponse, error) {
27-
return handlers.VideosResponseFromDB(&data.DB), nil
34+
return s.h.VideosResponseFromDB(&data.DB), nil
2835
}
2936

3037
func (s Server) Report(_ context.Context, in *pr12er.ReportRequest) (*pr12er.ReportResponse, error) {
31-
panic("implement me")
38+
return s.h.Report(in)
3239
}

0 commit comments

Comments
 (0)