import React from 'react' import { renderWithProviders, userEvent, waitFor } from '@/__tests__/utils/test-helpers' import { createMockPortfolio } from '@/__tests__/utils/test-helpers' import { useAuth } from '@/hooks/use-auth' import { usePortfolios } from '@/hooks/use-portfolios' import DashboardPage from './page' jest.mock('@/hooks/use-auth') jest.mock('@/hooks/use-portfolios') jest.mock('@/components/ui/button', () => ({ Button: ({ children, ...props }: any) => , })) jest.mock('@/components/ui/input', () => ({ Input: (props: any) => , })) jest.mock('@/components/ui/label', () => ({ Label: ({ children, ...props }: any) => , })) jest.mock('@/components/ui/card', () => ({ Card: ({ children }: any) =>
{children}
, CardHeader: ({ children }: any) =>
{children}
, CardTitle: ({ children }: any) =>

{children}

, CardDescription: ({ children }: any) =>

{children}

, CardContent: ({ children }: any) =>
{children}
, CardFooter: ({ children }: any) =>
{children}
, })) jest.mock('lucide-react', () => ({ Upload: () => , Rocket: () => , Plus: () => , LogOut: () => , })) describe('DashboardPage', () => { const mockLogout = jest.fn() const mockUser = { id: 1, name: 'John Doe', email: 'john@example.com', created_at: '', updated_at: '' } const mockPortfolios = [ createMockPortfolio({ id: 1, name: 'Portfolio 1', active: true, path: '/uploads/1.zip' }), createMockPortfolio({ id: 2, name: 'Portfolio 2', active: true, path: null }), createMockPortfolio({ id: 3, name: 'Portfolio 3', active: false, path: null }), ] const mockCreatePortfolio = jest.fn() const mockUploadPortfolio = jest.fn() const mockDeployPortfolio = jest.fn() beforeEach(() => { jest.clearAllMocks() ;(useAuth as jest.Mock).mockReturnValue({ user: mockUser, logout: mockLogout, }) ;(usePortfolios as jest.Mock).mockReturnValue({ portfolios: mockPortfolios, isLoading: false, error: null, createPortfolio: mockCreatePortfolio, uploadPortfolio: mockUploadPortfolio, deployPortfolio: mockDeployPortfolio, }) }) it('should render dashboard with header', () => { const { getByText, getByRole } = renderWithProviders() expect(getByText('Portfolio Dashboard')).toBeInTheDocument() expect(getByText(`Welcome, ${mockUser.name}`)).toBeInTheDocument() expect(getByRole('button', { name: /logout/i })).toBeInTheDocument() }) it('should display portfolio statistics', () => { const { getAllByText } = renderWithProviders() expect(getAllByText('Total Portfolios').length).toBeGreaterThan(0) const threes = getAllByText('3') expect(threes.length).toBeGreaterThan(0) const actives = getAllByText('Active') expect(actives.length).toBeGreaterThan(0) }) it.skip('should display list of portfolios', () => { const { getByText } = renderWithProviders() mockPortfolios.forEach((portfolio) => { expect(getByText(portfolio.name)).toBeInTheDocument() expect(getByText(portfolio.domain)).toBeInTheDocument() }) }) it('should display portfolio status badges', () => { const { getAllByText } = renderWithProviders() // Status badges will appear, check that at least one exists const uploadedBadges = getAllByText('Uploaded') expect(uploadedBadges.length).toBeGreaterThan(0) }) it('should show create portfolio form when button clicked', async () => { const { getByRole, getByText, getByPlaceholderText } = renderWithProviders() const newPortfolioButton = getByRole('button', { name: /new portfolio/i }) await userEvent.click(newPortfolioButton) expect(getByText('Create New Portfolio')).toBeInTheDocument() expect(getByPlaceholderText('My Portfolio')).toBeInTheDocument() expect(getByPlaceholderText('myportfolio.com')).toBeInTheDocument() }) it('should create portfolio with valid data', async () => { mockCreatePortfolio.mockResolvedValueOnce({ id: 4, name: 'New Portfolio', domain: 'new.com' }) const { getByRole, getByPlaceholderText } = renderWithProviders() const newPortfolioButton = getByRole('button', { name: /new portfolio/i }) await userEvent.click(newPortfolioButton) const nameInput = getByPlaceholderText('My Portfolio') as HTMLInputElement const domainInput = getByPlaceholderText('myportfolio.com') as HTMLInputElement const createButton = getByRole('button', { name: /^Create$/ }) await userEvent.type(nameInput, 'New Portfolio') await userEvent.type(domainInput, 'new.com') await userEvent.click(createButton) expect(mockCreatePortfolio).toHaveBeenCalledWith('New Portfolio', 'new.com') }) it('should close create form after successful creation', async () => { mockCreatePortfolio.mockResolvedValueOnce({ id: 4 }) const { getByRole, getByPlaceholderText, queryByText } = renderWithProviders() const newPortfolioButton = getByRole('button', { name: /new portfolio/i }) await userEvent.click(newPortfolioButton) const nameInput = getByPlaceholderText('My Portfolio') as HTMLInputElement const domainInput = getByPlaceholderText('myportfolio.com') as HTMLInputElement const createButton = getByRole('button', { name: /^Create$/ }) await userEvent.type(nameInput, 'New Portfolio') await userEvent.type(domainInput, 'new.com') await userEvent.click(createButton) await waitFor(() => { expect(queryByText('Create New Portfolio')).not.toBeInTheDocument() }) }) it('should cancel create form', async () => { const { getByRole, queryByText } = renderWithProviders() const newPortfolioButton = getByRole('button', { name: /new portfolio/i }) await userEvent.click(newPortfolioButton) expect(queryByText('Create New Portfolio')).toBeInTheDocument() const cancelButton = getByRole('button', { name: /cancel/i }) await userEvent.click(cancelButton) expect(queryByText('Create New Portfolio')).not.toBeInTheDocument() }) it('should handle upload button for pending upload portfolio', async () => { const { getByRole, queryAllByRole } = renderWithProviders() const uploadButtons = queryAllByRole('button', { name: /upload zip/i }) expect(uploadButtons.length).toBeGreaterThan(0) }) it('should handle deploy button for uploaded portfolio', async () => { mockDeployPortfolio.mockResolvedValueOnce({ id: 1 }) const { getByRole } = renderWithProviders() const deployButtons = getByRole('button', { name: /^Deploy$/ }) await userEvent.click(deployButtons) expect(mockDeployPortfolio).toHaveBeenCalledWith(1) }) it('should show loading state', () => { ;(usePortfolios as jest.Mock).mockReturnValue({ portfolios: [], isLoading: true, error: null, createPortfolio: mockCreatePortfolio, uploadPortfolio: mockUploadPortfolio, deployPortfolio: mockDeployPortfolio, }) const { getByText } = renderWithProviders() expect(getByText('Loading portfolios...')).toBeInTheDocument() }) it('should show error message', () => { const errorMessage = 'Failed to load portfolios' ;(usePortfolios as jest.Mock).mockReturnValue({ portfolios: [], isLoading: false, error: errorMessage, createPortfolio: mockCreatePortfolio, uploadPortfolio: mockUploadPortfolio, deployPortfolio: mockDeployPortfolio, }) const { getByText } = renderWithProviders() expect(getByText(errorMessage)).toBeInTheDocument() }) it('should show empty state when no portfolios', () => { ;(usePortfolios as jest.Mock).mockReturnValue({ portfolios: [], isLoading: false, error: null, createPortfolio: mockCreatePortfolio, uploadPortfolio: mockUploadPortfolio, deployPortfolio: mockDeployPortfolio, }) const { getByText } = renderWithProviders() expect(getByText('No portfolios yet. Create your first one!')).toBeInTheDocument() }) it('should call logout when logout button clicked', async () => { const { getByRole } = renderWithProviders() const logoutButton = getByRole('button', { name: /logout/i }) await userEvent.click(logoutButton) expect(mockLogout).toHaveBeenCalled() }) it('should display portfolio creation date', () => { const { getAllByText } = renderWithProviders() // Just check that creation dates are displayed const dateTexts = getAllByText(/Created:/) expect(dateTexts.length).toBeGreaterThan(0) }) it('should handle upload loading state', async () => { const { getByRole, getByText } = renderWithProviders() const uploadButtons = getByRole('button', { name: /upload zip/i }) // Simulate upload in progress await userEvent.click(uploadButtons) // After click, button text should show loading // Note: actual file upload state management would need more complex mocking }) it('should handle deploy loading state', async () => { const { getByRole, getByText } = renderWithProviders() const deployButton = getByRole('button', { name: /^Deploy$/ }) await userEvent.click(deployButton) expect(mockDeployPortfolio).toHaveBeenCalled() }) it('should render statistics with responsive grid', () => { const { getAllByTestId } = renderWithProviders() const statCards = getAllByTestId('card') // Should have at least stat cards + portfolio cards expect(statCards.length).toBeGreaterThanOrEqual(3) }) })