Files
webmail/lib/__tests__/unread-first.test.ts
T

55 lines
2.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type { Email } from '@/lib/jmap/types';
import { andFilters, isUnreadFirstView, mergeUnreadSection, withoutReached, type UnreadSection } from '../unread-first';
const mail = (id: string, threadId = `thread-${id}`) => ({ id, threadId, keywords: {} }) as Email;
const section = (...ids: string[]): UnreadSection => ({ mailboxId: 'inbox', ids: new Set(ids), total: ids.length });
describe('mergeUnreadSection', () => {
it('puts the fresh section first and drops the rows that left it', () => {
const list = [mail('u1'), mail('u2'), mail('r1'), mail('r2')];
const merged = mergeUnreadSection(list, section('u1', 'u2'), [mail('u3'), mail('u1')], null);
expect(merged.emails.map((e) => e.id)).toEqual(['u3', 'u1', 'r1', 'r2']);
expect([...merged.ids]).toEqual(['u3', 'u1']);
});
it('keeps the open conversation\'s message that left the section', () => {
const list = [mail('u1'), mail('u2', 'open'), mail('r1')];
const merged = mergeUnreadSection(list, section('u1', 'u2'), [mail('u1')], 'open');
expect(merged.emails.map((e) => e.id)).toEqual(['u1', 'u2', 'r1']);
expect(merged.ids.has('u2')).toBe(true);
});
it('takes a row of the main list the section now has into the section', () => {
const merged = mergeUnreadSection([mail('r1'), mail('r2')], section(), [mail('r2')], null);
expect(merged.emails.map((e) => e.id)).toEqual(['r2', 'r1']);
});
});
describe('withoutReached', () => {
it('returns the same section when a page reached none of its rows', () => {
const before = section('u1');
expect(withoutReached(before, ['r1'])).toBe(before);
expect([...withoutReached(before, ['u1'])!.ids]).toEqual([]);
});
});
describe('andFilters', () => {
it('ANDs two fragments and passes a lone one through', () => {
expect(andFilters(null, { a: 1 })).toEqual({ a: 1 });
expect(andFilters({ a: 1 }, undefined)).toEqual({ a: 1 });
expect(andFilters({ a: 1 }, { b: 2 })).toEqual({ operator: 'AND', conditions: [{ a: 1 }, { b: 2 }] });
});
});
describe('isUnreadFirstView', () => {
const view = { interfaceLayout: 'mountain-view', mvInboxType: 'unread-first', mailboxRole: 'inbox', otherView: false } as const;
it('is Mountain View\'s inbox with the inbox type set, and nothing else', () => {
expect(isUnreadFirstView(view)).toBe(true);
expect(isUnreadFirstView({ ...view, interfaceLayout: 'default' })).toBe(false);
expect(isUnreadFirstView({ ...view, mvInboxType: 'default' })).toBe(false);
expect(isUnreadFirstView({ ...view, mailboxRole: 'archive' })).toBe(false);
expect(isUnreadFirstView({ ...view, otherView: true })).toBe(false);
});
});