update_place_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package place
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "net/http/httptest"
  7. "strconv"
  8. "testing"
  9. API "git.dmitriygnatenko.ru/dima/homethings/internal/api/v1"
  10. "git.dmitriygnatenko.ru/dima/homethings/internal/dto"
  11. "git.dmitriygnatenko.ru/dima/homethings/internal/helpers"
  12. "git.dmitriygnatenko.ru/dima/homethings/internal/interfaces"
  13. "git.dmitriygnatenko.ru/dima/homethings/internal/models"
  14. repoMocks "git.dmitriygnatenko.ru/dima/homethings/internal/repositories/mocks"
  15. sp "git.dmitriygnatenko.ru/dima/homethings/internal/service_provider"
  16. "github.com/brianvoe/gofakeit/v6"
  17. "github.com/gofiber/fiber/v2"
  18. "github.com/gojuno/minimock/v3"
  19. "github.com/stretchr/testify/assert"
  20. )
  21. func Test_UpdatePlaceHandler(t *testing.T) {
  22. type req struct {
  23. method string
  24. route string
  25. contentType string
  26. body *dto.UpdatePlaceRequest
  27. }
  28. var (
  29. mc = minimock.NewController(t)
  30. placeID = gofakeit.Number(1, 1000)
  31. parentID = gofakeit.Number(1, 1000)
  32. title = gofakeit.Phrase()
  33. testError = errors.New(gofakeit.Phrase())
  34. layout = "2006-01-02 15:04:05"
  35. correctReq = req{
  36. method: fiber.MethodPut,
  37. route: "/v1/places/" + strconv.Itoa(placeID),
  38. body: &dto.UpdatePlaceRequest{
  39. Title: title,
  40. ParentID: &parentID,
  41. },
  42. contentType: fiber.MIMEApplicationJSON,
  43. }
  44. repoRes = models.Place{
  45. ID: placeID,
  46. Title: title,
  47. ParentID: sql.NullInt64{Int64: int64(parentID), Valid: true},
  48. CreatedAt: gofakeit.Date(),
  49. UpdatedAt: gofakeit.Date(),
  50. }
  51. expectedRes = dto.PlaceResponse{
  52. ID: placeID,
  53. ParentID: &parentID,
  54. Title: repoRes.Title,
  55. CreatedAt: repoRes.CreatedAt.Format(layout),
  56. UpdatedAt: repoRes.UpdatedAt.Format(layout),
  57. }
  58. )
  59. tests := []struct {
  60. name string
  61. req req
  62. resCode int
  63. resBody interface{}
  64. placeRepoMock func(mc *minimock.Controller) interfaces.PlaceRepository
  65. }{
  66. {
  67. name: "positive case",
  68. req: correctReq,
  69. resCode: fiber.StatusOK,
  70. resBody: expectedRes,
  71. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  72. mock := repoMocks.NewPlaceRepositoryMock(mc)
  73. mock.UpdateMock.Inspect(func(ctx context.Context, req models.UpdatePlaceRequest, tx *sql.Tx) {
  74. assert.Equal(mc, title, req.Title)
  75. assert.Equal(mc, parentID, int(req.ParentID.Int64))
  76. }).Return(nil)
  77. mock.GetMock.Inspect(func(ctx context.Context, id int) {
  78. assert.Equal(mc, placeID, id)
  79. }).Return(&repoRes, nil)
  80. return mock
  81. },
  82. },
  83. {
  84. name: "negative case - bad request",
  85. req: req{
  86. method: fiber.MethodPut,
  87. route: "/v1/places/" + gofakeit.Word(),
  88. },
  89. resCode: fiber.StatusBadRequest,
  90. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  91. return repoMocks.NewPlaceRepositoryMock(mc)
  92. },
  93. },
  94. {
  95. name: "negative case - body parse error",
  96. req: req{
  97. method: fiber.MethodPut,
  98. route: "/v1/places/" + strconv.Itoa(placeID),
  99. },
  100. resCode: fiber.StatusBadRequest,
  101. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  102. return repoMocks.NewPlaceRepositoryMock(mc)
  103. },
  104. },
  105. {
  106. name: "negative case - request without title",
  107. req: req{
  108. method: fiber.MethodPut,
  109. route: "/v1/places/" + strconv.Itoa(placeID),
  110. contentType: fiber.MIMEApplicationJSON,
  111. body: &dto.UpdatePlaceRequest{},
  112. },
  113. resCode: fiber.StatusBadRequest,
  114. resBody: []*dto.ValidateErrorResponse{
  115. {
  116. Field: "UpdatePlaceRequest.Title",
  117. Tag: "required",
  118. },
  119. },
  120. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  121. return repoMocks.NewPlaceRepositoryMock(mc)
  122. },
  123. },
  124. {
  125. name: "negative case - repository error (update place)",
  126. req: correctReq,
  127. resCode: fiber.StatusInternalServerError,
  128. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  129. mock := repoMocks.NewPlaceRepositoryMock(mc)
  130. mock.UpdateMock.Inspect(func(ctx context.Context, req models.UpdatePlaceRequest, tx *sql.Tx) {
  131. assert.Equal(mc, title, req.Title)
  132. assert.Equal(mc, parentID, int(req.ParentID.Int64))
  133. }).Return(testError)
  134. return mock
  135. },
  136. },
  137. {
  138. name: "negative case - repository error (get place)",
  139. req: correctReq,
  140. resCode: fiber.StatusInternalServerError,
  141. placeRepoMock: func(mc *minimock.Controller) interfaces.PlaceRepository {
  142. mock := repoMocks.NewPlaceRepositoryMock(mc)
  143. mock.UpdateMock.Inspect(func(ctx context.Context, req models.UpdatePlaceRequest, tx *sql.Tx) {
  144. assert.Equal(mc, title, req.Title)
  145. assert.Equal(mc, parentID, int(req.ParentID.Int64))
  146. }).Return(nil)
  147. mock.GetMock.Inspect(func(ctx context.Context, id int) {
  148. assert.Equal(mc, placeID, id)
  149. }).Return(nil, testError)
  150. return mock
  151. },
  152. },
  153. }
  154. for _, tt := range tests {
  155. t.Run(tt.name, func(t *testing.T) {
  156. fiberApp := fiber.New()
  157. serviceProvider := sp.InitMock(tt.placeRepoMock(mc))
  158. fiberApp.Put("/v1/places/:placeId", UpdatePlaceHandler(serviceProvider))
  159. fiberReq := httptest.NewRequest(tt.req.method, tt.req.route, helpers.ConvertDataToIOReader(tt.req.body))
  160. fiberReq.Header.Add(fiber.HeaderContentType, tt.req.contentType)
  161. fiberRes, _ := fiberApp.Test(fiberReq, API.DefaultTestTimeOut)
  162. assert.Equal(t, tt.resCode, fiberRes.StatusCode)
  163. if tt.resBody != nil {
  164. assert.Equal(t, helpers.MarshalResponse(tt.resBody), helpers.ConvertBodyToString(fiberRes.Body))
  165. }
  166. })
  167. }
  168. }