diff --git a/dashboard/frontend/src/pages/Register.test.tsx b/dashboard/frontend/src/pages/Register.test.tsx
new file mode 100644
index 0000000..85c1835
--- /dev/null
+++ b/dashboard/frontend/src/pages/Register.test.tsx
@@ -0,0 +1,79 @@
+import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { MemoryRouter } from 'react-router-dom'
+import { QueryClient, QueryClientProvider } from 'react-query'
+import Register from './Register'
+
+// Register usa useNavigate/Link (Router) y useMutation (QueryClient),
+// por eso hay que envolverlo antes de renderizar.
+function renderRegister() {
+ const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: { retry: false },
+ mutations: { retry: false },
+ },
+ })
+ return render(
+
+
+
+
+
+ )
+}
+
+// React 18 emite los propTypes warnings estilo printf:
+// console.error('Warning: Failed %s type: %s%s', 'prop', 'Invalid prop `error` ...', stack)
+// El texto util esta repartido entre argumentos, por eso se inspeccionan todos.
+// Nota: React deduplica estos warnings por componente dentro del proceso, asi que
+// este test DEBE renderizar Register antes que los demas (orden del describe).
+function hasPropTypesErrorWarning(spy: ReturnType): boolean {
+ return spy.mock.calls.some((call) =>
+ call.some((arg) => String(arg).includes('Invalid prop `error`'))
+ )
+}
+
+describe('Register - prop error de TextField/FormControl (card 9151895a)', () => {
+ let consoleErrorSpy: ReturnType
+
+ beforeEach(() => {
+ // MUI valida propTypes cuando NODE_ENV !== production: los warnings de
+ // React llegan via console.error, asi que espiamos ahi.
+ consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
+ })
+
+ afterEach(() => {
+ consoleErrorSpy.mockRestore()
+ })
+
+ it('con confirmPassword vacio no emite propTypes warning por error:string', () => {
+ renderRegister()
+
+ expect(hasPropTypesErrorWarning(consoleErrorSpy)).toBe(false)
+ })
+
+ it('muestra helper de mismatch cuando password y confirm no coinciden', async () => {
+ const user = userEvent.setup()
+ renderRegister()
+
+ await user.type(screen.getByLabelText('Username'), 'joker')
+ await user.type(screen.getByLabelText('Email'), 'joker@test.com')
+ await user.type(screen.getByLabelText('Password'), 'password123')
+ await user.type(screen.getByLabelText('Confirm Password'), 'password999')
+
+ expect(await screen.findByText('Passwords do not match')).toBeInTheDocument()
+ })
+
+ it('no muestra helper de error cuando las passwords coinciden', async () => {
+ const user = userEvent.setup()
+ renderRegister()
+
+ await user.type(screen.getByLabelText('Password'), 'password123')
+ await user.type(screen.getByLabelText('Confirm Password'), 'password123')
+
+ expect(
+ screen.queryByText('Passwords do not match')
+ ).not.toBeInTheDocument()
+ })
+})
diff --git a/dashboard/frontend/src/pages/Register.tsx b/dashboard/frontend/src/pages/Register.tsx
index 6903e7c..5626cdb 100644
--- a/dashboard/frontend/src/pages/Register.tsx
+++ b/dashboard/frontend/src/pages/Register.tsx
@@ -175,7 +175,7 @@ export default function Register() {
margin="normal"
value={formData.confirmPassword}
onChange={handleChange('confirmPassword')}
- error={formData.confirmPassword && formData.password !== formData.confirmPassword}
+ error={Boolean(formData.confirmPassword && formData.password !== formData.confirmPassword)}
helperText={
formData.confirmPassword && formData.password !== formData.confirmPassword
? 'Passwords do not match'