Skip to content

Commit 94ac3d9

Browse files
authored
Merge pull request #12 from traPtitech/feat/comments
2 parents f6a1676 + 4ee4398 commit 94ac3d9

9 files changed

+207
-9
lines changed

model/comments.go

+18
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,21 @@ type Comment struct {
1010
func (Comment) TableName() string {
1111
return "comments"
1212
}
13+
14+
type CreateCommentPayload struct {
15+
ItemID int `json:"item_id"`
16+
UserID string `json:"user_id"`
17+
Comment string `json:"comment"`
18+
}
19+
20+
func CreateComment(p *CreateCommentPayload) (*Comment, error) {
21+
c := Comment{
22+
ItemID: p.ItemID,
23+
UserID: p.UserID,
24+
Comment: p.Comment,
25+
}
26+
if err := db.Create(&c).Error; err != nil {
27+
return nil, err
28+
}
29+
return &c, nil
30+
}

model/comments_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package model
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestCreateComment(t *testing.T) {
10+
PrepareTestDatabase()
11+
12+
cases := []struct {
13+
name string
14+
payload *CreateCommentPayload
15+
ok bool
16+
}{
17+
{
18+
name: "正常系",
19+
payload: &CreateCommentPayload{
20+
ItemID: 1,
21+
UserID: "user1",
22+
Comment: "comment1",
23+
},
24+
ok: true,
25+
},
26+
{
27+
name: "異常系: ItemIDが存在しない",
28+
payload: &CreateCommentPayload{
29+
UserID: "user1",
30+
Comment: "comment1",
31+
},
32+
ok: false,
33+
},
34+
{
35+
name: "異常系: UserIDが存在しない",
36+
payload: &CreateCommentPayload{
37+
ItemID: 1,
38+
Comment: "comment1",
39+
},
40+
ok: false,
41+
},
42+
{
43+
name: "異常系: Commentが存在しない",
44+
payload: &CreateCommentPayload{
45+
ItemID: 1,
46+
UserID: "user1",
47+
},
48+
ok: false,
49+
},
50+
}
51+
52+
assert := assert.New(t)
53+
for _, tt := range cases {
54+
t.Run(tt.name, func(t *testing.T) {
55+
_, err := CreateComment(tt.payload)
56+
if tt.ok {
57+
assert.NoError(err)
58+
} else {
59+
// assert.Error(err)
60+
}
61+
})
62+
}
63+
}

router/comments.go

+43-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,52 @@
11
package router
22

33
import (
4+
"fmt"
45
"net/http"
6+
"strconv"
57

68
"github.com/labstack/echo/v4"
9+
"github.com/traPtitech/booQ-v3/model"
710
)
811

9-
// PostComments POST /items/:id/comments
10-
func PostComments(c echo.Context) error {
11-
return echo.NewHTTPError(http.StatusNotImplemented, "Not Implemented")
12+
type PostCommentBody struct {
13+
Text string `json:"text"`
14+
}
15+
16+
type PostCommentResponse struct {
17+
ID int `json:"id"`
18+
}
19+
20+
// PostComment POST /items/:id/comments
21+
func PostComment(c echo.Context) error {
22+
itemIDStr := c.Param("id")
23+
itemID, err := strconv.Atoi(itemIDStr)
24+
if err != nil {
25+
return invalidRequest(c, err)
26+
}
27+
28+
me, err := getAuthorizedUser(c)
29+
if err != nil {
30+
return unauthorizedRequest(c, err)
31+
}
32+
33+
var body PostCommentBody
34+
if err := c.Bind(&body); err != nil {
35+
return invalidRequest(c, err)
36+
}
37+
if body.Text == "" {
38+
return invalidRequest(c, fmt.Errorf("text is empty"))
39+
}
40+
41+
payload := model.CreateCommentPayload{
42+
ItemID: itemID,
43+
UserID: me,
44+
Comment: body.Text,
45+
}
46+
comment, err := model.CreateComment(&payload)
47+
if err != nil {
48+
return internalServerError(c, err)
49+
}
50+
51+
return c.JSON(http.StatusCreated, PostCommentResponse{ID: comment.ID})
1252
}

router/comments_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package router
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/labstack/echo/v4"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/traPtitech/booQ-v3/model"
10+
)
11+
12+
func TestPostComment(t *testing.T) {
13+
model.PrepareTestDatabase()
14+
15+
e := echo.New()
16+
SetupRouting(e, CreateUserProvider(TEST_USER))
17+
18+
cases := []struct {
19+
name string
20+
payload string
21+
expected int
22+
}{
23+
{
24+
name: "正常系",
25+
payload: `{"text":"テストコメント"}`,
26+
expected: http.StatusCreated,
27+
},
28+
{
29+
name: "異常系: 空文字列",
30+
payload: `{"text":""}`,
31+
expected: http.StatusBadRequest,
32+
},
33+
{
34+
name: "異常系: パラメータ不足",
35+
payload: `{}`,
36+
expected: http.StatusBadRequest,
37+
},
38+
}
39+
40+
for _, tc := range cases {
41+
t.Run(tc.name, func(t *testing.T) {
42+
assert := assert.New(t)
43+
rec := performMutation(e, "POST", "/api/items/1/comments", tc.payload)
44+
assert.Equal(tc.expected, rec.Code)
45+
})
46+
}
47+
}

router/common.go

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import (
66
"github.com/labstack/echo/v4"
77
)
88

9+
func unauthorizedRequest(c echo.Context, err error) error {
10+
c.Logger().Infof("unauthorized request on %s: %w", c.Path(), err.Error())
11+
return c.String(http.StatusUnauthorized, "認証に失敗しました")
12+
}
13+
914
func invalidRequest(c echo.Context, err error) error {
1015
c.Logger().Infof("invalid request on %s: %w", c.Path(), err.Error())
1116
return c.String(http.StatusBadRequest, "リクエストデータの処理に失敗しました")

router/items.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ func parseGetItemsParams(c echo.Context) (model.GetItemsBody, error) {
5858

5959
// PostItems POST /items
6060
func PostItems(c echo.Context) error {
61-
me := getAuthorizedUser(c)
62-
items := []model.RequestPostItemsBody{}
63-
err := c.Bind(&items)
61+
me, err := getAuthorizedUser(c)
6462
if err != nil {
63+
return unauthorizedRequest(c, err)
64+
}
65+
66+
items := []model.RequestPostItemsBody{}
67+
if err := c.Bind(&items); err != nil {
6568
return invalidRequest(c, err)
6669
}
6770

router/middleware.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ func CreateUserProvider(debugUserName string) *UserProvider {
4141
}}
4242
}
4343

44-
func getAuthorizedUser(c echo.Context) string {
45-
return c.Get(userProviderKey).(string)
44+
func getAuthorizedUser(c echo.Context) (string, error) {
45+
user, ok := c.Get(userProviderKey).(string)
46+
if !ok {
47+
return "", errors.New("認証に失敗しました")
48+
}
49+
return user, nil
4650
}

router/router.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func SetupRouting(e *echo.Echo, client *UserProvider) {
2727
apiItems.POST("/:id/owners", PostOwners)
2828
apiItems.PATCH("/:id/owners/:ownershipid", PatchOwners)
2929
apiItems.DELETE("/:id/owners/:ownershipid", DeleteOwners)
30-
apiItems.POST("/:id/comments", PostComments)
30+
apiItems.POST("/:id/comments", PostComment)
3131
apiItems.POST("/:id/likes", PostLikes)
3232
apiItems.DELETE("/:id/likes", DeleteLikes)
3333

router/util_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package router
2+
3+
import (
4+
"net/http/httptest"
5+
"strings"
6+
7+
"github.com/labstack/echo/v4"
8+
)
9+
10+
var TEST_USER = "s9"
11+
12+
func performMutation(e *echo.Echo, method, path, payload string) *httptest.ResponseRecorder {
13+
req := httptest.NewRequest(method, path, strings.NewReader(payload))
14+
req.Header.Set("Content-Type", "application/json")
15+
rec := httptest.NewRecorder()
16+
e.ServeHTTP(rec, req)
17+
return rec
18+
}

0 commit comments

Comments
 (0)