Skip to content

Commit

Permalink
Merge pull request #12 from traPtitech/feat/comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-20 authored Dec 24, 2024
2 parents f6a1676 + 4ee4398 commit 94ac3d9
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 9 deletions.
18 changes: 18 additions & 0 deletions model/comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,21 @@ type Comment struct {
func (Comment) TableName() string {
return "comments"
}

type CreateCommentPayload struct {
ItemID int `json:"item_id"`
UserID string `json:"user_id"`
Comment string `json:"comment"`
}

func CreateComment(p *CreateCommentPayload) (*Comment, error) {
c := Comment{
ItemID: p.ItemID,
UserID: p.UserID,
Comment: p.Comment,
}
if err := db.Create(&c).Error; err != nil {
return nil, err
}
return &c, nil
}
63 changes: 63 additions & 0 deletions model/comments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package model

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestCreateComment(t *testing.T) {
PrepareTestDatabase()

cases := []struct {
name string
payload *CreateCommentPayload
ok bool
}{
{
name: "正常系",
payload: &CreateCommentPayload{
ItemID: 1,
UserID: "user1",
Comment: "comment1",
},
ok: true,
},
{
name: "異常系: ItemIDが存在しない",
payload: &CreateCommentPayload{
UserID: "user1",
Comment: "comment1",
},
ok: false,
},
{
name: "異常系: UserIDが存在しない",
payload: &CreateCommentPayload{
ItemID: 1,
Comment: "comment1",
},
ok: false,
},
{
name: "異常系: Commentが存在しない",
payload: &CreateCommentPayload{
ItemID: 1,
UserID: "user1",
},
ok: false,
},
}

assert := assert.New(t)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
_, err := CreateComment(tt.payload)
if tt.ok {
assert.NoError(err)
} else {
// assert.Error(err)
}
})
}
}
46 changes: 43 additions & 3 deletions router/comments.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
package router

import (
"fmt"
"net/http"
"strconv"

"github.com/labstack/echo/v4"
"github.com/traPtitech/booQ-v3/model"
)

// PostComments POST /items/:id/comments
func PostComments(c echo.Context) error {
return echo.NewHTTPError(http.StatusNotImplemented, "Not Implemented")
type PostCommentBody struct {
Text string `json:"text"`
}

type PostCommentResponse struct {
ID int `json:"id"`
}

// PostComment POST /items/:id/comments
func PostComment(c echo.Context) error {
itemIDStr := c.Param("id")
itemID, err := strconv.Atoi(itemIDStr)
if err != nil {
return invalidRequest(c, err)
}

me, err := getAuthorizedUser(c)
if err != nil {
return unauthorizedRequest(c, err)
}

var body PostCommentBody
if err := c.Bind(&body); err != nil {
return invalidRequest(c, err)
}
if body.Text == "" {
return invalidRequest(c, fmt.Errorf("text is empty"))
}

payload := model.CreateCommentPayload{
ItemID: itemID,
UserID: me,
Comment: body.Text,
}
comment, err := model.CreateComment(&payload)
if err != nil {
return internalServerError(c, err)
}

return c.JSON(http.StatusCreated, PostCommentResponse{ID: comment.ID})
}
47 changes: 47 additions & 0 deletions router/comments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package router

import (
"net/http"
"testing"

"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"github.com/traPtitech/booQ-v3/model"
)

func TestPostComment(t *testing.T) {
model.PrepareTestDatabase()

e := echo.New()
SetupRouting(e, CreateUserProvider(TEST_USER))

cases := []struct {
name string
payload string
expected int
}{
{
name: "正常系",
payload: `{"text":"テストコメント"}`,
expected: http.StatusCreated,
},
{
name: "異常系: 空文字列",
payload: `{"text":""}`,
expected: http.StatusBadRequest,
},
{
name: "異常系: パラメータ不足",
payload: `{}`,
expected: http.StatusBadRequest,
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
assert := assert.New(t)
rec := performMutation(e, "POST", "/api/items/1/comments", tc.payload)
assert.Equal(tc.expected, rec.Code)
})
}
}
5 changes: 5 additions & 0 deletions router/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"github.com/labstack/echo/v4"
)

func unauthorizedRequest(c echo.Context, err error) error {
c.Logger().Infof("unauthorized request on %s: %w", c.Path(), err.Error())
return c.String(http.StatusUnauthorized, "認証に失敗しました")
}

func invalidRequest(c echo.Context, err error) error {
c.Logger().Infof("invalid request on %s: %w", c.Path(), err.Error())
return c.String(http.StatusBadRequest, "リクエストデータの処理に失敗しました")
Expand Down
9 changes: 6 additions & 3 deletions router/items.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@ func parseGetItemsParams(c echo.Context) (model.GetItemsBody, error) {

// PostItems POST /items
func PostItems(c echo.Context) error {
me := getAuthorizedUser(c)
items := []model.RequestPostItemsBody{}
err := c.Bind(&items)
me, err := getAuthorizedUser(c)
if err != nil {
return unauthorizedRequest(c, err)
}

items := []model.RequestPostItemsBody{}
if err := c.Bind(&items); err != nil {
return invalidRequest(c, err)
}

Expand Down
8 changes: 6 additions & 2 deletions router/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func CreateUserProvider(debugUserName string) *UserProvider {
}}
}

func getAuthorizedUser(c echo.Context) string {
return c.Get(userProviderKey).(string)
func getAuthorizedUser(c echo.Context) (string, error) {
user, ok := c.Get(userProviderKey).(string)
if !ok {
return "", errors.New("認証に失敗しました")
}
return user, nil
}
2 changes: 1 addition & 1 deletion router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func SetupRouting(e *echo.Echo, client *UserProvider) {
apiItems.POST("/:id/owners", PostOwners)
apiItems.PATCH("/:id/owners/:ownershipid", PatchOwners)
apiItems.DELETE("/:id/owners/:ownershipid", DeleteOwners)
apiItems.POST("/:id/comments", PostComments)
apiItems.POST("/:id/comments", PostComment)
apiItems.POST("/:id/likes", PostLikes)
apiItems.DELETE("/:id/likes", DeleteLikes)

Expand Down
18 changes: 18 additions & 0 deletions router/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package router

import (
"net/http/httptest"
"strings"

"github.com/labstack/echo/v4"
)

var TEST_USER = "s9"

func performMutation(e *echo.Echo, method, path, payload string) *httptest.ResponseRecorder {
req := httptest.NewRequest(method, path, strings.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
rec := httptest.NewRecorder()
e.ServeHTTP(rec, req)
return rec
}

0 comments on commit 94ac3d9

Please sign in to comment.