diff --git a/go.mod b/go.mod index e8593852..86732007 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23.3 require ( entgo.io/ent v0.14.1 github.com/go-sql-driver/mysql v1.8.1 + github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/gorilla/sessions v1.4.0 github.com/labstack/echo-contrib v0.17.2 @@ -24,7 +25,6 @@ require ( github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-openapi/inflect v0.21.0 // indirect - github.com/google/go-cmp v0.6.0 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/hashicorp/hcl/v2 v2.23.0 // indirect diff --git a/model/admin_impl_test.go b/model/admin_impl_test.go index 57a962c0..5ac48115 100644 --- a/model/admin_impl_test.go +++ b/model/admin_impl_test.go @@ -36,13 +36,11 @@ func TestEntRepository_GetAdmins(t *testing.T) { got, err := repo.GetAdmins(ctx) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == user1.ID { - assert.Equal(t, got[0].ID, user1.ID) - assert.Equal(t, got[1].ID, user2.ID) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].ID, user2.ID) - assert.Equal(t, got[1].ID, user1.ID) + exp := []*Admin{ + {ID: user1.ID}, + {ID: user2.ID}, } + assert.ElementsMatch(t, exp, got) }) t.Run("Success2", func(t *testing.T) { @@ -50,7 +48,7 @@ func TestEntRepository_GetAdmins(t *testing.T) { got, err := repo2.GetAdmins(ctx) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) } diff --git a/model/comment_impl_test.go b/model/comment_impl_test.go index dd7b8af5..c76c4137 100644 --- a/model/comment_impl_test.go +++ b/model/comment_impl_test.go @@ -3,10 +3,13 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -42,21 +45,13 @@ func TestEntRepository_GetComments(t *testing.T) { got, err := repo.GetComments(ctx, request.ID) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == comment1.ID { - assert.Equal(t, got[0].ID, comment1.ID) - assert.Equal(t, got[0].User, comment1.User) - assert.Equal(t, got[0].Comment, comment1.Comment) - assert.Equal(t, got[1].ID, comment2.ID) - assert.Equal(t, got[1].User, comment2.User) - assert.Equal(t, got[1].Comment, comment2.Comment) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].ID, comment2.ID) - assert.Equal(t, got[0].User, comment2.User) - assert.Equal(t, got[0].Comment, comment2.Comment) - assert.Equal(t, got[1].ID, comment1.ID) - assert.Equal(t, got[1].User, comment1.User) - assert.Equal(t, got[1].Comment, comment1.Comment) - } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(l, r *Comment) bool { + return l.ID.ID() < r.ID.ID() + })) + exp := []*Comment{comment1, comment2} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -77,7 +72,7 @@ func TestEntRepository_GetComments(t *testing.T) { got, err := repo2.GetComments(ctx, request.ID) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) t.Run("UnknownRequest", func(t *testing.T) { @@ -118,8 +113,16 @@ func TestEntRepository_CreateComment(t *testing.T) { require.NoError(t, err) created, err := repo.CreateComment(ctx, comment, request.ID, user2.ID) assert.NoError(t, err) - assert.Equal(t, created.User, user2.ID) - assert.Equal(t, created.Comment, comment) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(Comment{}, "ID")) + exp := &Comment{ + User: user2.ID, + Comment: comment, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, created, opts...) }) t.Run("UnknownRequest", func(t *testing.T) { @@ -155,7 +158,7 @@ func TestEntRepository_CreateComment(t *testing.T) { }) } -func TestEntREpository_UpdateComment(t *testing.T) { +func TestEntRepository_UpdateComment(t *testing.T) { ctx := context.Background() client, storage, err := setup(t, ctx, "update_comment") require.NoError(t, err) @@ -182,9 +185,15 @@ func TestEntREpository_UpdateComment(t *testing.T) { comment := random.AlphaNumeric(t, 30) updated, err := repo.UpdateComment(ctx, comment, request.ID, created.ID) assert.NoError(t, err) - assert.Equal(t, updated.ID, created.ID) - assert.Equal(t, updated.User, created.User) - assert.Equal(t, updated.Comment, comment) + opts := testutil.ApproxEqualOptions() + exp := &Comment{ + ID: created.ID, + User: created.User, + Comment: comment, + CreatedAt: created.CreatedAt, + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, updated, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -214,15 +223,19 @@ func TestEntREpository_UpdateComment(t *testing.T) { require.NoError(t, err) updated, err := repo.UpdateComment(ctx, comment.Comment, request2.ID, comment.ID) assert.NoError(t, err) - assert.Equal(t, updated.ID, comment.ID) - assert.Equal(t, updated.User, comment.User) - assert.Equal(t, updated.Comment, comment.Comment) + opts := testutil.ApproxEqualOptions() + exp := &Comment{ + ID: comment.ID, + User: comment.User, + Comment: comment.Comment, + CreatedAt: comment.CreatedAt, + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, updated, opts...) got, err := repo.GetComments(ctx, request2.ID) require.NoError(t, err) - assert.Equal(t, got[0].ID, updated.ID) - assert.Equal(t, got[0].User, updated.User) - assert.Equal(t, got[0].Comment, updated.Comment) + testutil.RequireEqual(t, []*Comment{updated}, got, opts...) }) t.Run("UnknownComment", func(t *testing.T) { @@ -297,6 +310,10 @@ func TestEntRepository_DeleteComment(t *testing.T) { err = repo.DeleteComment(ctx, request.ID, comment.ID) assert.NoError(t, err) + + comments, err := repo.GetComments(ctx, request.ID) + require.NoError(t, err) + assert.Empty(t, comments) }) t.Run("UnknownRequest", func(t *testing.T) { diff --git a/model/file_impl_test.go b/model/file_impl_test.go index 0fd3178f..8bda6143 100644 --- a/model/file_impl_test.go +++ b/model/file_impl_test.go @@ -3,10 +3,13 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -43,8 +46,16 @@ func TestEntRepository_CreateFile(t *testing.T) { file, err := repo.CreateFile(ctx, name, mimetype, request.ID, user.ID) assert.NoError(t, err) - assert.Equal(t, name, file.Name) - assert.Equal(t, mimetype, file.MimeType) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(File{}, "ID")) + exp := &File{ + Name: name, + MimeType: mimetype, + CreatedBy: user.ID, + CreatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, file, opts...) }) t.Run("UnknownRequest", func(t *testing.T) { @@ -132,9 +143,15 @@ func TestEntRepository_GetFile(t *testing.T) { assert.NoError(t, err) got, err := repo.GetFile(ctx, file.ID) assert.NoError(t, err) - assert.Equal(t, file.ID, got.ID) - assert.Equal(t, file.Name, got.Name) - assert.Equal(t, file.MimeType, got.MimeType) + opts := testutil.ApproxEqualOptions() + exp := &File{ + ID: file.ID, + Name: name, + MimeType: mimetype, + CreatedBy: user.ID, + CreatedAt: file.CreatedAt, + } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("UnknownFile", func(t *testing.T) { @@ -185,7 +202,7 @@ func TestEntRepository_DeleteFile(t *testing.T) { r, err := repo.GetRequest(ctx, request.ID) require.NoError(t, err) - assert.Len(t, r.Files, 0) + assert.Empty(t, r.Files) }) t.Run("UnknownFile", func(t *testing.T) { diff --git a/model/group_impl_test.go b/model/group_impl_test.go index 6104647d..c45247e8 100644 --- a/model/group_impl_test.go +++ b/model/group_impl_test.go @@ -3,10 +3,13 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -31,8 +34,8 @@ func TestEntRepository_GetGroups(t *testing.T) { groups, err := repo.GetGroups(ctx) require.NoError(t, err) - assert.Equal(t, 1, len(groups)) - assert.Equal(t, group.ID, groups[0].ID) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, []*Group{group}, groups, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -52,19 +55,17 @@ func TestEntRepository_GetGroup(t *testing.T) { t.Run("Success", func(t *testing.T) { t.Parallel() budget := random.Numeric(t, 100000) - group, err := repo.CreateGroup( + created, err := repo.CreateGroup( ctx, random.AlphaNumeric(t, 20), random.AlphaNumeric(t, 15), &budget) require.NoError(t, err) - g, err := repo.GetGroup(ctx, group.ID) + got, err := repo.GetGroup(ctx, created.ID) assert.NoError(t, err) - assert.Equal(t, group.ID, g.ID) - assert.Equal(t, group.Name, g.Name) - assert.Equal(t, group.Description, g.Description) - assert.Equal(t, group.Budget, g.Budget) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, created, got, opts...) }) t.Run("UnknownGroup", func(t *testing.T) { @@ -85,22 +86,40 @@ func TestEntRepository_CreateGroup(t *testing.T) { budget := random.Numeric(t, 100000) name := random.AlphaNumeric(t, 20) description := random.AlphaNumeric(t, 15) - group, err := repo.CreateGroup(ctx, name, description, &budget) + created, err := repo.CreateGroup(ctx, name, description, &budget) require.NoError(t, err) - assert.Equal(t, name, group.Name) - assert.Equal(t, description, group.Description) - assert.Equal(t, *group.Budget, budget) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(Group{}, "ID")) + exp := &Group{ + Name: name, + Description: description, + Budget: &budget, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, created, opts...) }) t.Run("SuccessWithNilBudget", func(t *testing.T) { t.Parallel() name := random.AlphaNumeric(t, 20) description := random.AlphaNumeric(t, 15) - group, err := repo.CreateGroup(ctx, name, description, nil) + created, err := repo.CreateGroup(ctx, name, description, nil) assert.NoError(t, err) - assert.Equal(t, name, group.Name) - assert.Equal(t, description, group.Description) - assert.Nil(t, group.Budget) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(Group{}, "ID")) + exp := &Group{ + Name: name, + Description: description, + Budget: nil, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, created, opts...) }) t.Run("FailedWithEmptyName", func(t *testing.T) { @@ -120,7 +139,7 @@ func TestEntRepository_UpdateGroup(t *testing.T) { t.Run("Success", func(t *testing.T) { t.Parallel() budget := random.Numeric(t, 100000) - group, err := repo.CreateGroup( + created, err := repo.CreateGroup( ctx, random.AlphaNumeric(t, 20), random.AlphaNumeric(t, 15), @@ -129,16 +148,24 @@ func TestEntRepository_UpdateGroup(t *testing.T) { updatedBudget := random.Numeric(t, 10000) ug := Group{ - ID: group.ID, + ID: created.ID, Name: random.AlphaNumeric(t, 20), Description: random.AlphaNumeric(t, 15), Budget: &updatedBudget, } - updated, err := repo.UpdateGroup(ctx, group.ID, ug.Name, ug.Description, ug.Budget) + updated, err := repo.UpdateGroup(ctx, created.ID, ug.Name, ug.Description, ug.Budget) assert.NoError(t, err) - assert.Equal(t, ug.Name, updated.Name) - assert.Equal(t, ug.Description, updated.Description) - assert.Equal(t, ug.Budget, updated.Budget) + opts := testutil.ApproxEqualOptions() + exp := &Group{ + ID: created.ID, + Name: ug.Name, + Description: ug.Description, + Budget: &updatedBudget, + CreatedAt: created.CreatedAt, + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, updated, opts...) }) t.Run("UnknownGroup", func(t *testing.T) { @@ -156,7 +183,7 @@ func TestEntRepository_UpdateGroup(t *testing.T) { t.Run("SuccessWithNilBudget", func(t *testing.T) { t.Parallel() budget := random.Numeric(t, 100000) - group, err := repo.CreateGroup( + created, err := repo.CreateGroup( ctx, random.AlphaNumeric(t, 20), random.AlphaNumeric(t, 15), @@ -164,16 +191,24 @@ func TestEntRepository_UpdateGroup(t *testing.T) { require.NoError(t, err) ug := Group{ - ID: group.ID, + ID: created.ID, Name: random.AlphaNumeric(t, 20), Description: random.AlphaNumeric(t, 15), Budget: nil, } - updated, err := repo.UpdateGroup(ctx, group.ID, ug.Name, ug.Description, ug.Budget) + updated, err := repo.UpdateGroup(ctx, created.ID, ug.Name, ug.Description, ug.Budget) assert.NoError(t, err) - assert.Equal(t, ug.Name, updated.Name) - assert.Equal(t, ug.Description, updated.Description) - assert.Nil(t, updated.Budget) + opts := testutil.ApproxEqualOptions() + exp := &Group{ + ID: created.ID, + Name: ug.Name, + Description: ug.Description, + Budget: nil, + CreatedAt: created.CreatedAt, + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, updated, opts...) }) t.Run("FailedWithEmptyName", func(t *testing.T) { @@ -209,6 +244,10 @@ func TestEntRepository_DeleteGroup(t *testing.T) { err = repo.DeleteGroup(ctx, group.ID) assert.NoError(t, err) + + groups, err := repo.GetGroups(ctx) + require.NoError(t, err) + assert.Empty(t, groups) }) t.Run("UnknownGroup", func(t *testing.T) { @@ -255,13 +294,14 @@ func TestEntRepository_GetMembers(t *testing.T) { got, err := repo.GetMembers(ctx, group.ID) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == user1.ID { - assert.Equal(t, got[0].ID, user1.ID) - assert.Equal(t, got[1].ID, user2.ID) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].ID, user2.ID) - assert.Equal(t, got[1].ID, user1.ID) + sortOpt := cmpopts.SortSlices(func(a, b *Member) bool { + return a.ID.ID() < b.ID.ID() + }) + exp := []*Member{ + {ID: user1.ID}, + {ID: user2.ID}, } + testutil.RequireEqual(t, exp, got, sortOpt) }) t.Run("Success2", func(t *testing.T) { @@ -304,9 +344,10 @@ func TestEntRepository_CreateMember(t *testing.T) { true) require.NoError(t, err) - member, err := repo.AddMembers(ctx, group.ID, []uuid.UUID{user.ID}) + got, err := repo.AddMembers(ctx, group.ID, []uuid.UUID{user.ID}) assert.NoError(t, err) - assert.Equal(t, member[0].ID, user.ID) + exp := []*Member{{ID: user.ID}} + testutil.RequireEqual(t, exp, got) }) t.Run("UnknownUser", func(t *testing.T) { @@ -374,7 +415,8 @@ func TestEntRepository_GetOwners(t *testing.T) { user1, err := repo.CreateUser( ctx, random.AlphaNumeric(t, 20), - random.AlphaNumeric(t, 15), true) + random.AlphaNumeric(t, 15), + true) require.NoError(t, err) user2, err := repo.CreateUser( ctx, @@ -388,13 +430,14 @@ func TestEntRepository_GetOwners(t *testing.T) { got, err := repo.GetOwners(ctx, group.ID) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == user1.ID { - assert.Equal(t, got[0].ID, user1.ID) - assert.Equal(t, got[1].ID, user2.ID) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[1].ID, user1.ID) - assert.Equal(t, got[0].ID, user2.ID) + sortOpt := cmpopts.SortSlices(func(a, b *Owner) bool { + return a.ID.ID() < b.ID.ID() + }) + exp := []*Owner{ + {ID: user1.ID}, + {ID: user2.ID}, } + testutil.RequireEqual(t, exp, got, sortOpt) }) t.Run("Success2", func(t *testing.T) { @@ -410,10 +453,11 @@ func TestEntRepository_GetOwners(t *testing.T) { got, err := repo.GetOwners(ctx, group.ID) assert.NoError(t, err) - assert.Equal(t, got, []*Owner{}) + assert.Empty(t, got) }) } +// FIXME: これAddOwnersでは? func TestEntRepository_CreateOwner(t *testing.T) { ctx := context.Background() client, storage, err := setup(t, ctx, "create_owner") @@ -439,7 +483,8 @@ func TestEntRepository_CreateOwner(t *testing.T) { owner, err := repo.AddOwners(ctx, group.ID, []uuid.UUID{user.ID}) assert.NoError(t, err) - assert.Equal(t, owner[0].ID, user.ID) + exp := []*Owner{{ID: user.ID}} + testutil.RequireEqual(t, exp, owner) }) t.Run("UnknownUser", func(t *testing.T) { diff --git a/model/request_impl.go b/model/request_impl.go index 9efc5174..8b2cb147 100644 --- a/model/request_impl.go +++ b/model/request_impl.go @@ -170,10 +170,11 @@ func (repo *EntRepository) CreateRequest( return nil, err } if group != nil { - _, err = tx.Client().Group. + g, err := tx.Client().Group. UpdateOneID(group.ID). AddRequest(created). Save(ctx) + group = ConvertEntGroupToModelGroup(g) if err != nil { err = RollbackWithError(tx, err) return nil, err @@ -321,7 +322,6 @@ func (repo *EntRepository) UpdateRequest( } entstatuses, err := updated.QueryStatus(). - Select(requeststatus.FieldStatus). WithUser(). Order(ent.Desc(requeststatus.FieldCreatedAt)). All(ctx) diff --git a/model/request_impl_test.go b/model/request_impl_test.go index a690f7b7..643d6c50 100644 --- a/model/request_impl_test.go +++ b/model/request_impl_test.go @@ -5,12 +5,31 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) +func (rd *RequestDetail) toExpectedRequestResponse(t *testing.T) *RequestResponse { + t.Helper() + return &RequestResponse{ + ID: rd.ID, + Status: rd.Status, + CreatedAt: rd.CreatedAt, + UpdatedAt: rd.UpdatedAt, + CreatedBy: rd.CreatedBy, + Title: rd.Title, + Content: rd.Content, + Tags: rd.Tags, + //Targets: rd.Targets, + //Statuses: rd.Statuses, + Group: rd.Group, + } +} + func TestEntRepository_GetRequests(t *testing.T) { ctx := context.Background() client, storage, err := setup(t, ctx, "get_requests") @@ -97,20 +116,16 @@ func TestEntRepository_GetRequests(t *testing.T) { Sort: &sort, }) assert.NoError(t, err) - if assert.Len(t, got, 2) && assert.Equal(t, got[1].ID, request1.ID) { - assert.Equal(t, got[1].ID, request1.ID) - assert.Equal(t, got[1].Status, request1.Status) - assert.Equal(t, got[1].Title, request1.Title) - assert.Equal(t, got[1].Content, request1.Content) - assert.Equal(t, got[1].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[1].Tags[0].Name, request1.Tags[0].Name) - assert.Equal(t, got[0].ID, request2.ID) - assert.Equal(t, got[0].Status, request2.Status) - assert.Equal(t, got[0].Title, request2.Title) - assert.Equal(t, got[0].Content, request2.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(a, b *RequestResponse) bool { + return a.ID.ID() < b.ID.ID() + })) + exp := []*RequestResponse{ + request1.toExpectedRequestResponse(t), + request2.toExpectedRequestResponse(t), } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithReverseSortCreatedAt", func(t *testing.T) { @@ -169,20 +184,16 @@ func TestEntRepository_GetRequests(t *testing.T) { Sort: &sort, }) assert.NoError(t, err) - if assert.Len(t, got, 2) && assert.Equal(t, got[0].ID, request1.ID) { - assert.Equal(t, got[0].ID, request1.ID) - assert.Equal(t, got[0].Status, request1.Status) - assert.Equal(t, got[0].Title, request1.Title) - assert.Equal(t, got[0].Content, request1.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) - assert.Equal(t, got[1].ID, request2.ID) - assert.Equal(t, got[1].Status, request2.Status) - assert.Equal(t, got[1].Title, request2.Title) - assert.Equal(t, got[1].Content, request2.Content) - assert.Equal(t, got[1].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[1].Tags[0].Name, request1.Tags[0].Name) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(a, b *RequestResponse) bool { + return a.ID.ID() < b.ID.ID() + })) + exp := []*RequestResponse{ + request1.toExpectedRequestResponse(t), + request2.toExpectedRequestResponse(t), } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSortTitle", func(t *testing.T) { @@ -240,20 +251,16 @@ func TestEntRepository_GetRequests(t *testing.T) { Sort: &sort, }) assert.NoError(t, err) - if assert.Len(t, got, 2) && assert.Equal(t, got[0].ID, request2.ID) { - assert.Equal(t, got[0].ID, request2.ID) - assert.Equal(t, got[0].Status, request2.Status) - assert.Equal(t, got[0].Title, request2.Title) - assert.Equal(t, got[0].Content, request2.Content) - assert.Equal(t, got[0].Tags[0].ID, request2.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request2.Tags[0].Name) - assert.Equal(t, got[1].ID, request1.ID) - assert.Equal(t, got[1].Status, request1.Status) - assert.Equal(t, got[1].Title, request1.Title) - assert.Equal(t, got[1].Content, request1.Content) - assert.Equal(t, got[1].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[1].Tags[0].Name, request1.Tags[0].Name) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(a, b *RequestResponse) bool { + return a.ID.ID() < b.ID.ID() + })) + exp := []*RequestResponse{ + request2.toExpectedRequestResponse(t), + request1.toExpectedRequestResponse(t), } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithReverseSortTitle", func(t *testing.T) { @@ -311,20 +318,16 @@ func TestEntRepository_GetRequests(t *testing.T) { Sort: &sort, }) assert.NoError(t, err) - if assert.Len(t, got, 2) && assert.Equal(t, got[0].ID, request1.ID) { - assert.Equal(t, got[0].ID, request1.ID) - assert.Equal(t, got[0].Status, request1.Status) - assert.Equal(t, got[0].Title, request1.Title) - assert.Equal(t, got[0].Content, request1.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) - assert.Equal(t, got[1].ID, request2.ID) - assert.Equal(t, got[1].Status, request2.Status) - assert.Equal(t, got[1].Title, request2.Title) - assert.Equal(t, got[1].Content, request2.Content) - assert.Equal(t, got[1].Tags[0].ID, request2.Tags[0].ID) - assert.Equal(t, got[1].Tags[0].Name, request2.Tags[0].Name) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(a, b *RequestResponse) bool { + return a.ID.ID() < b.ID.ID() + })) + exp := []*RequestResponse{ + request1.toExpectedRequestResponse(t), + request2.toExpectedRequestResponse(t), } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithQueryTarget", func(t *testing.T) { @@ -386,12 +389,9 @@ func TestEntRepository_GetRequests(t *testing.T) { }) assert.NoError(t, err) if assert.Len(t, got, 1) { - assert.Equal(t, got[0].ID, request1.ID) - assert.Equal(t, got[0].Status, request1.Status) - assert.Equal(t, got[0].Title, request1.Title) - assert.Equal(t, got[0].Content, request1.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) + exp := request1.toExpectedRequestResponse(t) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, exp, got[0], opts...) } }) @@ -451,12 +451,9 @@ func TestEntRepository_GetRequests(t *testing.T) { }) assert.NoError(t, err) if assert.Len(t, got, 1) { - assert.Equal(t, got[0].ID, request2.ID) - assert.Equal(t, got[0].Status, request2.Status) - assert.Equal(t, got[0].Title, request2.Title) - assert.Equal(t, got[0].Content, request2.Content) - assert.Equal(t, got[0].Tags[0].ID, request2.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request2.Tags[0].Name) + exp := request2.toExpectedRequestResponse(t) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, exp, got[0], opts...) } }) @@ -516,12 +513,10 @@ func TestEntRepository_GetRequests(t *testing.T) { }) assert.NoError(t, err) if assert.Len(t, got, 1) { - assert.Equal(t, got[0].ID, request1.ID) - assert.Equal(t, got[0].Status, request1.Status) - assert.Equal(t, got[0].Title, request1.Title) - assert.Equal(t, got[0].Content, request1.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) + exp := request1.toExpectedRequestResponse(t) + exp.Group.UpdatedAt = request2.Group.UpdatedAt + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, exp, got[0], opts...) } }) @@ -565,7 +560,7 @@ func TestEntRepository_GetRequests(t *testing.T) { user1.ID) require.NoError(t, err) time.Sleep(2 * time.Second) - _, err = repo8.CreateRequest( + request2, err := repo8.CreateRequest( ctx, "a", random.AlphaNumeric(t, 100), @@ -586,12 +581,11 @@ func TestEntRepository_GetRequests(t *testing.T) { }) assert.NoError(t, err) if assert.Len(t, got, 1) { - assert.Equal(t, got[0].ID, request1.ID) - assert.Equal(t, got[0].Status, Accepted) - assert.Equal(t, got[0].Title, request1.Title) - assert.Equal(t, got[0].Content, request1.Content) - assert.Equal(t, got[0].Tags[0].ID, request1.Tags[0].ID) - assert.Equal(t, got[0].Tags[0].Name, request1.Tags[0].Name) + exp := request1.toExpectedRequestResponse(t) + exp.Status = Accepted + exp.Group.UpdatedAt = request2.Group.UpdatedAt + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, exp, got[0], opts...) } }) @@ -647,30 +641,9 @@ func TestEntRepository_GetRequests(t *testing.T) { }) require.NoError(t, err) if assert.Len(t, got, 1) { - got := got[0] - exp := &RequestResponse{ - ID: request1.ID, - Status: request1.Status, - // FIXME: time.Time の内部表現が異なるため、比較ができない - CreatedAt: got.CreatedAt, - UpdatedAt: got.UpdatedAt, - CreatedBy: request1.CreatedBy, - Title: request1.Title, - Content: request1.Content, - Tags: request1.Tags, - // Targets: request1.Targets, - // Statuses: request1.Statuses, - Group: &Group{ - ID: request1.Group.ID, - Name: request1.Group.Name, - Description: request1.Group.Description, - Budget: request1.Group.Budget, - CreatedAt: got.Group.CreatedAt, - UpdatedAt: got.Group.UpdatedAt, - DeletedAt: request1.Group.DeletedAt, - }, - } - require.Equal(t, exp, got) + exp := request1.toExpectedRequestResponse(t) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, exp, got[0], opts...) } }) } @@ -722,12 +695,30 @@ func TestEntRepository_CreateRequest(t *testing.T) { []*Tag{tag}, []*RequestTarget{target}, group, user.ID) assert.NoError(t, err) - assert.Equal(t, request.CreatedBy, user.ID) - assert.Equal(t, request.Status, Status(1)) - assert.Equal(t, request.Title, title) - assert.Equal(t, request.Content, content) - assert.Equal(t, request.Tags, []*Tag{tag}) - assert.Equal(t, request.Group, group) + exp := &RequestDetail{ + Status: Submitted, + Title: title, + Content: content, + Tags: []*Tag{tag}, + Targets: []*RequestTargetDetail{{ + Target: target.Target, + Amount: target.Amount, + }}, + Statuses: []*RequestStatus{{ + CreatedBy: user.ID, + Status: Submitted, + }}, + Group: group, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + CreatedBy: user.ID, + } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestDetail{}, "ID"), + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt", "CreatedAt"), + cmpopts.IgnoreFields(RequestStatus{}, "ID", "CreatedAt")) + testutil.AssertEqual(t, exp, request, opts...) }) t.Run("UnknownUser", func(t *testing.T) { @@ -865,18 +856,8 @@ func TestEntRepository_GetRequest(t *testing.T) { got, err := repo.GetRequest(ctx, request.ID) assert.NoError(t, err) - assert.Equal(t, got.CreatedBy, user.ID) - assert.Equal(t, got.Status, Status(1)) - assert.Equal(t, got.Title, request.Title) - assert.Equal(t, got.Content, request.Content) - assert.Equal(t, got.Tags[0].ID, request.Tags[0].ID) - assert.Equal(t, got.Tags[0].Name, request.Tags[0].Name) - assert.Equal(t, got.Targets[0].Target, request.Targets[0].Target) - assert.Equal(t, got.Targets[0].Amount, request.Targets[0].Amount) - assert.Equal(t, got.Group.ID, request.Group.ID) - assert.Equal(t, got.Group.Name, request.Group.Name) - assert.Equal(t, got.Group.Description, request.Group.Description) - assert.Equal(t, got.Group.Budget, request.Group.Budget) + opts := testutil.ApproxEqualOptions() + testutil.AssertEqual(t, request, got, opts...) }) t.Run("UnknownRequest", func(t *testing.T) { @@ -941,16 +922,29 @@ func TestEntRepository_UpdateRequest(t *testing.T) { []*Tag{tag}, []*RequestTarget{target}, group) assert.NoError(t, err) - assert.Equal(t, updatedRequest.ID, request.ID) - assert.Equal(t, updatedRequest.Status, request.Status) - assert.Equal(t, updatedRequest.Title, request.Title) - assert.Equal(t, updatedRequest.Content, request.Content) - assert.Equal(t, updatedRequest.Tags[0].ID, tag.ID) - assert.Equal(t, updatedRequest.Tags[0].Name, tag.Name) - assert.Equal(t, updatedRequest.Group.ID, request.Group.ID) - assert.Equal(t, updatedRequest.Group.Name, request.Group.Name) - assert.Equal(t, updatedRequest.Group.Description, request.Group.Description) - assert.Equal(t, updatedRequest.Group.Budget, request.Group.Budget) + exp := &RequestDetail{ + ID: request.ID, + Status: request.Status, + Title: request.Title, + Content: request.Content, + Comments: request.Comments, + Files: request.Files, + Tags: []*Tag{tag}, + Targets: []*RequestTargetDetail{{ + Target: target.Target, + Amount: target.Amount, + CreatedAt: time.Now(), + }}, + Statuses: request.Statuses, + Group: group, + CreatedAt: request.CreatedAt, + UpdatedAt: time.Now(), + CreatedBy: request.CreatedBy, + } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt")) + testutil.AssertEqual(t, exp, updatedRequest, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -990,16 +984,29 @@ func TestEntRepository_UpdateRequest(t *testing.T) { []*Tag{tag}, []*RequestTarget{target}, group) assert.NoError(t, err) - assert.Equal(t, updatedRequest.ID, request.ID) - assert.Equal(t, updatedRequest.Status, request.Status) - assert.Equal(t, updatedRequest.Title, title) - assert.Equal(t, updatedRequest.Content, request.Content) - assert.Equal(t, updatedRequest.Tags[0].ID, tag.ID) - assert.Equal(t, updatedRequest.Tags[0].Name, tag.Name) - assert.Equal(t, updatedRequest.Group.ID, request.Group.ID) - assert.Equal(t, updatedRequest.Group.Name, request.Group.Name) - assert.Equal(t, updatedRequest.Group.Description, request.Group.Description) - assert.Equal(t, updatedRequest.Group.Budget, request.Group.Budget) + exp := &RequestDetail{ + ID: request.ID, + Status: request.Status, + Title: title, + Content: request.Content, + Comments: request.Comments, + Files: request.Files, + Tags: []*Tag{tag}, + Targets: []*RequestTargetDetail{{ + Target: target.Target, + Amount: target.Amount, + CreatedAt: time.Now(), + }}, + Statuses: request.Statuses, + Group: group, + CreatedAt: request.CreatedAt, + UpdatedAt: time.Now(), + CreatedBy: request.CreatedBy, + } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt")) + testutil.AssertEqual(t, exp, updatedRequest, opts...) }) t.Run("Success3", func(t *testing.T) { @@ -1038,16 +1045,29 @@ func TestEntRepository_UpdateRequest(t *testing.T) { []*Tag{tag}, []*RequestTarget{target}, group) assert.NoError(t, err) - assert.Equal(t, updatedRequest.ID, request.ID) - assert.Equal(t, updatedRequest.Status, request.Status) - assert.Equal(t, updatedRequest.Title, request.Title) - assert.Equal(t, updatedRequest.Content, content) - assert.Equal(t, updatedRequest.Tags[0].ID, tag.ID) - assert.Equal(t, updatedRequest.Tags[0].Name, tag.Name) - assert.Equal(t, updatedRequest.Group.ID, request.Group.ID) - assert.Equal(t, updatedRequest.Group.Name, request.Group.Name) - assert.Equal(t, updatedRequest.Group.Description, request.Group.Description) - assert.Equal(t, updatedRequest.Group.Budget, request.Group.Budget) + exp := &RequestDetail{ + ID: request.ID, + Status: request.Status, + Title: request.Title, + Content: content, + Comments: request.Comments, + Files: request.Files, + Tags: []*Tag{tag}, + Targets: []*RequestTargetDetail{{ + Target: target.Target, + Amount: target.Amount, + CreatedAt: time.Now(), + }}, + Statuses: request.Statuses, + Group: group, + CreatedAt: request.CreatedAt, + UpdatedAt: time.Now(), + CreatedBy: request.CreatedBy, + } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt")) + testutil.AssertEqual(t, exp, updatedRequest, opts...) }) t.Run("UnknownTag", func(t *testing.T) { diff --git a/model/request_status_impl_test.go b/model/request_status_impl_test.go index b3ecd830..f5eee7e2 100644 --- a/model/request_status_impl_test.go +++ b/model/request_status_impl_test.go @@ -3,10 +3,13 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -35,7 +38,15 @@ func TestEntRepository_CreateStatus(t *testing.T) { status := Status(random.Numeric(t, 5) + 1) created, err := repo.CreateStatus(ctx, request.ID, user.ID, status) assert.NoError(t, err) - assert.Equal(t, created.Status, status) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestStatus{}, "ID")) + exp := &RequestStatus{ + CreatedBy: user.ID, + Status: status, + CreatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, created, opts...) }) t.Run("InvalidStatus", func(t *testing.T) { diff --git a/model/request_target_impl_test.go b/model/request_target_impl_test.go index 402caa45..c81210a2 100644 --- a/model/request_target_impl_test.go +++ b/model/request_target_impl_test.go @@ -3,9 +3,12 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -50,17 +53,17 @@ func TestEntRepository_GetRequestTargets(t *testing.T) { require.NoError(t, err) got, err := repo.GetRequestTargets(ctx, request.ID) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].Target == target1.Target { - assert.Equal(t, got[0].Target, target1.Target) - assert.Equal(t, got[0].Amount, target1.Amount) - assert.Equal(t, got[1].Target, target2.Target) - assert.Equal(t, got[1].Amount, target2.Amount) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].Target, target2.Target) - assert.Equal(t, got[0].Amount, target2.Amount) - assert.Equal(t, got[1].Target, target1.Target) - assert.Equal(t, got[1].Amount, target1.Amount) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt"), + cmpopts.SortSlices(func(l, r *RequestTargetDetail) bool { + return l.Target.ID() < r.Target.ID() + })) + exp := []*RequestTargetDetail{ + {Target: target1.Target, Amount: target1.Amount, CreatedAt: time.Now()}, + {Target: target2.Target, Amount: target2.Amount, CreatedAt: time.Now()}, } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -81,7 +84,7 @@ func TestEntRepository_GetRequestTargets(t *testing.T) { require.NoError(t, err) got, err := repo2.GetRequestTargets(ctx, request.ID) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) } @@ -121,17 +124,17 @@ func TestEntRepository_createRequestTargets(t *testing.T) { nil, []*RequestTarget{target1, target2}, nil, user1.ID) assert.NoError(t, err) - if got.Targets[0].Target == target1.Target { - assert.Equal(t, got.Targets[0].Target, target1.Target) - assert.Equal(t, got.Targets[0].Amount, target1.Amount) - assert.Equal(t, got.Targets[1].Target, target2.Target) - assert.Equal(t, got.Targets[1].Amount, target2.Amount) - } else { - assert.Equal(t, got.Targets[0].Target, target2.Target) - assert.Equal(t, got.Targets[0].Amount, target2.Amount) - assert.Equal(t, got.Targets[1].Target, target1.Target) - assert.Equal(t, got.Targets[1].Amount, target1.Amount) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(RequestTargetDetail{}, "ID", "PaidAt"), + cmpopts.SortSlices(func(l, r *RequestTargetDetail) bool { + return l.Target.ID() < r.Target.ID() + })) + exp := []*RequestTargetDetail{ + {Target: target1.Target, Amount: target1.Amount, CreatedAt: time.Now()}, + {Target: target2.Target, Amount: target2.Amount, CreatedAt: time.Now()}, } + testutil.RequireEqual(t, exp, got.Targets, opts...) }) } @@ -184,7 +187,7 @@ func TestEntRepository_deleteRequestTargets(t *testing.T) { assert.NoError(t, err) got, err := repo.GetRequestTargets(ctx, request.ID) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) t.Run("Success2", func(t *testing.T) { diff --git a/model/tag_impl_test.go b/model/tag_impl_test.go index 86fac005..d734d002 100644 --- a/model/tag_impl_test.go +++ b/model/tag_impl_test.go @@ -3,9 +3,12 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -25,24 +28,20 @@ func TestEntRepository_GetTags(t *testing.T) { got, err := repo.GetTags(ctx) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == tag1.ID { - assert.Equal(t, got[0].ID, tag1.ID) - assert.Equal(t, got[0].Name, tag1.Name) - assert.Equal(t, got[1].ID, tag2.ID) - assert.Equal(t, got[1].Name, tag2.Name) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].ID, tag2.ID) - assert.Equal(t, got[0].Name, tag2.Name) - assert.Equal(t, got[1].ID, tag1.ID) - assert.Equal(t, got[1].Name, tag1.Name) - } + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(l, r *Tag) bool { + return l.ID.ID() < r.ID.ID() + })) + exp := []*Tag{tag1, tag2} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { t.Parallel() got, err := repo2.GetTags(ctx) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) } @@ -58,7 +57,16 @@ func TestEntRepository_CreateTag(t *testing.T) { tag, err := repo.CreateTag(ctx, name) assert.NoError(t, err) - assert.Equal(t, name, tag.Name) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(Tag{}, "ID")) + exp := &Tag{ + Name: name, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, tag, opts...) }) t.Run("MissingName", func(t *testing.T) { @@ -78,16 +86,23 @@ func TestEntRepository_UpdateTag(t *testing.T) { t.Run("Success1", func(t *testing.T) { t.Parallel() - tag, err := repo.CreateTag(ctx, random.AlphaNumeric(t, 20)) + created, err := repo.CreateTag(ctx, random.AlphaNumeric(t, 20)) assert.NoError(t, err) name := random.AlphaNumeric(t, 20) - updated, err := repo.UpdateTag(ctx, tag.ID, name) + updated, err := repo.UpdateTag(ctx, created.ID, name) assert.NoError(t, err) - assert.Equal(t, tag.ID, updated.ID) - assert.Equal(t, name, updated.Name) + opts := testutil.ApproxEqualOptions() + exp := &Tag{ + ID: created.ID, + Name: name, + CreatedAt: created.CreatedAt, + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, updated, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -98,8 +113,8 @@ func TestEntRepository_UpdateTag(t *testing.T) { updated, err := repo.UpdateTag(ctx, tag.ID, tag.Name) assert.NoError(t, err) - assert.Equal(t, tag.ID, updated.ID) - assert.Equal(t, tag.Name, updated.Name) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, tag, updated, opts...) }) t.Run("MissingName", func(t *testing.T) { diff --git a/model/transaction_detail_impl_test.go b/model/transaction_detail_impl_test.go index 046f6883..bc118967 100644 --- a/model/transaction_detail_impl_test.go +++ b/model/transaction_detail_impl_test.go @@ -3,9 +3,12 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -30,14 +33,21 @@ func TestEntRepository_createTransactionDetail(t *testing.T) { title := random.AlphaNumeric(t, 20) amount := random.Numeric(t, 100000) target := random.AlphaNumeric(t, 10) - // Create TransactionDetail td, err := repo.createTransactionDetail(ctx, tx, title, amount, target) assert.NoError(t, err) err = tx.Commit() assert.NoError(t, err) - assert.NotNil(t, td) - assert.Equal(t, td.Amount, amount) - assert.Equal(t, td.Target, target) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.IgnoreFields(TransactionDetail{}, "ID")) + exp := &TransactionDetail{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, td, opts...) }) } @@ -77,8 +87,15 @@ func TestEntRepository_updateTransactionDetail(t *testing.T) { assert.NoError(t, err) err = tx.Commit() assert.NoError(t, err) - assert.NotNil(t, td) - assert.Equal(t, td.Amount, updatedAmount) - assert.Equal(t, td.Target, updatedTarget) + opts := testutil.ApproxEqualOptions() + exp := &TransactionDetail{ + ID: td.ID, + Title: updateTitle, + Amount: updatedAmount, + Target: updatedTarget, + CreatedAt: td.CreatedAt, + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, td, opts...) }) } diff --git a/model/transaction_impl_test.go b/model/transaction_impl_test.go index a69f9444..e9bd4795 100644 --- a/model/transaction_impl_test.go +++ b/model/transaction_impl_test.go @@ -5,9 +5,11 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -83,19 +85,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { } got, err := repo.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 2) { - assert.Equal(t, tx1.ID, got[1].ID) - assert.Equal(t, tx1.Title, got[1].Title) - assert.Equal(t, tx1.Amount, got[1].Amount) - assert.Equal(t, tx1.Target, got[1].Target) - assert.Equal(t, tx1.CreatedAt, got[1].CreatedAt) - assert.Equal(t, tx1.UpdatedAt, got[1].UpdatedAt) - assert.Equal(t, tx2.ID, got[0].ID) - assert.Equal(t, tx2.Amount, got[0].Amount) - assert.Equal(t, tx2.Target, got[0].Target) - assert.Equal(t, tx2.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx2.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx2, tx1} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSortCreatedAtDesc", func(t *testing.T) { @@ -134,19 +127,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { } got, err := repo2.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 2) { - assert.Equal(t, tx1.ID, got[0].ID) - assert.Equal(t, tx1.Title, got[0].Title) - assert.Equal(t, tx1.Amount, got[0].Amount) - assert.Equal(t, tx1.Target, got[0].Target) - assert.Equal(t, tx1.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx1.UpdatedAt, got[0].UpdatedAt) - assert.Equal(t, tx2.ID, got[1].ID) - assert.Equal(t, tx2.Amount, got[1].Amount) - assert.Equal(t, tx2.Target, got[1].Target) - assert.Equal(t, tx2.CreatedAt, got[1].CreatedAt) - assert.Equal(t, tx2.UpdatedAt, got[1].UpdatedAt) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx1, tx2} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSortAmount", func(t *testing.T) { @@ -184,19 +168,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { } got, err := repo3.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 2) { - assert.Equal(t, tx1.ID, got[0].ID) - assert.Equal(t, tx1.Title, got[0].Title) - assert.Equal(t, tx1.Amount, got[0].Amount) - assert.Equal(t, tx1.Target, got[0].Target) - assert.Equal(t, tx1.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx1.UpdatedAt, got[0].UpdatedAt) - assert.Equal(t, tx2.ID, got[1].ID) - assert.Equal(t, tx2.Amount, got[1].Amount) - assert.Equal(t, tx2.Target, got[1].Target) - assert.Equal(t, tx2.CreatedAt, got[1].CreatedAt) - assert.Equal(t, tx2.UpdatedAt, got[1].UpdatedAt) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx1, tx2} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSortAmountDesc", func(t *testing.T) { @@ -241,19 +216,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { // nolint:contextcheck got, err := repo4.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 2) { - assert.Equal(t, tx2.ID, got[0].ID) - assert.Equal(t, tx2.Title, got[0].Title) - assert.Equal(t, tx2.Amount, got[0].Amount) - assert.Equal(t, tx2.Target, got[0].Target) - assert.Equal(t, tx2.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx2.UpdatedAt, got[0].UpdatedAt) - assert.Equal(t, tx1.ID, got[1].ID) - assert.Equal(t, tx1.Amount, got[1].Amount) - assert.Equal(t, tx1.Target, got[1].Target) - assert.Equal(t, tx1.CreatedAt, got[1].CreatedAt) - assert.Equal(t, tx1.UpdatedAt, got[1].UpdatedAt) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx2, tx1} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithNoneSort", func(t *testing.T) { @@ -292,19 +258,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { } got, err := repo5.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 2) { - assert.Equal(t, tx1.ID, got[1].ID) - assert.Equal(t, tx1.Title, got[1].Title) - assert.Equal(t, tx1.Amount, got[1].Amount) - assert.Equal(t, tx1.Target, got[1].Target) - assert.Equal(t, tx1.CreatedAt, got[1].CreatedAt) - assert.Equal(t, tx1.UpdatedAt, got[1].UpdatedAt) - assert.Equal(t, tx2.ID, got[0].ID) - assert.Equal(t, tx2.Amount, got[0].Amount) - assert.Equal(t, tx2.Target, got[0].Target) - assert.Equal(t, tx2.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx2.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx2, tx1} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTarget", func(t *testing.T) { @@ -342,14 +299,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { } got, err := repo6.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 1) { - assert.Equal(t, tx.ID, got[0].ID) - assert.Equal(t, tx.Title, got[0].Title) - assert.Equal(t, tx.Amount, got[0].Amount) - assert.Equal(t, tx.Target, got[0].Target) - assert.Equal(t, tx.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 1) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSinceUntil", func(t *testing.T) { @@ -392,13 +345,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { got, err := repo7.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 1) { - assert.Equal(t, tx.ID, got[0].ID) - assert.Equal(t, tx.Amount, got[0].Amount) - assert.Equal(t, tx.Target, got[0].Target) - assert.Equal(t, tx.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 1) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTag", func(t *testing.T) { @@ -442,14 +392,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { got, err := repo8.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 1) { - assert.Equal(t, tx.ID, got[0].ID) - assert.Equal(t, tx.Title, got[0].Title) - assert.Equal(t, tx.Amount, got[0].Amount) - assert.Equal(t, tx.Target, got[0].Target) - assert.Equal(t, tx.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 1) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithGroup", func(t *testing.T) { @@ -495,14 +441,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { got, err := repo9.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 1) { - assert.Equal(t, tx.ID, got[0].ID) - assert.Equal(t, tx.Title, got[0].Title) - assert.Equal(t, tx.Amount, got[0].Amount) - assert.Equal(t, tx.Target, got[0].Target) - assert.Equal(t, tx.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 1) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithRequest", func(t *testing.T) { @@ -541,14 +483,10 @@ func TestEntRepository_GetTransactions(t *testing.T) { got, err := repo10.GetTransactions(ctx, query) assert.NoError(t, err) - if assert.Len(t, got, 1) { - assert.Equal(t, tx.ID, got[0].ID) - assert.Equal(t, tx.Title, got[0].Title) - assert.Equal(t, tx.Amount, got[0].Amount) - assert.Equal(t, tx.Target, got[0].Target) - assert.Equal(t, tx.CreatedAt, got[0].CreatedAt) - assert.Equal(t, tx.UpdatedAt, got[0].UpdatedAt) - } + assert.Len(t, got, 1) + opts := testutil.ApproxEqualOptions() + exp := []*TransactionResponse{tx} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success", func(t *testing.T) { @@ -558,7 +496,7 @@ func TestEntRepository_GetTransactions(t *testing.T) { query := TransactionQuery{} got, err := repo11.GetTransactions(ctx, query) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) } @@ -597,14 +535,9 @@ func TestEntRepository_GetTransaction(t *testing.T) { // Get Transaction got, err := repo.GetTransaction(ctx, tx.ID) assert.NoError(t, err) - if assert.NotNil(t, got) { - assert.Equal(t, tx.ID, got.ID) - assert.Equal(t, tx.Title, got.Title) - assert.Equal(t, tx.Amount, got.Amount) - assert.Equal(t, tx.Target, got.Target) - assert.Equal(t, tx.CreatedAt, got.CreatedAt) - assert.Equal(t, tx.UpdatedAt, got.UpdatedAt) - } + assert.NotNil(t, got) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, tx, got, opts...) }) } @@ -656,21 +589,21 @@ func TestEntRepository_CreateTransaction(t *testing.T) { title, amount, target, []*uuid.UUID{&tag.ID}, &group.ID, &request.ID) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - if assert.Len(t, tx.Tags, 1) { - assert.Equal(t, tag.ID, tx.Tags[0].ID) - assert.Equal(t, tag.Name, tx.Tags[0].Name) - } - if assert.NotNil(t, tx.Group) { - assert.Equal(t, group.ID, tx.Group.ID) - assert.Equal(t, group.Name, tx.Group.Name) - assert.Equal(t, group.Description, tx.Group.Description) - assert.Equal(t, group.Budget, tx.Group.Budget) - } + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "ID", "UpdatedAt")) + exp := &TransactionResponse{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Request: &request.ID, + Tags: []*Tag{tag}, + Group: group, } + testutil.RequireEqual(t, exp, tx, opts...) }) t.Run("SuccessWithoutTags", func(t *testing.T) { @@ -708,18 +641,21 @@ func TestEntRepository_CreateTransaction(t *testing.T) { tx, err := repo.CreateTransaction(ctx, title, amount, target, nil, &group.ID, &request.ID) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - assert.Len(t, tx.Tags, 0) - if assert.NotNil(t, tx.Group) { - assert.Equal(t, group.ID, tx.Group.ID) - assert.Equal(t, group.Name, tx.Group.Name) - assert.Equal(t, group.Description, tx.Group.Description) - assert.Equal(t, group.Budget, tx.Group.Budget) - } + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "ID", "UpdatedAt")) + exp := &TransactionResponse{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Request: &request.ID, + Tags: []*Tag{}, + Group: group, } + testutil.RequireEqual(t, exp, tx, opts...) }) t.Run("SuccessWithoutGroup", func(t *testing.T) { @@ -756,16 +692,21 @@ func TestEntRepository_CreateTransaction(t *testing.T) { title, amount, target, []*uuid.UUID{&tag.ID}, nil, &request.ID) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - if assert.Len(t, tx.Tags, 1) { - assert.Equal(t, tag.ID, tx.Tags[0].ID) - assert.Equal(t, tag.Name, tx.Tags[0].Name) - } - assert.Nil(t, tx.Group) + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "ID", "UpdatedAt")) + exp := &TransactionResponse{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Request: &request.ID, + Tags: []*Tag{tag}, + Group: nil, } + testutil.RequireEqual(t, exp, tx, opts...) }) t.Run("Success", func(t *testing.T) { @@ -779,13 +720,21 @@ func TestEntRepository_CreateTransaction(t *testing.T) { tx, err := repo.CreateTransaction(ctx, title, amount, target, nil, nil, nil) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - assert.Len(t, tx.Tags, 0) - assert.Nil(t, tx.Group) + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "ID", "UpdatedAt")) + exp := &TransactionResponse{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Request: nil, + Tags: []*Tag{}, + Group: nil, } + testutil.RequireEqual(t, exp, tx, opts...) }) t.Run("SuccessWithNegativeAmount", func(t *testing.T) { @@ -799,13 +748,20 @@ func TestEntRepository_CreateTransaction(t *testing.T) { tx, err := repo.CreateTransaction(ctx, title, amount, target, nil, nil, nil) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - assert.Len(t, tx.Tags, 0) - assert.Nil(t, tx.Group) + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "ID", "UpdatedAt")) + exp := &TransactionResponse{ + Title: title, + Amount: amount, + Target: target, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + Tags: []*Tag{}, + Group: nil, } + testutil.RequireEqual(t, exp, tx, opts...) }) } @@ -884,25 +840,26 @@ func TestEntRepository_UpdateTransaction(t *testing.T) { nil, user.ID) require.NoError(t, err) - tx, err = repo.UpdateTransaction( + updated, err := repo.UpdateTransaction( ctx, tx.ID, title, amount, target, []*uuid.UUID{&tag.ID}, &group.ID, &request.ID) assert.NoError(t, err) - if assert.NotNil(t, tx) { - assert.Equal(t, title, tx.Title) - assert.Equal(t, amount, tx.Amount) - assert.Equal(t, target, tx.Target) - if assert.Len(t, tx.Tags, 1) { - assert.Equal(t, tag.ID, tx.Tags[0].ID) - assert.Equal(t, tag.Name, tx.Tags[0].Name) - } - if assert.NotNil(t, tx.Group) { - assert.Equal(t, group.ID, tx.Group.ID) - assert.Equal(t, group.Name, tx.Group.Name) - assert.Equal(t, group.Description, tx.Group.Description) - assert.Equal(t, group.Budget, tx.Group.Budget) - } + opts := testutil.ApproxEqualOptions() + // FIXME: #831 + opts = append(opts, + cmpopts.IgnoreFields(TransactionResponse{}, "UpdatedAt")) + exp := &TransactionResponse{ + ID: tx.ID, + Title: title, + Amount: amount, + Target: target, + CreatedAt: tx.CreatedAt, + UpdatedAt: time.Now(), + Request: &request.ID, + Tags: []*Tag{tag}, + Group: group, } + testutil.RequireEqual(t, exp, updated, opts...) }) } diff --git a/model/user_impl_test.go b/model/user_impl_test.go index 905060a7..50be2632 100644 --- a/model/user_impl_test.go +++ b/model/user_impl_test.go @@ -3,9 +3,12 @@ package model import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" ) @@ -24,7 +27,7 @@ func TestEntRepository_GetUsers(t *testing.T) { got, err := repo.GetUsers(ctx) assert.NoError(t, err) - assert.Len(t, got, 0) + assert.Empty(t, got) }) t.Run("Success2", func(t *testing.T) { @@ -38,25 +41,14 @@ func TestEntRepository_GetUsers(t *testing.T) { got, err := repo2.GetUsers(ctx) assert.NoError(t, err) - if assert.Len(t, got, 2) && got[0].ID == user1.ID { - assert.Equal(t, got[0].ID, user1.ID) - assert.Equal(t, got[0].Name, user1.Name) - assert.Equal(t, got[0].DisplayName, user1.DisplayName) - assert.Equal(t, got[0].Admin, user1.Admin) - assert.Equal(t, got[1].ID, user2.ID) - assert.Equal(t, got[1].Name, user2.Name) - assert.Equal(t, got[1].DisplayName, user2.DisplayName) - assert.Equal(t, got[1].Admin, user2.Admin) - } else if assert.Len(t, got, 2) { - assert.Equal(t, got[0].ID, user2.ID) - assert.Equal(t, got[0].Name, user2.Name) - assert.Equal(t, got[0].DisplayName, user2.DisplayName) - assert.Equal(t, got[0].Admin, user2.Admin) - assert.Equal(t, got[1].ID, user1.ID) - assert.Equal(t, got[1].Name, user1.Name) - assert.Equal(t, got[1].DisplayName, user1.DisplayName) - assert.Equal(t, got[1].Admin, user1.Admin) - } + assert.Len(t, got, 2) + opts := testutil.ApproxEqualOptions() + opts = append(opts, + cmpopts.SortSlices(func(l, r *User) bool { + return l.ID.ID() < r.ID.ID() + })) + exp := []*User{user1, user2} + testutil.RequireEqual(t, exp, got, opts...) }) } @@ -76,9 +68,17 @@ func TestEntRepository_CreateUser(t *testing.T) { user, err := repo.CreateUser(ctx, name, dn, admin) assert.NoError(t, err) - assert.Equal(t, user.Name, name) - assert.Equal(t, user.DisplayName, dn) - assert.Equal(t, user.Admin, admin) + opts := testutil.ApproxEqualOptions() + opts = append(opts, cmpopts.IgnoreFields(User{}, "ID")) + exp := &User{ + Name: name, + DisplayName: dn, + Admin: admin, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: nil, + } + testutil.RequireEqual(t, exp, user, opts...) }) t.Run("MissingName", func(t *testing.T) { @@ -115,10 +115,8 @@ func TestEntRepository_GetUserByName(t *testing.T) { got, err := repo.GetUserByName(ctx, name) assert.NoError(t, err) - assert.Equal(t, user.ID, got.ID) - assert.Equal(t, user.Name, got.Name) - assert.Equal(t, user.DisplayName, got.DisplayName) - assert.Equal(t, user.Admin, got.Admin) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, user, got, opts...) }) t.Run("UnknownName", func(t *testing.T) { @@ -150,10 +148,8 @@ func TestEntRepository_GetUserByID(t *testing.T) { got, err := repo.GetUserByID(ctx, user.ID) assert.NoError(t, err) - assert.Equal(t, user.ID, got.ID) - assert.Equal(t, user.Name, got.Name) - assert.Equal(t, user.DisplayName, got.DisplayName) - assert.Equal(t, user.Admin, got.Admin) + opts := testutil.ApproxEqualOptions() + testutil.RequireEqual(t, user, got, opts...) }) t.Run("UnknownUserID", func(t *testing.T) { @@ -186,11 +182,16 @@ func TestEntRepository_UpdateUser(t *testing.T) { uadmin := random.Numeric(t, 2) == 1 got, err := repo.UpdateUser(ctx, user.ID, uname, udn, uadmin) assert.NoError(t, err) - - assert.NoError(t, err) - assert.Equal(t, got.Name, uname) - assert.Equal(t, got.DisplayName, udn) - assert.Equal(t, got.Admin, uadmin) + opts := testutil.ApproxEqualOptions() + exp := &User{ + ID: user.ID, + Name: uname, + DisplayName: udn, + Admin: uadmin, + CreatedAt: user.CreatedAt, + UpdatedAt: time.Now(), + } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("MissingName", func(t *testing.T) { diff --git a/router/admin_test.go b/router/admin_test.go index d35df005..95b53553 100644 --- a/router/admin_test.go +++ b/router/admin_test.go @@ -1,11 +1,11 @@ package router import ( + "bytes" "encoding/json" "errors" "net/http" "net/http/httptest" - "strings" "testing" "github.com/google/uuid" @@ -46,22 +46,20 @@ func TestHandler_GetAdmins(t *testing.T) { GetAdmins(c.Request().Context()). Return(admins, nil) - res := []*uuid.UUID{ - &admin.ID, - } - resBody, err := json.Marshal(res) require.NoError(t, err) - if assert.NoError(t, h.Handlers.GetAdmins(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetAdmins(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var res []uuid.UUID + err = json.Unmarshal(rec.Body.Bytes(), &res) + require.NoError(t, err) + assert.Equal(t, []uuid.UUID{admin.ID}, res) }) t.Run("Success2", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - admins := []*model.Admin{} + var admins []*model.Admin e := echo.New() req, err := http.NewRequest(http.MethodGet, "/api/admins", nil) @@ -77,14 +75,14 @@ func TestHandler_GetAdmins(t *testing.T) { GetAdmins(c.Request().Context()). Return(admins, nil) - res := []*uuid.UUID{} - resBody, err := json.Marshal(res) require.NoError(t, err) - if assert.NoError(t, h.Handlers.GetAdmins(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetAdmins(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var res []uuid.UUID + err = json.Unmarshal(rec.Body.Bytes(), &res) + require.NoError(t, err) + assert.Equal(t, []uuid.UUID{}, res) }) t.Run("FailedWithError", func(t *testing.T) { @@ -108,9 +106,8 @@ func TestHandler_GetAdmins(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetAdmins(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -121,13 +118,16 @@ func TestHandler_PostAdmin(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - admin := []uuid.UUID{uuid.New()} + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodPost, "/api/admins", - strings.NewReader(`["`+admin[0].String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -137,25 +137,27 @@ func TestHandler_PostAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - AddAdmins(c.Request().Context(), admin). + AddAdmins(c.Request().Context(), admins). Return(nil) - if assert.NoError(t, h.Handlers.PostAdmins(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.PostAdmins(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedWithError", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - adminID := uuid.New() + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodPost, "/api/admins", - strings.NewReader(`["`+adminID.String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -167,26 +169,29 @@ func TestHandler_PostAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - AddAdmins(c.Request().Context(), []uuid.UUID{adminID}). + AddAdmins(c.Request().Context(), admins). Return(resErr) err = h.Handlers.PostAdmins(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("FailedWithEntConstraintError", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - adminID := uuid.New() + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodPost, "/api/admins", - strings.NewReader(`["`+adminID.String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -199,13 +204,13 @@ func TestHandler_PostAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - AddAdmins(c.Request().Context(), []uuid.UUID{adminID}). + AddAdmins(c.Request().Context(), admins). Return(resErr) err = h.Handlers.PostAdmins(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -216,13 +221,16 @@ func TestHandler_DeleteAdmin(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - admin := []uuid.UUID{uuid.New()} + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodDelete, "/api/admins", - strings.NewReader(`["`+admin[0].String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -232,25 +240,27 @@ func TestHandler_DeleteAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - DeleteAdmins(c.Request().Context(), admin). + DeleteAdmins(c.Request().Context(), admins). Return(nil) - if assert.NoError(t, h.Handlers.DeleteAdmins(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteAdmins(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedWithError", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - adminID := uuid.New() + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodDelete, "/api/admins", - strings.NewReader(`["`+adminID.String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -262,24 +272,26 @@ func TestHandler_DeleteAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - DeleteAdmins(c.Request().Context(), []uuid.UUID{adminID}). + DeleteAdmins(c.Request().Context(), admins). Return(resErr) err = h.Handlers.DeleteAdmins(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("InvalidAdminID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + body := `["invalid"]` + e := echo.New() req, err := http.NewRequest( http.MethodDelete, "/api/admins", - strings.NewReader(`["invalid"]`)) + bytes.NewReader([]byte(body))) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -290,19 +302,23 @@ func TestHandler_DeleteAdmin(t *testing.T) { err = h.Handlers.DeleteAdmins(c) assert.Error(t, err) + // FIXME: http.StatusBadRequestの判定をしたい }) t.Run("FailedWithEntConstraintError", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - adminID := uuid.New() + admin := uuid.New() + admins := []uuid.UUID{admin} + reqBody, err := json.Marshal(admins) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodDelete, "/api/admins", - strings.NewReader(`["`+adminID.String()+`"]`)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -315,12 +331,11 @@ func TestHandler_DeleteAdmin(t *testing.T) { assert.NoError(t, err) h.Repository.MockAdminRepository. EXPECT(). - DeleteAdmins(c.Request().Context(), []uuid.UUID{adminID}). + DeleteAdmins(c.Request().Context(), admins). Return(resErr) err = h.Handlers.DeleteAdmins(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } diff --git a/router/file_test.go b/router/file_test.go index a41c8810..2e3358c0 100644 --- a/router/file_test.go +++ b/router/file_test.go @@ -3,6 +3,7 @@ package router import ( "bytes" "encoding/base64" + "encoding/json" "errors" "fmt" "io" @@ -20,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/traPtitech/Jomon/model" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" "go.uber.org/mock/gomock" ) @@ -98,9 +100,8 @@ func TestHandlers_PostFile(t *testing.T) { Save(file.ID.String(), gomock.Any()). Return(nil) - if assert.NoError(t, h.Handlers.PostFile(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.PostFile(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedToRepositoryCreateFile", func(t *testing.T) { @@ -166,9 +167,9 @@ func TestHandlers_PostFile(t *testing.T) { Return(nil, mocErr) err = h.Handlers.PostFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("FailedToServiceCreateFile", func(t *testing.T) { @@ -242,9 +243,9 @@ func TestHandlers_PostFile(t *testing.T) { Return(mocErr) err = h.Handlers.PostFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) } @@ -288,9 +289,8 @@ func TestHandlers_GetFile(t *testing.T) { Open(file.ID.String()). Return(r, nil) - if assert.NoError(t, h.Handlers.GetFile(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.GetFile(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedToGetFile", func(t *testing.T) { @@ -324,9 +324,9 @@ func TestHandlers_GetFile(t *testing.T) { Return(nil, mocErr) err = h.Handlers.GetFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("FailedToOpenFile", func(t *testing.T) { @@ -365,9 +365,9 @@ func TestHandlers_GetFile(t *testing.T) { Return(nil, mocErr) err = h.Handlers.GetFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("UnknownFile", func(t *testing.T) { @@ -390,9 +390,9 @@ func TestHandlers_GetFile(t *testing.T) { _, mocErr := uuid.Parse("po") err = h.Handlers.GetFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) }) } @@ -428,9 +428,19 @@ func TestHandlers_GetFileMeta(t *testing.T) { GetFile(c.Request().Context(), file.ID). Return(file, nil) - if assert.NoError(t, h.Handlers.GetFileMeta(c)) { - assert.Equal(t, http.StatusOK, rec.Code) + assert.NoError(t, h.Handlers.GetFileMeta(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var res *FileMetaResponse + err = json.Unmarshal(rec.Body.Bytes(), &res) + require.NoError(t, err) + exp := &FileMetaResponse{ + ID: file.ID, + Name: file.Name, + MimeType: file.MimeType, + CreatedBy: file.CreatedBy, + CreatedAt: file.CreatedAt, } + testutil.RequireEqual(t, exp, res) }) t.Run("FailedToGetFile", func(t *testing.T) { @@ -465,9 +475,9 @@ func TestHandlers_GetFileMeta(t *testing.T) { Return(nil, mocErr) err = h.Handlers.GetFileMeta(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("UnknownFile", func(t *testing.T) { @@ -490,9 +500,9 @@ func TestHandlers_GetFileMeta(t *testing.T) { _, mocErr := uuid.Parse("po") err = h.Handlers.GetFileMeta(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) }) } @@ -532,9 +542,8 @@ func TestHandlers_DeleteFile(t *testing.T) { Delete(file.ID.String()). Return(nil) - if assert.NoError(t, h.Handlers.DeleteFile(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteFile(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedToRepositoryDeleteFile", func(t *testing.T) { @@ -568,9 +577,9 @@ func TestHandlers_DeleteFile(t *testing.T) { Return(mocErr) err = h.Handlers.DeleteFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("FailedToServiceDeleteFile", func(t *testing.T) { @@ -608,9 +617,9 @@ func TestHandlers_DeleteFile(t *testing.T) { Return(mocErr) err = h.Handlers.DeleteFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("UnknownFile", func(t *testing.T) { @@ -633,8 +642,8 @@ func TestHandlers_DeleteFile(t *testing.T) { _, mocErr := uuid.Parse("po") err = h.Handlers.DeleteFile(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) }) } diff --git a/router/group_test.go b/router/group_test.go index 4ca8482d..bf56d244 100644 --- a/router/group_test.go +++ b/router/group_test.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "net/http/httptest" - "strings" "testing" "time" @@ -18,6 +17,7 @@ import ( "github.com/stretchr/testify/require" "github.com/traPtitech/Jomon/ent" "github.com/traPtitech/Jomon/model" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" "go.uber.org/mock/gomock" ) @@ -67,7 +67,13 @@ func TestHandlers_GetGroups(t *testing.T) { GetGroups(c.Request().Context()). Return(groups, nil) - resOverview := lo.Map(groups, func(group *model.Group, _ int) *GroupOverview { + assert.NoError(t, h.Handlers.GetGroups(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*GroupOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := lo.Map(groups, func(group *model.Group, _ int) *GroupOverview { return &GroupOverview{ ID: group.ID, Name: group.Name, @@ -77,20 +83,14 @@ func TestHandlers_GetGroups(t *testing.T) { UpdatedAt: group.UpdatedAt, } }) - resBody, err := json.Marshal(resOverview) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetGroups(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - groups := []*model.Group{} + var groups []*model.Group e := echo.New() req, err := http.NewRequest(http.MethodGet, "/api/groups", nil) @@ -106,14 +106,14 @@ func TestHandlers_GetGroups(t *testing.T) { GetGroups(c.Request().Context()). Return(groups, nil) - resOverview := []*GroupOverview{} - resBody, err := json.Marshal(resOverview) + assert.NoError(t, h.Handlers.GetGroups(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*GroupOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetGroups(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := []*GroupOverview{} + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("FailedToGetGroups", func(t *testing.T) { @@ -136,9 +136,9 @@ func TestHandlers_GetGroups(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetGroups(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -162,13 +162,21 @@ func TestHandlers_PostGroup(t *testing.T) { } e := echo.New() - reqBody := fmt.Sprintf( - `{"name":"%s","description":"%s","budget":%d}`, - group.Name, group.Description, *group.Budget) + // FIXME: #833 + reqBody, err := json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + Budget int `json:"budget"` + }{ + Name: group.Name, + Description: group.Description, + Budget: *group.Budget, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPost, "/api/groups", - strings.NewReader(reqBody)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -181,7 +189,13 @@ func TestHandlers_PostGroup(t *testing.T) { CreateGroup(c.Request().Context(), group.Name, group.Description, group.Budget). Return(group, nil) - res := &GroupOverview{ + assert.NoError(t, h.Handlers.PostGroup(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got GroupOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &GroupOverview{ ID: group.ID, Name: group.Name, Description: group.Description, @@ -189,14 +203,7 @@ func TestHandlers_PostGroup(t *testing.T) { CreatedAt: group.CreatedAt, UpdatedAt: group.UpdatedAt, } - - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostGroup(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("FailedWithCreateGroup", func(t *testing.T) { @@ -206,11 +213,21 @@ func TestHandlers_PostGroup(t *testing.T) { budget := random.Numeric(t, 1000000) e := echo.New() - reqBody := fmt.Sprintf(`{"name":"test","description":"test","budget":%d}`, budget) + // FIXME: #833 + reqBody, err := json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + Budget int `json:"budget"` + }{ + Name: "test", + Description: "test", + Budget: budget, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPost, "/api/groups", - strings.NewReader(reqBody)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -225,9 +242,9 @@ func TestHandlers_PostGroup(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostGroup(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -295,6 +312,7 @@ func TestHandlers_GetGroupDetail(t *testing.T) { e := echo.New() req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/groups/%s", group.ID), nil) assert.NoError(t, err) + // FIXME: #822 req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) @@ -317,7 +335,14 @@ func TestHandlers_GetGroupDetail(t *testing.T) { GetMembers(c.Request().Context(), group.ID). Return(members, nil) - res := &GroupDetail{ + err = h.Handlers.GetGroupDetail(c) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rec.Code) + var got GroupDetail + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &GroupDetail{ ID: group.ID, Name: group.Name, Description: group.Description, @@ -327,14 +352,7 @@ func TestHandlers_GetGroupDetail(t *testing.T) { CreatedAt: group.CreatedAt, UpdatedAt: group.UpdatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - err = h.Handlers.GetGroupDetail(c) - if assert.NoError(t, err) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -355,6 +373,7 @@ func TestHandlers_GetGroupDetail(t *testing.T) { e := echo.New() req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/groups/%s", group.ID), nil) assert.NoError(t, err) + // FIXME: #822 req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) @@ -377,7 +396,14 @@ func TestHandlers_GetGroupDetail(t *testing.T) { GetMembers(c.Request().Context(), group.ID). Return([]*model.Member{}, nil) - res := &GroupDetail{ + err = h.Handlers.GetGroupDetail(c) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, rec.Code) + var got GroupDetail + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &GroupDetail{ ID: group.ID, Name: group.Name, Description: group.Description, @@ -387,14 +413,7 @@ func TestHandlers_GetGroupDetail(t *testing.T) { CreatedAt: group.CreatedAt, UpdatedAt: group.UpdatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - err = h.Handlers.GetGroupDetail(c) - if assert.NoError(t, err) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("FailedWithUUID", func(t *testing.T) { @@ -405,20 +424,23 @@ func TestHandlers_GetGroupDetail(t *testing.T) { ctrl := gomock.NewController(t) e := echo.New() - req, err := http.NewRequest(http.MethodGet, "/api/groups/invalid-uuid", nil) + req, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf("/api/groups/%s", invalidUUID), + nil) require.NoError(t, err) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("api/groups/:groupID") c.SetParamNames("groupID") - c.SetParamValues("invalid-uuid") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilGroupID", func(t *testing.T) { @@ -444,9 +466,9 @@ func TestHandlers_GetGroupDetail(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -477,9 +499,9 @@ func TestHandlers_GetGroupDetail(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("FailedToGetGroup", func(t *testing.T) { @@ -517,9 +539,9 @@ func TestHandlers_GetGroupDetail(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("FailedToGetOwners", func(t *testing.T) { @@ -562,9 +584,9 @@ func TestHandlers_GetGroupDetail(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("FailedToGetMembers", func(t *testing.T) { @@ -623,9 +645,9 @@ func TestHandlers_GetGroupDetail(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetGroupDetail(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -660,13 +682,21 @@ func TestHandlers_PutGroup(t *testing.T) { } e := echo.New() - reqBody := fmt.Sprintf( - `{"name":"%s","description":"%s","budget":%d}`, - updated.Name, updated.Description, *updated.Budget) + // FIXME: #833 + reqBody, err := json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + Budget int `json:"budget"` + }{ + Name: updated.Name, + Description: updated.Description, + Budget: *updated.Budget, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPut, fmt.Sprintf("/api/groups/%s", group.ID.String()), - strings.NewReader(reqBody)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -684,8 +714,13 @@ func TestHandlers_PutGroup(t *testing.T) { group.ID, updated.Name, updated.Description, updated.Budget). Return(updated, nil) - - res := &GroupOverview{ + assert.NoError(t, h.Handlers.PutGroup(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got GroupOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &GroupOverview{ ID: updated.ID, Name: updated.Name, Description: updated.Description, @@ -693,14 +728,7 @@ func TestHandlers_PutGroup(t *testing.T) { CreatedAt: updated.CreatedAt, UpdatedAt: updated.UpdatedAt, } - - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutGroup(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("FailedWithUpdateGroup", func(t *testing.T) { @@ -731,13 +759,21 @@ func TestHandlers_PutGroup(t *testing.T) { } e := echo.New() - reqBody := fmt.Sprintf( - `{"name":"%s","description":"%s","budget":%d}`, - updated.Name, updated.Description, *updated.Budget) + // FIXME: #833 + reqBody, err := json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + Budget int `json:"budget"` + }{ + Name: updated.Name, + Description: updated.Description, + Budget: *updated.Budget, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPut, fmt.Sprintf("/api/groups/%s", group.ID.String()), - strings.NewReader(reqBody)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -757,37 +793,47 @@ func TestHandlers_PutGroup(t *testing.T) { Return(nil, resErr) err = h.Handlers.PutGroup(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("FailedWithUUID", func(t *testing.T) { t.Parallel() - + ctrl := gomock.NewController(t) invalidUUID := "invalid-uuid" _, resErr := uuid.Parse(invalidUUID) - ctrl := gomock.NewController(t) e := echo.New() + // FIXME: #833 + reqBody, err := json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + Budget int `json:"budget"` + }{ + Name: "test", + Description: "test", + Budget: 1000000, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPut, - "/api/groups/invalid-uuid", - strings.NewReader(`{"name":"test","description":"test","budget":1000000}`)) + fmt.Sprintf("/api/groups/%s", invalidUUID), + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("api/groups/:groupID") c.SetParamNames("groupID") - c.SetParamValues("invalid-uuid") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) err = h.Handlers.PutGroup(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -829,9 +875,8 @@ func TestHandlers_DeleteGroup(t *testing.T) { DeleteGroup(c.Request().Context(), group.ID). Return(nil) - if assert.NoError(t, h.Handlers.DeleteGroup(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteGroup(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("FailedWithDeleteGroup", func(t *testing.T) { @@ -871,9 +916,9 @@ func TestHandlers_DeleteGroup(t *testing.T) { Return(resErr) err = h.Handlers.DeleteGroup(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("FailedWithUUID", func(t *testing.T) { @@ -884,20 +929,23 @@ func TestHandlers_DeleteGroup(t *testing.T) { ctrl := gomock.NewController(t) e := echo.New() - req, err := http.NewRequest(http.MethodDelete, "/api/groups/invalid-uuid", nil) + req, err := http.NewRequest( + http.MethodDelete, + fmt.Sprintf("/api/groups/%s", invalidUUID), + nil) require.NoError(t, err) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("api/groups/:groupID") c.SetParamNames("groupID") - c.SetParamValues("invalid-uuid") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) err = h.Handlers.DeleteGroup(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -957,20 +1005,22 @@ func TestHandlers_PostMember(t *testing.T) { modelMember, }, nil) - res := []uuid.UUID{modelMember.ID} - resBody, err := json.Marshal(res) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostMember(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PostMember(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []uuid.UUID + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + exp := []uuid.UUID{user.ID} + testutil.RequireEqual(t, exp, got) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) member := []uuid.UUID{uuid.New()} reqBody, err := json.Marshal(member) require.NoError(t, err) @@ -978,7 +1028,7 @@ func TestHandlers_PostMember(t *testing.T) { e := echo.New() req, err := http.NewRequest( http.MethodPost, - "/api/groups/hoge/members", + fmt.Sprintf("/api/groups/%s/members", invalidUUID), bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) @@ -986,17 +1036,15 @@ func TestHandlers_PostMember(t *testing.T) { c := e.NewContext(req, rec) c.SetPath("/api/groups/:groupID/members") c.SetParamNames("groupID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) - _, resErr := uuid.Parse(c.Param("groupID")) - err = h.Handlers.PostMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -1026,9 +1074,9 @@ func TestHandlers_PostMember(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.PostMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -1074,9 +1122,9 @@ func TestHandlers_PostMember(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("UnknownUserID", func(t *testing.T) { @@ -1123,9 +1171,9 @@ func TestHandlers_PostMember(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -1180,9 +1228,8 @@ func TestHandlers_DeleteMember(t *testing.T) { DeleteMembers(c.Request().Context(), group.ID, []uuid.UUID{user.ID}). Return(nil) - if assert.NoError(t, h.Handlers.DeleteMember(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteMember(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("NilGroupUUID", func(t *testing.T) { @@ -1222,9 +1269,9 @@ func TestHandlers_DeleteMember(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.DeleteMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -1270,9 +1317,9 @@ func TestHandlers_DeleteMember(t *testing.T) { Return(resErr) err = h.Handlers.DeleteMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("UnknownMemberID", func(t *testing.T) { @@ -1319,18 +1366,17 @@ func TestHandlers_DeleteMember(t *testing.T) { Return(resErr) err = h.Handlers.DeleteMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) t.Run("InvalidGroupUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - invID := "po" - - _, resErr := uuid.Parse(invID) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) member := []uuid.UUID{uuid.New()} reqBody, err := json.Marshal(member) @@ -1339,7 +1385,7 @@ func TestHandlers_DeleteMember(t *testing.T) { e := echo.New() req, err := http.NewRequest( http.MethodDelete, - fmt.Sprintf("/api/groups/%s/members", invID), + fmt.Sprintf("/api/groups/%s/members", invalidUUID), bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) @@ -1347,15 +1393,15 @@ func TestHandlers_DeleteMember(t *testing.T) { c := e.NewContext(req, rec) c.SetPath("/api/groups/:groupID/members") c.SetParamNames("groupID") - c.SetParamValues(invID) + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) err = h.Handlers.DeleteMember(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -1414,29 +1460,28 @@ func TestHandlers_PostOwner(t *testing.T) { Return([]*model.Owner{ modelOwner, }, nil) - - res := owner - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PostOwner(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []uuid.UUID + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostOwner(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + exp := []uuid.UUID{user.ID} + testutil.RequireEqual(t, exp, got) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - owner := []string{"hoge"} + invalidUUID := "invalid-uuid" + owner := []string{invalidUUID} reqBody, err := json.Marshal(owner) require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodPost, - "/api/groups/hoge/owners", + fmt.Sprintf("/api/groups/%s/owners", invalidUUID), bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) @@ -1444,7 +1489,7 @@ func TestHandlers_PostOwner(t *testing.T) { c := e.NewContext(req, rec) c.SetPath("/api/groups/:groupID/owners") c.SetParamNames("groupID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) @@ -1452,9 +1497,9 @@ func TestHandlers_PostOwner(t *testing.T) { _, resErr := uuid.Parse(c.Param("groupID")) err = h.Handlers.PostOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -1484,9 +1529,9 @@ func TestHandlers_PostOwner(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.PostOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -1532,9 +1577,9 @@ func TestHandlers_PostOwner(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownUserID", func(t *testing.T) { @@ -1581,9 +1626,9 @@ func TestHandlers_PostOwner(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -1638,9 +1683,8 @@ func TestHandlers_DeleteOwner(t *testing.T) { DeleteOwners(c.Request().Context(), group.ID, []uuid.UUID{user.ID}). Return(nil) - if assert.NoError(t, h.Handlers.DeleteOwner(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteOwner(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("NilGroupUUID", func(t *testing.T) { @@ -1670,9 +1714,9 @@ func TestHandlers_DeleteOwner(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.DeleteOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -1718,9 +1762,8 @@ func TestHandlers_DeleteOwner(t *testing.T) { Return(resErr) err = h.Handlers.DeleteOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("UnknownOwnerID", func(t *testing.T) { @@ -1765,9 +1808,9 @@ func TestHandlers_DeleteOwner(t *testing.T) { Return(resErr) err = h.Handlers.DeleteOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("InvalidGroupUUID", func(t *testing.T) { @@ -1798,8 +1841,8 @@ func TestHandlers_DeleteOwner(t *testing.T) { require.NoError(t, err) err = h.Handlers.DeleteOwner(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } diff --git a/router/request_test.go b/router/request_test.go index ac6d3778..2aad393e 100644 --- a/router/request_test.go +++ b/router/request_test.go @@ -7,24 +7,97 @@ import ( "fmt" "net/http" "net/http/httptest" - "strings" "testing" "time" - "github.com/gorilla/sessions" - "github.com/google/uuid" + "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" + "github.com/samber/lo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/traPtitech/Jomon/ent" "github.com/traPtitech/Jomon/model" "github.com/traPtitech/Jomon/service" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" "go.uber.org/mock/gomock" ) +func modelTagToTagOverview(t *model.Tag) *TagOverview { + return &TagOverview{ + ID: t.ID, + Name: t.Name, + CreatedAt: t.CreatedAt, + UpdatedAt: t.UpdatedAt, + } +} + +func modelRequestTargetDetailToTargetOverview(t *model.RequestTargetDetail) *TargetOverview { + return &TargetOverview{ + ID: t.ID, + Target: t.Target, + Amount: t.Amount, + CreatedAt: t.CreatedAt, + } +} + +func modelRequestStatusToStatusResponseOverview(s *model.RequestStatus) *StatusResponseOverview { + return &StatusResponseOverview{ + CreatedBy: s.CreatedBy, + Status: s.Status, + CreatedAt: s.CreatedAt, + } +} + +func modelCommentToCommentDetail(c *model.Comment) *CommentDetail { + return &CommentDetail{ + ID: c.ID, + User: c.User, + Comment: c.Comment, + CreatedAt: c.CreatedAt, + UpdatedAt: c.UpdatedAt, + } +} + +// FIXME: この処理はrequest.goにも書かれてある +func modelRequestDetailToRequestResponse(r *model.RequestDetail) *RequestResponse { + var group *GroupOverview + if r.Group != nil { + group = &GroupOverview{ + ID: r.Group.ID, + Name: r.Group.Name, + Description: r.Group.Description, + Budget: r.Group.Budget, + CreatedAt: r.Group.CreatedAt, + UpdatedAt: r.Group.UpdatedAt, + } + } + return &RequestResponse{ + ID: r.ID, + Status: r.Status, + CreatedAt: r.CreatedAt, + UpdatedAt: r.UpdatedAt, + CreatedBy: r.CreatedBy, + Title: r.Title, + Content: r.Content, + Group: group, + Tags: lo.Map(r.Tags, func(t *model.Tag, _ int) *TagOverview { + return modelTagToTagOverview(t) + }), + Targets: lo.Map(r.Targets, func(t *model.RequestTargetDetail, _ int) *TargetOverview { + return modelRequestTargetDetailToTargetOverview(t) + }), + Statuses: lo.Map(r.Statuses, func(s *model.RequestStatus, _ int) *StatusResponseOverview { + return modelRequestStatusToStatusResponseOverview(s) + }), + Comments: lo.Map(r.Comments, func(c *model.Comment, _ int) *CommentDetail { + return modelCommentToCommentDetail(c) + }), + } +} + // To do func TestHandlers_GetRequests(t *testing.T) { t.Parallel() @@ -73,7 +146,13 @@ func TestHandlers_GetRequests(t *testing.T) { }). Return(requests, nil) - res := []*RequestResponse{ + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request2.ID, Status: request2.Status, @@ -99,13 +178,7 @@ func TestHandlers_GetRequests(t *testing.T) { Tags: []*TagOverview{}, }, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -131,14 +204,12 @@ func TestHandlers_GetRequests(t *testing.T) { }). Return(requests, nil) - res := []*RequestResponse{} - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.Empty(t, got) }) t.Run("Success3", func(t *testing.T) { @@ -161,7 +232,10 @@ func TestHandlers_GetRequests(t *testing.T) { status := "submitted" e := echo.New() - req, err := http.NewRequest(http.MethodGet, "/api/requests?status=submitted", nil) + req, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf("/api/requests?status=%s", status), + nil) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -178,7 +252,13 @@ func TestHandlers_GetRequests(t *testing.T) { }). Return(requests, nil) - res := []*RequestResponse{ + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request1.ID, Status: request1.Status, @@ -192,13 +272,7 @@ func TestHandlers_GetRequests(t *testing.T) { Tags: []*TagOverview{}, }, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success4", func(t *testing.T) { @@ -242,7 +316,13 @@ func TestHandlers_GetRequests(t *testing.T) { }). Return(requests, nil) - res := []*RequestResponse{ + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request1.ID, Status: request1.Status, @@ -256,13 +336,7 @@ func TestHandlers_GetRequests(t *testing.T) { Tags: []*TagOverview{}, }, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success5", func(t *testing.T) { @@ -305,8 +379,13 @@ func TestHandlers_GetRequests(t *testing.T) { Offset: 0, }). Return(requests, nil) - - res := []*RequestResponse{ + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request1.ID, Status: request1.Status, @@ -320,13 +399,7 @@ func TestHandlers_GetRequests(t *testing.T) { Tags: []*TagOverview{}, }, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success6", func(t *testing.T) { @@ -381,8 +454,13 @@ func TestHandlers_GetRequests(t *testing.T) { Offset: 0, }). Return(requests, nil) - - res := []*RequestResponse{ + assert.NoError(t, h.Handlers.GetRequests(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request1.ID, Status: request1.Status, @@ -396,20 +474,14 @@ func TestHandlers_GetRequests(t *testing.T) { Comments: []*CommentDetail{}, }, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequests(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success7", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - date := time.Now().Round(time.Second).UTC() + date := time.Now() request := &model.RequestResponse{ ID: uuid.New(), Status: model.Submitted, @@ -445,10 +517,11 @@ func TestHandlers_GetRequests(t *testing.T) { return } require.Equal(t, http.StatusOK, rec.Code) - var res []*RequestResponse - err = json.Unmarshal(rec.Body.Bytes(), &res) + var got []*RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - expectedBody := []*RequestResponse{ + opts := testutil.ApproxEqualOptions() + exp := []*RequestResponse{ { ID: request.ID, Status: request.Status, @@ -462,7 +535,7 @@ func TestHandlers_GetRequests(t *testing.T) { Comments: []*CommentDetail{}, }, } - require.Equal(t, expectedBody, res) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("InvaildStatus", func(t *testing.T) { @@ -470,7 +543,7 @@ func TestHandlers_GetRequests(t *testing.T) { ctrl := gomock.NewController(t) e := echo.New() - req, err := http.NewRequest(http.MethodGet, "/api/requests?status=po", nil) + req, err := http.NewRequest(http.MethodGet, "/api/requests?status=invalid-status", nil) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -480,9 +553,9 @@ func TestHandlers_GetRequests(t *testing.T) { require.NoError(t, err) err = h.Handlers.GetRequests(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, "invalid status"), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, "invalid status"), err) }) t.Run("FailedToGetRequests", func(t *testing.T) { @@ -508,9 +581,9 @@ func TestHandlers_GetRequests(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetRequests(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } @@ -527,14 +600,12 @@ func TestHandlers_PostRequest(t *testing.T) { Status: model.Submitted, Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - CreatedBy: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + CreatedBy: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -569,31 +640,14 @@ func TestHandlers_PostRequest(t *testing.T) { group, reqRequest.CreatedBy). Return(request, nil) - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Statuses: []*StatusResponseOverview{ - { - CreatedBy: request.Statuses[0].CreatedBy, - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - }, - }, - Title: request.Title, - Content: request.Content, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - } - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PostRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTags", func(t *testing.T) { @@ -614,14 +668,12 @@ func TestHandlers_PostRequest(t *testing.T) { Status: model.Submitted, Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - CreatedBy: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + CreatedBy: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + }}, Tags: tags, CreatedAt: date, UpdatedAt: date, @@ -660,37 +712,14 @@ func TestHandlers_PostRequest(t *testing.T) { tags, targets, group, reqRequest.CreatedBy). Return(request, nil) - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Title: request.Title, - Content: request.Content, - Statuses: []*StatusResponseOverview{ - { - CreatedBy: request.Statuses[0].CreatedBy, - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - }, - }, - Tags: []*TagOverview{{ - ID: tag.ID, - Name: tag.Name, - CreatedAt: tag.CreatedAt, - UpdatedAt: tag.UpdatedAt, - }}, - Targets: []*TargetOverview{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PostRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithGroup", func(t *testing.T) { @@ -712,14 +741,12 @@ func TestHandlers_PostRequest(t *testing.T) { Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), Group: group, - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - CreatedBy: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + CreatedBy: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -757,40 +784,14 @@ func TestHandlers_PostRequest(t *testing.T) { tags, targets, group, reqRequest.CreatedBy). Return(request, nil) - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Title: request.Title, - Content: request.Content, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - Statuses: []*StatusResponseOverview{ - { - CreatedBy: request.Statuses[0].CreatedBy, - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - }, - }, - Group: &GroupOverview{ - ID: group.ID, - Name: group.Name, - Description: group.Description, - Budget: group.Budget, - CreatedAt: group.CreatedAt, - UpdatedAt: group.UpdatedAt, - }, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PostRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTarget", func(t *testing.T) { @@ -816,14 +817,12 @@ func TestHandlers_PostRequest(t *testing.T) { Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), Targets: []*model.RequestTargetDetail{tgd}, - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - CreatedBy: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + CreatedBy: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -862,39 +861,14 @@ func TestHandlers_PostRequest(t *testing.T) { tags, []*model.RequestTarget{target}, group, reqRequest.CreatedBy). Return(request, nil) - - tgov := &TargetOverview{ - ID: request.Targets[0].ID, - Target: request.Targets[0].Target, - Amount: request.Targets[0].Amount, - CreatedAt: request.Targets[0].CreatedAt, - } - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Statuses: []*StatusResponseOverview{ - { - CreatedBy: request.Statuses[0].CreatedBy, - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - }, - }, - Title: request.Title, - Content: request.Content, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{tgov}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PostRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("UnknownTagID", func(t *testing.T) { @@ -941,9 +915,9 @@ func TestHandlers_PostRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -990,9 +964,9 @@ func TestHandlers_PostRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("UnknownUserID", func(t *testing.T) { @@ -1043,9 +1017,9 @@ func TestHandlers_PostRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PostRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) } @@ -1065,14 +1039,12 @@ func TestHandlers_GetRequest(t *testing.T) { Files: []*uuid.UUID{}, Tags: []*model.Tag{}, Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -1101,33 +1073,14 @@ func TestHandlers_GetRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return(nil, nil) - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Title: request.Title, - Content: request.Content, - Statuses: []*StatusResponseOverview{ - { - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - CreatedBy: request.Statuses[0].CreatedBy, - }, - }, - Tags: []*TagOverview{}, - Comments: []*CommentDetail{}, - Targets: []*TargetOverview{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithComments", func(t *testing.T) { @@ -1142,14 +1095,12 @@ func TestHandlers_GetRequest(t *testing.T) { Comments: []*model.Comment{}, Files: []*uuid.UUID{}, Tags: []*model.Tag{}, - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, Content: random.AlphaNumeric(t, 50), CreatedAt: date, UpdatedAt: date, @@ -1196,49 +1147,17 @@ func TestHandlers_GetRequest(t *testing.T) { GetComments(c.Request().Context(), request.ID). Return(comments, nil) - resComments := []*CommentDetail{ - { - ID: comment1.ID, - User: comment1.User, - Comment: comment1.Comment, - CreatedAt: comment1.CreatedAt, - UpdatedAt: comment1.UpdatedAt, - }, - { - ID: comment2.ID, - User: comment2.User, - Comment: comment2.Comment, - CreatedAt: comment2.CreatedAt, - UpdatedAt: comment2.UpdatedAt, - }, - } - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Title: request.Title, - Content: request.Content, - Comments: resComments, - Statuses: []*StatusResponseOverview{ - { - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - CreatedBy: request.Statuses[0].CreatedBy, - }, - }, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + exp.Comments = lo.Map(comments, func(c *model.Comment, _ int) *CommentDetail { + return modelCommentToCommentDetail(c) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTarget", func(t *testing.T) { @@ -1246,7 +1165,7 @@ func TestHandlers_GetRequest(t *testing.T) { ctrl := gomock.NewController(t) date := time.Now() - target := &TargetOverview{ + target := &model.RequestTargetDetail{ ID: uuid.New(), Target: uuid.New(), Amount: random.Numeric(t, 1000000), @@ -1254,14 +1173,6 @@ func TestHandlers_GetRequest(t *testing.T) { CreatedAt: date, } - modeltarget := &model.RequestTargetDetail{ - ID: target.ID, - Target: target.Target, - Amount: target.Amount, - PaidAt: target.PaidAt, - CreatedAt: target.CreatedAt, - } - request := &model.RequestDetail{ ID: uuid.New(), Status: model.Submitted, @@ -1270,15 +1181,13 @@ func TestHandlers_GetRequest(t *testing.T) { Files: []*uuid.UUID{}, Tags: []*model.Tag{}, Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, - Targets: []*model.RequestTargetDetail{modeltarget}, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, + Targets: []*model.RequestTargetDetail{target}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -1307,59 +1216,45 @@ func TestHandlers_GetRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return(nil, nil) - - res := &RequestResponse{ - ID: request.ID, - Status: request.Status, - CreatedAt: request.CreatedAt, - UpdatedAt: request.UpdatedAt, - CreatedBy: request.CreatedBy, - Title: request.Title, - Content: request.Content, - Statuses: []*StatusResponseOverview{ - { - Status: request.Statuses[0].Status, - CreatedAt: request.Statuses[0].CreatedAt, - CreatedBy: request.Statuses[0].CreatedBy, - }, - }, - Targets: []*TargetOverview{target}, - Tags: []*TagOverview{}, - Comments: []*CommentDetail{}, - } - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(request) + exp.Targets = []*TargetOverview{ + modelRequestTargetDetailToTargetOverview(target), } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) e := echo.New() - req, err := http.NewRequest(http.MethodGet, "/api/requests/hoge", nil) + req, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf("/api/requests/%s", invalidUUID), + nil) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("/api/requests/:requestID") c.SetParamNames("requestID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) - _, resErr := uuid.Parse(c.Param("requestID")) - err = h.Handlers.GetRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -1382,9 +1277,9 @@ func TestHandlers_GetRequest(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.GetRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownID", func(t *testing.T) { @@ -1417,9 +1312,9 @@ func TestHandlers_GetRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.GetRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) } @@ -1439,13 +1334,11 @@ func TestHandlers_PutRequest(t *testing.T) { CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), - Statuses: []*model.RequestStatus{ - { - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, Tags: []*model.Tag{}, Targets: []*model.RequestTargetDetail{}, } @@ -1500,32 +1393,14 @@ func TestHandlers_PutRequest(t *testing.T) { GetComments(c.Request().Context(), request.ID). Return([]*model.Comment{}, nil) - res := &RequestResponse{ - ID: updateRequest.ID, - Status: updateRequest.Status, - CreatedAt: updateRequest.CreatedAt, - UpdatedAt: updateRequest.UpdatedAt, - CreatedBy: updateRequest.CreatedBy, - Title: updateRequest.Title, - Statuses: []*StatusResponseOverview{ - { - Status: updateRequest.Statuses[0].Status, - CreatedAt: updateRequest.Statuses[0].CreatedAt, - CreatedBy: updateRequest.Statuses[0].CreatedBy, - }, - }, - Content: updateRequest.Content, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - Comments: []*CommentDetail{}, - } - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PutRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(updateRequest) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTag", func(t *testing.T) { @@ -1538,14 +1413,12 @@ func TestHandlers_PutRequest(t *testing.T) { Status: model.Submitted, Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -1624,46 +1497,14 @@ func TestHandlers_PutRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return([]*model.Comment{}, nil) - - res := &RequestResponse{ - ID: updateRequest.ID, - Status: updateRequest.Status, - CreatedAt: updateRequest.CreatedAt, - UpdatedAt: updateRequest.UpdatedAt, - CreatedBy: updateRequest.CreatedBy, - Title: updateRequest.Title, - Content: updateRequest.Content, - Statuses: []*StatusResponseOverview{ - { - Status: updateRequest.Statuses[0].Status, - CreatedAt: updateRequest.Statuses[0].CreatedAt, - CreatedBy: updateRequest.Statuses[0].CreatedBy, - }, - }, - Tags: []*TagOverview{ - { - ID: tag1.ID, - Name: tag1.Name, - CreatedAt: tag1.CreatedAt, - UpdatedAt: tag1.UpdatedAt, - }, - { - ID: tag2.ID, - Name: tag2.Name, - CreatedAt: tag2.CreatedAt, - UpdatedAt: tag2.UpdatedAt, - }, - }, - Targets: []*TargetOverview{}, - Comments: []*CommentDetail{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PutRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(updateRequest) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTarget", func(t *testing.T) { @@ -1675,14 +1516,12 @@ func TestHandlers_PutRequest(t *testing.T) { ID: uuid.New(), Status: model.Submitted, Title: random.AlphaNumeric(t, 20), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -1702,14 +1541,8 @@ func TestHandlers_PutRequest(t *testing.T) { CreatedAt: date, } targets := []*model.RequestTarget{ - { - Target: target1.Target, - Amount: target1.Amount, - }, - { - Target: target2.Target, - Amount: target2.Amount, - }, + {Target: target1.Target, Amount: target1.Amount}, + {Target: target2.Target, Amount: target2.Amount}, } targetDetails := []*model.RequestTargetDetail{target1, target2} @@ -1717,14 +1550,8 @@ func TestHandlers_PutRequest(t *testing.T) { Title: random.AlphaNumeric(t, 30), Content: random.AlphaNumeric(t, 50), Targets: []*Target{ - { - Target: target1.Target, - Amount: target1.Amount, - }, - { - Target: target2.Target, - Amount: target2.Amount, - }, + {Target: target1.Target, Amount: target1.Amount}, + {Target: target2.Target, Amount: target2.Amount}, }, } reqBody, err := json.Marshal(reqRequest) @@ -1774,47 +1601,14 @@ func TestHandlers_PutRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return([]*model.Comment{}, nil) - - res := &RequestResponse{ - ID: updateRequest.ID, - Status: updateRequest.Status, - CreatedAt: updateRequest.CreatedAt, - UpdatedAt: updateRequest.UpdatedAt, - CreatedBy: updateRequest.CreatedBy, - Title: updateRequest.Title, - Statuses: []*StatusResponseOverview{ - { - Status: updateRequest.Statuses[0].Status, - CreatedAt: updateRequest.Statuses[0].CreatedAt, - CreatedBy: updateRequest.Statuses[0].CreatedBy, - }, - }, - Targets: []*TargetOverview{ - { - ID: target1.ID, - Target: target1.Target, - Amount: target1.Amount, - PaidAt: target1.PaidAt, - CreatedAt: target1.CreatedAt, - }, - { - ID: target2.ID, - Target: target2.Target, - Amount: target2.Amount, - PaidAt: target2.PaidAt, - CreatedAt: target2.CreatedAt, - }, - }, - Tags: []*TagOverview{}, - Comments: []*CommentDetail{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PutRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(updateRequest) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithGroup", func(t *testing.T) { @@ -1827,14 +1621,12 @@ func TestHandlers_PutRequest(t *testing.T) { Status: model.Submitted, Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -1905,41 +1697,14 @@ func TestHandlers_PutRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return([]*model.Comment{}, nil) - - res := &RequestResponse{ - ID: updateRequest.ID, - Status: updateRequest.Status, - CreatedAt: updateRequest.CreatedAt, - UpdatedAt: updateRequest.UpdatedAt, - CreatedBy: updateRequest.CreatedBy, - Title: updateRequest.Title, - Content: updateRequest.Content, - Statuses: []*StatusResponseOverview{ - { - Status: updateRequest.Statuses[0].Status, - CreatedAt: updateRequest.Statuses[0].CreatedAt, - CreatedBy: updateRequest.Statuses[0].CreatedBy, - }, - }, - Group: &GroupOverview{ - ID: group.ID, - Name: group.Name, - Description: group.Description, - Budget: group.Budget, - CreatedAt: group.CreatedAt, - UpdatedAt: group.UpdatedAt, - }, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - Comments: []*CommentDetail{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PutRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(updateRequest) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithComment", func(t *testing.T) { @@ -1952,14 +1717,12 @@ func TestHandlers_PutRequest(t *testing.T) { Status: model.Submitted, Title: random.AlphaNumeric(t, 20), Content: random.AlphaNumeric(t, 50), - Statuses: []*model.RequestStatus{ - { - ID: uuid.New(), - Status: model.Submitted, - CreatedAt: date, - CreatedBy: uuid.New(), - }, - }, + Statuses: []*model.RequestStatus{{ + ID: uuid.New(), + Status: model.Submitted, + CreatedAt: date, + CreatedBy: uuid.New(), + }}, CreatedAt: date, UpdatedAt: date, CreatedBy: uuid.New(), @@ -2030,75 +1793,45 @@ func TestHandlers_PutRequest(t *testing.T) { EXPECT(). GetComments(c.Request().Context(), request.ID). Return(comments, nil) - - resComments := []*CommentDetail{ - { - ID: comment1.ID, - User: comment1.User, - Comment: comment1.Comment, - CreatedAt: comment1.CreatedAt, - UpdatedAt: comment1.UpdatedAt, - }, - { - ID: comment2.ID, - User: comment2.User, - Comment: comment2.Comment, - CreatedAt: comment2.CreatedAt, - UpdatedAt: comment2.UpdatedAt, - }, - } - - res := &RequestResponse{ - ID: updateRequest.ID, - Status: updateRequest.Status, - CreatedAt: updateRequest.CreatedAt, - UpdatedAt: updateRequest.UpdatedAt, - CreatedBy: updateRequest.CreatedBy, - Statuses: []*StatusResponseOverview{ - { - Status: updateRequest.Statuses[0].Status, - CreatedAt: updateRequest.Statuses[0].CreatedAt, - CreatedBy: updateRequest.Statuses[0].CreatedBy, - }, - }, - Title: updateRequest.Title, - Content: updateRequest.Content, - Comments: resComments, - Tags: []*TagOverview{}, - Targets: []*TargetOverview{}, - } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutRequest(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.PutRequest(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *RequestResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelRequestDetailToRequestResponse(updateRequest) + exp.Comments = lo.Map(comments, func(c *model.Comment, _ int) *CommentDetail { + return modelCommentToCommentDetail(c) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) e := echo.New() - req, err := http.NewRequest(http.MethodPut, "/api/requests/hoge", nil) + req, err := http.NewRequest( + http.MethodPut, + fmt.Sprintf("/api/requests/%s", invalidUUID), + nil) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("/api/requests/:requestID") c.SetParamNames("requestID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) - _, resErr := uuid.Parse(c.Param("requestID")) - err = h.Handlers.PutRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -2121,9 +1854,9 @@ func TestHandlers_PutRequest(t *testing.T) { resErr := errors.New("invalid UUID") err = h.Handlers.PutRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownID", func(t *testing.T) { @@ -2170,9 +1903,9 @@ func TestHandlers_PutRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PutRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("UnknownTagID", func(t *testing.T) { @@ -2229,9 +1962,9 @@ func TestHandlers_PutRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PutRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("UnknownGroupID", func(t *testing.T) { @@ -2291,9 +2024,9 @@ func TestHandlers_PutRequest(t *testing.T) { Return(nil, resErr) err = h.Handlers.PutRequest(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) } @@ -2389,8 +2122,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2402,13 +2140,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessByAdminFromSubmittedToFixRequired", func(t *testing.T) { @@ -2500,8 +2232,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2513,13 +2250,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessByAdminFromSubmittedToAccepted", func(t *testing.T) { @@ -2611,8 +2342,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2624,13 +2360,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessByAdminFromSubmittedToFixRequired", func(t *testing.T) { @@ -2722,8 +2452,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2735,13 +2470,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessByAdminFromFixRequiredToSubmitted", func(t *testing.T) { @@ -2833,8 +2562,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2846,13 +2580,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessByAdminFromAcceptedToSubmitted", func(t *testing.T) { @@ -2955,8 +2683,13 @@ func TestHandlers_PutStatus(t *testing.T) { EXPECT(). CreateComment(ctx, reqStatus.Comment, request.ID, user.ID). Return(comment, nil) - - res := &StatusResponse{ + assert.NoError(t, h.Handlers.PutStatus(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *StatusResponse + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &StatusResponse{ CreatedBy: user.ID, Status: status.Status, Comment: CommentDetail{ @@ -2968,13 +2701,7 @@ func TestHandlers_PutStatus(t *testing.T) { }, CreatedAt: status.CreatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutStatus(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("InvalidStatus", func(t *testing.T) { @@ -3000,17 +2727,20 @@ func TestHandlers_PutStatus(t *testing.T) { } invalidStatus := random.AlphaNumeric(t, 20) - reqStatus := fmt.Sprintf(` - { - "status": "%s", - "comment": "%s" - }`, invalidStatus, random.AlphaNumeric(t, 20)) + reqBody, err := json.Marshal(&struct { + Status string `json:"status"` + Comment string `json:"comment"` + }{ + Status: invalidStatus, + Comment: random.AlphaNumeric(t, 20), + }) + require.NoError(t, err) e := echo.New() req, err := http.NewRequest( http.MethodPut, fmt.Sprintf("/api/requests/%s/status", request.ID.String()), - strings.NewReader(reqStatus)) + bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -3044,14 +2774,16 @@ func TestHandlers_PutStatus(t *testing.T) { resErr.Message = resErrMessage err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, resErr, err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい + assert.Equal(t, resErr, err) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) date := time.Now() user := &model.User{ @@ -3073,7 +2805,7 @@ func TestHandlers_PutStatus(t *testing.T) { e := echo.New() req, err := http.NewRequest( http.MethodPut, - fmt.Sprintf("/api/requests/%s/status", "hoge"), + fmt.Sprintf("/api/requests/%s/status", invalidUUID), bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) @@ -3081,7 +2813,7 @@ func TestHandlers_PutStatus(t *testing.T) { c := e.NewContext(req, rec) c.SetPath("api/requests/:requestID/status") c.SetParamNames("requestID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) mw := session.Middleware(sessions.NewCookieStore([]byte("secret"))) hn := mw(echo.HandlerFunc(func(c echo.Context) error { return c.NoContent(http.StatusOK) @@ -3100,12 +2832,10 @@ func TestHandlers_PutStatus(t *testing.T) { Admin: user.Admin, } - _, resErr := uuid.Parse(c.Param("requestID")) - err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NillUUID", func(t *testing.T) { @@ -3162,12 +2892,12 @@ func TestHandlers_PutStatus(t *testing.T) { _, resErr := uuid.Parse(c.Param("requestID")) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) - t.Run("SissionNotFound", func(t *testing.T) { + t.Run("SessionNotFound", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) date := time.Now() @@ -3221,9 +2951,9 @@ func TestHandlers_PutStatus(t *testing.T) { resErr := errors.New("sessionUser not found") err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusForbidden, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusForbiddenだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusForbidden, resErr), err) }) t.Run("SameStatusError", func(t *testing.T) { @@ -3294,9 +3024,9 @@ func TestHandlers_PutStatus(t *testing.T) { resErr := errors.New("invalid request: same status") err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("CommentRequiredErrorFromSubmittedToFixRequired", func(t *testing.T) { @@ -3369,9 +3099,9 @@ func TestHandlers_PutStatus(t *testing.T) { reqStatus.Status.String()) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("CommentRequiredErrorFromSubmittedToRejected", func(t *testing.T) { @@ -3444,9 +3174,9 @@ func TestHandlers_PutStatus(t *testing.T) { reqStatus.Status.String()) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("CommentRequiredErrorFromAcceptedToSubmitted", func(t *testing.T) { @@ -3519,9 +3249,9 @@ func TestHandlers_PutStatus(t *testing.T) { reqStatus.Status.String()) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("UnknownUser", func(t *testing.T) { @@ -3597,9 +3327,9 @@ func TestHandlers_PutStatus(t *testing.T) { Return(nil, resErr) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusNotFoundだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusNotFound, resErr), err) }) t.Run("AdminNoPrivilege", func(t *testing.T) { @@ -3677,9 +3407,9 @@ func TestHandlers_PutStatus(t *testing.T) { reqStatus.Status.String()) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusForbiddenだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("AlreadyPaid", func(t *testing.T) { @@ -3765,9 +3495,9 @@ func TestHandlers_PutStatus(t *testing.T) { resErr := errors.New("someone already paid") err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("CreatorNoPrivilege", func(t *testing.T) { @@ -3844,9 +3574,9 @@ func TestHandlers_PutStatus(t *testing.T) { request.Status.String(), reqStatus.Status.String()) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusForbiddenだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NoPrivilege", func(t *testing.T) { @@ -3919,9 +3649,9 @@ func TestHandlers_PutStatus(t *testing.T) { Return(user, nil) err = h.Handlers.PutStatus(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusForbidden), err) - } + assert.Error(t, err) + // FIXME: http.StatusForbiddenだけ判定したい + assert.Equal(t, echo.NewHTTPError(http.StatusForbidden), err) }) } diff --git a/router/tag_test.go b/router/tag_test.go index 93d831dd..ea4f75f6 100644 --- a/router/tag_test.go +++ b/router/tag_test.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "net/http/httptest" - "strings" "testing" "time" @@ -17,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/traPtitech/Jomon/model" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" "go.uber.org/mock/gomock" ) @@ -58,7 +58,13 @@ func TestHandlers_GetTags(t *testing.T) { GetTags(c.Request().Context()). Return(tags, nil) - resOverview := lo.Map(tags, func(tag *model.Tag, _ int) *TagOverview { + assert.NoError(t, h.Handlers.GetTags(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*TagOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := lo.Map(tags, func(tag *model.Tag, _ int) *TagOverview { return &TagOverview{ ID: tag.ID, Name: tag.Name, @@ -66,15 +72,7 @@ func TestHandlers_GetTags(t *testing.T) { UpdatedAt: tag.UpdatedAt, } }) - - res := resOverview - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTags(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { @@ -97,15 +95,14 @@ func TestHandlers_GetTags(t *testing.T) { GetTags(c.Request().Context()). Return(tags, nil) - resOverview := []*TagOverview{} - res := resOverview - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTags(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*TagOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTags(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + var exp []*TagOverview + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("FailedToGetTags", func(t *testing.T) { @@ -128,9 +125,9 @@ func TestHandlers_GetTags(t *testing.T) { Return(nil, mocErr) err = h.Handlers.GetTags(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) } @@ -170,19 +167,19 @@ func TestHandlers_PostTag(t *testing.T) { CreateTag(c.Request().Context(), tag.Name). Return(tag, nil) - res := TagOverview{ + assert.NoError(t, h.Handlers.PostTag(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got TagOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &TagOverview{ ID: tag.ID, Name: tag.Name, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostTag(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("MissingName", func(t *testing.T) { @@ -220,9 +217,9 @@ func TestHandlers_PostTag(t *testing.T) { Return(nil, mocErr) err = h.Handlers.PostTag(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) } @@ -276,19 +273,19 @@ func TestHandlers_PutTag(t *testing.T) { UpdateTag(c.Request().Context(), tag.ID, reqTag.Name). Return(updateTag, nil) - res := TagOverview{ + assert.NoError(t, h.Handlers.PutTag(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got TagOverview + err = json.Unmarshal(rec.Body.Bytes(), &got) + require.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := &TagOverview{ ID: updateTag.ID, Name: updateTag.Name, CreatedAt: updateTag.CreatedAt, UpdatedAt: updateTag.UpdatedAt, } - resBody, err := json.Marshal(res) - require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutTag(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("MissingName", func(t *testing.T) { @@ -332,14 +329,16 @@ func TestHandlers_PutTag(t *testing.T) { Return(nil, mocErr) err = h.Handlers.PutTag(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) date := time.Now() tag := &model.Tag{ @@ -357,24 +356,25 @@ func TestHandlers_PutTag(t *testing.T) { require.NoError(t, err) e := echo.New() - req, err := http.NewRequest(http.MethodPut, "/api/tags/hoge", bytes.NewReader(reqBody)) + req, err := http.NewRequest( + http.MethodPut, + fmt.Sprintf("/api/tags/%s", invalidUUID), + bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("/api/tags/:tagID") c.SetParamNames("tagID") - c.SetParamValues("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) assert.NoError(t, err) - _, resErr := uuid.Parse("hoge") - err = h.Handlers.PutTag(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -412,13 +412,11 @@ func TestHandlers_PutTag(t *testing.T) { h, err := NewTestHandlers(t, ctrl) assert.NoError(t, err) + resErr := errors.New("invalid tag ID") err = h.Handlers.PutTag(c) - if assert.Error(t, err) { - assert.Equal( - t, - echo.NewHTTPError(http.StatusBadRequest, errors.New("invalid tag ID")), - err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } @@ -465,9 +463,8 @@ func TestHandlers_DeleteTag(t *testing.T) { DeleteTag(c.Request().Context(), tag.ID). Return(nil) - if assert.NoError(t, h.Handlers.DeleteTag(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - } + assert.NoError(t, h.Handlers.DeleteTag(c)) + assert.Equal(t, http.StatusOK, rec.Code) }) t.Run("UnknownID", func(t *testing.T) { @@ -512,14 +509,16 @@ func TestHandlers_DeleteTag(t *testing.T) { Return(mocErr) err = h.Handlers.DeleteTag(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("InvalidUUID", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + invalidUUID := "invalid-uuid" + _, resErr := uuid.Parse(invalidUUID) date := time.Now() tag := &model.Tag{ @@ -537,24 +536,25 @@ func TestHandlers_DeleteTag(t *testing.T) { require.NoError(t, err) e := echo.New() - req, err := http.NewRequest(http.MethodDelete, "/api/tags/hoge", bytes.NewReader(reqBody)) + req, err := http.NewRequest( + http.MethodDelete, + fmt.Sprintf("/api/tags/%s", invalidUUID), + bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() c := e.NewContext(req, rec) c.SetPath("/api/tags/:tagID") c.SetParamNames("tagID") - c.SetParamValues("hoge") - - _, resErr := uuid.Parse("hoge") + c.SetParamValues(invalidUUID) h, err := NewTestHandlers(t, ctrl) assert.NoError(t, err) err = h.Handlers.DeleteTag(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) t.Run("NilUUID", func(t *testing.T) { @@ -592,12 +592,10 @@ func TestHandlers_DeleteTag(t *testing.T) { h, err := NewTestHandlers(t, ctrl) assert.NoError(t, err) + resErr := errors.New("invalid tag ID") err = h.Handlers.DeleteTag(c) - if assert.Error(t, err) { - assert.Equal( - t, - echo.NewHTTPError(http.StatusBadRequest, errors.New("invalid tag ID")), - err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, resErr), err) }) } diff --git a/router/transaction_test.go b/router/transaction_test.go index b92775c0..eafff5b9 100644 --- a/router/transaction_test.go +++ b/router/transaction_test.go @@ -1,6 +1,7 @@ package router import ( + "bytes" "encoding/json" "fmt" "net/http" @@ -16,10 +17,42 @@ import ( "github.com/stretchr/testify/require" "github.com/traPtitech/Jomon/model" "github.com/traPtitech/Jomon/service" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" "go.uber.org/mock/gomock" ) +// FIXME: 同様の処理がtransaction.goにもある +func modelTransactionResponseToTransaction(tx *model.TransactionResponse) *Transaction { + tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { + return &TagOverview{ + ID: modelTag.ID, + Name: modelTag.Name, + CreatedAt: modelTag.CreatedAt, + UpdatedAt: modelTag.UpdatedAt, + } + }) + + group := &GroupOverview{ + ID: tx.Group.ID, + Name: tx.Group.Name, + Description: tx.Group.Description, + Budget: tx.Group.Budget, + CreatedAt: tx.Group.CreatedAt, + UpdatedAt: tx.Group.UpdatedAt, + } + return &Transaction{ + ID: tx.ID, + Title: tx.Title, + Amount: tx.Amount, + Target: tx.Target, + Tags: tag, + Group: group, + CreatedAt: tx.CreatedAt, + UpdatedAt: tx.UpdatedAt, + } +} + func TestHandlers_GetTransactions(t *testing.T) { t.Parallel() @@ -101,44 +134,16 @@ func TestHandlers_GetTransactions(t *testing.T) { Group: nil, }). Return(txs, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransactions(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransactions(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSort", func(t *testing.T) { @@ -217,44 +222,16 @@ func TestHandlers_GetTransactions(t *testing.T) { Offset: 0, }). Return(txs, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransactions(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransactions(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithAscSort", func(t *testing.T) { @@ -334,44 +311,16 @@ func TestHandlers_GetTransactions(t *testing.T) { Offset: 0, }). Return(txs, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransactions(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransactions(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithTarget", func(t *testing.T) { @@ -456,44 +405,16 @@ func TestHandlers_GetTransactions(t *testing.T) { Offset: 0, }). Return(txs, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransactions(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransactions(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithSinceUntil", func(t *testing.T) { @@ -561,44 +482,16 @@ func TestHandlers_GetTransactions(t *testing.T) { Offset: 0, }). Return(txs, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransactions(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransactions(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) // TODO: SuccessWithLimit, SuccessWithOffset @@ -672,44 +565,16 @@ func TestHandlers_PostTransaction(t *testing.T) { c.Request().Context(), tx1.Title, tx1.Amount, tx1.Target, tags, &group, nil). Return(tx1, nil) - - res := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { - tag := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - group := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - return &Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: tag, - Group: group, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - }) - - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PostTransaction(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostTransaction(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map(txs, func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("SuccessWithRequest", func(t *testing.T) { @@ -768,15 +633,19 @@ func TestHandlers_PostTransaction(t *testing.T) { } e := echo.New() - // FIXME: json.Marshalを使う - // nolint:lll - reqBody := fmt.Sprintf( - `{"title": "%s", "amount": %d, "targets": ["%s"], "tags": ["%s"], "group": "%s", "request": "%s"}`, - tx.Title, tx.Amount, tx.Target, tag.ID, group, request.ID) + reqBody, err := json.Marshal(&TransactionOverview{ + Title: tx.Title, + Amount: tx.Amount, + Targets: []*string{&tx.Target}, + Tags: tags, + Group: &group, + Request: &request.ID, + }) + require.NoError(t, err) req, err := http.NewRequest( http.MethodPost, "/api/transactions", - strings.NewReader(reqBody)) + bytes.NewReader(reqBody)) require.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -793,42 +662,18 @@ func TestHandlers_PostTransaction(t *testing.T) { tags, &group, &request.ID). Return(tx, nil) - to := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - grov := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - res := []*Transaction{ - { - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: to, - Group: grov, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - }, - } - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PostTransaction(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PostTransaction(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := lo.Map( + []*model.TransactionResponse{tx}, + func(tx *model.TransactionResponse, _ int) *Transaction { + return modelTransactionResponseToTransaction(tx) + }) + testutil.RequireEqual(t, exp, got, opts...) }) // TODO: FailWithoutTitle @@ -887,42 +732,14 @@ func TestHandlers_GetTransaction(t *testing.T) { EXPECT(). GetTransaction(c.Request().Context(), tx.ID). Return(tx, nil) - - to := lo.Map(tx.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - - grov := &GroupOverview{ - ID: tx.Group.ID, - Name: tx.Group.Name, - Description: tx.Group.Description, - Budget: tx.Group.Budget, - CreatedAt: tx.Group.CreatedAt, - UpdatedAt: tx.Group.UpdatedAt, - } - resOverview := Transaction{ - ID: tx.ID, - Title: tx.Title, - Amount: tx.Amount, - Target: tx.Target, - Tags: to, - Group: grov, - CreatedAt: tx.CreatedAt, - UpdatedAt: tx.UpdatedAt, - } - res := resOverview - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.GetTransaction(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.GetTransaction(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := modelTransactionResponseToTransaction(tx) + testutil.RequireEqual(t, exp, got, opts...) }) } @@ -1017,40 +834,13 @@ func TestHandlers_PutTransaction(t *testing.T) { tx.ID, updated.Title, updated.Amount, updated.Target, updatedTags, nil, nil). Return(updated, nil) - - to := lo.Map(updated.Tags, func(modelTag *model.Tag, _ int) *TagOverview { - return &TagOverview{ - ID: modelTag.ID, - Name: modelTag.Name, - CreatedAt: modelTag.CreatedAt, - UpdatedAt: modelTag.UpdatedAt, - } - }) - grov := &GroupOverview{ - ID: updated.Group.ID, - Name: updated.Group.Name, - Description: updated.Group.Description, - Budget: updated.Group.Budget, - CreatedAt: updated.Group.CreatedAt, - UpdatedAt: updated.Group.UpdatedAt, - } - resOverview := Transaction{ - ID: tx.ID, - Title: updated.Title, - Amount: updated.Amount, - Target: updated.Target, - Tags: to, - Group: grov, - CreatedAt: updated.CreatedAt, - UpdatedAt: updated.UpdatedAt, - } - res := resOverview - resBody, err := json.Marshal(res) + assert.NoError(t, h.Handlers.PutTransaction(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got *Transaction + err = json.Unmarshal(rec.Body.Bytes(), &got) require.NoError(t, err) - - if assert.NoError(t, h.Handlers.PutTransaction(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + opts := testutil.ApproxEqualOptions() + exp := modelTransactionResponseToTransaction(updated) + testutil.RequireEqual(t, exp, got, opts...) }) } diff --git a/router/user_test.go b/router/user_test.go index b08047ac..433b7e83 100644 --- a/router/user_test.go +++ b/router/user_test.go @@ -6,22 +6,34 @@ import ( "errors" "net/http" "net/http/httptest" - "strings" "testing" "time" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/gorilla/sessions" - "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" + "github.com/samber/lo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - "github.com/traPtitech/Jomon/model" + "github.com/traPtitech/Jomon/testutil" "github.com/traPtitech/Jomon/testutil/random" + "go.uber.org/mock/gomock" ) +func modelUserToUser(user *model.User) *User { + return &User{ + ID: user.ID, + Name: user.Name, + DisplayName: user.DisplayName, + Admin: user.Admin, + CreatedAt: user.CreatedAt, + UpdatedAt: user.UpdatedAt, + DeletedAt: user.DeletedAt, + } +} + func TestHandlers_GetUsers(t *testing.T) { t.Parallel() @@ -33,26 +45,6 @@ func TestHandlers_GetUsers(t *testing.T) { user2 := makeUser(t, random.Numeric(t, 2) == 1) users := []*model.User{user1, user2} - resUser1 := &User{ - ID: user1.ID, - Name: user1.Name, - DisplayName: user1.DisplayName, - Admin: user1.Admin, - CreatedAt: user1.CreatedAt, - UpdatedAt: user1.UpdatedAt, - } - resUser2 := &User{ - ID: user2.ID, - Name: user2.Name, - DisplayName: user2.DisplayName, - Admin: user2.Admin, - CreatedAt: user2.CreatedAt, - UpdatedAt: user2.UpdatedAt, - } - resUsers := []*User{resUser1, resUser2} - resBody, err := json.Marshal(resUsers) - assert.NoError(t, err) - e := echo.New() req, err := http.NewRequest(http.MethodGet, "/api/users", nil) assert.NoError(t, err) @@ -67,20 +59,22 @@ func TestHandlers_GetUsers(t *testing.T) { GetUsers(c.Request().Context()). Return(users, nil) - if assert.NoError(t, h.Handlers.GetUsers(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(resBody), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetUsers(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*User + err = json.Unmarshal(rec.Body.Bytes(), &got) + assert.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := lo.Map(users, func(u *model.User, _ int) *User { + return modelUserToUser(u) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("Success2", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - resUsers := []*User{} - body, err := json.Marshal(resUsers) - assert.NoError(t, err) - users := []*model.User{} e := echo.New() @@ -96,10 +90,16 @@ func TestHandlers_GetUsers(t *testing.T) { GetUsers(c.Request().Context()). Return(users, nil) - if assert.NoError(t, h.Handlers.GetUsers(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(body), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetUsers(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got []*User + err = json.Unmarshal(rec.Body.Bytes(), &got) + assert.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := lo.Map(users, func(u *model.User, _ int) *User { + return modelUserToUser(u) + }) + testutil.RequireEqual(t, exp, got, opts...) }) t.Run("FailedToGetUsers", func(t *testing.T) { @@ -122,9 +122,9 @@ func TestHandlers_GetUsers(t *testing.T) { Return(nil, mocErr) err = h.Handlers.GetUsers(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) } @@ -146,25 +146,16 @@ func TestHandlers_UpdateUserInfo(t *testing.T) { UpdatedAt: time.Now(), } - resUser := User{ - ID: updateUser.ID, - Name: updateUser.Name, - DisplayName: updateUser.DisplayName, - Admin: updateUser.Admin, - } - bodyResUser, err := json.Marshal(resUser) - assert.NoError(t, err) - reqUser := PutUserRequest{ Name: updateUser.Name, DisplayName: updateUser.DisplayName, Admin: updateUser.Admin, } - bodyReqUser, err := json.Marshal(reqUser) + reqBody, err := json.Marshal(reqUser) assert.NoError(t, err) e := echo.New() - req, err := http.NewRequest(http.MethodPut, "/api/users", bytes.NewReader(bodyReqUser)) + req, err := http.NewRequest(http.MethodPut, "/api/users", bytes.NewReader(reqBody)) assert.NoError(t, err) req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) rec := httptest.NewRecorder() @@ -183,12 +174,19 @@ func TestHandlers_UpdateUserInfo(t *testing.T) { c.Request().Context(), user.ID, updateUser.Name, updateUser.DisplayName, updateUser.Admin). Return(updateUser, nil) - - if assert.NoError(t, h.Handlers.UpdateUserInfo(c)) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(bodyResUser), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.UpdateUserInfo(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got User + err = json.Unmarshal(rec.Body.Bytes(), &got) + assert.NoError(t, err) + opts := testutil.ApproxEqualOptions() + // FIXME: #835 + opts = append(opts, + cmpopts.IgnoreFields(User{}, "CreatedAt", "UpdatedAt", "DeletedAt")) + exp := modelUserToUser(updateUser) + testutil.RequireEqual(t, exp, &got, opts...) }) + t.Run("FailedToUpdateUser", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) @@ -234,9 +232,9 @@ func TestHandlers_UpdateUserInfo(t *testing.T) { Return(nil, mocErr) err = h.Handlers.UpdateUserInfo(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, mocErr), err) }) t.Run("FailedToGetUser", func(t *testing.T) { @@ -278,28 +276,20 @@ func TestHandlers_UpdateUserInfo(t *testing.T) { Return(nil, mocErr) err = h.Handlers.UpdateUserInfo(c) - if assert.Error(t, err) { - assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) - } + assert.Error(t, err) + // FIXME: http.StatusBadRequestだけ判定したい; mocErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusBadRequest, mocErr), err) }) } func TestHandlers_GetMe(t *testing.T) { t.Parallel() + t.Run("Success", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) accessUser := makeUser(t, random.Numeric(t, 2) == 1) - user := User{ - ID: accessUser.ID, - Name: accessUser.Name, - DisplayName: accessUser.DisplayName, - Admin: accessUser.Admin, - CreatedAt: accessUser.CreatedAt, - UpdatedAt: accessUser.UpdatedAt, - } - bodyAccessUser, err := json.Marshal(user) - assert.NoError(t, err) + user := modelUserToUser(accessUser) e := echo.New() req, err := http.NewRequest(http.MethodPut, "/api/users/me", nil) @@ -318,7 +308,7 @@ func TestHandlers_GetMe(t *testing.T) { require.NoError(t, err) sess, err := session.Get(h.Handlers.SessionName, c) require.NoError(t, err) - sess.Values[sessionUserKey] = user + sess.Values[sessionUserKey] = *user require.NoError(t, sess.Save(c.Request(), c.Response())) h.Repository.MockUserRepository. @@ -326,11 +316,14 @@ func TestHandlers_GetMe(t *testing.T) { GetUserByID(c.Request().Context(), user.ID). Return(accessUser, nil) - err = h.Handlers.GetMe(c) - if assert.NoError(t, err) { - assert.Equal(t, http.StatusOK, rec.Code) - assert.Equal(t, string(bodyAccessUser), strings.TrimRight(rec.Body.String(), "\n")) - } + assert.NoError(t, h.Handlers.GetMe(c)) + assert.Equal(t, http.StatusOK, rec.Code) + var got User + err = json.Unmarshal(rec.Body.Bytes(), &got) + assert.NoError(t, err) + opts := testutil.ApproxEqualOptions() + exp := modelUserToUser(accessUser) + testutil.RequireEqual(t, exp, &got, opts...) }) t.Run("FailedToGetUser", func(t *testing.T) { @@ -353,12 +346,10 @@ func TestHandlers_GetMe(t *testing.T) { h, err := NewTestHandlers(t, ctrl) require.NoError(t, err) + resErr := "failed to get user info" err = h.Handlers.GetMe(c) - if assert.Error(t, err) { - assert.Equal( - t, - echo.NewHTTPError(http.StatusInternalServerError, "failed to get user info"), - err) - } + assert.Error(t, err) + // FIXME: http.StatusInternalServerErrorだけ判定したい; resErrの内容は関係ない + assert.Equal(t, echo.NewHTTPError(http.StatusInternalServerError, resErr), err) }) } diff --git a/testutil/cmp.go b/testutil/cmp.go new file mode 100644 index 00000000..ce57fd2b --- /dev/null +++ b/testutil/cmp.go @@ -0,0 +1,35 @@ +package testutil + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +func ApproxEqualOptions() []cmp.Option { + return []cmp.Option{ + cmpopts.EquateApproxTime(time.Second), + cmpopts.EquateEmpty(), + } +} + +func AssertEqual(t *testing.T, expected, actual interface{}, opts ...cmp.Option) bool { + t.Helper() + diff := cmp.Diff(expected, actual, opts...) + if diff == "" { + return true + } + t.Errorf("Not equal (-expected +actual):\n"+ + "expected: %s\n"+ + "actual : %s\n%s", expected, actual, diff) + return false +} + +func RequireEqual(t *testing.T, expected, actual interface{}, opts ...cmp.Option) { + t.Helper() + if !AssertEqual(t, expected, actual, opts...) { + t.FailNow() + } +}