package image import ( "context" "database/sql" "errors" "net/http/httptest" "strconv" "testing" "github.com/brianvoe/gofakeit/v6" "github.com/gofiber/fiber/v2" "github.com/gojuno/minimock/v3" "github.com/stretchr/testify/assert" API "git.dmitriygnatenko.ru/dima/homethings/internal/api/v1" "git.dmitriygnatenko.ru/dima/homethings/internal/api/v1/image/mocks" "git.dmitriygnatenko.ru/dima/homethings/internal/dto" "git.dmitriygnatenko.ru/dima/homethings/internal/helpers" "git.dmitriygnatenko.ru/dima/homethings/internal/models" ) func TestDeletePlaceImageHandler(t *testing.T) { t.Parallel() type req struct { method string route string } var ( imageID = gofakeit.Number(1, 1000) imageURL = gofakeit.URL() testError = errors.New(gofakeit.Phrase()) correctReq = req{ method: fiber.MethodDelete, route: "/v1/images/place/" + strconv.Itoa(imageID), } repoRes = &models.Image{ Image: imageURL, } ) tests := []struct { name string req req resCode int resBody interface{} placeImageRepoMock func(mc *minimock.Controller) PlaceImageRepository fileRepoMock func(mc *minimock.Controller) FileRepository }{ { name: "negative case - bad request", req: req{ method: fiber.MethodDelete, route: "/v1/images/place/" + gofakeit.Word(), }, resCode: fiber.StatusBadRequest, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { return mocks.NewPlaceImageRepositoryMock(mc) }, fileRepoMock: func(mc *minimock.Controller) FileRepository { return mocks.NewFileRepositoryMock(mc) }, }, { name: "negative case - bad request (image not exists)", req: correctReq, resCode: fiber.StatusBadRequest, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { mock := mocks.NewPlaceImageRepositoryMock(mc) mock.GetMock.Inspect(func(ctx context.Context, id int) { assert.Equal(mc, imageID, id) }).Return(nil, sql.ErrNoRows) return mock }, fileRepoMock: func(mc *minimock.Controller) FileRepository { return mocks.NewFileRepositoryMock(mc) }, }, { name: "negative case - repository error (get)", req: correctReq, resCode: fiber.StatusInternalServerError, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { mock := mocks.NewPlaceImageRepositoryMock(mc) mock.GetMock.Inspect(func(ctx context.Context, id int) { assert.Equal(mc, imageID, id) }).Return(nil, testError) return mock }, fileRepoMock: func(mc *minimock.Controller) FileRepository { return mocks.NewFileRepositoryMock(mc) }, }, { name: "negative case - repository error (update)", req: correctReq, resCode: fiber.StatusInternalServerError, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { mock := mocks.NewPlaceImageRepositoryMock(mc) mock.GetMock.Inspect(func(ctx context.Context, id int) { assert.Equal(mc, imageID, id) }).Return(nil, nil) mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) { assert.Equal(mc, imageID, id) }).Return(testError) return mock }, fileRepoMock: func(mc *minimock.Controller) FileRepository { return mocks.NewFileRepositoryMock(mc) }, }, { name: "negative case - file delete error", req: correctReq, resCode: fiber.StatusInternalServerError, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { mock := mocks.NewPlaceImageRepositoryMock(mc) mock.GetMock.Inspect(func(ctx context.Context, id int) { assert.Equal(mc, imageID, id) }).Return(repoRes, nil) mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) { assert.Equal(mc, imageID, id) }).Return(nil) return mock }, fileRepoMock: func(mc *minimock.Controller) FileRepository { mock := mocks.NewFileRepositoryMock(mc) mock.DeleteMock.Return(testError) return mock }, }, { name: "positive case", req: correctReq, resCode: fiber.StatusOK, resBody: dto.EmptyResponse{}, placeImageRepoMock: func(mc *minimock.Controller) PlaceImageRepository { mock := mocks.NewPlaceImageRepositoryMock(mc) mock.GetMock.Inspect(func(ctx context.Context, id int) { assert.Equal(mc, imageID, id) }).Return(repoRes, nil) mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) { assert.Equal(mc, imageID, id) }).Return(nil) return mock }, fileRepoMock: func(mc *minimock.Controller) FileRepository { mock := mocks.NewFileRepositoryMock(mc) mock.DeleteMock.Return(nil) return mock }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() mc := minimock.NewController(t) fiberApp := fiber.New() fiberApp.Delete("/v1/images/place/:imageId", DeletePlaceImageHandler( tt.fileRepoMock(mc), tt.placeImageRepoMock(mc), )) fiberRes, _ := fiberApp.Test(httptest.NewRequest(tt.req.method, tt.req.route, nil), API.DefaultTestTimeOut) assert.Equal(t, tt.resCode, fiberRes.StatusCode) if tt.resBody != nil { assert.Equal(t, helpers.MarshalResponse(tt.resBody), helpers.ConvertBodyToString(fiberRes.Body)) } }) } }