ATProto social network
Something went wrong. Try again.
2.5 kB · 86 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687import { describe, it, expect, vi, beforeEach } from 'vitest';import { render, screen, fireEvent, act } from '@testing-library/svelte';import PostView from './PostView.svelte';import type { PostData } from '$lib/types/content-blocks';import { page } from '$app/state';
// Mock toast storevi.mock('$lib/stores/toast.svelte', () => ({ addToast: vi.fn()}));
const mockPost: PostData = { uri: 'at://did:plc:user1/at.riven.post/123', cid: 'cid123', author: { did: 'did:plc:user1', handle: 'user1.test', displayName: 'User One' }, createdAt: new Date().toISOString(), body: { text: 'Hello world' }};
describe('PostView', () => { beforeEach(() => { vi.useFakeTimers(); // @ts-ignore page.data.session = null; });
it('renders post content', () => { render(PostView, { post: mockPost }); expect(screen.getByText('User One')).toBeInTheDocument(); expect(screen.getByText('Hello world')).toBeInTheDocument(); });
it('shows reactive time updates', async () => { const past = new Date(Date.now() - 1000 * 60).toISOString(); // 1m ago const post = { ...mockPost, createdAt: past }; render(PostView, { post }); expect(screen.getByText(/1m ago/)).toBeInTheDocument();
// Fast forward 1 minute await act(() => { vi.advanceTimersByTime(60000); });
expect(screen.getByText(/2m ago/)).toBeInTheDocument(); });
it('shows delete button only for owner', () => { // Not owner const { unmount } = render(PostView, { post: mockPost }); expect(screen.queryByLabelText('Delete post')).not.toBeInTheDocument(); unmount();
// Owner // @ts-ignore page.data.session = { did: 'did:plc:user1' }; render(PostView, { post: mockPost }); expect(screen.getByLabelText('Delete post')).toBeInTheDocument(); });
it('calls delete API when delete button is clicked', async () => { // @ts-ignore page.data.session = { did: 'did:plc:user1' }; const fetchMock = vi.fn().mockResolvedValue({ ok: true }); global.fetch = fetchMock;
render(PostView, { post: mockPost }); // Initial delete button click to show confirmation const deleteBtn = screen.getByLabelText('Delete post'); await fireEvent.click(deleteBtn);
// Click confirm button const confirmBtn = screen.getByLabelText('Confirm delete post'); await fireEvent.click(confirmBtn);
expect(fetchMock).toHaveBeenCalledWith('/api/posts', expect.objectContaining({ method: 'DELETE', body: JSON.stringify({ uri: mockPost.uri }) })); });});