Add OMS WMS ERP platform
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
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
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* 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)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user