Files
tfm_ainventory/frontend/e2e/workflows/4-admin-settings.spec.ts

333 lines
12 KiB
TypeScript

import { test, expect } from '@playwright/test';
import * as auth from '../fixtures/auth';
import * as assertions from '../utils/assertions';
import * as helpers from '../utils/helpers';
import { LOCAL_USERS, TEST_CATEGORIES } from '../fixtures/test-data';
test.describe('Admin Settings Workflow', () => {
const BASE_URL = process.env.BASE_URL || 'http://localhost:8917';
test.beforeEach(async ({ page }) => {
// Navigate to app and login as admin
await page.goto(BASE_URL);
await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
await assertions.assertUserAuthenticated(page, BASE_URL);
// Open admin panel
const adminButton = page.locator('[data-testid="admin-button"]');
await adminButton.click();
// Wait for admin overlay to appear
await assertions.assertAdminDashboardVisible(page);
});
test('should display admin dashboard with all tabs', async ({ page }) => {
await assertions.assertAdminDashboardVisible(page);
// Verify all tabs are present
const identityTab = page.locator('[data-testid="admin-tab-identity"]');
const databaseTab = page.locator('[data-testid="admin-tab-database"]');
const ldapTab = page.locator('[data-testid="admin-tab-ldap"]');
const aiTab = page.locator('[data-testid="admin-tab-ai"]');
const categoriesTab = page.locator('[data-testid="admin-tab-categories"]');
await expect(identityTab).toBeVisible();
await expect(databaseTab).toBeVisible();
await expect(ldapTab).toBeVisible();
await expect(aiTab).toBeVisible();
await expect(categoriesTab).toBeVisible();
});
test('should display users in identity tab', async ({ page }) => {
const identityTab = page.locator('[data-testid="admin-tab-identity"]');
await identityTab.click();
// User list should be displayed
const userList = page.locator('[data-testid="user-list"]');
await expect(userList).toBeVisible();
// Should have at least one user (admin)
const userItems = page.locator('[data-testid="user-list-item"]');
const count = await userItems.count();
expect(count).toBeGreaterThanOrEqual(1);
});
test('should allow creating new user', async ({ page }) => {
const identityTab = page.locator('[data-testid="admin-tab-identity"]');
await identityTab.click();
// Click add user button
const addUserButton = page.locator('[data-testid="add-user-button"]');
await addUserButton.click();
// Modal should appear
const modal = page.locator('[data-testid="create-user-modal"]');
await expect(modal).toBeVisible();
// Fill form
await page.fill('[data-testid="new-user-name"]', 'TestUser123');
await page.fill('[data-testid="new-user-password"]', 'Password123!');
// Submit
const submitButton = page.locator('[data-testid="create-user-submit"]');
await submitButton.click();
// Should show success
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 5000 });
});
test('should allow deleting user with confirmation', async ({ page }) => {
const identityTab = page.locator('[data-testid="admin-tab-identity"]');
await identityTab.click();
// Find a non-admin user to delete
const deleteButtons = page.locator('[data-testid="delete-user-button"]');
if (await deleteButtons.count() > 0) {
// Click delete on first user
await deleteButtons.first().click();
// Confirmation should appear
const confirmDialog = page.locator('[data-testid="confirmation-modal"]');
await expect(confirmDialog).toBeVisible();
// Confirm deletion
const confirmButton = page.locator('[data-testid="confirm-action"]');
await confirmButton.click();
// Should show success
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 5000 });
}
});
test('should display database info in database tab', async ({ page }) => {
const databaseTab = page.locator('[data-testid="admin-tab-database"]');
await databaseTab.click();
// Database info should be displayed
const dbInfo = page.locator('[data-testid="database-info"]');
await expect(dbInfo).toBeVisible();
// Should show stats
const itemCount = page.locator('[data-testid="item-count"]');
if (await itemCount.isVisible()) {
const count = await itemCount.textContent();
expect(count).toMatch(/\d+/);
}
});
test('should allow backup creation', async ({ page }) => {
const databaseTab = page.locator('[data-testid="admin-tab-database"]');
await databaseTab.click();
// Backup button should be present
const backupButton = page.locator('[data-testid="backup-button"]');
if (await backupButton.isVisible()) {
await backupButton.click();
// Should show progress or success
const progressOrSuccess = page.locator(
'[data-testid="backup-progress"], [data-testid="backup-success"]'
);
await expect(progressOrSuccess).toBeVisible({ timeout: 10000 });
}
});
test('should display LDAP configuration in ldap tab', async ({ page }) => {
const ldapTab = page.locator('[data-testid="admin-tab-ldap"]');
await ldapTab.click();
// LDAP config should be displayed
const ldapConfig = page.locator('[data-testid="ldap-config"]');
await expect(ldapConfig).toBeVisible();
});
test('should allow enabling/disabling LDAP', async ({ page }) => {
const ldapTab = page.locator('[data-testid="admin-tab-ldap"]');
await ldapTab.click();
// Toggle LDAP
const ldapToggle = page.locator('[data-testid="ldap-enabled-toggle"]');
if (await ldapToggle.isVisible()) {
const initialState = await ldapToggle.isChecked();
// Click toggle
await ldapToggle.click();
// Verify state changed
const newState = await ldapToggle.isChecked();
expect(newState).not.toBe(initialState);
}
});
test('should allow saving LDAP settings', async ({ page }) => {
const ldapTab = page.locator('[data-testid="admin-tab-ldap"]');
await ldapTab.click();
// Modify LDAP setting
const ldapServerInput = page.locator('[data-testid="ldap-server-input"]');
if (await ldapServerInput.isVisible()) {
const currentValue = await ldapServerInput.inputValue();
await ldapServerInput.fill('ldap.example.com');
// Save
const saveButton = page.locator('[data-testid="save-settings-button"]');
await saveButton.click();
// Should show success
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 5000 });
}
});
test('should display AI configuration in ai tab', async ({ page }) => {
const aiTab = page.locator('[data-testid="admin-tab-ai"]');
await aiTab.click();
// AI config should be displayed
const aiConfig = page.locator('[data-testid="ai-config"]');
await expect(aiConfig).toBeVisible();
// Provider selection should be visible
const providerSelect = page.locator('[data-testid="ai-provider-select"]');
await expect(providerSelect).toBeVisible();
});
test('should allow selecting AI provider', async ({ page }) => {
const aiTab = page.locator('[data-testid="admin-tab-ai"]');
await aiTab.click();
const providerSelect = page.locator('[data-testid="ai-provider-select"]');
const options = page.locator('[data-testid="provider-option"]');
if (await options.count() > 1) {
// Select second option
await options.nth(1).click();
// Should trigger save
const successToast = page.locator('[data-testid="toast-success"]');
if (await successToast.isVisible({ timeout: 1000 }).catch(() => false)) {
await expect(successToast).toBeVisible();
}
}
});
test('should allow entering API keys', async ({ page }) => {
const aiTab = page.locator('[data-testid="admin-tab-ai"]');
await aiTab.click();
// API key input should be present
const apiKeyInput = page.locator('[data-testid="ai-api-key-input"]');
if (await apiKeyInput.isVisible()) {
await apiKeyInput.fill('test-api-key-12345');
// Key should be masked
const inputType = await apiKeyInput.getAttribute('type');
expect(inputType).toBe('password');
// Save
const saveButton = page.locator('[data-testid="save-settings-button"]');
if (await saveButton.isVisible()) {
await saveButton.click();
}
}
});
test('should display categories list in categories tab', async ({ page }) => {
const categoriesTab = page.locator('[data-testid="admin-tab-categories"]');
await categoriesTab.click();
// Categories list should be displayed
const categoryList = page.locator('[data-testid="category-list"]');
await expect(categoryList).toBeVisible();
// Should have category items
const categoryItems = page.locator('[data-testid="category-item"]');
const count = await categoryItems.count();
expect(count).toBeGreaterThanOrEqual(1);
});
test('should allow adding new category', async ({ page }) => {
const categoriesTab = page.locator('[data-testid="admin-tab-categories"]');
await categoriesTab.click();
// Add category button
const addButton = page.locator('[data-testid="add-category-button"]');
if (await addButton.isVisible()) {
await addButton.click();
// Form should appear
const categoryForm = page.locator('[data-testid="category-form"]');
await expect(categoryForm).toBeVisible();
// Fill form
const nameInput = page.locator('[data-testid="category-name-input"]');
await nameInput.fill('New Category');
// Submit
const submitButton = page.locator('[data-testid="add-category-submit"]');
await submitButton.click();
// Should show success
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 5000 });
}
});
test('should allow deleting category', async ({ page }) => {
const categoriesTab = page.locator('[data-testid="admin-tab-categories"]');
await categoriesTab.click();
// Delete button
const deleteButtons = page.locator('[data-testid="delete-category-button"]');
if (await deleteButtons.count() > 0) {
await deleteButtons.first().click();
// Confirmation should appear
const confirmDialog = page.locator('[data-testid="confirmation-modal"]');
await expect(confirmDialog).toBeVisible();
// Confirm
const confirmButton = page.locator('[data-testid="confirm-action"]');
await confirmButton.click();
// Should show success
const successToast = page.locator('[data-testid="toast-success"]');
await expect(successToast).toBeVisible({ timeout: 5000 });
}
});
test('should close admin dashboard', async ({ page }) => {
// Close button should be present
const closeButton = page.locator('[data-testid="close-admin-overlay"]');
if (await closeButton.isVisible()) {
await closeButton.click();
// Admin overlay should close
const adminOverlay = page.locator('[data-testid="admin-overlay"]');
await expect(adminOverlay).not.toBeVisible({ timeout: 3000 });
}
});
test('should prevent non-admin users from accessing admin panel', async ({ page }) => {
// Login as regular user first
await page.goto(BASE_URL);
await auth.logout(page, BASE_URL);
// Login with regular user (if available)
await page.goto(BASE_URL);
// Try to access admin endpoint directly
await page.goto(`${BASE_URL}/admin`);
// Should be redirected or show error
const adminOverlay = page.locator('[data-testid="admin-overlay"]');
const errorMessage = page.locator('[data-testid="unauthorized-error"]');
const isBlocked = !(await adminOverlay.isVisible().catch(() => false)) ||
(await errorMessage.isVisible().catch(() => false));
expect(isBlocked).toBe(true);
});
});