README / client /src /lib /hierarchyUtils.test.ts
firoruheqo4's picture
Upload 139 files
926b211 verified
Raw
History Blame Contribute Delete
7.5 kB
/**
* Tests for Hierarchy Grouping Utilities
*/
import { describe, it, expect } from 'vitest';
import {
groupProjectsByHierarchy,
isDateStale,
formatDateShort,
getNodeBadgeClass
} from './hierarchyUtils';
import { ProjectData } from '@/types/project';
describe('groupProjectsByHierarchy', () => {
it('should group projects by project name and product name', () => {
const mockProjects: ProjectData[] = [
{
no: '1',
identity: {
projectName: 'Ziti2',
productName: 'housing',
moldNumber: 'LA25463',
customerName: '罗技',
customerBase: '苏州',
factory: 'A厂',
moldSets: '1',
partNumber: '400-009150',
cavityNumber: 'CAV1-4',
projectManager: '张舜杰',
projectEngineer: '袁任杰',
moldProject: '胡荣武',
qe: '柳彬彬',
riskLevel: '正常'
},
milestones: {
projectStart: '2001-05-14',
t1: '2001-06-08',
glTime: '2001-12-02',
vmp: '2001-10-18',
mp: '-',
currentStage: 'PQR',
trialCount: 'T26',
t1SizeQualified: '-',
toolingFAI: '79.40%',
partFAI: '100%',
currentNode: 'PQR'
},
details: {
detailDate: '2026-01-02',
detailProgress: '苏州跑线通过, PB2 越南试产 400PCS,1/26海运, 预计2/9号到达'
}
},
{
no: '2',
identity: {
projectName: 'Ziti2',
productName: 'housing',
moldNumber: 'LA25464',
customerName: '罗技',
customerBase: '苏州',
factory: 'A厂',
moldSets: '1',
partNumber: '400-009151',
cavityNumber: 'CAV1-4',
projectManager: '张舜杰',
projectEngineer: '袁任杰',
moldProject: '胡荣武',
qe: '柳彬彬',
riskLevel: '正常'
},
milestones: {
projectStart: '2001-05-14',
t1: '2001-06-08',
glTime: '2001-12-02',
vmp: '2001-10-18',
mp: '-',
currentStage: 'T1',
trialCount: 'T10',
t1SizeQualified: '-',
toolingFAI: '50%',
partFAI: '80%',
currentNode: 'T1'
},
details: {
detailDate: '2026-01-15',
detailProgress: '第二次试模完成'
}
}
];
const result = groupProjectsByHierarchy(mockProjects);
expect(result).toHaveLength(1);
expect(result[0].projectName).toBe('Ziti2');
expect(result[0].products).toHaveLength(1);
expect(result[0].products[0].productName).toBe('housing');
expect(result[0].products[0].molds).toHaveLength(2);
expect(result[0].products[0].molds[0].moldNumber).toBe('LA25463');
expect(result[0].products[0].molds[1].moldNumber).toBe('LA25464');
});
it('should handle multiple projects and products', () => {
const mockProjects: ProjectData[] = [
{
no: '1',
identity: {
projectName: 'Project A',
productName: 'Product 1',
moldNumber: 'M001',
customerName: '', customerBase: '', factory: '', moldSets: '',
partNumber: '', cavityNumber: '', projectManager: '',
projectEngineer: '', moldProject: '', qe: '', riskLevel: ''
},
milestones: {
projectStart: '', t1: '', glTime: '', vmp: '', mp: '',
currentStage: 'PQR', trialCount: '', t1SizeQualified: '',
toolingFAI: '', partFAI: '', currentNode: 'PQR'
},
details: { detailDate: '2026-01-01', detailProgress: 'Test' }
},
{
no: '2',
identity: {
projectName: 'Project A',
productName: 'Product 2',
moldNumber: 'M002',
customerName: '', customerBase: '', factory: '', moldSets: '',
partNumber: '', cavityNumber: '', projectManager: '',
projectEngineer: '', moldProject: '', qe: '', riskLevel: ''
},
milestones: {
projectStart: '', t1: '', glTime: '', vmp: '', mp: '',
currentStage: 'T1', trialCount: '', t1SizeQualified: '',
toolingFAI: '', partFAI: '', currentNode: 'T1'
},
details: { detailDate: '2026-01-01', detailProgress: 'Test' }
},
{
no: '3',
identity: {
projectName: 'Project B',
productName: 'Product 3',
moldNumber: 'M003',
customerName: '', customerBase: '', factory: '', moldSets: '',
partNumber: '', cavityNumber: '', projectManager: '',
projectEngineer: '', moldProject: '', qe: '', riskLevel: ''
},
milestones: {
projectStart: '', t1: '', glTime: '', vmp: '', mp: '',
currentStage: 'MP', trialCount: '', t1SizeQualified: '',
toolingFAI: '', partFAI: '', currentNode: 'MP'
},
details: { detailDate: '2026-01-01', detailProgress: 'Test' }
}
];
const result = groupProjectsByHierarchy(mockProjects);
expect(result).toHaveLength(2);
expect(result[0].projectName).toBe('Project A');
expect(result[0].products).toHaveLength(2);
expect(result[1].projectName).toBe('Project B');
expect(result[1].products).toHaveLength(1);
});
});
describe('isDateStale', () => {
it('should return true for dates older than 7 days', () => {
const oldDate = new Date();
oldDate.setDate(oldDate.getDate() - 10);
const dateStr = oldDate.toISOString().split('T')[0];
expect(isDateStale(dateStr)).toBe(true);
});
it('should return false for recent dates', () => {
const recentDate = new Date();
recentDate.setDate(recentDate.getDate() - 3);
const dateStr = recentDate.toISOString().split('T')[0];
expect(isDateStale(dateStr)).toBe(false);
});
it('should return false for invalid dates', () => {
expect(isDateStale('-')).toBe(false);
expect(isDateStale('')).toBe(false);
expect(isDateStale('invalid')).toBe(false);
});
});
describe('formatDateShort', () => {
it('should format date as "月日"', () => {
const result = formatDateShort('2026-01-15');
// Date parsing may vary by timezone, check format instead
expect(result).toMatch(/\d+月\d+日/);
});
it('should handle different date formats', () => {
const result = formatDateShort('1/2/26');
expect(result).toMatch(/\d+月\d+日/);
});
it('should return "-" for invalid dates', () => {
expect(formatDateShort('-')).toBe('-');
expect(formatDateShort('')).toBe('-');
});
});
describe('getNodeBadgeClass', () => {
it('should return green class for completed stages', () => {
expect(getNodeBadgeClass('MP')).toContain('green');
expect(getNodeBadgeClass('完成')).toContain('green');
});
it('should return blue class for in-progress stages', () => {
expect(getNodeBadgeClass('PQR')).toContain('blue');
expect(getNodeBadgeClass('T1')).toContain('blue');
// VMP is considered completed stage, should be green
expect(getNodeBadgeClass('进行中')).toContain('blue');
});
it('should return slate class for early stages', () => {
expect(getNodeBadgeClass('KICK OFF')).toContain('slate');
expect(getNodeBadgeClass('G/L')).toContain('slate');
});
it('should handle empty or invalid input', () => {
const result = getNodeBadgeClass('');
expect(result).toContain('slate');
});
});