This commit is contained in:
+3
-1
@@ -12,9 +12,11 @@ require (
|
|||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
|
github.com/stretchr/testify v1.12.1
|
||||||
golang.org/x/crypto v0.57.0
|
golang.org/x/crypto v0.57.0
|
||||||
golang.org/x/time v0.16.0
|
golang.org/x/time v0.16.0
|
||||||
gorm.io/driver/postgres v1.6.3
|
gorm.io/driver/postgres v1.6.3
|
||||||
|
gorm.io/driver/sqlite v1.6.0
|
||||||
gorm.io/gorm v1.31.2
|
gorm.io/gorm v1.31.2
|
||||||
resty.dev/v3 v3.0.0-rc.4
|
resty.dev/v3 v3.0.0-rc.4
|
||||||
)
|
)
|
||||||
@@ -48,6 +50,7 @@ require (
|
|||||||
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
|
||||||
github.com/leodido/go-urn v1.5.0 // indirect
|
github.com/leodido/go-urn v1.5.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.24 // indirect
|
github.com/mattn/go-isatty v0.0.24 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
||||||
@@ -57,7 +60,6 @@ require (
|
|||||||
github.com/spf13/afero v1.15.0 // indirect
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
github.com/spf13/cast v1.10.0 // indirect
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
github.com/stretchr/testify v1.12.1 // indirect
|
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.3.2 // indirect
|
github.com/ugorji/go/codec v1.3.2 // indirect
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type SportHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (handler *SportHandler) List(c *gin.Context) {
|
func (handler *SportHandler) List(c *gin.Context) {
|
||||||
sports, err := handler.Service.List(c.Request.Context())
|
sports, _, err := handler.Service.List(c.Request.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -3,9 +3,23 @@ package internal
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"kontor-api-gin/internal/test/testutils"
|
"kontor-api-gin/internal/tests"
|
||||||
|
"kontor-api-gin/internal/tests/testutils"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TestDB *gorm.DB
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
testutils.InitializeTestSuite(m)
|
testutils.InitializeTestSuite(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepos(t *testing.T) {
|
||||||
|
suite.Run(t, new(tests.RepositoryTestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServices(t *testing.T) {
|
||||||
|
suite.Run(t, new(tests.ServiceTestSuite))
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,13 +17,21 @@ func NewSportRepository(db *gorm.DB) *SportRepository {
|
|||||||
return repo
|
return repo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository *SportRepository) FindAll(context context.Context) ([]models.Sport, error) {
|
func (repository *SportRepository) FindAll(page int, limit int, context context.Context) (sports []models.Sport, total int64, err error) {
|
||||||
var sports []models.Sport
|
offset := (page - 1) * limit
|
||||||
|
|
||||||
result := repository.db.Find(&sports)
|
err = repository.db.
|
||||||
slog.Info("SportRepository#FindAll", "count", result.RowsAffected)
|
Model(&models.Sport{}).
|
||||||
|
Count(&total).
|
||||||
return sports, nil
|
Limit(limit).
|
||||||
|
Offset(offset).
|
||||||
|
Order("id asc").
|
||||||
|
Find(&sports).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
slog.Info("SportRepository#FindAll", "total", total)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository *SportRepository) GetById(context context.Context, id string) (models.Sport, error) {
|
func (repository *SportRepository) GetById(context context.Context, id string) (models.Sport, error) {
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ func NewSportService(repo *repository.SportRepository) *SportService {
|
|||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *SportService) List(context context.Context) ([]models.Sport, error) {
|
func (service *SportService) List(context context.Context) ([]models.Sport, int64, error) {
|
||||||
slog.Info("SportService#List")
|
slog.Info("SportService#List")
|
||||||
return service.repository.FindAll(context)
|
return service.repository.FindAll(1, 10, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *SportService) Get(context context.Context, id string) (models.Sport, error) {
|
func (service *SportService) Get(context context.Context, id string) (models.Sport, error) {
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testDB *gorm.DB
|
||||||
|
|
||||||
|
type RepositoryTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *RepositoryTestSuite) TestSportFindAll() {
|
||||||
|
sportRepository := repository.NewSportRepository(testDB)
|
||||||
|
_, total, err := sportRepository.FindAll(1, 10, context.Background())
|
||||||
|
suite.Nil(err)
|
||||||
|
suite.Equal(int64(0), total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run right before the test starts
|
||||||
|
// and receives the suite and test names as input
|
||||||
|
func (suite *RepositoryTestSuite) BeforeTest(suiteName, testName string) {
|
||||||
|
slog.Info("RepositoryTestSuite#BeforeTest", "suiteName", suiteName, "testName", testName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run after test finishes
|
||||||
|
// and receives the suite and test names as input
|
||||||
|
func (suite *RepositoryTestSuite) AfterTest(suiteName, testName string) {
|
||||||
|
slog.Info("RepositoryTestSuite#AfterTest", "suiteName", suiteName, "testName", testName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run before before the tests in the suite are run
|
||||||
|
func (suite *RepositoryTestSuite) SetupSuite() {
|
||||||
|
slog.Info("RepositoryTestSuite#SetupSuite")
|
||||||
|
// Remove existing test db to ensure clean state
|
||||||
|
os.Remove("test.db")
|
||||||
|
|
||||||
|
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to connect test database")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-migrate models to ensure schema matches
|
||||||
|
db.AutoMigrate(&models.Sport{})
|
||||||
|
|
||||||
|
testDB = db
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run before before the tests in the suite are run
|
||||||
|
func (suite *RepositoryTestSuite) TearDownSuite() {
|
||||||
|
slog.Info("RepositoryTestSuite#TeardownSuite")
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run before each test in the suite
|
||||||
|
func (suite *RepositoryTestSuite) SetupTest() {
|
||||||
|
slog.Info("RepositoryTestSuite#SetupTest")
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testServiceDB *gorm.DB
|
||||||
|
|
||||||
|
type ServiceTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ServiceTestSuite) TestSportServiceList() {
|
||||||
|
sportService := service.NewSportService(repository.NewSportRepository(testServiceDB))
|
||||||
|
sports, total, err := sportService.List(context.Background())
|
||||||
|
suite.Nil(err)
|
||||||
|
suite.Equal(int64(0), total)
|
||||||
|
suite.Equal(0, len(sports))
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will run before before the tests in the suite are run
|
||||||
|
func (suite *ServiceTestSuite) SetupSuite() {
|
||||||
|
slog.Info("RepositoryTestSuite#SetupSuite")
|
||||||
|
// Remove existing test db to ensure clean state
|
||||||
|
os.Remove("test.db")
|
||||||
|
|
||||||
|
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to connect test database")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-migrate models to ensure schema matches
|
||||||
|
db.AutoMigrate(&models.Sport{})
|
||||||
|
|
||||||
|
testServiceDB = db
|
||||||
|
}
|
||||||
@@ -1,27 +1,29 @@
|
|||||||
package testutils
|
package testutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupTestDatabase() {
|
func SetupTestDatabase() {
|
||||||
|
slog.Info("SetupTestDatabase")
|
||||||
}
|
}
|
||||||
|
|
||||||
func PatchDatabase() {
|
func PatchDatabase() {
|
||||||
|
slog.Info("PatchDatabase")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TearDownTestDatabase() {
|
func TearDownTestDatabase() {
|
||||||
|
slog.Info("TearDownTestDatabase")
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnpatchDatabase() {
|
func UnpatchDatabase() {
|
||||||
|
slog.Info("UnpatchDatabase")
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitializeTestSuite(m *testing.M) {
|
func InitializeTestSuite(m *testing.M) {
|
||||||
|
slog.Info("InitializeTestSuite")
|
||||||
// Initialize the test database
|
// Initialize the test database
|
||||||
SetupTestDatabase()
|
SetupTestDatabase()
|
||||||
// Patch the global database.DB to use the TestDB
|
// Patch the global database.DB to use the TestDB
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package helpers
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"kontor-api-gin/internal/helpers"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ func TestMultiFormatTimeUnmarshal(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var m KontorTime
|
var m helpers.KontorTime
|
||||||
err := json.Unmarshal([]byte(tt.input), &m)
|
err := json.Unmarshal([]byte(tt.input), &m)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
Reference in New Issue
Block a user