mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 21:41:55 +00:00
392 lines
12 KiB
Go
392 lines
12 KiB
Go
package test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/glebarez/sqlite"
|
|
"github.com/gofiber/fiber/v2"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
|
|
"gitlab.com/mbugroup/lti-api.git/internal/entities"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/route"
|
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
|
)
|
|
|
|
func setupIntegrationApp(t *testing.T) (*fiber.App, *gorm.DB) {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
dsn := filepath.Join(dir, "integration.db")
|
|
|
|
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
|
|
if err != nil {
|
|
t.Fatalf("failed to open sqlite database: %v", err)
|
|
}
|
|
|
|
if err := db.Exec("PRAGMA foreign_keys = ON").Error; err != nil {
|
|
t.Fatalf("failed to enable foreign keys: %v", err)
|
|
}
|
|
|
|
if err := db.AutoMigrate(
|
|
&entities.User{},
|
|
&entities.Area{},
|
|
&entities.Location{},
|
|
&entities.Flock{},
|
|
&entities.ProjectFlock{},
|
|
&entities.Kandang{},
|
|
&entities.Warehouse{},
|
|
&entities.Uom{},
|
|
&entities.Customer{},
|
|
&entities.Supplier{},
|
|
&entities.Flag{},
|
|
&entities.ProductCategory{},
|
|
&entities.Nonstock{},
|
|
&entities.NonstockSupplier{},
|
|
&entities.Product{},
|
|
&entities.ProductSupplier{},
|
|
&entities.Fcr{},
|
|
&entities.FcrStandard{},
|
|
&entities.Bank{},
|
|
); err != nil {
|
|
t.Fatalf("auto migrate failed: %v", err)
|
|
}
|
|
|
|
seedUser := entities.User{
|
|
Id: 1,
|
|
IdUser: 1001,
|
|
Email: "tester@example.com",
|
|
Name: "Tester",
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
if err := db.Create(&seedUser).Error; err != nil {
|
|
t.Fatalf("failed to seed user: %v", err)
|
|
}
|
|
|
|
app := fiber.New(fiber.Config{ErrorHandler: utils.ErrorHandler})
|
|
route.Routes(app, db)
|
|
return app, db
|
|
}
|
|
|
|
func doJSONRequest(t *testing.T, app *fiber.App, method, path string, payload any) (*http.Response, []byte) {
|
|
t.Helper()
|
|
|
|
var body io.Reader
|
|
if payload != nil {
|
|
buf := &bytes.Buffer{}
|
|
if err := json.NewEncoder(buf).Encode(payload); err != nil {
|
|
t.Fatalf("failed to encode payload: %v", err)
|
|
}
|
|
body = buf
|
|
}
|
|
|
|
req := httptest.NewRequest(method, path, body)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
resp, err := app.Test(req, -1)
|
|
if err != nil {
|
|
t.Fatalf("request failed: %v", err)
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
t.Fatalf("failed to read response body: %v", err)
|
|
}
|
|
return resp, data
|
|
}
|
|
|
|
func parseID(t *testing.T, body []byte) uint {
|
|
t.Helper()
|
|
var resp struct {
|
|
Data struct {
|
|
Id uint `json:"id"`
|
|
} `json:"data"`
|
|
}
|
|
if err := json.Unmarshal(body, &resp); err != nil {
|
|
t.Fatalf("failed to parse response: %v", err)
|
|
}
|
|
return resp.Data.Id
|
|
}
|
|
|
|
func createArea(t *testing.T, app *fiber.App, name string) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/areas", map[string]any{"name": name})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating area, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createLocation(t *testing.T, app *fiber.App, name, address string, areaID uint) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/locations", map[string]any{
|
|
"name": name,
|
|
"address": address,
|
|
"area_id": areaID,
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating location, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createUom(t *testing.T, app *fiber.App, name string) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/uoms", map[string]any{"name": name})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating uom, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createKandang(t *testing.T, app *fiber.App, name string, locationID, picID uint) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{
|
|
"name": name,
|
|
"status": "ACTIVE",
|
|
"location_id": locationID,
|
|
"pic_id": picID,
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating kandang, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createCustomer(t *testing.T, app *fiber.App, name string, picID uint) uint {
|
|
t.Helper()
|
|
identifier := strings.ToLower(strings.ReplaceAll(name, " ", "_"))
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/customers", map[string]any{
|
|
"name": name,
|
|
"pic_id": picID,
|
|
"type": utils.CustomerSupplierTypeBisnis,
|
|
"address": "Customer address",
|
|
"phone": "081234567890",
|
|
"email": fmt.Sprintf("%s@example.com", identifier),
|
|
"account_number": fmt.Sprintf("ACC-%s", identifier),
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating customer, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchCustomer(t *testing.T, db *gorm.DB, id uint) entities.Customer {
|
|
t.Helper()
|
|
var customer entities.Customer
|
|
if err := db.Preload("Pic").Preload("CreatedUser").First(&customer, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch customer: %v", err)
|
|
}
|
|
return customer
|
|
}
|
|
|
|
func createSupplier(t *testing.T, app *fiber.App, name, alias, category string) uint {
|
|
t.Helper()
|
|
identifier := strings.ToLower(strings.ReplaceAll(name, " ", "_"))
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{
|
|
"name": name,
|
|
"alias": alias,
|
|
"pic": "John Doe",
|
|
"type": utils.CustomerSupplierTypeBisnis,
|
|
"category": category,
|
|
"hatchery": "Hatchery A",
|
|
"phone": "081234567890",
|
|
"email": fmt.Sprintf("%s@supplier.com", identifier),
|
|
"address": "Supplier address",
|
|
"npwp": "NPWP-123",
|
|
"account_number": "ACC-SUPPLIER",
|
|
"due_date": 30,
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating supplier, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createProductCategory(t *testing.T, app *fiber.App, name, code string) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/product-categories", map[string]any{
|
|
"name": name,
|
|
"code": code,
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating product category, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchProductCategory(t *testing.T, db *gorm.DB, id uint) entities.ProductCategory {
|
|
t.Helper()
|
|
var pc entities.ProductCategory
|
|
if err := db.Preload("CreatedUser").First(&pc, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch product category: %v", err)
|
|
}
|
|
return pc
|
|
}
|
|
|
|
func createProduct(t *testing.T, app *fiber.App, name, brand string, sku *string, uomID, categoryID uint, productPrice float64, supplierIDs []uint, flags []string) uint {
|
|
t.Helper()
|
|
payload := map[string]any{
|
|
"name": name,
|
|
"brand": brand,
|
|
"uom_id": uomID,
|
|
"product_category_id": categoryID,
|
|
"product_price": productPrice,
|
|
"supplier_ids": supplierIDs,
|
|
}
|
|
if sku != nil {
|
|
payload["sku"] = *sku
|
|
}
|
|
if len(flags) > 0 {
|
|
payload["flags"] = flags
|
|
}
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", payload)
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating product, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchProduct(t *testing.T, db *gorm.DB, id uint) entities.Product {
|
|
t.Helper()
|
|
var product entities.Product
|
|
if err := db.Preload("CreatedUser").
|
|
Preload("Uom").
|
|
Preload("ProductCategory").
|
|
Preload("Suppliers", func(tx *gorm.DB) *gorm.DB { return tx.Order("suppliers.name ASC") }).
|
|
Preload("Flags", func(tx *gorm.DB) *gorm.DB { return tx.Order("flags.name ASC") }).
|
|
First(&product, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch product: %v", err)
|
|
}
|
|
return product
|
|
}
|
|
|
|
func fetchSupplier(t *testing.T, db *gorm.DB, id uint) entities.Supplier {
|
|
t.Helper()
|
|
var supplier entities.Supplier
|
|
if err := db.Preload("CreatedUser").First(&supplier, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch supplier: %v", err)
|
|
}
|
|
return supplier
|
|
}
|
|
|
|
func createFcr(t *testing.T, app *fiber.App, name string, standards []map[string]any) uint {
|
|
t.Helper()
|
|
payload := map[string]any{
|
|
"name": name,
|
|
"fcr_standards": standards,
|
|
}
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/fcrs", payload)
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating fcr, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func createFlock(t *testing.T, app *fiber.App, name string) uint {
|
|
t.Helper()
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/flocks", map[string]any{
|
|
"name": name,
|
|
})
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating flock, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchFcr(t *testing.T, db *gorm.DB, id uint) entities.Fcr {
|
|
t.Helper()
|
|
var fcr entities.Fcr
|
|
if err := db.Preload("CreatedUser").
|
|
Preload("Standards", func(tx *gorm.DB) *gorm.DB {
|
|
return tx.Order("weight ASC")
|
|
}).
|
|
First(&fcr, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch fcr: %v", err)
|
|
}
|
|
return fcr
|
|
}
|
|
|
|
func createNonstock(t *testing.T, app *fiber.App, name string, uomID uint, supplierIDs []uint, flags []string) uint {
|
|
t.Helper()
|
|
payload := map[string]any{
|
|
"name": name,
|
|
"uom_id": uomID,
|
|
"supplier_ids": supplierIDs,
|
|
}
|
|
if len(flags) > 0 {
|
|
payload["flags"] = flags
|
|
}
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", payload)
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating nonstock, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchNonstock(t *testing.T, db *gorm.DB, id uint) entities.Nonstock {
|
|
t.Helper()
|
|
var nonstock entities.Nonstock
|
|
if err := db.Preload("CreatedUser").
|
|
Preload("Uom").
|
|
Preload("Suppliers", func(tx *gorm.DB) *gorm.DB { return tx.Order("suppliers.name ASC") }).
|
|
Preload("Flags", func(tx *gorm.DB) *gorm.DB { return tx.Order("flags.name ASC") }).
|
|
First(&nonstock, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch nonstock: %v", err)
|
|
}
|
|
return nonstock
|
|
}
|
|
|
|
func fetchAreaName(t *testing.T, db *gorm.DB, id uint) string {
|
|
t.Helper()
|
|
var area entities.Area
|
|
if err := db.First(&area, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch area: %v", err)
|
|
}
|
|
return area.Name
|
|
}
|
|
|
|
func fetchWarehouse(t *testing.T, db *gorm.DB, id uint) entities.Warehouse {
|
|
t.Helper()
|
|
var wh entities.Warehouse
|
|
if err := db.First(&wh, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch warehouse: %v", err)
|
|
}
|
|
return wh
|
|
}
|
|
|
|
func createBank(t *testing.T, app *fiber.App, name, alias, accountNumber string, owner any) uint {
|
|
t.Helper()
|
|
payload := map[string]any{
|
|
"name": name,
|
|
"alias": alias,
|
|
"account_number": accountNumber,
|
|
"owner": owner,
|
|
}
|
|
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/banks", payload)
|
|
if resp.StatusCode != fiber.StatusCreated {
|
|
t.Fatalf("expected 201 when creating bank, got %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
return parseID(t, body)
|
|
}
|
|
|
|
func fetchBank(t *testing.T, db *gorm.DB, id uint) entities.Bank {
|
|
t.Helper()
|
|
var bank entities.Bank
|
|
if err := db.Preload("CreatedUser").First(&bank, id).Error; err != nil {
|
|
t.Fatalf("failed to fetch bank: %v", err)
|
|
}
|
|
return bank
|
|
}
|