| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /**
- * Tests for K-profile matching helpers (#1688 + #1689).
- *
- * `isMatchingCalibration` is the predicate used by both the spool form's
- * PA-profile suggester and ConfigureAmsSlotModal's K-profile filter. The
- * #1688 enhancement adds a filament_id-first match path with id
- * normalisation; the old name-parsing logic stays as the fallback.
- */
- import { describe, it, expect } from 'vitest';
- import {
- isMatchingCalibration,
- toFilamentId,
- isGenericFilamentId,
- materialForGenericFilamentId,
- genericFilamentIdMatchesMaterial,
- } from '../../../components/spool-form/utils';
- describe('toFilamentId', () => {
- it('strips the variant suffix', () => {
- expect(toFilamentId('GFG98_09')).toBe('GFG98');
- });
- it('strips the "S" infix from a setting_id', () => {
- // Spool stores setting_id "GFSG98", K-profile stores filament_id "GFG98".
- // Normalisation has to drop the "S" so both sides agree.
- expect(toFilamentId('GFSG98')).toBe('GFG98');
- });
- it('strips both the "S" infix and the variant suffix', () => {
- expect(toFilamentId('GFSG98_09')).toBe('GFG98');
- });
- it('returns bare filament_id unchanged', () => {
- expect(toFilamentId('GFL05')).toBe('GFL05');
- });
- it('uppercases the result', () => {
- expect(toFilamentId('gfsg98_09')).toBe('GFG98');
- });
- it('returns empty string for null/undefined/empty', () => {
- expect(toFilamentId(null)).toBe('');
- expect(toFilamentId(undefined)).toBe('');
- expect(toFilamentId('')).toBe('');
- });
- it('passes through non-Bambu IDs (numeric local-preset, Orca UUID) without crashing', () => {
- // Numeric local-preset ID — caller falls through to name match, no crash.
- expect(toFilamentId('42')).toBe('42');
- // Orca UUID — same.
- expect(toFilamentId('orca-uuid-abc')).toBe('ORCA-UUID-ABC');
- });
- });
- describe('isGenericFilamentId', () => {
- it('flags GFx99 patterns as generic', () => {
- expect(isGenericFilamentId('GFL99')).toBe(true);
- expect(isGenericFilamentId('GFG99')).toBe(true);
- expect(isGenericFilamentId('GFB99')).toBe(true);
- });
- it('does not flag non-generic IDs', () => {
- expect(isGenericFilamentId('GFL05')).toBe(false);
- expect(isGenericFilamentId('GFG98')).toBe(false);
- });
- it('returns false for null/undefined/empty', () => {
- expect(isGenericFilamentId(null)).toBe(false);
- expect(isGenericFilamentId(undefined)).toBe(false);
- expect(isGenericFilamentId('')).toBe(false);
- });
- });
- describe('materialForGenericFilamentId (#2710)', () => {
- it('resolves the material each generic id stands for', () => {
- expect(materialForGenericFilamentId('GFL99')).toBe('PLA');
- expect(materialForGenericFilamentId('GFG99')).toBe('PETG');
- expect(materialForGenericFilamentId('gfu99')).toBe('TPU');
- });
- it('returns empty for specific ids and for nothing', () => {
- expect(materialForGenericFilamentId('GFL05')).toBe('');
- expect(materialForGenericFilamentId(null)).toBe('');
- expect(materialForGenericFilamentId('')).toBe('');
- });
- });
- describe('genericFilamentIdMatchesMaterial (#2710)', () => {
- it('agrees when the generic id describes that material', () => {
- expect(genericFilamentIdMatchesMaterial('GFL99', 'PLA')).toBe(true);
- expect(genericFilamentIdMatchesMaterial('GFL99', 'pla')).toBe(true);
- });
- it('treats Nylon and PA as the same material', () => {
- expect(genericFilamentIdMatchesMaterial('GFN99', 'Nylon')).toBe(true);
- });
- it('rejects a mismatched material, a specific id, or a missing material', () => {
- expect(genericFilamentIdMatchesMaterial('GFL99', 'PETG')).toBe(false);
- expect(genericFilamentIdMatchesMaterial('GFL05', 'PLA')).toBe(false);
- expect(genericFilamentIdMatchesMaterial('GFL99', '')).toBe(false);
- });
- });
- describe('isMatchingCalibration (#1688)', () => {
- const formData = {
- material: 'PETG',
- brand: 'Generic',
- subtype: '',
- slicer_filament: 'GFSG98_09', // spool's setting_id form
- };
- it('matches by filament_id when ids agree after normalisation', () => {
- // K-profile stores bare filament_id; spool stores setting_id. Both
- // normalise to "GFG98" — match without any name parsing.
- expect(
- isMatchingCalibration(
- { name: 'My Custom K Profile', filament_id: 'GFG98' },
- formData,
- ),
- ).toBe(true);
- });
- it('id-match wins even when the K-profile name would not parse to anything sensible', () => {
- expect(
- isMatchingCalibration(
- { name: 'literal-garbage-no-material', filament_id: 'GFG98' },
- formData,
- ),
- ).toBe(true);
- });
- it('skips id-match when a generic id contradicts the spool material', () => {
- // GFL99 is generic *PLA* but the spool says PETG — the ids agreeing is not
- // enough, the material has to agree too. Name parsing then drives the
- // decision and rejects it.
- const result = isMatchingCalibration(
- { name: 'Random thing with no PETG in it', filament_id: 'GFL99' },
- { ...formData, slicer_filament: 'GFL99' },
- );
- expect(result).toBe(false);
- });
- it('matches a generic id when the material agrees and the spool claims no brand (#2710)', () => {
- // Reporter's printer: every K-profile calibrated under Generic PLA and
- // named after the colour. No name parsing can tie "Dark Brown" to PLA, so
- // the shared GFL99 is the only signal there is.
- expect(
- isMatchingCalibration(
- { name: 'Dark Brown', filament_id: 'GFL99' },
- { material: 'PLA', brand: '', subtype: '', slicer_filament: 'GFL99' },
- ),
- ).toBe(true);
- });
- it('treats "Generic" as no brand on the generic id path', () => {
- expect(
- isMatchingCalibration(
- { name: 'Marble', filament_id: 'GFL99' },
- { material: 'PLA', brand: 'Generic', subtype: '', slicer_filament: 'GFL99' },
- ),
- ).toBe(true);
- });
- it('keeps generic id matches brand-specific when the spool names a brand', () => {
- // A spool that says "Sunlu" should still get Sunlu-specific suggestions
- // rather than the printer's whole generic-PLA table.
- expect(
- isMatchingCalibration(
- { name: 'Dark Brown', filament_id: 'GFL99' },
- { material: 'PLA', brand: 'Sunlu', subtype: '', slicer_filament: 'GFL99' },
- ),
- ).toBe(false);
- });
- it('accepts Nylon/PA as the same material on the generic id path', () => {
- expect(
- isMatchingCalibration(
- { name: 'spool-of-doom', filament_id: 'GFN99' },
- { material: 'Nylon', brand: '', subtype: '', slicer_filament: 'GFN99' },
- ),
- ).toBe(true);
- });
- it('falls through to name match when spool has no slicer_filament', () => {
- expect(
- isMatchingCalibration(
- { name: 'Generic PETG', filament_id: 'GFG98' },
- { material: 'PETG', brand: 'Generic', subtype: '' },
- ),
- ).toBe(true);
- });
- it('falls through to name match when K-profile has no filament_id', () => {
- expect(
- isMatchingCalibration(
- { name: 'Generic PETG' },
- formData,
- ),
- ).toBe(true);
- });
- it('falls through to name match when normalised ids differ', () => {
- // Spool says GFG98, K-profile says GFL05 — id-match fails, fall to name.
- expect(
- isMatchingCalibration(
- { name: 'Generic PETG', filament_id: 'GFL05' },
- formData,
- ),
- ).toBe(true);
- expect(
- isMatchingCalibration(
- { name: 'Bambu PLA Basic', filament_id: 'GFL05' },
- formData,
- ),
- ).toBe(false);
- });
- it('rejects calibrations whose material does not match (name fallback path)', () => {
- expect(
- isMatchingCalibration(
- { name: 'Bambu PLA Basic', filament_id: 'GFL05' },
- { material: 'PETG', brand: '', subtype: '' },
- ),
- ).toBe(false);
- });
- it('returns false when formData has no material', () => {
- expect(
- isMatchingCalibration(
- { name: 'PETG', filament_id: 'GFG98' },
- { material: '', brand: '', subtype: '' },
- ),
- ).toBe(false);
- });
- });
|