Files
nexu-io__open-design/apps/web/tests/utils/completion-feedback-activation.test.ts
open-design-crew[bot] 50c15417a9 fix(web): enable completion feedback by default (#7038)
Enable completion sound and desktop notifications for fresh configurations while preserving saved opt-outs. Activate browser audio and permission flows only from the first real task submission gesture.

Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com>
2026-08-18 09:42:37 +00:00

72 lines
2.4 KiB
TypeScript

// @vitest-environment jsdom
import { fireEvent } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
armCompletionFeedbackOnFirstGesture,
notifyCompletionFeedbackGesture,
type CompletionFeedbackActivationResult,
} from '../../src/utils/notifications';
const BASE_CONFIG = {
soundEnabled: true,
successSoundId: 'ding',
failureSoundId: 'buzz',
desktopEnabled: true,
};
afterEach(() => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
});
describe('armCompletionFeedbackOnFirstGesture', () => {
it('waits for the first task submission, then primes audio and requests permission once', async () => {
const resume = vi.fn().mockResolvedValue(undefined);
class MockAudioContext {
state: AudioContextState = 'suspended';
resume = resume;
}
const requestPermission = vi.fn().mockResolvedValue('granted');
class MockNotification {
static permission: NotificationPermission = 'default';
static requestPermission = requestPermission;
}
vi.stubGlobal('AudioContext', MockAudioContext);
vi.stubGlobal('Notification', MockNotification);
const onResult = vi.fn<(result: CompletionFeedbackActivationResult) => void>();
const dispose = armCompletionFeedbackOnFirstGesture(BASE_CONFIG, onResult);
fireEvent.pointerDown(window);
expect(resume).not.toHaveBeenCalled();
expect(requestPermission).not.toHaveBeenCalled();
notifyCompletionFeedbackGesture();
notifyCompletionFeedbackGesture();
await vi.waitFor(() => expect(onResult).toHaveBeenCalledWith({ desktopPermission: 'granted' }));
expect(resume).toHaveBeenCalledTimes(1);
expect(requestPermission).toHaveBeenCalledTimes(1);
dispose();
});
it('reports a denied permission so the caller can turn the persisted switch off', async () => {
const requestPermission = vi.fn().mockResolvedValue('denied');
class MockNotification {
static permission: NotificationPermission = 'default';
static requestPermission = requestPermission;
}
vi.stubGlobal('Notification', MockNotification);
const onResult = vi.fn<(result: CompletionFeedbackActivationResult) => void>();
const dispose = armCompletionFeedbackOnFirstGesture(
{ ...BASE_CONFIG, soundEnabled: false },
onResult,
);
notifyCompletionFeedbackGesture();
await vi.waitFor(() => expect(onResult).toHaveBeenCalledWith({ desktopPermission: 'denied' }));
dispose();
});
});