From 3f6d276449f8601921409eb8653c794a61436324 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 8 Jan 2026 02:55:59 +0000 Subject: [PATCH] Add unit and E2E tests for Table Manager and Column Manager features Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com> --- tests/e2e/AdminDashboard.e2e.ts | 99 +++++++++++++++++++ tests/integration/ColumnManager.spec.ts | 122 ++++++++++++++++++++++++ tests/integration/TableManager.spec.ts | 102 ++++++++++++++++++++ 3 files changed, 323 insertions(+) create mode 100644 tests/e2e/AdminDashboard.e2e.ts create mode 100644 tests/integration/ColumnManager.spec.ts create mode 100644 tests/integration/TableManager.spec.ts diff --git a/tests/e2e/AdminDashboard.e2e.ts b/tests/e2e/AdminDashboard.e2e.ts new file mode 100644 index 0000000..0be4570 --- /dev/null +++ b/tests/e2e/AdminDashboard.e2e.ts @@ -0,0 +1,99 @@ +import { expect, test } from '@playwright/test'; + +test.describe('Admin Dashboard', () => { + test.describe('Navigation', () => { + test('should redirect to login when not authenticated', async ({ page }) => { + await page.goto('/admin/dashboard'); + + // Should redirect to login page or show 401 + await expect(page).toHaveURL(/\/admin\/login/); + }); + + test('should display login page with form', async ({ page }) => { + await page.goto('/admin/login'); + + await expect(page.getByLabel(/username/i)).toBeVisible(); + await expect(page.getByLabel(/password/i)).toBeVisible(); + await expect(page.getByRole('button', { name: /login/i })).toBeVisible(); + }); + }); + + test.describe('Table Manager UI', () => { + test.skip('should display Table Manager tab after login', async ({ page }) => { + // This test would require actual authentication + // Skipping for now as it needs a real admin user + await page.goto('/admin/login'); + + // Login flow would go here + // await page.fill('input[name="username"]', 'admin'); + // await page.fill('input[name="password"]', 'admin123'); + // await page.click('button[type="submit"]'); + + // Then verify Table Manager tab exists + // await expect(page.getByText('Table Manager')).toBeVisible(); + }); + + test.skip('should open create table dialog', async ({ page }) => { + // This test would require authentication + // Skipping for now + + // await page.goto('/admin/dashboard'); + // await page.getByText('Table Manager').click(); + // await page.getByRole('button', { name: /create table/i }).click(); + + // await expect(page.getByText('Create New Table')).toBeVisible(); + // await expect(page.getByLabel(/table name/i)).toBeVisible(); + }); + }); + + test.describe('Column Manager UI', () => { + test.skip('should display Column Manager tab after login', async ({ page }) => { + // This test would require actual authentication + // Skipping for now + + // await page.goto('/admin/dashboard'); + // await expect(page.getByText('Column Manager')).toBeVisible(); + }); + + test.skip('should show table selector in Column Manager', async ({ page }) => { + // This test would require authentication + // Skipping for now + + // await page.goto('/admin/dashboard'); + // await page.getByText('Column Manager').click(); + + // await expect(page.getByText(/select a table/i)).toBeVisible(); + }); + }); + + test.describe('Admin Panel Security', () => { + test('should not allow access to admin API without auth', async ({ page }) => { + const response = await page.request.get('/api/admin/tables'); + + expect(response.status()).toBe(401); + }); + + test('should not allow table management without auth', async ({ page }) => { + const response = await page.request.post('/api/admin/table-manage', { + data: { + tableName: 'test', + columns: [{ name: 'id', type: 'INTEGER' }], + }, + }); + + expect(response.status()).toBe(401); + }); + + test('should not allow column management without auth', async ({ page }) => { + const response = await page.request.post('/api/admin/column-manage', { + data: { + tableName: 'test', + columnName: 'col', + dataType: 'INTEGER', + }, + }); + + expect(response.status()).toBe(401); + }); + }); +}); diff --git a/tests/integration/ColumnManager.spec.ts b/tests/integration/ColumnManager.spec.ts new file mode 100644 index 0000000..4df9f2d --- /dev/null +++ b/tests/integration/ColumnManager.spec.ts @@ -0,0 +1,122 @@ +import { expect, test } from '@playwright/test'; + +test.describe('Column Manager', () => { + test.describe('Add Column API', () => { + test('should reject add column without authentication', async ({ page }) => { + const response = await page.request.post('/api/admin/column-manage', { + data: { + tableName: 'test_table', + columnName: 'new_column', + dataType: 'VARCHAR', + nullable: true, + }, + }); + + expect(response.status()).toBe(401); + }); + + test('should reject add column without required fields', async ({ page }) => { + const response = await page.request.post('/api/admin/column-manage', { + data: { + tableName: 'test_table', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject add column with invalid table name', async ({ page }) => { + const response = await page.request.post('/api/admin/column-manage', { + data: { + tableName: 'invalid-name!@#', + columnName: 'test_col', + dataType: 'INTEGER', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject add column with invalid column name', async ({ page }) => { + const response = await page.request.post('/api/admin/column-manage', { + data: { + tableName: 'test_table', + columnName: 'invalid-col!@#', + dataType: 'INTEGER', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + }); + + test.describe('Modify Column API', () => { + test('should reject modify column without authentication', async ({ page }) => { + const response = await page.request.put('/api/admin/column-manage', { + data: { + tableName: 'test_table', + columnName: 'test_column', + newType: 'TEXT', + }, + }); + + expect(response.status()).toBe(401); + }); + + test('should reject modify without required fields', async ({ page }) => { + const response = await page.request.put('/api/admin/column-manage', { + data: { + tableName: 'test_table', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject modify with invalid identifiers', async ({ page }) => { + const response = await page.request.put('/api/admin/column-manage', { + data: { + tableName: 'invalid!@#', + columnName: 'invalid!@#', + newType: 'TEXT', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + }); + + test.describe('Drop Column API', () => { + test('should reject drop column without authentication', async ({ page }) => { + const response = await page.request.delete('/api/admin/column-manage', { + data: { + tableName: 'test_table', + columnName: 'test_column', + }, + }); + + expect(response.status()).toBe(401); + }); + + test('should reject drop without required fields', async ({ page }) => { + const response = await page.request.delete('/api/admin/column-manage', { + data: { + tableName: 'test_table', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject drop with invalid identifiers', async ({ page }) => { + const response = await page.request.delete('/api/admin/column-manage', { + data: { + tableName: 'invalid!@#', + columnName: 'invalid!@#', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + }); +}); diff --git a/tests/integration/TableManager.spec.ts b/tests/integration/TableManager.spec.ts new file mode 100644 index 0000000..1e0626d --- /dev/null +++ b/tests/integration/TableManager.spec.ts @@ -0,0 +1,102 @@ +import { faker } from '@faker-js/faker'; +import { expect, test } from '@playwright/test'; + +test.describe('Table Manager', () => { + const testTableName = `test_table_${faker.string.alphanumeric(8)}`; + + test.describe('Create Table API', () => { + test('should create a new table with columns', async ({ page }) => { + const response = await page.request.post('/api/admin/table-manage', { + data: { + tableName: testTableName, + columns: [ + { + name: 'id', + type: 'SERIAL', + primaryKey: true, + nullable: false, + }, + { + name: 'name', + type: 'VARCHAR', + length: 255, + nullable: false, + }, + { + name: 'email', + type: 'VARCHAR', + length: 255, + nullable: true, + }, + ], + }, + }); + + // Note: This will fail without authentication, which is expected + // In a real test, you would need to authenticate first + expect([200, 401]).toContain(response.status()); + }); + + test('should reject table creation without table name', async ({ page }) => { + const response = await page.request.post('/api/admin/table-manage', { + data: { + columns: [ + { + name: 'id', + type: 'INTEGER', + }, + ], + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject table creation without columns', async ({ page }) => { + const response = await page.request.post('/api/admin/table-manage', { + data: { + tableName: 'test_table', + columns: [], + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject table with invalid name format', async ({ page }) => { + const response = await page.request.post('/api/admin/table-manage', { + data: { + tableName: 'invalid-table-name!@#', + columns: [ + { + name: 'id', + type: 'INTEGER', + }, + ], + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + }); + + test.describe('Drop Table API', () => { + test('should reject drop without table name', async ({ page }) => { + const response = await page.request.delete('/api/admin/table-manage', { + data: {}, + }); + + expect([400, 401]).toContain(response.status()); + }); + + test('should reject drop with invalid table name', async ({ page }) => { + const response = await page.request.delete('/api/admin/table-manage', { + data: { + tableName: 'invalid-name!@#', + }, + }); + + expect([400, 401]).toContain(response.status()); + }); + }); +});