Feat(BE-36,37,38,39): finish master data management api

This commit is contained in:
Hafizh A. Y
2025-10-03 21:04:21 +07:00
parent e8905be856
commit 2d49ffe4cd
103 changed files with 6974 additions and 117 deletions
@@ -0,0 +1,238 @@
package test
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"testing"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
"gitlab.com/mbugroup/lti-api.git/internal/entities"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
)
func TestSupplierIntegration(t *testing.T) {
app, db := setupIntegrationApp(t)
t.Run("creating supplier with invalid type fails", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{
"name": "Invalid Supplier",
"alias": "inv01",
"pic": "Jane Doe",
"type": "random-type",
"category": utils.SupplierCategoryBOP,
"hatchery": "Hatchery X",
"phone": "081234567891",
"email": "invalid@supplier.com",
"address": "Somewhere",
"npwp": "NPWP-INVALID",
"account_number": "ACC-INVALID",
"due_date": 30,
})
if resp.StatusCode != fiber.StatusBadRequest {
t.Fatalf("expected 400 when type is invalid, got %d: %s", resp.StatusCode, string(body))
}
})
t.Run("creating supplier with invalid category fails", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{
"name": "Invalid Category Supplier",
"alias": "cat01",
"pic": "Jane Doe",
"type": utils.CustomerSupplierTypeBisnis,
"category": "invalid",
"phone": "081234567892",
"email": "invalid-category@supplier.com",
"address": "Somewhere",
"due_date": 30,
})
if resp.StatusCode != fiber.StatusBadRequest {
t.Fatalf("expected 400 when category is invalid, got %d: %s", resp.StatusCode, string(body))
}
})
const supplierName = "Supplier Alpha"
const alias = "al001"
var supplierID uint
t.Run("creating supplier succeeds", func(t *testing.T) {
supplierID = createSupplier(t, app, supplierName, alias, string(utils.SupplierCategoryBOP))
supplier := fetchSupplier(t, db, supplierID)
if supplier.Name != supplierName {
t.Fatalf("expected name %q, got %q", supplierName, supplier.Name)
}
if supplier.Alias != strings.ToUpper(alias) {
t.Fatalf("expected alias %q, got %q", strings.ToUpper(alias), supplier.Alias)
}
if supplier.Type != string(utils.CustomerSupplierTypeBisnis) {
t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeBisnis, supplier.Type)
}
if supplier.Category != string(utils.SupplierCategoryBOP) {
t.Fatalf("expected category %q, got %q", utils.SupplierCategoryBOP, supplier.Category)
}
if supplier.DueDate != 30 {
t.Fatalf("expected due date 30, got %d", supplier.DueDate)
}
if supplier.CreatedUser.Id != 1 {
t.Fatalf("expected created user id 1, got %d", supplier.CreatedUser.Id)
}
})
t.Run("creating supplier with duplicate name fails", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{
"name": supplierName,
"alias": "dup01",
"pic": "Jane Doe",
"type": utils.CustomerSupplierTypeBisnis,
"category": utils.SupplierCategoryBOP,
"phone": "0811111111",
"email": "duplicate@supplier.com",
"address": "Duplicate address",
"due_date": 15,
})
if resp.StatusCode != fiber.StatusConflict {
t.Fatalf("expected 409 when creating duplicate supplier, got %d: %s", resp.StatusCode, string(body))
}
})
t.Run("getting existing supplier succeeds", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil)
if resp.StatusCode != fiber.StatusOK {
t.Fatalf("expected 200 when fetching supplier, got %d: %s", resp.StatusCode, string(body))
}
var payload struct {
Data struct {
Id uint `json:"id"`
Name string `json:"name"`
Alias string `json:"alias"`
Type string `json:"type"`
Category string `json:"category"`
CreatedUser *struct {
Id uint `json:"id"`
} `json:"created_user"`
} `json:"data"`
}
if err := json.Unmarshal(body, &payload); err != nil {
t.Fatalf("failed to parse supplier response: %v", err)
}
if payload.Data.Id != supplierID {
t.Fatalf("expected id %d, got %d", supplierID, payload.Data.Id)
}
if payload.Data.Name != supplierName {
t.Fatalf("expected name %q, got %q", supplierName, payload.Data.Name)
}
if payload.Data.Alias != strings.ToUpper(alias) {
t.Fatalf("expected alias %q, got %q", strings.ToUpper(alias), payload.Data.Alias)
}
if payload.Data.Type != string(utils.CustomerSupplierTypeBisnis) {
t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeBisnis, payload.Data.Type)
}
if payload.Data.Category != string(utils.SupplierCategoryBOP) {
t.Fatalf("expected category %q, got %q", utils.SupplierCategoryBOP, payload.Data.Category)
}
if payload.Data.CreatedUser == nil || payload.Data.CreatedUser.Id != 1 {
t.Fatalf("expected created_user id 1, got %+v", payload.Data.CreatedUser)
}
})
const updatedAlias = "beta1"
t.Run("updating supplier fields succeeds", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{
"alias": updatedAlias,
"type": utils.CustomerSupplierTypeIndividual,
"category": utils.SupplierCategorySapronak,
"due_date": 45,
})
if resp.StatusCode != fiber.StatusOK {
t.Fatalf("expected 200 when updating supplier, got %d: %s", resp.StatusCode, string(body))
}
var payload struct {
Data struct {
Alias string `json:"alias"`
Type string `json:"type"`
Category string `json:"category"`
} `json:"data"`
}
if err := json.Unmarshal(body, &payload); err != nil {
t.Fatalf("failed to parse update response: %v", err)
}
if payload.Data.Alias != strings.ToUpper(updatedAlias) {
t.Fatalf("expected alias %q, got %q", strings.ToUpper(updatedAlias), payload.Data.Alias)
}
if payload.Data.Type != string(utils.CustomerSupplierTypeIndividual) {
t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeIndividual, payload.Data.Type)
}
if payload.Data.Category != string(utils.SupplierCategorySapronak) {
t.Fatalf("expected category %q, got %q", utils.SupplierCategorySapronak, payload.Data.Category)
}
supplier := fetchSupplier(t, db, supplierID)
if supplier.Alias != strings.ToUpper(updatedAlias) {
t.Fatalf("expected persisted alias %q, got %q", strings.ToUpper(updatedAlias), supplier.Alias)
}
if supplier.Type != string(utils.CustomerSupplierTypeIndividual) {
t.Fatalf("expected persisted type %q, got %q", utils.CustomerSupplierTypeIndividual, supplier.Type)
}
if supplier.Category != string(utils.SupplierCategorySapronak) {
t.Fatalf("expected persisted category %q, got %q", utils.SupplierCategorySapronak, supplier.Category)
}
if supplier.DueDate != 45 {
t.Fatalf("expected due date 45, got %d", supplier.DueDate)
}
})
t.Run("updating supplier with invalid type fails", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{
"type": "invalid-type",
})
if resp.StatusCode != fiber.StatusBadRequest {
t.Fatalf("expected 400 when updating with invalid type, got %d: %s", resp.StatusCode, string(body))
}
supplier := fetchSupplier(t, db, supplierID)
if supplier.Type != string(utils.CustomerSupplierTypeIndividual) {
t.Fatalf("expected type to remain %q after invalid update, got %q", utils.CustomerSupplierTypeIndividual, supplier.Type)
}
})
t.Run("updating supplier with invalid category fails", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{
"category": "invalid",
})
if resp.StatusCode != fiber.StatusBadRequest {
t.Fatalf("expected 400 when updating with invalid category, got %d: %s", resp.StatusCode, string(body))
}
supplier := fetchSupplier(t, db, supplierID)
if supplier.Category != string(utils.SupplierCategorySapronak) {
t.Fatalf("expected category to remain %q after invalid update, got %q", utils.SupplierCategorySapronak, supplier.Category)
}
})
t.Run("deleting supplier succeeds", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil)
if resp.StatusCode != fiber.StatusOK {
t.Fatalf("expected 200 when deleting supplier, got %d: %s", resp.StatusCode, string(body))
}
var supplier entities.Supplier
if err := db.First(&supplier, supplierID).Error; !errors.Is(err, gorm.ErrRecordNotFound) {
t.Fatalf("expected supplier to be deleted, got error %v", err)
}
})
t.Run("deleting non existent supplier returns 404", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil)
if resp.StatusCode != fiber.StatusNotFound {
t.Fatalf("expected 404 when deleting missing supplier, got %d: %s", resp.StatusCode, string(body))
}
})
t.Run("getting deleted supplier returns 404", func(t *testing.T) {
resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil)
if resp.StatusCode != fiber.StatusNotFound {
t.Fatalf("expected 404 when fetching deleted supplier, got %d: %s", resp.StatusCode, string(body))
}
})
}