1
0

2 Коміти e5b773430f ... 67177dd393

Автор SHA1 Опис Дата
  Dmitriy Gnatenko 67177dd393 Refactoring 4 тижнів тому
  Dmitriy Gnatenko e5b773430f Refactoring 4 тижнів тому

+ 5 - 2
Makefile

@@ -27,8 +27,11 @@ test:
 	go test ./...
 
 test-cover:
-	go test ./... -coverprofile=./coverage.out
-	go tool cover -html=./coverage.out
+	go clean -testcache
+	go test ./... -coverprofile=coverage.tmp.out -covermode count -coverpkg=git.dmitriygnatenko.ru/dima/homethings/internal/api/...
+	grep -v 'mocks\|config' coverage.tmp.out  > coverage.out
+	rm coverage.tmp.out
+	go tool cover -html=coverage.out;
 
 lint:
 	golangci-lint run --timeout=3m


+ 1 - 1
cmd/app/main.go

@@ -26,7 +26,7 @@ func main() {
 		log.Fatal(err)
 	}
 
-	if err = fiberApp.Listen(":" + serviceProvider.EnvService().AppPort()); err != nil {
+	if err = fiberApp.Listen(":" + serviceProvider.ConfigService().AppPort()); err != nil {
 		log.Fatal(err)
 	}
 }

+ 2 - 1
go.mod

@@ -10,7 +10,7 @@ require (
 	github.com/go-playground/validator/v10 v10.22.0
 	github.com/gofiber/fiber/v2 v2.52.5
 	github.com/gofiber/jwt/v3 v3.3.6
-	github.com/gofiber/swagger v0.1.7
+	github.com/gofiber/swagger v1.1.0
 	github.com/gojuno/minimock/v3 v3.3.13
 	github.com/golang-jwt/jwt/v4 v4.4.3
 	github.com/lib/pq v1.10.9
@@ -61,6 +61,7 @@ require (
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect
+	github.com/swaggo/files/v2 v2.0.1 // indirect
 	github.com/tinylib/msgp v1.1.8 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 	github.com/valyala/fasthttp v1.55.0 // indirect

+ 2 - 1
internal/api/v1/thing/add_thing.go

@@ -92,7 +92,8 @@ func AddThingHandler(
 		var id uint64
 
 		err := tm.ReadCommitted(ctx, func(ctx context.Context) error {
-			id, txErr := thingRepository.Add(ctx, mappers.ToAddThingRequest(req))
+			var txErr error
+			id, txErr = thingRepository.Add(ctx, mappers.ToAddThingRequest(req))
 			if txErr != nil {
 				return txErr
 			}

+ 52 - 69
internal/api/v1/thing/add_thing_test.go

@@ -11,10 +11,9 @@ import (
 	"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/thing/mocks"
 	"git.dmitriygnatenko.ru/dima/homethings/internal/dto"
-	"git.dmitriygnatenko.ru/dima/homethings/internal/helpers"
+	"git.dmitriygnatenko.ru/dima/homethings/internal/helpers/test"
 	"git.dmitriygnatenko.ru/dima/homethings/internal/models"
 )
 
@@ -29,13 +28,17 @@ func TestAddThingHandler(t *testing.T) {
 	}
 
 	var (
-		placeID     = gofakeit.Number(1, 1000)
-		thingID     = gofakeit.Number(1, 1000)
+		placeID     = uint64(gofakeit.Number(1, 1000))
+		thingID     = uint64(gofakeit.Number(1, 1000))
 		title       = gofakeit.Phrase()
 		description = gofakeit.Phrase()
 		testError   = gofakeit.Error()
 		layout      = "2006-01-02 15:04:05"
 
+		txMockFunc = func(ctx context.Context, f func(ctx context.Context) error) error {
+			return f(ctx)
+		}
+
 		correctReq = req{
 			method: fiber.MethodPost,
 			route:  "/v1/things",
@@ -71,6 +74,7 @@ func TestAddThingHandler(t *testing.T) {
 		req                req
 		resCode            int
 		resBody            interface{}
+		tmMock             func(mc *minimock.Controller) TransactionManager
 		thingRepoMock      func(mc *minimock.Controller) ThingRepository
 		placeThingRepoMock func(mc *minimock.Controller) PlaceThingRepository
 	}{
@@ -79,19 +83,20 @@ func TestAddThingHandler(t *testing.T) {
 			req:     correctReq,
 			resCode: fiber.StatusOK,
 			resBody: expectedRes,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest) {
 					assert.Equal(mc, title, req.Title)
 					assert.Equal(mc, description, req.Description)
 				}).Return(thingID, nil)
 
-				mock.CommitTxMock.Return(nil)
-
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(&repoRes, nil)
 
@@ -100,7 +105,7 @@ func TestAddThingHandler(t *testing.T) {
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest) {
 					assert.Equal(mc, thingID, req.ThingID)
 					assert.Equal(mc, placeID, req.PlaceID)
 				}).Return(nil)
@@ -115,6 +120,9 @@ func TestAddThingHandler(t *testing.T) {
 				route:  "/v1/things",
 			},
 			resCode: fiber.StatusBadRequest,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				return mocks.NewThingRepositoryMock(mc)
 			},
@@ -140,6 +148,9 @@ func TestAddThingHandler(t *testing.T) {
 					Tag:   "required",
 				},
 			},
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				return mocks.NewThingRepositoryMock(mc)
 			},
@@ -165,6 +176,9 @@ func TestAddThingHandler(t *testing.T) {
 					Tag:   "required",
 				},
 			},
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				return mocks.NewThingRepositoryMock(mc)
 			},
@@ -173,28 +187,18 @@ func TestAddThingHandler(t *testing.T) {
 			},
 		},
 		{
-			name:    "negative case - repository error (begin tx)",
+			name:    "negative case - repository error (add thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
-			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
-				mock := mocks.NewThingRepositoryMock(mc)
-				mock.BeginTxMock.Return(nil, testError)
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
 				return mock
 			},
-			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
-				return mocks.NewPlaceThingRepositoryMock(mc)
-			},
-		},
-		{
-			name:    "negative case - repository error (add thing)",
-			req:     correctReq,
-			resCode: fiber.StatusInternalServerError,
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest) {
 					assert.Equal(mc, title, req.Title)
 					assert.Equal(mc, description, req.Description)
 				}).Return(0, testError)
@@ -209,54 +213,28 @@ func TestAddThingHandler(t *testing.T) {
 			name:    "negative case - repository error (add place thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
-			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
-				mock := mocks.NewThingRepositoryMock(mc)
-
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest, tx *sql.Tx) {
-					assert.Equal(mc, title, req.Title)
-					assert.Equal(mc, description, req.Description)
-				}).Return(thingID, nil)
-
-				return mock
-			},
-			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
-				mock := mocks.NewPlaceThingRepositoryMock(mc)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest, tx *sql.Tx) {
-					assert.Equal(mc, thingID, req.ThingID)
-					assert.Equal(mc, placeID, req.PlaceID)
-				}).Return(testError)
-
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
 				return mock
 			},
-		},
-		{
-			name:    "negative case - repository error (commit tx)",
-			req:     correctReq,
-			resCode: fiber.StatusInternalServerError,
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest) {
 					assert.Equal(mc, title, req.Title)
 					assert.Equal(mc, description, req.Description)
 				}).Return(thingID, nil)
 
-				mock.CommitTxMock.Return(testError)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest) {
 					assert.Equal(mc, thingID, req.ThingID)
 					assert.Equal(mc, placeID, req.PlaceID)
-				}).Return(nil)
+				}).Return(testError)
 
 				return mock
 			},
@@ -265,19 +243,20 @@ func TestAddThingHandler(t *testing.T) {
 			name:    "negative case - repository error (get thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddThingRequest) {
 					assert.Equal(mc, title, req.Title)
 					assert.Equal(mc, description, req.Description)
 				}).Return(thingID, nil)
 
-				mock.CommitTxMock.Return(nil)
-
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, sql.ErrNoRows)
 
@@ -286,7 +265,7 @@ func TestAddThingHandler(t *testing.T) {
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest, tx *sql.Tx) {
+				mock.AddMock.Inspect(func(ctx context.Context, req models.AddPlaceThingRequest) {
 					assert.Equal(mc, thingID, req.ThingID)
 					assert.Equal(mc, placeID, req.PlaceID)
 				}).Return(nil)
@@ -302,15 +281,19 @@ func TestAddThingHandler(t *testing.T) {
 
 			mc := minimock.NewController(t)
 			fiberApp := fiber.New()
-			fiberApp.Post("/v1/things", AddThingHandler(tt.thingRepoMock(mc), tt.placeThingRepoMock(mc)))
+			fiberApp.Post("/v1/things", AddThingHandler(
+				tt.tmMock(mc),
+				tt.thingRepoMock(mc),
+				tt.placeThingRepoMock(mc),
+			))
 
-			fiberReq := httptest.NewRequest(tt.req.method, tt.req.route, helpers.ConvertDataToIOReader(tt.req.body))
+			fiberReq := httptest.NewRequest(tt.req.method, tt.req.route, test.ConvertDataToIOReader(tt.req.body))
 			fiberReq.Header.Add(fiber.HeaderContentType, tt.req.contentType)
-			fiberRes, _ := fiberApp.Test(fiberReq, API.DefaultTestTimeOut)
+			fiberRes, _ := fiberApp.Test(fiberReq, test.TestTimeout)
 
 			assert.Equal(t, tt.resCode, fiberRes.StatusCode)
 			if tt.resBody != nil {
-				assert.Equal(t, helpers.MarshalResponse(tt.resBody), helpers.ConvertBodyToString(fiberRes.Body))
+				assert.Equal(t, test.MarshalResponse(tt.resBody), test.ConvertBodyToString(fiberRes.Body))
 			}
 		})
 	}

+ 105 - 164
internal/api/v1/thing/delete_thing_test.go

@@ -12,10 +12,9 @@ import (
 	"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/thing/mocks"
 	"git.dmitriygnatenko.ru/dima/homethings/internal/dto"
-	"git.dmitriygnatenko.ru/dima/homethings/internal/helpers"
+	"git.dmitriygnatenko.ru/dima/homethings/internal/helpers/test"
 	"git.dmitriygnatenko.ru/dima/homethings/internal/models"
 )
 
@@ -28,14 +27,18 @@ func TestDeleteThingHandler(t *testing.T) {
 	}
 
 	var (
-		thingID   = gofakeit.Number(1, 1000)
-		imageID   = gofakeit.Number(1, 1000)
+		thingID   = uint64(gofakeit.Number(1, 1000))
+		imageID   = uint64(gofakeit.Number(1, 1000))
 		imageURL  = gofakeit.URL()
 		testError = gofakeit.Error()
 
+		txMockFunc = func(ctx context.Context, f func(ctx context.Context) error) error {
+			return f(ctx)
+		}
+
 		correctReq = req{
 			method: fiber.MethodDelete,
-			route:  "/v1/things/" + strconv.Itoa(thingID),
+			route:  "/v1/things/" + strconv.FormatUint(thingID, 10),
 		}
 
 		repoImagesRes = []models.Image{
@@ -51,6 +54,7 @@ func TestDeleteThingHandler(t *testing.T) {
 		req                       req
 		resCode                   int
 		resBody                   interface{}
+		tmMock                    func(mc *minimock.Controller) TransactionManager
 		thingRepoMock             func(mc *minimock.Controller) ThingRepository
 		placeThingRepoMock        func(mc *minimock.Controller) PlaceThingRepository
 		thingImageRepoMock        func(mc *minimock.Controller) ThingImageRepository
@@ -65,6 +69,9 @@ func TestDeleteThingHandler(t *testing.T) {
 				route:  "/v1/things/" + gofakeit.Word(),
 			},
 			resCode: fiber.StatusBadRequest,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				return mocks.NewThingRepositoryMock(mc)
 			},
@@ -88,10 +95,13 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - bad request (thing not found)",
 			req:     correctReq,
 			resCode: fiber.StatusBadRequest,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, sql.ErrNoRows)
 
@@ -117,10 +127,13 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (get thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				return mocks.NewTransactionManagerMock(mc)
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, testError)
 
@@ -143,55 +156,27 @@ func TestDeleteThingHandler(t *testing.T) {
 			},
 		},
 		{
-			name:    "negative case - repository error (begin tx)",
+			name:    "negative case - repository error (delete place thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
-			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
-				mock := mocks.NewThingRepositoryMock(mc)
-
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
-					assert.Equal(mc, thingID, id)
-				}).Return(nil, nil)
-
-				mock.BeginTxMock.Return(nil, testError)
-
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
 				return mock
 			},
-			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
-				return mocks.NewPlaceThingRepositoryMock(mc)
-			},
-			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
-				return mocks.NewThingImageRepositoryMock(mc)
-			},
-			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
-				return mocks.NewThingTagRepositoryMock(mc)
-			},
-			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
-				return mocks.NewThingNotificationRepositoryMock(mc)
-			},
-			fileRepoMock: func(mc *minimock.Controller) FileRepository {
-				return mocks.NewFileRepositoryMock(mc)
-			},
-		},
-		{
-			name:    "negative case - repository error (delete place thing)",
-			req:     correctReq,
-			resCode: fiber.StatusInternalServerError,
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(testError)
 
@@ -214,21 +199,24 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (get images)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -237,7 +225,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, testError)
 
@@ -257,21 +245,24 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (delete images)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -280,11 +271,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(testError)
 
@@ -304,21 +295,24 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (delete thing tags)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -327,11 +321,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(nil)
 
@@ -340,7 +334,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
 				mock := mocks.NewThingTagRepositoryMock(mc)
 
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(testError)
 
@@ -357,21 +351,24 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (delete notification)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -380,11 +377,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(nil)
 
@@ -393,7 +390,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
 				mock := mocks.NewThingTagRepositoryMock(mc)
 
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -402,7 +399,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
 				mock := mocks.NewThingNotificationRepositoryMock(mc)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(testError)
 
@@ -416,90 +413,28 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - repository error (delete thing)",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
-			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
-				mock := mocks.NewThingRepositoryMock(mc)
-
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
-					assert.Equal(mc, thingID, id)
-				}).Return(nil, nil)
-
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
-					assert.Equal(mc, thingID, id)
-				}).Return(testError)
-
-				return mock
-			},
-			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
-				mock := mocks.NewPlaceThingRepositoryMock(mc)
-
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
-					assert.Equal(mc, thingID, id)
-				}).Return(nil)
-
-				return mock
-			},
-			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
-				mock := mocks.NewThingImageRepositoryMock(mc)
-
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
-					assert.Equal(mc, thingID, id)
-				}).Return(repoImagesRes, nil)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
-					assert.Equal(mc, imageID, id)
-				}).Return(nil)
-
-				return mock
-			},
-			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
-				mock := mocks.NewThingTagRepositoryMock(mc)
-
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
-					assert.Equal(mc, thingID, id)
-				}).Return(nil)
-
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
 				return mock
 			},
-			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
-				mock := mocks.NewThingNotificationRepositoryMock(mc)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
-					assert.Equal(mc, thingID, id)
-				}).Return(nil)
-
-				return mock
-			},
-			fileRepoMock: func(mc *minimock.Controller) FileRepository {
-				return mocks.NewFileRepositoryMock(mc)
-			},
-		},
-		{
-			name:    "negative case - repository error (commit tx)",
-			req:     correctReq,
-			resCode: fiber.StatusInternalServerError,
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
-				}).Return(nil)
-
-				mock.CommitTxMock.Return(testError)
+				}).Return(testError)
 
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -508,11 +443,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(nil)
 
@@ -521,7 +456,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
 				mock := mocks.NewThingTagRepositoryMock(mc)
 
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -530,7 +465,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
 				mock := mocks.NewThingNotificationRepositoryMock(mc)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -544,27 +479,28 @@ func TestDeleteThingHandler(t *testing.T) {
 			name:    "negative case - file delete error",
 			req:     correctReq,
 			resCode: fiber.StatusInternalServerError,
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
-				mock.CommitTxMock.Return(nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -573,11 +509,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(nil)
 
@@ -586,7 +522,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
 				mock := mocks.NewThingTagRepositoryMock(mc)
 
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -595,7 +531,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
 				mock := mocks.NewThingNotificationRepositoryMock(mc)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -612,27 +548,28 @@ func TestDeleteThingHandler(t *testing.T) {
 			req:     correctReq,
 			resCode: fiber.StatusOK,
 			resBody: dto.EmptyResponse{},
+			tmMock: func(mc *minimock.Controller) TransactionManager {
+				mock := mocks.NewTransactionManagerMock(mc)
+				mock.ReadCommittedMock.Set(txMockFunc)
+				return mock
+			},
 			thingRepoMock: func(mc *minimock.Controller) ThingRepository {
 				mock := mocks.NewThingRepositoryMock(mc)
 
-				mock.GetMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil, nil)
 
-				mock.BeginTxMock.Return(nil, nil)
-
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
-				mock.CommitTxMock.Return(nil)
-
 				return mock
 			},
 			placeThingRepoMock: func(mc *minimock.Controller) PlaceThingRepository {
 				mock := mocks.NewPlaceThingRepositoryMock(mc)
 
-				mock.DeleteThingMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteThingMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -641,11 +578,11 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingImageRepoMock: func(mc *minimock.Controller) ThingImageRepository {
 				mock := mocks.NewThingImageRepositoryMock(mc)
 
-				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id int) {
+				mock.GetByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(repoImagesRes, nil)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, imageID, id)
 				}).Return(nil)
 
@@ -654,7 +591,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingTagRepoMock: func(mc *minimock.Controller) ThingTagRepository {
 				mock := mocks.NewThingTagRepositoryMock(mc)
 
-				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteByThingIDMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -663,7 +600,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			thingNotificationRepoMock: func(mc *minimock.Controller) ThingNotificationRepository {
 				mock := mocks.NewThingNotificationRepositoryMock(mc)
 
-				mock.DeleteMock.Inspect(func(ctx context.Context, id int, tx *sql.Tx) {
+				mock.DeleteMock.Inspect(func(ctx context.Context, id uint64) {
 					assert.Equal(mc, thingID, id)
 				}).Return(nil)
 
@@ -685,6 +622,7 @@ func TestDeleteThingHandler(t *testing.T) {
 			fiberApp := fiber.New()
 
 			fiberApp.Delete("/v1/things/:thingId", DeleteThingHandler(
+				tt.tmMock(mc),
 				tt.thingRepoMock(mc),
 				tt.thingTagRepoMock(mc),
 				tt.placeThingRepoMock(mc),
@@ -693,10 +631,13 @@ func TestDeleteThingHandler(t *testing.T) {
 				tt.fileRepoMock(mc),
 			))
 
-			fiberRes, _ := fiberApp.Test(httptest.NewRequest(tt.req.method, tt.req.route, nil), API.DefaultTestTimeOut)
+			fiberRes, _ := fiberApp.Test(
+				httptest.NewRequest(tt.req.method, tt.req.route, nil),
+				test.TestTimeout,
+			)
 			assert.Equal(t, tt.resCode, fiberRes.StatusCode)
 			if tt.resBody != nil {
-				assert.Equal(t, helpers.MarshalResponse(tt.resBody), helpers.ConvertBodyToString(fiberRes.Body))
+				assert.Equal(t, test.MarshalResponse(tt.resBody), test.ConvertBodyToString(fiberRes.Body))
 			}
 		})
 	}

+ 6 - 0
internal/fiber/fiber.go

@@ -215,6 +215,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Delete(
 		"/v1/places/:placeId<int>",
 		placeAPI.DeletePlaceHandler(
+			sp.TransactionManager(),
 			sp.PlaceRepository(),
 			sp.ThingRepository(),
 			sp.PlaceImageRepository(),
@@ -247,6 +248,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Post(
 		"/v1/things",
 		thingAPI.AddThingHandler(
+			sp.TransactionManager(),
 			sp.ThingRepository(),
 			sp.PlaceThingRepository(),
 		),
@@ -255,6 +257,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Put(
 		"/v1/things/:thingId<int>",
 		thingAPI.UpdateThingHandler(
+			sp.TransactionManager(),
 			sp.ThingRepository(),
 			sp.PlaceThingRepository(),
 		),
@@ -263,6 +266,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Delete(
 		"/v1/things/:thingId<int>",
 		thingAPI.DeleteThingHandler(
+			sp.TransactionManager(),
 			sp.ThingRepository(),
 			sp.ThingTagRepository(),
 			sp.PlaceThingRepository(),
@@ -359,6 +363,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Delete(
 		"/v1/tags/:tagId<int>",
 		tagAPI.DeleteTagHandler(
+			sp.TransactionManager(),
 			sp.TagRepository(),
 			sp.ThingTagRepository(),
 		),
@@ -397,6 +402,7 @@ func registerHandlers(r fiber.Router, sp ServiceProvider) {
 	r.Delete(
 		"/v1/tags/:id<int>",
 		tagAPI.DeleteTagHandler(
+			sp.TransactionManager(),
 			sp.TagRepository(),
 			sp.ThingTagRepository(),
 		),