feat(filters): add tag and price dimensions (#188)

This commit is contained in:
2026-08-25 15:06:15 -05:00
parent 5d0b66a982
commit abd3dd4e2e
2 changed files with 192 additions and 2 deletions
+51 -1
View File
@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { EMPTY_FILTERS, ItemFilters } from '../../src/filters';
import type { FilterContext } from '../../src/components/filters/dimension';
import { categoryDimension } from '../../src/components/filters/standardDimensions';
import { categoryDimension, priceDimension, tagDimension } from '../../src/components/filters/standardDimensions';
import type { Category, Tag as ItemTag } from '../../src/api';
const CATEGORIES: Category[] = [
@@ -55,3 +55,53 @@ describe('categoryDimension', () => {
expect(state.latest?.categoryIds).toEqual([3]);
});
});
describe('tagDimension', () => {
it('reports no chips when nothing is selected', () => {
const { ctx } = contextFor({});
expect(tagDimension.chips(ctx)).toEqual([]);
});
// #185: a tag looks like itself wherever it appears.
it('reports one chip per tag, carrying that tag colour', () => {
const { ctx } = contextFor({ tagIds: [10, 11] });
expect(tagDimension.chips(ctx).map((chip) => [chip.label, chip.color])).toEqual([
['vintage', 'red'],
['oak', 'lime']
]);
});
it('falls back to the id, uncoloured, for a tag not loaded yet', () => {
const { ctx } = contextFor({ tagIds: [99] });
const [chip] = tagDimension.chips(ctx);
expect(chip?.label).toBe('Tag 99');
expect(chip?.color).toBeUndefined();
});
it('removes only the chip that was closed', () => {
const { ctx, state } = contextFor({ tagIds: [10, 11] });
tagDimension.chips(ctx)[0]?.onRemove();
expect(state.latest?.tagIds).toEqual([11]);
});
});
describe('priceDimension', () => {
it('reports no chip when neither end is set', () => {
const { ctx } = contextFor({});
expect(priceDimension.chips(ctx)).toEqual([]);
});
// One chip for the range rather than one per end: they are one filter, and
// removing half of it is not a thing anyone means.
it('reports a single chip when either end is set', () => {
expect(priceDimension.chips(contextFor({ minPriceCents: 1000 }).ctx)).toHaveLength(1);
expect(priceDimension.chips(contextFor({ maxPriceCents: 5000 }).ctx)).toHaveLength(1);
});
it('clears both ends when removed', () => {
const { ctx, state } = contextFor({ minPriceCents: 1000, maxPriceCents: 5000 });
priceDimension.chips(ctx)[0]?.onRemove();
expect(state.latest?.minPriceCents).toBeNull();
expect(state.latest?.maxPriceCents).toBeNull();
});
});