inventorySearch.test.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { describe, it, expect } from 'vitest';
  2. import { spoolMatchesQuery, filterSpoolsByQuery } from '../../utils/inventorySearch';
  3. import type { InventorySpool } from '../../api/client';
  4. function makeSpool(overrides: Partial<InventorySpool> = {}): InventorySpool {
  5. return {
  6. id: 1,
  7. material: 'PLA',
  8. subtype: 'Basic',
  9. color_name: 'Red',
  10. rgba: 'FF0000FF',
  11. brand: 'Bambu Lab',
  12. label_weight: 1000,
  13. core_weight: 250,
  14. core_weight_catalog_id: null,
  15. weight_used: 0,
  16. slicer_filament: null,
  17. slicer_filament_name: null,
  18. nozzle_temp_min: 220,
  19. nozzle_temp_max: 240,
  20. note: null,
  21. added_full: null,
  22. last_used: null,
  23. encode_time: null,
  24. tag_uid: null,
  25. tray_uuid: null,
  26. data_origin: 'local',
  27. tag_type: null,
  28. archived_at: null,
  29. created_at: '2024-01-01T00:00:00Z',
  30. updated_at: '2024-01-01T00:00:00Z',
  31. cost_per_kg: null,
  32. last_scale_weight: null,
  33. last_weighed_at: null,
  34. category: null,
  35. low_stock_threshold_pct: null,
  36. ...overrides,
  37. };
  38. }
  39. describe('spoolMatchesQuery', () => {
  40. it('returns true for empty query', () => {
  41. expect(spoolMatchesQuery(makeSpool(), '')).toBe(true);
  42. });
  43. it('matches on material (case-insensitive)', () => {
  44. const spool = makeSpool({ material: 'PETG' });
  45. expect(spoolMatchesQuery(spool, 'petg')).toBe(true);
  46. expect(spoolMatchesQuery(spool, 'PET')).toBe(true);
  47. expect(spoolMatchesQuery(spool, 'pla')).toBe(false);
  48. });
  49. it('matches on brand (case-insensitive)', () => {
  50. const spool = makeSpool({ brand: 'Prusament' });
  51. expect(spoolMatchesQuery(spool, 'prusa')).toBe(true);
  52. expect(spoolMatchesQuery(spool, 'PRUSA')).toBe(true);
  53. });
  54. it('matches on color_name (case-insensitive)', () => {
  55. const spool = makeSpool({ color_name: 'Galaxy Black' });
  56. expect(spoolMatchesQuery(spool, 'galaxy')).toBe(true);
  57. expect(spoolMatchesQuery(spool, 'GALAXY')).toBe(true);
  58. expect(spoolMatchesQuery(spool, 'blue')).toBe(false);
  59. });
  60. it('matches on subtype (case-insensitive)', () => {
  61. const spool = makeSpool({ subtype: 'Matte' });
  62. expect(spoolMatchesQuery(spool, 'matt')).toBe(true);
  63. expect(spoolMatchesQuery(spool, 'MATTE')).toBe(true);
  64. });
  65. it('returns false when null optional fields do not match', () => {
  66. const spool = makeSpool({ brand: null, color_name: null, subtype: null });
  67. expect(spoolMatchesQuery(spool, 'bambu')).toBe(false);
  68. });
  69. it('matches on numeric id (#1336)', () => {
  70. const spool = makeSpool({ id: 42, material: 'PLA', brand: null, color_name: null, subtype: null, note: null });
  71. expect(spoolMatchesQuery(spool, '42')).toBe(true);
  72. expect(spoolMatchesQuery(spool, '4')).toBe(true);
  73. expect(spoolMatchesQuery(spool, '99')).toBe(false);
  74. });
  75. });
  76. describe('filterSpoolsByQuery', () => {
  77. const spools = [
  78. makeSpool({ id: 1, material: 'PLA', brand: 'Bambu Lab', color_name: 'Red' }),
  79. makeSpool({ id: 2, material: 'PETG', brand: 'Prusament', color_name: 'Blue' }),
  80. makeSpool({ id: 3, material: 'ABS', brand: null, color_name: 'Black', subtype: 'Matte' }),
  81. ];
  82. it('returns all spools for empty query', () => {
  83. expect(filterSpoolsByQuery(spools, '')).toHaveLength(3);
  84. });
  85. it('filters by material', () => {
  86. const result = filterSpoolsByQuery(spools, 'pla');
  87. expect(result).toHaveLength(1);
  88. expect(result[0].id).toBe(1);
  89. });
  90. it('filters by brand', () => {
  91. const result = filterSpoolsByQuery(spools, 'prusa');
  92. expect(result).toHaveLength(1);
  93. expect(result[0].id).toBe(2);
  94. });
  95. it('filters by subtype', () => {
  96. const result = filterSpoolsByQuery(spools, 'matte');
  97. expect(result).toHaveLength(1);
  98. expect(result[0].id).toBe(3);
  99. });
  100. it('returns empty array when no match', () => {
  101. expect(filterSpoolsByQuery(spools, 'nylon')).toHaveLength(0);
  102. });
  103. });