Files
agent/apps/web/src/features/workbench/ObjectInspector.test.ts

74 lines
2.4 KiB
TypeScript

import '@testing-library/jest-dom/vitest';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import { afterEach, describe, expect, it, vi } from 'vitest';
import ObjectInspector from './ObjectInspector.svelte';
const item = {
title: 'Review navigation',
type: 'Task',
description: 'Check the project navigation flow.',
properties: [],
};
const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');
function setClipboard(writeText: Clipboard['writeText']) {
Object.defineProperty(navigator, 'clipboard', {
configurable: true,
value: { writeText } as Clipboard,
});
}
afterEach(() => {
cleanup();
if (originalClipboard) {
Object.defineProperty(navigator, 'clipboard', originalClipboard);
} else {
Reflect.deleteProperty(navigator, 'clipboard');
}
});
describe('ObjectInspector', () => {
async function openMoreActions() {
await fireEvent.click(screen.getByRole('button', { name: 'More' }));
}
it('shows copy success only after clipboard writing resolves', async () => {
let resolveWrite: (() => void) | undefined;
const writeText = vi.fn(
() =>
new Promise<void>((resolve) => {
resolveWrite = resolve;
}),
);
setClipboard(writeText);
render(ObjectInspector, { props: { item } });
await openMoreActions();
await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
expect(screen.queryByRole('status')).not.toBeInTheDocument();
resolveWrite?.();
await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('Link copied to clipboard.'));
});
it('reports a copy failure when clipboard writing rejects', async () => {
setClipboard(vi.fn().mockRejectedValue(new Error('Permission denied')));
render(ObjectInspector, { props: { item } });
await openMoreActions();
await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('Unable to copy link.'));
});
it('reports unavailable clipboard access without showing success', async () => {
Reflect.deleteProperty(navigator, 'clipboard');
render(ObjectInspector, { props: { item } });
await openMoreActions();
await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
expect(screen.getByRole('status')).toHaveTextContent('Clipboard access is unavailable.');
});
});