71 lines
2.4 KiB
TypeScript
71 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 CustomLinkChannel from './CustomLinkChannel.svelte';
|
|
|
|
const channel = {
|
|
id: 'project-custom-link',
|
|
projectID: 1,
|
|
type: 'custom_link' as const,
|
|
title: 'Roadmap Board',
|
|
icon: 'link',
|
|
url: 'https://example.com/roadmap',
|
|
sortOrder: 1,
|
|
};
|
|
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('CustomLinkChannel', () => {
|
|
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(CustomLinkChannel, { props: { channel } });
|
|
|
|
await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
|
|
|
|
expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
|
|
resolveWrite?.();
|
|
await waitFor(() => expect(screen.getByText('URL copied.')).toBeInTheDocument());
|
|
});
|
|
|
|
it('reports a copy failure when clipboard writing rejects', async () => {
|
|
setClipboard(vi.fn().mockRejectedValue(new Error('Permission denied')));
|
|
render(CustomLinkChannel, { props: { channel } });
|
|
|
|
await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
|
|
|
|
await waitFor(() => expect(screen.getByText('Unable to copy URL.')).toBeInTheDocument());
|
|
});
|
|
|
|
it('reports unavailable clipboard access without showing URL copied', async () => {
|
|
Reflect.deleteProperty(navigator, 'clipboard');
|
|
render(CustomLinkChannel, { props: { channel } });
|
|
|
|
await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
|
|
|
|
await waitFor(() => expect(screen.getByText('Copy unavailable in this browser.')).toBeInTheDocument());
|
|
expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
|
|
});
|
|
});
|