mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 08:15:41 +00:00
Uploads in Files had their own card with a thick progress bar, larger corners and a heavier shadow, so they looked unlike the toasts around them. Toasts can now show work in progress: the thin line at the bottom fills with progress instead of counting down, and the toast stays until it is updated or removed. Uploads use it, with the file and percentage below the title and Cancel as the toast action.
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { act, render, screen } from '@testing-library/react';
|
|
import { ToastContainer } from '../toast';
|
|
import { toast, useToastStore } from '@/stores/toast-store';
|
|
|
|
function Toasts() {
|
|
const toasts = useToastStore((s) => s.toasts);
|
|
const removeToast = useToastStore((s) => s.removeToast);
|
|
return <ToastContainer toasts={toasts} onClose={removeToast} />;
|
|
}
|
|
|
|
describe('progress toasts', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
useToastStore.setState({ toasts: [] });
|
|
});
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('shows progress on the bottom line and stays until removed', () => {
|
|
render(<Toasts />);
|
|
let id = '';
|
|
act(() => { id = toast.progress('Uploading...', { message: 'a.stl', progress: 0.25 }); });
|
|
expect(screen.getByRole('progressbar')).toHaveAttribute('aria-valuenow', '25');
|
|
|
|
act(() => { vi.advanceTimersByTime(60_000); });
|
|
expect(screen.getByText('Uploading...')).toBeInTheDocument();
|
|
|
|
act(() => { toast.update(id, { progress: 0.8, message: 'a.stl · 80%' }); });
|
|
expect(screen.getByRole('progressbar')).toHaveAttribute('aria-valuenow', '80');
|
|
expect(screen.getByText('a.stl · 80%')).toBeInTheDocument();
|
|
|
|
act(() => { toast.dismiss(id); });
|
|
expect(screen.queryByText('Uploading...')).toBeNull();
|
|
});
|
|
|
|
it('runs the action, e.g. Cancel, from the toast', () => {
|
|
const onCancel = vi.fn();
|
|
render(<Toasts />);
|
|
act(() => { toast.progress('Uploading...', { progress: null, action: { label: 'Cancel', onClick: onCancel } }); });
|
|
act(() => { screen.getByText('Cancel').click(); });
|
|
expect(onCancel).toHaveBeenCalled();
|
|
});
|
|
|
|
it('counts down normally once turned into a regular toast', () => {
|
|
render(<Toasts />);
|
|
let id = '';
|
|
act(() => { id = toast.progress('Uploading...', { progress: 0.5 }); });
|
|
act(() => { toast.update(id, { title: 'Uploaded', progress: undefined, duration: 1000, type: 'success' }); });
|
|
expect(screen.getByText('Uploaded')).toBeInTheDocument();
|
|
act(() => { vi.advanceTimersByTime(1500); });
|
|
expect(useToastStore.getState().toasts).toHaveLength(0);
|
|
});
|
|
});
|