Files
BIPMaterialManager/tests/fixtures/other-factories.test.ts
Misaka 7473f34485 test: complete Wave 2 - all entity factories + documentation
- tests/fixtures/factory.ts: Config/Database + 6 additional factories (547 lines total)
  - UserFactory (3 methods: createAdmin, createUserDefault, createGuest)
  - OrderFactory (2 methods: createOrder, createOrders)
  - MaterialFactory (2 methods: createMaterial, createMaterials)
  - ConfigFactory (1 method: createErpConfig)
  - DatabaseFactory (1 method: createDatabaseConfig)
  - ExtractResultFactory (2 methods)
  - CleanerResultFactory (2 methods)
  - AuditLogFactory (1 method)
  - UpdateReleaseFactory (1 method)
  - ProductionInputFactory (1 method)
  - ValidationErrorFactory (1 method)
  Total: 17 factory methods across 10 factory classes

- Test coverage:
  - user-factory.test.ts: 3 tests
  - order-material-factory.test.ts: 4 tests
  - config-factory.test.ts: 5 tests
  - other-factories.test.ts: 15 tests
  Total: 27 factory tests

- docs/TEST_FACTORY_USAGE.md: User guide with examples (152 lines)

All factories support overrides customization and follow the <=100 lines per factory constraint.
2026-04-04 20:23:45 +08:00

193 lines
6.2 KiB
TypeScript

/**
* Other Factories Unit Tests
*
* Tests for ExtractResult, CleanerResult, AuditLog, UpdateRelease,
* ProductionInput, and ValidationError factories.
*/
import { describe, it, expect } from 'vitest'
import {
ExtractResultFactory,
CleanerResultFactory,
AuditLogFactory,
UpdateReleaseFactory,
ProductionInputFactory,
ValidationErrorFactory
} from './factory'
import { AuditAction, AuditStatus } from '../../src/main/types/audit.types'
import { VALIDATION_ERROR_CODES } from '../../src/main/types/errors'
describe('ExtractResultFactory', () => {
it('creates extract result with default values', () => {
const result = ExtractResultFactory.createExtractResult()
expect(result.downloadedFiles).toHaveLength(1)
expect(result.downloadedFiles[0]).toMatch(/download_\d+\.xlsx/)
expect(result.mergedFile).toMatch(/merged_\d+\.xlsx/)
expect(result.recordCount).toBe(100)
expect(result.errors).toEqual([])
expect(result.orderRecordCounts).toHaveLength(1)
})
it('creates extract result with overrides', () => {
const result = ExtractResultFactory.createExtractResult({
recordCount: 50,
errors: ['Network timeout']
})
expect(result.recordCount).toBe(50)
expect(result.errors).toEqual(['Network timeout'])
})
it('creates import result with default values', () => {
const importResult = ExtractResultFactory.createImportResult()
expect(importResult.success).toBe(true)
expect(importResult.recordsRead).toBe(100)
expect(importResult.recordsImported).toBe(95)
expect(importResult.errors).toEqual([])
})
})
describe('CleanerResultFactory', () => {
it('creates cleaner result with default values', () => {
const result = CleanerResultFactory.createCleanerResult()
expect(result.ordersProcessed).toBe(5)
expect(result.materialsDeleted).toBe(20)
expect(result.materialsSkipped).toBe(2)
expect(result.errors).toEqual([])
expect(result.details).toEqual([])
expect(result.retriedOrders).toBe(0)
})
it('creates cleaner result with overrides', () => {
const result = CleanerResultFactory.createCleanerResult({
ordersProcessed: 10,
materialsDeleted: 40,
retriedOrders: 2,
successfulRetries: 1
})
expect(result.ordersProcessed).toBe(10)
expect(result.materialsDeleted).toBe(40)
expect(result.retriedOrders).toBe(2)
expect(result.successfulRetries).toBe(1)
})
it('creates order clean detail with default values', () => {
const detail = CleanerResultFactory.createOrderCleanDetail()
expect(detail.orderNumber).toMatch(/SC\d+/)
expect(detail.materialsDeleted).toBe(5)
expect(detail.materialsSkipped).toBe(0)
expect(detail.errors).toEqual([])
expect(detail.skippedMaterials).toEqual([])
expect(detail.retryCount).toBe(0)
})
})
describe('AuditLogFactory', () => {
it('creates audit log with default values', () => {
const entry = AuditLogFactory.createAuditLog()
expect(entry.timestamp).toBeInstanceOf(Date)
expect(entry.action).toBe(AuditAction.LOGIN)
expect(entry.status).toBe(AuditStatus.SUCCESS)
expect(entry.userId).toBe('USR-001')
expect(entry.username).toBe('test_user')
expect(entry.computerName).toBe('TEST-PC')
expect(entry.appVersion).toBe('1.0.0')
})
it('creates audit log with custom action and status', () => {
const entry = AuditLogFactory.createAuditLog(AuditAction.EXTRACT, AuditStatus.FAILURE, {
userId: 'USR-999',
resource: 'Order SC123'
})
expect(entry.action).toBe(AuditAction.EXTRACT)
expect(entry.status).toBe(AuditStatus.FAILURE)
expect(entry.userId).toBe('USR-999')
expect(entry.resource).toBe('Order SC123')
})
})
describe('UpdateReleaseFactory', () => {
it('creates stable release with default values', () => {
const release = UpdateReleaseFactory.createUpdateRelease('stable')
expect(release.version).toBe('1.0.0')
expect(release.channel).toBe('stable')
expect(release.artifactKey).toMatch(/erputo-stable-v1\.0\.0\.exe/)
expect(release.size).toBe(52428800)
expect(release.publishedAt).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)
})
it('creates preview release with overrides', () => {
const release = UpdateReleaseFactory.createUpdateRelease('preview', {
version: '2.0.0-beta.1',
size: 62914560
})
expect(release.channel).toBe('preview')
expect(release.version).toBe('2.0.0-beta.1')
expect(release.size).toBe(62914560)
})
})
describe('ProductionInputFactory', () => {
it('creates validation result with default values', () => {
const result = ProductionInputFactory.createValidationResult()
expect(result.materialName).toBe('Test Material')
expect(result.materialCode).toMatch(/MAT-\d+/)
expect(result.specification).toBe('Standard Spec')
expect(result.model).toBe('Model-A')
expect(result.managerName).toBe('Test Manager')
expect(result.isMarkedForDeletion).toBe(false)
})
it('creates validation result marked for deletion', () => {
const result = ProductionInputFactory.createValidationResult({
isMarkedForDeletion: true,
materialCode: 'MAT-999'
})
expect(result.isMarkedForDeletion).toBe(true)
expect(result.materialCode).toBe('MAT-999')
})
})
describe('ValidationErrorFactory', () => {
it('creates validation error with default values', () => {
const error = ValidationErrorFactory.createValidationError()
expect(error.name).toBe('ValidationError')
expect(error.message).toBe('Validation failed')
expect(error.code).toBe(VALIDATION_ERROR_CODES.INVALID_INPUT)
})
it('creates validation error with custom message and code', () => {
const error = ValidationErrorFactory.createValidationError(
'Missing required field',
VALIDATION_ERROR_CODES.MISSING_REQUIRED
)
expect(error.message).toBe('Missing required field')
expect(error.code).toBe(VALIDATION_ERROR_CODES.MISSING_REQUIRED)
})
it('creates validation error with cause', () => {
const cause = new Error('Underlying cause')
const error = ValidationErrorFactory.createValidationError(
'Invalid format',
VALIDATION_ERROR_CODES.INVALID_FORMAT,
cause
)
expect(error.cause).toBe(cause)
expect(error.message).toBe('Invalid format')
})
})