- Updated EmailContextMenu to replace color tag functionality with label tags. - Modified EmailListItem to display label badges for emails based on keywords. - Enhanced EmailViewer to include a tag picker for emails. - Adjusted ThreadListItem to show label badges for email subjects. - Added tests for email list item and keyword settings to ensure proper functionality of the new tagging system. - Updated localization files to reflect changes from color tags to labels in multiple languages.
160 lines
6.3 KiB
TypeScript
160 lines
6.3 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { useSettingsStore, DEFAULT_KEYWORDS, KEYWORD_PALETTE } from '../settings-store';
|
|
import type { KeywordDefinition } from '../settings-store';
|
|
|
|
describe('settings-store keywords', () => {
|
|
beforeEach(() => {
|
|
useSettingsStore.setState({ emailKeywords: [...DEFAULT_KEYWORDS] });
|
|
});
|
|
|
|
describe('DEFAULT_KEYWORDS', () => {
|
|
it('has 7 default keywords', () => {
|
|
expect(DEFAULT_KEYWORDS).toHaveLength(7);
|
|
});
|
|
|
|
it('each default keyword has a valid palette color', () => {
|
|
DEFAULT_KEYWORDS.forEach((kw) => {
|
|
expect(KEYWORD_PALETTE[kw.color]).toBeDefined();
|
|
expect(KEYWORD_PALETTE[kw.color].dot).toBeTruthy();
|
|
expect(KEYWORD_PALETTE[kw.color].bg).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
it('all default keyword ids are unique', () => {
|
|
const ids = DEFAULT_KEYWORDS.map((k) => k.id);
|
|
expect(new Set(ids).size).toBe(ids.length);
|
|
});
|
|
});
|
|
|
|
describe('KEYWORD_PALETTE', () => {
|
|
it('has 13 colors', () => {
|
|
expect(Object.keys(KEYWORD_PALETTE)).toHaveLength(13);
|
|
});
|
|
|
|
it('each color has dot and bg classes', () => {
|
|
Object.values(KEYWORD_PALETTE).forEach((entry) => {
|
|
expect(entry.dot).toMatch(/^bg-/);
|
|
expect(entry.bg).toMatch(/^bg-/);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('addKeyword', () => {
|
|
it('adds a new keyword to the list', () => {
|
|
const newKw: KeywordDefinition = { id: 'custom', label: 'Custom', color: 'teal' };
|
|
useSettingsStore.getState().addKeyword(newKw);
|
|
const keywords = useSettingsStore.getState().emailKeywords;
|
|
expect(keywords).toHaveLength(DEFAULT_KEYWORDS.length + 1);
|
|
expect(keywords[keywords.length - 1]).toEqual(newKw);
|
|
});
|
|
|
|
it('does not add duplicate keyword id', () => {
|
|
const duplicate: KeywordDefinition = { id: 'red', label: 'Another Red', color: 'red' };
|
|
useSettingsStore.getState().addKeyword(duplicate);
|
|
expect(useSettingsStore.getState().emailKeywords).toHaveLength(DEFAULT_KEYWORDS.length);
|
|
});
|
|
|
|
it('allows adding keyword after removing one with same id', () => {
|
|
useSettingsStore.getState().removeKeyword('red');
|
|
const newRed: KeywordDefinition = { id: 'red', label: 'New Red', color: 'red' };
|
|
useSettingsStore.getState().addKeyword(newRed);
|
|
const kw = useSettingsStore.getState().emailKeywords.find((k) => k.id === 'red');
|
|
expect(kw?.label).toBe('New Red');
|
|
});
|
|
});
|
|
|
|
describe('updateKeyword', () => {
|
|
it('updates label of existing keyword', () => {
|
|
useSettingsStore.getState().updateKeyword('red', { label: 'Crimson' });
|
|
const kw = useSettingsStore.getState().emailKeywords.find((k) => k.id === 'red');
|
|
expect(kw?.label).toBe('Crimson');
|
|
expect(kw?.color).toBe('red'); // color unchanged
|
|
});
|
|
|
|
it('updates color of existing keyword', () => {
|
|
useSettingsStore.getState().updateKeyword('blue', { color: 'cyan' });
|
|
const kw = useSettingsStore.getState().emailKeywords.find((k) => k.id === 'blue');
|
|
expect(kw?.color).toBe('cyan');
|
|
expect(kw?.label).toBe('Blue'); // label unchanged
|
|
});
|
|
|
|
it('updates both label and color', () => {
|
|
useSettingsStore.getState().updateKeyword('green', { label: 'Emerald', color: 'teal' });
|
|
const kw = useSettingsStore.getState().emailKeywords.find((k) => k.id === 'green');
|
|
expect(kw?.label).toBe('Emerald');
|
|
expect(kw?.color).toBe('teal');
|
|
});
|
|
|
|
it('does not affect other keywords', () => {
|
|
useSettingsStore.getState().updateKeyword('red', { label: 'Crimson' });
|
|
const blue = useSettingsStore.getState().emailKeywords.find((k) => k.id === 'blue');
|
|
expect(blue?.label).toBe('Blue');
|
|
});
|
|
|
|
it('is a no-op for non-existent id', () => {
|
|
const before = useSettingsStore.getState().emailKeywords;
|
|
useSettingsStore.getState().updateKeyword('nonexistent', { label: 'Test' });
|
|
const after = useSettingsStore.getState().emailKeywords;
|
|
expect(after).toHaveLength(before.length);
|
|
});
|
|
});
|
|
|
|
describe('removeKeyword', () => {
|
|
it('removes a keyword by id', () => {
|
|
useSettingsStore.getState().removeKeyword('red');
|
|
const keywords = useSettingsStore.getState().emailKeywords;
|
|
expect(keywords).toHaveLength(DEFAULT_KEYWORDS.length - 1);
|
|
expect(keywords.find((k) => k.id === 'red')).toBeUndefined();
|
|
});
|
|
|
|
it('is a no-op for non-existent id', () => {
|
|
useSettingsStore.getState().removeKeyword('nonexistent');
|
|
expect(useSettingsStore.getState().emailKeywords).toHaveLength(DEFAULT_KEYWORDS.length);
|
|
});
|
|
|
|
it('preserves order of remaining keywords', () => {
|
|
useSettingsStore.getState().removeKeyword('green');
|
|
const ids = useSettingsStore.getState().emailKeywords.map((k) => k.id);
|
|
expect(ids).toEqual(['red', 'orange', 'yellow', 'blue', 'purple', 'pink']);
|
|
});
|
|
});
|
|
|
|
describe('reorderKeywords', () => {
|
|
it('replaces keyword list with new ordering', () => {
|
|
const reversed = [...DEFAULT_KEYWORDS].reverse();
|
|
useSettingsStore.getState().reorderKeywords(reversed);
|
|
const ids = useSettingsStore.getState().emailKeywords.map((k) => k.id);
|
|
expect(ids).toEqual(reversed.map((k) => k.id));
|
|
});
|
|
|
|
it('can set to empty list', () => {
|
|
useSettingsStore.getState().reorderKeywords([]);
|
|
expect(useSettingsStore.getState().emailKeywords).toHaveLength(0);
|
|
});
|
|
|
|
it('can reset to defaults', () => {
|
|
useSettingsStore.getState().removeKeyword('red');
|
|
useSettingsStore.getState().removeKeyword('blue');
|
|
useSettingsStore.getState().reorderKeywords(DEFAULT_KEYWORDS);
|
|
expect(useSettingsStore.getState().emailKeywords).toEqual(DEFAULT_KEYWORDS);
|
|
});
|
|
});
|
|
|
|
describe('getKeywordById', () => {
|
|
it('finds keyword by id', () => {
|
|
const kw = useSettingsStore.getState().getKeywordById('blue');
|
|
expect(kw).toEqual({ id: 'blue', label: 'Blue', color: 'blue' });
|
|
});
|
|
|
|
it('returns undefined for non-existent id', () => {
|
|
expect(useSettingsStore.getState().getKeywordById('nonexistent')).toBeUndefined();
|
|
});
|
|
|
|
it('returns updated keyword data after updateKeyword', () => {
|
|
useSettingsStore.getState().updateKeyword('red', { label: 'Scarlet' });
|
|
const kw = useSettingsStore.getState().getKeywordById('red');
|
|
expect(kw?.label).toBe('Scarlet');
|
|
});
|
|
});
|
|
});
|