88 lines
3.1 KiB
TypeScript
88 lines
3.1 KiB
TypeScript
|
|
import { describe, it, expect } from 'vitest';
|
||
|
|
import {
|
||
|
|
Filament,
|
||
|
|
StockLevel,
|
||
|
|
getRemainingPercent,
|
||
|
|
classifyStockLevel,
|
||
|
|
} from '../../models/filament.model';
|
||
|
|
|
||
|
|
/** Create a test filament with defaults — override specific fields */
|
||
|
|
function createFilament(overrides: Partial<Filament> = {}): Filament {
|
||
|
|
return {
|
||
|
|
id: '00000000-0000-0000-0000-000000000001',
|
||
|
|
materialBaseId: '10000000-0000-0000-0000-000000000001',
|
||
|
|
materialBaseName: 'PLA',
|
||
|
|
materialFinishId: '20000000-0000-0000-0000-000000000001',
|
||
|
|
materialFinishName: 'Basic',
|
||
|
|
materialModifierId: null,
|
||
|
|
materialModifierName: null,
|
||
|
|
brand: 'Bambu Lab',
|
||
|
|
colorName: 'White',
|
||
|
|
colorHex: '#FFFFFF',
|
||
|
|
weightTotalGrams: 1000,
|
||
|
|
weightRemainingGrams: 750,
|
||
|
|
filamentDiameterMm: 1.75,
|
||
|
|
spoolSerial: 'SN-001',
|
||
|
|
purchasePrice: null,
|
||
|
|
purchaseDate: null,
|
||
|
|
isActive: true,
|
||
|
|
createdAt: '2026-01-01T00:00:00Z',
|
||
|
|
updatedAt: '2026-01-01T00:00:00Z',
|
||
|
|
qrCodeUrl: '',
|
||
|
|
...overrides,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('getRemainingPercent', () => {
|
||
|
|
it('should return correct percentage', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 250 });
|
||
|
|
expect(getRemainingPercent(filament)).toBe(25);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return 0 when total weight is 0', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 0, weightRemainingGrams: 0 });
|
||
|
|
expect(getRemainingPercent(filament)).toBe(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should cap at 100%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 100, weightRemainingGrams: 200 });
|
||
|
|
expect(getRemainingPercent(filament)).toBe(100);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should floor at 0%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 100, weightRemainingGrams: -10 });
|
||
|
|
expect(getRemainingPercent(filament)).toBe(0);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('classifyStockLevel', () => {
|
||
|
|
it('should classify as critical when ≤10%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 50 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('critical');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should classify as critical at exactly 10%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 100 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('critical');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should classify as low when ≤25%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 200 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('low');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should classify as moderate when ≤50%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 400 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('moderate');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should classify as healthy when >50%', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 750 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('healthy');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should classify 0 grams remaining as critical', () => {
|
||
|
|
const filament = createFilament({ weightTotalGrams: 1000, weightRemainingGrams: 0 });
|
||
|
|
expect(classifyStockLevel(filament)).toBe('critical');
|
||
|
|
});
|
||
|
|
});
|