search_thing_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package thing
  2. import (
  3. "context"
  4. "errors"
  5. "net/http/httptest"
  6. "net/url"
  7. "testing"
  8. API "git.dmitriygnatenko.ru/dima/homethings/internal/api/v1"
  9. "git.dmitriygnatenko.ru/dima/homethings/internal/dto"
  10. "git.dmitriygnatenko.ru/dima/homethings/internal/helpers"
  11. "git.dmitriygnatenko.ru/dima/homethings/internal/interfaces"
  12. "git.dmitriygnatenko.ru/dima/homethings/internal/models"
  13. repoMocks "git.dmitriygnatenko.ru/dima/homethings/internal/repositories/mocks"
  14. sp "git.dmitriygnatenko.ru/dima/homethings/internal/service_provider"
  15. "github.com/brianvoe/gofakeit/v6"
  16. "github.com/gofiber/fiber/v2"
  17. "github.com/gojuno/minimock/v3"
  18. "github.com/stretchr/testify/assert"
  19. )
  20. func Test_SearchThingHandler(t *testing.T) {
  21. type req struct {
  22. method string
  23. route string
  24. }
  25. var (
  26. mc = minimock.NewController(t)
  27. search = gofakeit.LetterN(10)
  28. testError = errors.New(gofakeit.Phrase())
  29. layout = "2006-01-02 15:04:05"
  30. correctReq = req{
  31. method: fiber.MethodGet,
  32. route: "/v1/things/search/" + url.QueryEscape(search),
  33. }
  34. thingRepoRes = []models.Thing{
  35. {
  36. ID: gofakeit.Number(1, 1000),
  37. PlaceID: gofakeit.Number(1, 1000),
  38. Title: gofakeit.Phrase(),
  39. Description: gofakeit.Phrase(),
  40. CreatedAt: gofakeit.Date(),
  41. UpdatedAt: gofakeit.Date(),
  42. },
  43. {
  44. ID: gofakeit.Number(1, 1000),
  45. PlaceID: gofakeit.Number(1, 1000),
  46. Title: gofakeit.Phrase(),
  47. Description: gofakeit.Phrase(),
  48. CreatedAt: gofakeit.Date(),
  49. UpdatedAt: gofakeit.Date(),
  50. },
  51. }
  52. expectedRes = dto.ThingsResponse{
  53. Things: []dto.ThingResponse{
  54. {
  55. ID: thingRepoRes[0].ID,
  56. PlaceID: thingRepoRes[0].PlaceID,
  57. Title: thingRepoRes[0].Title,
  58. Description: thingRepoRes[0].Description,
  59. CreatedAt: thingRepoRes[0].CreatedAt.Format(layout),
  60. UpdatedAt: thingRepoRes[0].UpdatedAt.Format(layout),
  61. },
  62. {
  63. ID: thingRepoRes[1].ID,
  64. PlaceID: thingRepoRes[1].PlaceID,
  65. Title: thingRepoRes[1].Title,
  66. Description: thingRepoRes[1].Description,
  67. CreatedAt: thingRepoRes[1].CreatedAt.Format(layout),
  68. UpdatedAt: thingRepoRes[1].UpdatedAt.Format(layout),
  69. },
  70. },
  71. }
  72. )
  73. tests := []struct {
  74. name string
  75. req req
  76. resCode int
  77. resBody interface{}
  78. thingRepoMock func(mc *minimock.Controller) interfaces.ThingRepository
  79. }{
  80. {
  81. name: "negative case - bad request",
  82. req: req{
  83. method: fiber.MethodGet,
  84. route: "/v1/things/search/" + url.QueryEscape(gofakeit.LetterN(2)),
  85. },
  86. resCode: fiber.StatusBadRequest,
  87. thingRepoMock: func(mc *minimock.Controller) interfaces.ThingRepository {
  88. return repoMocks.NewThingRepositoryMock(mc)
  89. },
  90. },
  91. {
  92. name: "negative case - bad request",
  93. req: req{
  94. method: fiber.MethodGet,
  95. route: "/v1/things/search/" + url.QueryEscape(gofakeit.LetterN(10)+":"),
  96. },
  97. resCode: fiber.StatusBadRequest,
  98. thingRepoMock: func(mc *minimock.Controller) interfaces.ThingRepository {
  99. return repoMocks.NewThingRepositoryMock(mc)
  100. },
  101. },
  102. {
  103. name: "negative case - repository error",
  104. req: correctReq,
  105. resCode: fiber.StatusInternalServerError,
  106. thingRepoMock: func(mc *minimock.Controller) interfaces.ThingRepository {
  107. mock := repoMocks.NewThingRepositoryMock(mc)
  108. mock.SearchMock.Inspect(func(ctx context.Context, s string) {
  109. assert.Equal(mc, search, s)
  110. }).Return(nil, testError)
  111. return mock
  112. },
  113. },
  114. {
  115. name: "positive case",
  116. req: correctReq,
  117. resCode: fiber.StatusOK,
  118. resBody: expectedRes,
  119. thingRepoMock: func(mc *minimock.Controller) interfaces.ThingRepository {
  120. mock := repoMocks.NewThingRepositoryMock(mc)
  121. mock.SearchMock.Inspect(func(ctx context.Context, s string) {
  122. assert.Equal(mc, search, s)
  123. }).Return(thingRepoRes, nil)
  124. return mock
  125. },
  126. },
  127. }
  128. for _, tt := range tests {
  129. t.Run(tt.name, func(t *testing.T) {
  130. fiberApp := fiber.New()
  131. serviceProvider := sp.InitMock(tt.thingRepoMock(mc))
  132. fiberApp.Get("/v1/things/search/:search", SearchThingHandler(serviceProvider))
  133. fiberRes, _ := fiberApp.Test(httptest.NewRequest(tt.req.method, tt.req.route, nil), API.DefaultTestTimeOut)
  134. assert.Equal(t, tt.resCode, fiberRes.StatusCode)
  135. if tt.resBody != nil {
  136. assert.Equal(t, helpers.MarshalResponse(tt.resBody), helpers.ConvertBodyToString(fiberRes.Body))
  137. }
  138. })
  139. }
  140. }