package examples import ( "context" "database/sql" "testing" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "erp-mvp/core-service/internal/models" "erp-mvp/core-service/internal/repository" ) // TestOrganizationRepository_Create тестирует создание организации func TestOrganizationRepository_Create(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewOrganizationRepository(db) orgID := uuid.New() org := &models.Organization{ ID: orgID, Name: "Test Organization", Type: "workshop", Settings: models.JSON{ "created_at": 1234567890, }, CreatedAt: time.Now(), } // Ожидаем SQL запрос mock.ExpectExec("INSERT INTO organizations"). WithArgs(orgID, org.Name, org.Type, sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) // Act err = repo.Create(context.Background(), org) // Assert assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } // TestOrganizationRepository_GetByID тестирует получение организации по ID func TestOrganizationRepository_GetByID(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewOrganizationRepository(db) orgID := uuid.New() expectedOrg := &models.Organization{ ID: orgID, Name: "Test Organization", Type: "workshop", Settings: models.JSON{ "created_at": 1234567890, }, } // Ожидаем SQL запрос rows := sqlmock.NewRows([]string{"id", "name", "type", "settings", "created_at"}). AddRow(orgID, expectedOrg.Name, expectedOrg.Type, `{"created_at":1234567890}`, time.Now()) mock.ExpectQuery("SELECT (.+) FROM organizations"). WithArgs(orgID). WillReturnRows(rows) // Act org, err := repo.GetByID(context.Background(), orgID) // Assert assert.NoError(t, err) assert.NotNil(t, org) assert.Equal(t, expectedOrg.ID, org.ID) assert.Equal(t, expectedOrg.Name, org.Name) assert.Equal(t, expectedOrg.Type, org.Type) assert.NoError(t, mock.ExpectationsWereMet()) } // TestOrganizationRepository_GetByID_NotFound тестирует случай, когда организация не найдена func TestOrganizationRepository_GetByID_NotFound(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewOrganizationRepository(db) orgID := uuid.New() // Ожидаем SQL запрос с пустым результатом mock.ExpectQuery("SELECT (.+) FROM organizations"). WithArgs(orgID). WillReturnError(sql.ErrNoRows) // Act org, err := repo.GetByID(context.Background(), orgID) // Assert assert.Error(t, err) assert.Nil(t, org) assert.Equal(t, "organization not found", err.Error()) assert.NoError(t, mock.ExpectationsWereMet()) } // TestUserRepository_Create тестирует создание пользователя func TestUserRepository_Create(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewUserRepository(db) userID := uuid.New() orgID := uuid.New() user := &models.User{ ID: userID, OrganizationID: orgID, Email: "test@example.com", PasswordHash: "hashed_password", Role: "admin", CreatedAt: time.Now(), } password := "hashed_password" // Ожидаем SQL запрос mock.ExpectExec("INSERT INTO users"). WithArgs(userID, orgID, user.Email, password, user.Role, sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) // Act err = repo.Create(context.Background(), user, password) // Assert assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } // TestUserRepository_GetByEmail тестирует получение пользователя по email func TestUserRepository_GetByEmail(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewUserRepository(db) userID := uuid.New() orgID := uuid.New() email := "test@example.com" expectedUser := &models.User{ ID: userID, OrganizationID: orgID, Email: email, PasswordHash: "hashed_password", Role: "admin", } // Ожидаем SQL запрос rows := sqlmock.NewRows([]string{"id", "organization_id", "email", "password_hash", "role", "created_at"}). AddRow(userID, orgID, email, "hashed_password", "admin", time.Now()) mock.ExpectQuery("SELECT (.+) FROM users"). WithArgs(email). WillReturnRows(rows) // Act user, err := repo.GetByEmail(context.Background(), email) // Assert assert.NoError(t, err) assert.NotNil(t, user) assert.Equal(t, expectedUser.ID, user.ID) assert.Equal(t, expectedUser.Email, user.Email) assert.Equal(t, expectedUser.Role, user.Role) assert.NoError(t, mock.ExpectationsWereMet()) } // TestLocationRepository_Create тестирует создание места хранения func TestLocationRepository_Create(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewLocationRepository(db) locationID := uuid.New() orgID := uuid.New() location := &models.StorageLocation{ ID: locationID, OrganizationID: orgID, Name: "Test Location", Address: "Test Address", Type: "warehouse", Coordinates: models.JSON{ "lat": 55.7558, "lng": 37.6176, }, CreatedAt: time.Now(), } // Ожидаем SQL запрос mock.ExpectExec("INSERT INTO storage_locations"). WithArgs(locationID, orgID, sqlmock.AnyArg(), location.Name, location.Address, location.Type, sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) // Act err = repo.Create(context.Background(), location) // Assert assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } // TestLocationRepository_GetByID тестирует получение места хранения по ID func TestLocationRepository_GetByID(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewLocationRepository(db) locationID := uuid.New() orgID := uuid.New() expectedLocation := &models.StorageLocation{ ID: locationID, OrganizationID: orgID, Name: "Test Location", Address: "Test Address", Type: "warehouse", Coordinates: models.JSON{ "lat": 55.7558, "lng": 37.6176, }, } // Ожидаем SQL запрос rows := sqlmock.NewRows([]string{"id", "organization_id", "parent_id", "name", "address", "type", "coordinates", "created_at"}). AddRow(locationID, orgID, nil, expectedLocation.Name, expectedLocation.Address, expectedLocation.Type, `{"lat":55.7558,"lng":37.6176}`, time.Now()) mock.ExpectQuery("SELECT (.+) FROM storage_locations"). WithArgs(locationID, orgID). WillReturnRows(rows) // Act location, err := repo.GetByID(context.Background(), locationID, orgID) // Assert assert.NoError(t, err) assert.NotNil(t, location) assert.Equal(t, expectedLocation.ID, location.ID) assert.Equal(t, expectedLocation.Name, location.Name) assert.Equal(t, expectedLocation.Type, location.Type) assert.NoError(t, mock.ExpectationsWereMet()) } // TestItemRepository_Create тестирует создание товара func TestItemRepository_Create(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewItemRepository(db) itemID := uuid.New() orgID := uuid.New() item := &models.Item{ ID: itemID, OrganizationID: orgID, Name: "Test Item", Description: "Test Description", Category: "Test Category", CreatedAt: time.Now(), } // Ожидаем SQL запрос mock.ExpectExec("INSERT INTO items"). WithArgs(itemID, orgID, item.Name, item.Description, item.Category, sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) // Act err = repo.Create(context.Background(), item) // Assert assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } // TestOperationsRepository_PlaceItem тестирует размещение товара func TestOperationsRepository_PlaceItem(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewOperationsRepository(db) placementID := uuid.New() orgID := uuid.New() itemID := uuid.New() locationID := uuid.New() placement := &models.ItemPlacement{ ID: placementID, OrganizationID: orgID, ItemID: itemID, LocationID: locationID, Quantity: 5, CreatedAt: time.Now(), } // Ожидаем SQL запрос mock.ExpectExec("INSERT INTO item_placements"). WithArgs(placementID, orgID, itemID, locationID, placement.Quantity, sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) // Act err = repo.PlaceItem(context.Background(), placement) // Assert assert.NoError(t, err) assert.NoError(t, mock.ExpectationsWereMet()) } // TestOperationsRepository_Search тестирует поиск товаров с местами размещения func TestOperationsRepository_Search(t *testing.T) { // Arrange db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() repo := repository.NewOperationsRepository(db) orgID := uuid.New() itemID := uuid.New() locationID := uuid.New() // Ожидаем SQL запрос с JOIN rows := sqlmock.NewRows([]string{ "i.id", "i.organization_id", "i.name", "i.description", "i.category", "i.created_at", "sl.id", "sl.organization_id", "sl.parent_id", "sl.name", "sl.address", "sl.type", "sl.coordinates", "sl.created_at", "ip.quantity", }).AddRow( itemID, orgID, "Test Item", "Test Description", "Test Category", time.Now(), locationID, orgID, nil, "Test Location", "Test Address", "warehouse", `{"lat":55.7558,"lng":37.6176}`, time.Now(), 5, ) mock.ExpectQuery("SELECT (.+) FROM items i"). WithArgs(orgID, "%test%"). WillReturnRows(rows) // Act results, err := repo.Search(context.Background(), orgID, "test", "", "") // Assert assert.NoError(t, err) assert.NotNil(t, results) assert.Len(t, results, 1) assert.NoError(t, mock.ExpectationsWereMet()) }