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,297 @@
|
||||
/**
|
||||
* Integration Tests: Products (ERP) Store
|
||||
* Tests product catalog management with mocked API
|
||||
*
|
||||
* Run: npm run test:integration
|
||||
*/
|
||||
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import { server } from '@/tests/mocks/server'
|
||||
import { http, HttpResponse } from 'msw'
|
||||
|
||||
/**
|
||||
* Mock Products Store (placeholder until actual store is created)
|
||||
*/
|
||||
class MockProductsStore {
|
||||
products: any[] = []
|
||||
loading = false
|
||||
error: string | null = null
|
||||
filters: Record<string, any> = {}
|
||||
|
||||
async fetchProducts() {
|
||||
this.loading = true
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/products`
|
||||
)
|
||||
const data = await response.json()
|
||||
this.products = data.data || []
|
||||
} catch (err) {
|
||||
this.error = (err as Error).message
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
async createProduct(payload: any) {
|
||||
this.loading = true
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/products`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
)
|
||||
if (!response.ok) throw new Error('Creation failed')
|
||||
const data = await response.json()
|
||||
this.products.push(data)
|
||||
return data
|
||||
} catch (err) {
|
||||
this.error = (err as Error).message
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
async getProduct(productId: string) {
|
||||
this.loading = true
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/products/${productId}`
|
||||
)
|
||||
if (!response.ok) throw new Error('Not found')
|
||||
const data = await response.json()
|
||||
return data
|
||||
} catch (err) {
|
||||
this.error = (err as Error).message
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
setFilter(key: string, value: any) {
|
||||
this.filters[key] = value
|
||||
}
|
||||
|
||||
clearFilters() {
|
||||
this.filters = {}
|
||||
}
|
||||
}
|
||||
|
||||
describe('Products (ERP) Store Integration', () => {
|
||||
let store: MockProductsStore
|
||||
|
||||
beforeEach(() => {
|
||||
store = new MockProductsStore()
|
||||
})
|
||||
|
||||
describe('fetchProducts', () => {
|
||||
it('loads products from ERP API', async () => {
|
||||
await store.fetchProducts()
|
||||
|
||||
expect(store.products).toHaveLength(1)
|
||||
expect(store.products[0].productId).toBe('PROD-001')
|
||||
expect(store.products[0].productName).toBe('Product A')
|
||||
expect(store.loading).toBe(false)
|
||||
})
|
||||
|
||||
it('includes product metadata', async () => {
|
||||
await store.fetchProducts()
|
||||
|
||||
const product = store.products[0]
|
||||
expect(product).toHaveProperty('sku')
|
||||
expect(product).toHaveProperty('categoryId')
|
||||
expect(product).toHaveProperty('status')
|
||||
expect(product).toHaveProperty('createdAt')
|
||||
})
|
||||
|
||||
it('handles empty product list', async () => {
|
||||
server.use(
|
||||
http.get('*/api/products', () => {
|
||||
return HttpResponse.json({ data: [] })
|
||||
})
|
||||
)
|
||||
|
||||
await store.fetchProducts()
|
||||
|
||||
expect(store.products).toHaveLength(0)
|
||||
expect(store.error).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('createProduct', () => {
|
||||
it('creates new product with required fields', async () => {
|
||||
const payload = {
|
||||
sku: 'SKU-NEW',
|
||||
productName: 'New Product',
|
||||
categoryId: 'CAT-002'
|
||||
}
|
||||
|
||||
const created = await store.createProduct(payload)
|
||||
|
||||
expect(created.productId).toBe('PROD-NEW')
|
||||
expect(created.sku).toBe('SKU-NEW')
|
||||
expect(created.productName).toBe('New Product')
|
||||
expect(created.status).toBe('ACTIVE')
|
||||
})
|
||||
|
||||
it('adds created product to store', async () => {
|
||||
const initialCount = store.products.length
|
||||
|
||||
await store.createProduct({
|
||||
sku: 'SKU-NEW-2',
|
||||
productName: 'Another Product',
|
||||
categoryId: 'CAT-003'
|
||||
})
|
||||
|
||||
expect(store.products.length).toBeGreaterThan(initialCount)
|
||||
})
|
||||
|
||||
it('validates required fields', async () => {
|
||||
server.use(
|
||||
http.post('*/api/products', () => {
|
||||
return HttpResponse.json(
|
||||
{ message: 'Product name is required' },
|
||||
{ status: 400 }
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
await expect(
|
||||
store.createProduct({ sku: 'SKU-INVALID' })
|
||||
).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('ensures unique SKU', async () => {
|
||||
server.use(
|
||||
http.post('*/api/products', () => {
|
||||
return HttpResponse.json(
|
||||
{ message: 'SKU already exists' },
|
||||
{ status: 409 }
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
await expect(
|
||||
store.createProduct({ sku: 'SKU-001', productName: 'Duplicate' })
|
||||
).rejects.toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getProduct', () => {
|
||||
it('fetches single product by ID', async () => {
|
||||
const product = await store.getProduct('PROD-001')
|
||||
|
||||
expect(product.productId).toBe('PROD-001')
|
||||
expect(product.productName).toBe('Product Sample')
|
||||
})
|
||||
|
||||
it('handles product not found', async () => {
|
||||
server.use(
|
||||
http.get('*/api/products/:productId', () => {
|
||||
return HttpResponse.json(
|
||||
{ message: 'Product not found' },
|
||||
{ status: 404 }
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
await expect(store.getProduct('PROD-INVALID')).rejects.toThrow()
|
||||
expect(store.error).not.toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('product filtering', () => {
|
||||
beforeEach(async () => {
|
||||
server.use(
|
||||
http.get('*/api/products', () => {
|
||||
return HttpResponse.json({
|
||||
data: [
|
||||
{ productId: 'PROD-001', categoryId: 'CAT-001', status: 'ACTIVE' },
|
||||
{ productId: 'PROD-002', categoryId: 'CAT-001', status: 'ACTIVE' },
|
||||
{ productId: 'PROD-003', categoryId: 'CAT-002', status: 'INACTIVE' },
|
||||
{ productId: 'PROD-004', categoryId: 'CAT-002', status: 'ACTIVE' }
|
||||
]
|
||||
})
|
||||
})
|
||||
)
|
||||
await store.fetchProducts()
|
||||
})
|
||||
|
||||
it('filters by category', () => {
|
||||
store.setFilter('categoryId', 'CAT-001')
|
||||
|
||||
const filtered = store.products.filter((p) => p.categoryId === store.filters.categoryId)
|
||||
expect(filtered).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('filters by status', () => {
|
||||
store.setFilter('status', 'ACTIVE')
|
||||
|
||||
const filtered = store.products.filter((p) => p.status === store.filters.status)
|
||||
expect(filtered.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('combines multiple filters', () => {
|
||||
store.setFilter('categoryId', 'CAT-001')
|
||||
store.setFilter('status', 'ACTIVE')
|
||||
|
||||
const filtered = store.products.filter(
|
||||
(p) =>
|
||||
p.categoryId === store.filters.categoryId &&
|
||||
p.status === store.filters.status
|
||||
)
|
||||
expect(filtered).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('clears all filters', () => {
|
||||
store.setFilter('categoryId', 'CAT-001')
|
||||
store.setFilter('status', 'ACTIVE')
|
||||
store.clearFilters()
|
||||
|
||||
expect(Object.keys(store.filters)).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('bulk operations', () => {
|
||||
it('handles bulk product creation', async () => {
|
||||
server.use(
|
||||
http.post('*/api/products/bulk', async ({ request }) => {
|
||||
const body = await request.json() as any
|
||||
return HttpResponse.json(
|
||||
{
|
||||
created: body.items.length,
|
||||
items: body.items.map((item: any, idx: number) => ({
|
||||
productId: `PROD-BULK-${idx + 1}`,
|
||||
...item
|
||||
}))
|
||||
},
|
||||
{ status: 201 }
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
const items = [
|
||||
{ sku: 'SKU-BULK-1', productName: 'Bulk Product 1' },
|
||||
{ sku: 'SKU-BULK-2', productName: 'Bulk Product 2' }
|
||||
]
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/products/bulk`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ items })
|
||||
}
|
||||
)
|
||||
|
||||
const data = await response.json()
|
||||
expect(data.created).toBe(2)
|
||||
expect(data.items).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user