import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'; import type { FormEvent } from 'react'; import { afterEach, beforeEach, expect, it, vi } from 'vitest'; import { invokeIpc } from '@/lib/api-client'; import { COMMUNITY_URL } from '@/lib/community'; import { CommunityLink } from '@/components/community/CommunityLink'; import { CodingStartHeading } from '@/pages/Chat/CodingStartHeading'; vi.mock('@/lib/api-client', () => ({ invokeIpc: vi.fn() })); beforeEach(() => { vi.mocked(invokeIpc).mockReset().mockResolvedValue(undefined); }); afterEach(() => { cleanup(); vi.restoreAllMocks(); }); it('only opens the public explore URL after a click, without fetching or embedding works', async () => { const fetch = vi.spyOn(globalThis, 'fetch'); render(); expect(screen.getByRole('heading', { name: '今天,你想创造什么?' })).toBeInTheDocument(); expect(screen.getByText('一个游戏、一段故事,或是一个天马行空的想法。')).toBeInTheDocument(); expect(screen.queryByTestId('community-invitation')).not.toBeInTheDocument(); expect(invokeIpc).not.toHaveBeenCalled(); expect(fetch).not.toHaveBeenCalled(); expect(document.querySelector('iframe')).toBeNull(); const button = screen.getByRole('button', { name: '作品广场' }); expect(button).toHaveAttribute('type', 'button'); expect(button.querySelector('.coding-start-mark img')).not.toBeNull(); expect(button.querySelectorAll('.coding-start-mark > svg')).toHaveLength(2); fireEvent.click(button); await waitFor(() => expect(invokeIpc).toHaveBeenCalledExactlyOnceWith('shell:openExternal', COMMUNITY_URL)); fetch.mockRestore(); }); it('provides an accessible collapsed sidebar entry and a retry after opening fails', async () => { vi.mocked(invokeIpc).mockRejectedValueOnce(new Error('unavailable')); render(); const button = screen.getByRole('button', { name: '作品广场' }); expect(button.querySelector('.community-link-icon svg')).not.toBeNull(); fireEvent.click(button); await screen.findByRole('alert'); await waitFor(() => expect(button).toBeEnabled()); fireEvent.click(button); await waitFor(() => expect(invokeIpc).toHaveBeenCalledTimes(2)); expect(screen.queryByRole('alert')).not.toBeInTheDocument(); }); it('keeps the welcome entry available for retry without submitting its surrounding form', async () => { const submit = vi.fn((event: FormEvent) => event.preventDefault()); vi.mocked(invokeIpc).mockRejectedValueOnce(new Error('unavailable')); render(
); const button = screen.getByRole('button', { name: '作品广场' }); fireEvent.click(button); await screen.findByRole('alert'); await waitFor(() => expect(button).toBeEnabled()); expect(submit).not.toHaveBeenCalled(); fireEvent.click(button); await waitFor(() => expect(invokeIpc).toHaveBeenCalledTimes(2)); expect(invokeIpc).toHaveBeenLastCalledWith('shell:openExternal', COMMUNITY_URL); expect(screen.queryByRole('alert')).not.toBeInTheDocument(); expect(submit).not.toHaveBeenCalled(); });