fix(test): replace duplicated business logic in cleaner test with real CleanerService

The shouldDeleteMaterial tests had a mockCleaner that reimplemented the
production logic inline, meaning bugs in the real code would never be caught.
Now uses an actual CleanerService instance instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-04-05 08:16:02 +08:00
parent 9086aa753f
commit 406a8dfd2f

View File

@@ -1,36 +1,15 @@
import { describe, it, expect } from 'vitest' import { describe, it, expect } from 'vitest'
import { import {
CleanerService,
createBatches, createBatches,
getMissingOrders, getMissingOrders,
runWithConcurrency runWithConcurrency
} from '../../src/main/services/erp/cleaner' } from '../../src/main/services/erp/cleaner'
import type { ShouldDeleteParams } from '../../src/main/services/erp/cleaner'
describe('Cleaner Service (Unit)', () => { describe('Cleaner Service (Unit)', () => {
describe('shouldDeleteMaterial', () => { describe('shouldDeleteMaterial', () => {
// Create a mock cleaner service (no auth needed for this pure function test) // CleanerService constructor requires ErpAuthService, but shouldDeleteMaterial doesn't use it
const mockCleaner = { const cleaner = new CleanerService({} as any)
shouldDeleteMaterial: (params: ShouldDeleteParams): boolean => {
const { rowNumber, pendingQty, materialCode, deleteSet } = params
// Check if material is in delete list
if (!deleteSet.has(materialCode)) {
return false
}
// Check row number range (2000-7999 are protected)
if (rowNumber >= 2000 && rowNumber < 8000) {
return false
}
// Check pending quantity (must be empty)
if (pendingQty && pendingQty.trim() !== '') {
return false
}
return true
}
}
it('should skip materials with row number 2000-7999', () => { it('should skip materials with row number 2000-7999', () => {
const testCases = [ const testCases = [
@@ -42,7 +21,7 @@ describe('Cleaner Service (Unit)', () => {
] ]
for (const tc of testCases) { for (const tc of testCases) {
const shouldDelete = mockCleaner.shouldDeleteMaterial({ const shouldDelete = cleaner.shouldDeleteMaterial({
rowNumber: tc.rowNumber, rowNumber: tc.rowNumber,
pendingQty: tc.pendingQty, pendingQty: tc.pendingQty,
materialCode: tc.materialCode, materialCode: tc.materialCode,
@@ -53,7 +32,7 @@ describe('Cleaner Service (Unit)', () => {
}) })
it('should skip materials with non-empty pending quantity', () => { it('should skip materials with non-empty pending quantity', () => {
const result = mockCleaner.shouldDeleteMaterial({ const result = cleaner.shouldDeleteMaterial({
rowNumber: 100, rowNumber: 100,
pendingQty: '5', pendingQty: '5',
materialCode: 'TEST001', materialCode: 'TEST001',
@@ -64,7 +43,7 @@ describe('Cleaner Service (Unit)', () => {
}) })
it('should skip materials not in delete list', () => { it('should skip materials not in delete list', () => {
const result = mockCleaner.shouldDeleteMaterial({ const result = cleaner.shouldDeleteMaterial({
rowNumber: 100, rowNumber: 100,
pendingQty: '', pendingQty: '',
materialCode: 'NOT_IN_LIST', materialCode: 'NOT_IN_LIST',
@@ -84,7 +63,7 @@ describe('Cleaner Service (Unit)', () => {
] ]
for (const tc of testCases) { for (const tc of testCases) {
const shouldDelete = mockCleaner.shouldDeleteMaterial({ const shouldDelete = cleaner.shouldDeleteMaterial({
rowNumber: tc.rowNumber, rowNumber: tc.rowNumber,
pendingQty: tc.pendingQty, pendingQty: tc.pendingQty,
materialCode: tc.materialCode, materialCode: tc.materialCode,
@@ -97,7 +76,7 @@ describe('Cleaner Service (Unit)', () => {
it('should handle multiple conditions correctly', () => { it('should handle multiple conditions correctly', () => {
// Material in list, valid row, no pending qty = should delete // Material in list, valid row, no pending qty = should delete
expect( expect(
mockCleaner.shouldDeleteMaterial({ cleaner.shouldDeleteMaterial({
rowNumber: 100, rowNumber: 100,
pendingQty: '', pendingQty: '',
materialCode: 'TEST001', materialCode: 'TEST001',
@@ -107,7 +86,7 @@ describe('Cleaner Service (Unit)', () => {
// Material in list, protected row, no pending qty = should NOT delete // Material in list, protected row, no pending qty = should NOT delete
expect( expect(
mockCleaner.shouldDeleteMaterial({ cleaner.shouldDeleteMaterial({
rowNumber: 7500, rowNumber: 7500,
pendingQty: '', pendingQty: '',
materialCode: 'TEST001', materialCode: 'TEST001',
@@ -117,7 +96,7 @@ describe('Cleaner Service (Unit)', () => {
// Material in list, valid row, has pending qty = should NOT delete // Material in list, valid row, has pending qty = should NOT delete
expect( expect(
mockCleaner.shouldDeleteMaterial({ cleaner.shouldDeleteMaterial({
rowNumber: 100, rowNumber: 100,
pendingQty: '10', pendingQty: '10',
materialCode: 'TEST001', materialCode: 'TEST001',
@@ -127,7 +106,7 @@ describe('Cleaner Service (Unit)', () => {
// Material NOT in list = should NOT delete // Material NOT in list = should NOT delete
expect( expect(
mockCleaner.shouldDeleteMaterial({ cleaner.shouldDeleteMaterial({
rowNumber: 100, rowNumber: 100,
pendingQty: '', pendingQty: '',
materialCode: 'OTHER', materialCode: 'OTHER',