import React from 'react'
import { renderWithProviders, userEvent, waitFor } from '@/__tests__/utils/test-helpers'
import { useAuth } from '@/hooks/use-auth'
import RegisterPage from './page'
jest.mock('@/hooks/use-auth')
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', () => ({
Eye: () => ,
EyeOff: () => ,
}))
jest.mock('next/link', () => ({
__esModule: true,
default: ({ children, href }: any) => {children},
}))
describe('RegisterPage', () => {
const mockRegister = jest.fn()
beforeEach(() => {
jest.clearAllMocks()
;(useAuth as jest.Mock).mockReturnValue({
register: mockRegister,
})
})
it('should render registration form', () => {
const { getByText, getByPlaceholderText } = renderWithProviders()
expect(getByText('Create an account')).toBeInTheDocument()
expect(getByText('Get started with your portfolio hosting')).toBeInTheDocument()
expect(getByPlaceholderText('John Doe')).toBeInTheDocument()
expect(getByPlaceholderText('you@example.com')).toBeInTheDocument()
})
it('should display required field errors', async () => {
const { getByRole, getByText } = renderWithProviders()
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.click(submitButton)
expect(getByText('Name is required')).toBeInTheDocument()
expect(getByText('Email is required')).toBeInTheDocument()
expect(getByText('Password is required')).toBeInTheDocument()
expect(getByText('Please confirm your password')).toBeInTheDocument()
})
it.skip('should validate email format', async () => {
const { getByPlaceholderText, getByRole, getByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'invalid-email')
await userEvent.click(submitButton)
expect(getByText('Invalid email address')).toBeInTheDocument()
})
it.skip('should validate password minimum length', async () => {
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole, getByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'test@example.com')
await userEvent.type(inputs[2], '12345') // Password field
await userEvent.click(submitButton)
expect(getByText('Password must be at least 6 characters')).toBeInTheDocument()
})
it.skip('should validate password confirmation match', async () => {
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole, getByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'test@example.com')
await userEvent.type(inputs[2], 'password123') // Password
await userEvent.type(inputs[3], 'password456') // Confirm password - different
await userEvent.click(submitButton)
expect(getByText('Passwords do not match')).toBeInTheDocument()
})
it.skip('should submit form with valid data', async () => {
mockRegister.mockResolvedValueOnce(undefined)
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'john@example.com')
await userEvent.type(inputs[2], 'password123')
await userEvent.type(inputs[3], 'password123')
await userEvent.click(submitButton)
expect(mockRegister).toHaveBeenCalledWith({
name: 'John Doe',
email: 'john@example.com',
password: 'password123',
password_confirmation: 'password123',
})
})
it.skip('should display error message on registration failure', async () => {
const errorMessage = 'Email already exists'
mockRegister.mockRejectedValueOnce(new Error(errorMessage))
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole, getByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'existing@example.com')
await userEvent.type(inputs[2], 'password123')
await userEvent.type(inputs[3], 'password123')
await userEvent.click(submitButton)
await waitFor(() => {
expect(getByText(errorMessage)).toBeInTheDocument()
})
})
it.skip('should toggle password visibility', async () => {
const inputs = document.querySelectorAll('input')
renderWithProviders()
const passwordInput = inputs[2] as HTMLInputElement
const toggleButton = passwordInput.parentElement?.querySelector('button')
expect(passwordInput.type).toBe('password')
if (toggleButton) {
await userEvent.click(toggleButton)
expect(passwordInput.type).toBe('text')
await userEvent.click(toggleButton)
expect(passwordInput.type).toBe('password')
}
})
it.skip('should toggle confirm password visibility', async () => {
const inputs = document.querySelectorAll('input')
renderWithProviders()
const confirmPasswordInput = inputs[3] as HTMLInputElement
const toggleButtons = document.querySelectorAll('button')
const confirmToggleButton = toggleButtons[toggleButtons.length - 1]
expect(confirmPasswordInput.type).toBe('password')
await userEvent.click(confirmToggleButton)
expect(confirmPasswordInput.type).toBe('text')
await userEvent.click(confirmToggleButton)
expect(confirmPasswordInput.type).toBe('password')
})
it.skip('should show loading state during submission', async () => {
mockRegister.mockImplementationOnce(
() =>
new Promise((resolve) => {
setTimeout(resolve, 100)
})
)
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole, getByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const emailInput = getByPlaceholderText('you@example.com') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i }) as HTMLButtonElement
await userEvent.type(nameInput, 'John Doe')
await userEvent.type(emailInput, 'test@example.com')
await userEvent.type(inputs[2], 'password123')
await userEvent.type(inputs[3], 'password123')
await userEvent.click(submitButton)
expect(submitButton.disabled).toBe(true)
expect(getByText('Creating account...')).toBeInTheDocument()
})
it('should have link to login page', () => {
const { getByRole } = renderWithProviders()
const loginLink = getByRole('link', { name: /sign in/i })
expect(loginLink).toHaveAttribute('href', '/login')
})
it('should validate all fields before submission', async () => {
const { getByRole } = renderWithProviders()
const submitButton = getByRole('button', { name: /create account/i })
await userEvent.click(submitButton)
expect(mockRegister).not.toHaveBeenCalled()
})
it('should handle real-time validation updates', async () => {
const inputs = document.querySelectorAll('input')
const { getByPlaceholderText, getByRole, queryByText } = renderWithProviders()
const nameInput = getByPlaceholderText('John Doe') as HTMLInputElement
const submitButton = getByRole('button', { name: /create account/i })
// Try to submit without name
await userEvent.click(submitButton)
expect(queryByText('Name is required')).toBeInTheDocument()
// Add name
await userEvent.type(nameInput, 'John Doe')
// Trigger re-validation
await userEvent.click(submitButton)
expect(queryByText('Email is required')).toBeInTheDocument()
})
})