academia/src/frontend/e2e/role-access.spec.ts

217 lines
6.6 KiB
TypeScript

import { test, expect, Page } from '@playwright/test';
/**
* E2E Tests: Control de Acceso por Roles
* Verifica que las rutas estén correctamente protegidas según el rol del usuario.
*/
// Helper para simular sesión de usuario
async function setUserSession(page: Page, role: 'Admin' | 'Student', studentId?: number) {
const mockToken = 'mock.jwt.token';
const mockUser = {
id: 1,
username: role === 'Admin' ? 'admin' : 'student',
role,
studentId: studentId || (role === 'Student' ? 1 : null),
studentName: role === 'Student' ? 'Test Student' : null,
};
await page.evaluate(
({ token, user }) => {
localStorage.setItem('auth_token', token);
localStorage.setItem('user', JSON.stringify(user));
},
{ token: mockToken, user: mockUser }
);
}
test.describe('Control de Acceso - Rol Admin', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await setUserSession(page, 'Admin');
});
test('admin debe poder acceder al panel de administración', async ({ page }) => {
await page.goto('/admin');
// No debe redirigir a otra página
await expect(page).toHaveURL(/\/admin/);
// Debe mostrar contenido de admin
await expect(
page.getByRole('heading', { name: /panel.*admin|administración|gestión/i })
).toBeVisible({ timeout: 10000 });
});
test('admin debe poder acceder a gestión de estudiantes', async ({ page }) => {
await page.goto('/students');
await expect(page).toHaveURL(/\/students/);
await expect(
page.getByRole('heading', { name: /estudiantes|listado/i })
).toBeVisible({ timeout: 10000 });
});
test('admin debe poder crear estudiantes', async ({ page }) => {
await page.goto('/students/new');
await expect(page).toHaveURL(/\/students\/new/);
await expect(
page.getByRole('heading', { name: /nuevo estudiante/i })
).toBeVisible({ timeout: 10000 });
});
test('admin debe ver menú de navegación completo', async ({ page }) => {
await page.goto('/admin');
// Admin debe ver opciones de administración
await expect(
page.getByRole('link', { name: /panel admin|administración/i }).or(
page.getByRole('button', { name: /panel admin|administración/i })
)
).toBeVisible({ timeout: 10000 });
await expect(
page.getByRole('link', { name: /estudiantes|gestión/i }).or(
page.getByRole('button', { name: /estudiantes|gestión/i })
)
).toBeVisible();
});
});
test.describe('Control de Acceso - Rol Student', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await setUserSession(page, 'Student', 1);
});
test('estudiante debe acceder a su dashboard', async ({ page }) => {
await page.goto('/dashboard');
await expect(page).toHaveURL(/\/dashboard/);
await expect(
page.getByText(/bienvenido|mi portal|dashboard/i)
).toBeVisible({ timeout: 10000 });
});
test('estudiante debe acceder a sus inscripciones', async ({ page }) => {
await page.goto('/enrollment/1');
// No debe redirigir si es su propio ID
await expect(page).toHaveURL(/\/enrollment/);
});
test('estudiante debe acceder a compañeros', async ({ page }) => {
await page.goto('/classmates/1');
await expect(page).toHaveURL(/\/classmates/);
});
test('estudiante NO debe acceder al panel de admin', async ({ page }) => {
await page.goto('/admin');
// Debe redirigir a dashboard
await expect(page).toHaveURL(/\/dashboard/);
});
test('estudiante NO debe acceder a gestión de estudiantes', async ({ page }) => {
await page.goto('/students');
// Debe redirigir a dashboard
await expect(page).toHaveURL(/\/dashboard/);
});
test('estudiante NO debe poder crear estudiantes', async ({ page }) => {
await page.goto('/students/new');
// Debe redirigir a dashboard
await expect(page).toHaveURL(/\/dashboard/);
});
test('estudiante debe ver menú de navegación limitado', async ({ page }) => {
await page.goto('/dashboard');
// Estudiante debe ver opciones de estudiante
await expect(
page.getByRole('link', { name: /mi portal|dashboard/i }).or(
page.getByRole('button', { name: /mi portal|dashboard/i })
)
).toBeVisible({ timeout: 10000 });
await expect(
page.getByRole('link', { name: /mis materias|inscripción/i }).or(
page.getByRole('button', { name: /mis materias|inscripción/i })
)
).toBeVisible();
// NO debe ver opciones de admin
await expect(
page.getByRole('link', { name: /panel admin/i })
).not.toBeVisible();
});
});
test.describe('Control de Acceso - Sin Autenticación', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});
});
test('usuario no autenticado debe ir a login desde dashboard', async ({ page }) => {
await page.goto('/dashboard');
await expect(page).toHaveURL(/\/login/);
});
test('usuario no autenticado debe ir a login desde admin', async ({ page }) => {
await page.goto('/admin');
await expect(page).toHaveURL(/\/login/);
});
test('usuario no autenticado debe ir a login desde students', async ({ page }) => {
await page.goto('/students');
await expect(page).toHaveURL(/\/login/);
});
test('usuario no autenticado puede acceder a login', async ({ page }) => {
await page.goto('/login');
await expect(page).toHaveURL(/\/login/);
await expect(page.getByRole('heading', { name: /iniciar sesión/i })).toBeVisible();
});
test('usuario no autenticado puede acceder a registro', async ({ page }) => {
await page.goto('/register');
await expect(page).toHaveURL(/\/register/);
await expect(page.getByRole('heading', { name: /crear cuenta|registro/i })).toBeVisible();
});
test('usuario no autenticado puede acceder a reset password', async ({ page }) => {
await page.goto('/reset-password');
await expect(page).toHaveURL(/\/reset-password/);
});
});
test.describe('Control de Acceso - Navegación Post-Login', () => {
test('usuario autenticado no debe ver página de login', async ({ page }) => {
await page.goto('/');
await setUserSession(page, 'Student', 1);
await page.goto('/login');
// Debe redirigir a dashboard
await expect(page).toHaveURL(/\/dashboard/);
});
test('usuario autenticado no debe ver página de registro', async ({ page }) => {
await page.goto('/');
await setUserSession(page, 'Student', 1);
await page.goto('/register');
// Debe redirigir a dashboard
await expect(page).toHaveURL(/\/dashboard/);
});
});