feat(filters): add favorites and status dimensions (#188)

This commit is contained in:
2026-08-25 15:12:35 -05:00
parent 60b76cae82
commit eb5799dd17
2 changed files with 130 additions and 1 deletions
+51 -1
View File
@@ -1,7 +1,13 @@
import { describe, it, expect } from 'vitest';
import { EMPTY_FILTERS, ItemFilters } from '../../src/filters';
import type { FilterContext } from '../../src/components/filters/dimension';
import { categoryDimension, priceDimension, tagDimension } from '../../src/components/filters/standardDimensions';
import {
categoryDimension,
favoritesDimension,
priceDimension,
statusDimension,
tagDimension
} from '../../src/components/filters/standardDimensions';
import type { Category, Tag as ItemTag } from '../../src/api';
const CATEGORIES: Category[] = [
@@ -105,3 +111,47 @@ describe('priceDimension', () => {
expect(state.latest?.maxPriceCents).toBeNull();
});
});
describe('favoritesDimension', () => {
it('reports no chip when off', () => {
expect(favoritesDimension.chips(contextFor({}).ctx)).toEqual([]);
});
it('reports one chip when on', () => {
const { ctx } = contextFor({ favoritesOnly: true });
expect(favoritesDimension.chips(ctx).map((chip) => chip.label)).toEqual(['My favorites']);
});
it('switches off when removed', () => {
const { ctx, state } = contextFor({ favoritesOnly: true });
favoritesDimension.chips(ctx)[0]?.onRemove();
expect(state.latest?.favoritesOnly).toBe(false);
});
});
describe('statusDimension', () => {
it('reports no chips when no status is filtered', () => {
expect(statusDimension.chips(contextFor({ status: null }).ctx)).toEqual([]);
});
// The behaviour change in #188: one chip each, so the tally reads 3 rather
// than 1, consistent with how categories and tags already count.
it('reports one chip per status, labelled for a human', () => {
const { ctx } = contextFor({ status: ['pending', 'sold'] });
expect(statusDimension.chips(ctx).map((chip) => chip.label)).toEqual(['Pending', 'Sold']);
});
it('removes one status and keeps the rest', () => {
const { ctx, state } = contextFor({ status: ['pending', 'sold'] });
statusDimension.chips(ctx)[0]?.onRemove();
expect(state.latest?.status).toEqual(['sold']);
});
// Emptying the control means "no status filter", not "no statuses" — the
// latter would empty the table.
it('returns to no filter when the last status is removed', () => {
const { ctx, state } = contextFor({ status: ['sold'] });
statusDimension.chips(ctx)[0]?.onRemove();
expect(state.latest?.status).toBeNull();
});
});