search_thing_test.go 4.1 KB

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