Files
QuantEngineByItz/oms-wms-erp/tests/integration/inventory.spec.ts
T
kjh2064 b34b0dd7d6
Validators (Pushes and Pull Requests) / UI & Storage Validation (pull_request) Failing after 12s
Validators (Pushes and Pull Requests) / Database & Schema Validation (pull_request) Successful in 13s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (pull_request) Failing after 28s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / CI Workflow Lint (pull_request) Failing after 10s
Validators (Pushes and Pull Requests) / Security & Secrets (pull_request) Successful in 12s
Validators (Pushes and Pull Requests) / Notify PR Results (pull_request) Successful in 2s
Frontend CI Pipeline / ci-frontend-8-steps (pull_request) Failing after 2m50s
Add OMS WMS ERP platform
2026-07-27 00:45:39 +09:00

202 lines
5.7 KiB
TypeScript

/**
* Integration Tests: Inventory (WMS) Store
* Tests warehouse inventory management with mocked API
*
* Run: npm run test:integration
*/
import { beforeEach, describe, expect, it } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { server } from '@/tests/mocks/server'
import { http, HttpResponse } from 'msw'
/**
* Mock Inventory Store (placeholder until actual store is created)
*/
class MockInventoryStore {
inventory: any[] = []
loading = false
error: string | null = null
async fetchInventory() {
this.loading = true
try {
const response = await fetch(`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/inventory`)
const data = await response.json()
this.inventory = data.data || []
} catch (err) {
this.error = (err as Error).message
} finally {
this.loading = false
}
}
async updateInventory(inventoryId: string, payload: any) {
this.loading = true
try {
const response = await fetch(
`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/inventory/${inventoryId}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
)
if (!response.ok) throw new Error('Update failed')
const data = await response.json()
const index = this.inventory.findIndex((i) => i.inventoryId === inventoryId)
if (index !== -1) this.inventory[index] = data
return data
} catch (err) {
this.error = (err as Error).message
throw err
} finally {
this.loading = false
}
}
}
describe('Inventory (WMS) Store Integration', () => {
let store: MockInventoryStore
beforeEach(() => {
store = new MockInventoryStore()
})
describe('fetchInventory', () => {
it('loads inventory from WMS API', async () => {
await store.fetchInventory()
expect(store.inventory).toHaveLength(1)
expect(store.inventory[0].inventoryId).toBe('INV-001')
expect(store.inventory[0].qtyOnHand).toBe(1000)
expect(store.loading).toBe(false)
expect(store.error).toBeNull()
})
it('calculates available quantity correctly', async () => {
await store.fetchInventory()
const inv = store.inventory[0]
const available = inv.qtyOnHand - inv.qtyReserved
expect(available).toBe(900)
expect(inv.qtyAvailable).toBe(available)
})
it('handles API errors gracefully', async () => {
server.use(
http.get('*/api/inventory', () => {
return HttpResponse.json(
{ message: 'Database connection failed' },
{ status: 500 }
)
})
)
await store.fetchInventory()
expect(store.error).not.toBeNull()
expect(store.inventory).toHaveLength(0)
})
})
describe('updateInventory', () => {
beforeEach(async () => {
await store.fetchInventory()
})
it('updates inventory quantities', async () => {
const updates = { qtyOnHand: 1200, qtyReserved: 150 }
const updated = await store.updateInventory('INV-001', updates)
expect(updated.qtyOnHand).toBe(1200)
expect(updated.qtyReserved).toBe(150)
expect(updated.qtyAvailable).toBe(1050)
})
it('reflects updates in store', async () => {
const updates = { qtyOnHand: 800, qtyReserved: 100 }
await store.updateInventory('INV-001', updates)
const inv = store.inventory.find((i) => i.inventoryId === 'INV-001')
expect(inv?.qtyOnHand).toBe(800)
})
it('handles update validation errors', async () => {
server.use(
http.patch('*/api/inventory/:inventoryId', () => {
return HttpResponse.json(
{ message: 'Quantity cannot be negative' },
{ status: 400 }
)
})
)
await expect(
store.updateInventory('INV-001', { qtyOnHand: -100 })
).rejects.toThrow()
})
})
describe('stock availability checks', () => {
beforeEach(async () => {
await store.fetchInventory()
})
it('reserves stock correctly', async () => {
const initial = store.inventory[0]
const reservation = 100
const updated = await store.updateInventory('INV-001', {
qtyOnHand: initial.qtyOnHand,
qtyReserved: initial.qtyReserved + reservation
})
expect(updated.qtyAvailable).toBe(initial.qtyAvailable - reservation)
})
it('prevents over-reservation', async () => {
const current = store.inventory[0]
// Try to reserve more than available
server.use(
http.patch('*/api/inventory/:inventoryId', () => {
return HttpResponse.json(
{ message: 'Cannot reserve more than available quantity' },
{ status: 422 }
)
})
)
await expect(
store.updateInventory('INV-001', {
qtyOnHand: current.qtyOnHand,
qtyReserved: 10000 // Exceed available
})
).rejects.toThrow()
})
})
describe('multi-warehouse scenarios', () => {
it('handles inventory across multiple warehouses', async () => {
server.use(
http.get('*/api/inventory', () => {
return HttpResponse.json({
data: [
{ inventoryId: 'INV-001', warehouseId: 'WH-SEOUL', qtyOnHand: 1000 },
{ inventoryId: 'INV-002', warehouseId: 'WH-BUSAN', qtyOnHand: 500 },
{ inventoryId: 'INV-003', warehouseId: 'WH-DAEGU', qtyOnHand: 300 }
]
})
})
)
const tempStore = new MockInventoryStore()
await tempStore.fetchInventory()
expect(tempStore.inventory).toHaveLength(3)
const totalQty = tempStore.inventory.reduce((sum, inv) => sum + inv.qtyOnHand, 0)
expect(totalQty).toBe(1800)
})
})
})