import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/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 { CommunityInvitation } from '@/components/community/CommunityInvitation'; vi.mock('@/lib/api-client', () => ({ invokeIpc: vi.fn() })); beforeEach(() => { vi.mocked(invokeIpc).mockReset().mockResolvedValue(undefined); }); afterEach(cleanup); it('only opens the public explore URL after a click, without fetching or embedding works', async () => { const fetch = vi.spyOn(globalThis, 'fetch'); render(); expect(invokeIpc).not.toHaveBeenCalled(); expect(fetch).not.toHaveBeenCalled(); expect(document.querySelector('iframe')).toBeNull(); fireEvent.click(screen.getByRole('button', { name: '去作品广场逛逛' })); 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: '作品广场' }); 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(); });