test: fix broken suites
This commit is contained in:
@@ -136,6 +136,7 @@ vi.mock('@/lib/plugin-hooks', () => ({
|
||||
getRecipientSuggestions: { call: async () => [] },
|
||||
onSend: { call: async () => [] },
|
||||
beforeSend: { call: async () => [] },
|
||||
onRecipientChipsChange: { transform: async (chips: unknown) => chips },
|
||||
},
|
||||
contactHooks: {
|
||||
search: { call: async () => [] },
|
||||
@@ -229,8 +230,10 @@ describe('RecipientChipInput drag and drop', () => {
|
||||
const dt = new MockDataTransfer();
|
||||
fireEvent.dragStart(chipSpan, { dataTransfer: dt });
|
||||
|
||||
// The enrichment pass may have stamped extra display metadata on the
|
||||
// chip by drag time, so match the essential fields rather than deep-equal.
|
||||
const payload = JSON.parse(dt.getData('application/x-recipient-chip'));
|
||||
expect(payload).toEqual({ recipient: { email: 'alice@example.com' }, fromField: 'to', fromIndex: 0 });
|
||||
expect(payload).toMatchObject({ recipient: { email: 'alice@example.com' }, fromField: 'to', fromIndex: 0 });
|
||||
});
|
||||
|
||||
it('keeps a display name with a comma in a single chip (array model)', async () => {
|
||||
@@ -244,7 +247,7 @@ describe('RecipientChipInput drag and drop', () => {
|
||||
const dt = new MockDataTransfer();
|
||||
fireEvent.dragStart(chipSpan, { dataTransfer: dt });
|
||||
const payload = JSON.parse(dt.getData('application/x-recipient-chip'));
|
||||
expect(payload).toEqual({ recipient: { name: 'Doo, John', email: 'john@doo.org' }, fromField: 'to', fromIndex: 0 });
|
||||
expect(payload).toMatchObject({ recipient: { name: 'Doo, John', email: 'john@doo.org' }, fromField: 'to', fromIndex: 0 });
|
||||
});
|
||||
|
||||
it('onDragEnd clears the opacity class on the chip', async () => {
|
||||
|
||||
@@ -135,6 +135,7 @@ vi.mock('@/lib/plugin-hooks', () => ({
|
||||
getRecipientSuggestions: { call: async () => [] },
|
||||
onSend: { call: async () => [] },
|
||||
beforeSend: { call: async () => [] },
|
||||
onRecipientChipsChange: { transform: async (chips: unknown) => chips },
|
||||
},
|
||||
contactHooks: {
|
||||
search: { call: async () => [] },
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { unlink, writeFileSync } from "fs";
|
||||
import { mkdtempSync, unlink, writeFileSync } from "fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
// The route consults admin-dashboard overrides (ADMIN_CONFIG_DIR, default
|
||||
// data/admin) before env vars. Point it at an empty temp dir so local admin
|
||||
// state on the developer's machine can't leak into these env-driven
|
||||
// assertions. Must happen before the first GET, because the config manager
|
||||
// singleton loads the directory once and caches it.
|
||||
process.env.ADMIN_CONFIG_DIR = mkdtempSync(path.join(tmpdir(), 'bw-config-route-'));
|
||||
|
||||
// Mock NextResponse before importing the route
|
||||
vi.mock('next/server', () => ({
|
||||
NextResponse: {
|
||||
|
||||
@@ -302,6 +302,11 @@ describe('JMAPClient resilience', () => {
|
||||
});
|
||||
|
||||
it('does not mark the connection lost or reconnect repeatedly while rate limited', async () => {
|
||||
// The file-level shouldAdvanceTime lets fake time creep forward with
|
||||
// the wall clock, which can fire the 30s keep-alive an extra time on a
|
||||
// slow or loaded machine. This test counts pings, so pin the clock and
|
||||
// advance it explicitly.
|
||||
vi.useFakeTimers({ shouldAdvanceTime: false });
|
||||
const client = await createConnectedClient();
|
||||
const callback = vi.fn();
|
||||
client.onConnectionChange(callback);
|
||||
|
||||
@@ -247,18 +247,18 @@ describe('contact-store', () => {
|
||||
expect(results.length).toBeLessThanOrEqual(10);
|
||||
});
|
||||
|
||||
it('should expand group members when group name matches', () => {
|
||||
it('should suggest a matching group as a single entry with member count', () => {
|
||||
const member1 = makeContact({ id: 'm1', name: { components: [{ kind: 'given', value: 'Alice' }], isOrdered: true }, emails: { e0: { address: 'alice@test.com' } } });
|
||||
const member2 = makeContact({ id: 'm2', name: { components: [{ kind: 'given', value: 'Bob' }], isOrdered: true }, emails: { e0: { address: 'bob@test.com' } } });
|
||||
const group = makeGroup({ id: 'g1', members: { m1: true, m2: true } });
|
||||
useContactStore.setState({ contacts: [member1, member2, group] });
|
||||
|
||||
const results = useContactStore.getState().getAutocomplete('Team');
|
||||
expect(results).toHaveLength(2);
|
||||
expect(results.map(r => r.email).sort()).toEqual(['alice@test.com', 'bob@test.com']);
|
||||
expect(results).toHaveLength(1);
|
||||
expect(results[0]).toEqual({ name: 'Team', email: '', group: { id: 'g1', memberCount: 2 } });
|
||||
});
|
||||
|
||||
it('should not include group itself in results', () => {
|
||||
it('should not suggest a group with no addressable members', () => {
|
||||
const group = makeGroup({ id: 'g1' });
|
||||
useContactStore.setState({ contacts: [group] });
|
||||
const results = useContactStore.getState().getAutocomplete('Team');
|
||||
|
||||
+5
-3
@@ -9,9 +9,11 @@ export default defineConfig({
|
||||
globals: true,
|
||||
setupFiles: ['./vitest.setup.ts'],
|
||||
// integration/** is the dockerized Playwright suite (run via
|
||||
// `npm run test:integration`); examples/** is untracked sample code. Both
|
||||
// use their own runners and must not be collected by vitest.
|
||||
exclude: ['e2e/**', 'integration/**', 'examples/**', 'node_modules/**', '.next/**'],
|
||||
// `npm run test:integration`); examples/** is untracked sample code; and
|
||||
// repos/** holds sibling checkouts with their own runners. node_modules
|
||||
// must be globbed at any depth or the nested repos/*/node_modules trees
|
||||
// get collected too.
|
||||
exclude: ['e2e/**', 'integration/**', 'examples/**', 'repos/**', '**/node_modules/**', '.next/**'],
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
|
||||
Reference in New Issue
Block a user