From 676b1c1fc668558ca7e2b553534c338e8c3710db Mon Sep 17 00:00:00 2001 From: juancarmore Date: Sun, 11 May 2025 20:12:12 +0200 Subject: [PATCH] tests: Add security preferences API tests --- backend/tests/helpers/request-helpers.ts | 41 ++-- .../api/global-preferences/appearance.test.ts | 8 +- .../api/global-preferences/security.test.ts | 229 ++++++++++++++++++ .../api/global-preferences/webhook.test.ts | 12 +- 4 files changed, 264 insertions(+), 26 deletions(-) create mode 100644 backend/tests/integration/api/global-preferences/security.test.ts diff --git a/backend/tests/helpers/request-helpers.ts b/backend/tests/helpers/request-helpers.ts index 0fc1b3e..5a870b4 100644 --- a/backend/tests/helpers/request-helpers.ts +++ b/backend/tests/helpers/request-helpers.ts @@ -111,30 +111,35 @@ export const getSecurityPreferences = async () => { return response; }; +export const updateSecurityPreferences = async (preferences: any) => { + checkAppIsRunning(); + + const adminCookie = await loginUserAsRole(UserRole.ADMIN); + const response = await request(app) + .put(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/preferences/security`) + .set('Cookie', adminCookie) + .send(preferences); + return response; +}; + export const changeSecurityPreferences = async ({ usersCanCreateRooms = true, authRequired = true, authMode = AuthMode.NONE }) => { - checkAppIsRunning(); - - const adminCookie = await loginUserAsRole(UserRole.ADMIN); - await request(app) - .put(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/preferences/security`) - .set('Cookie', adminCookie) - .send({ - roomCreationPolicy: { - allowRoomCreation: usersCanCreateRooms, - requireAuthentication: authRequired - }, - authentication: { - authMode: authMode, - method: { - type: AuthType.SINGLE_USER - } + const response = await updateSecurityPreferences({ + roomCreationPolicy: { + allowRoomCreation: usersCanCreateRooms, + requireAuthentication: authRequired + }, + authentication: { + authMode: authMode, + method: { + type: AuthType.SINGLE_USER } - }) - .expect(200); + } + }); + expect(response.status).toBe(200); }; /** diff --git a/backend/tests/integration/api/global-preferences/appearance.test.ts b/backend/tests/integration/api/global-preferences/appearance.test.ts index c51dc2c..f36a562 100644 --- a/backend/tests/integration/api/global-preferences/appearance.test.ts +++ b/backend/tests/integration/api/global-preferences/appearance.test.ts @@ -1,6 +1,9 @@ import { beforeAll, describe, expect, it } from '@jest/globals'; -import { startTestServer } from '../../../helpers/request-helpers.js'; -import { getAppearancePreferences, updateAppearancePreferences } from '../../../helpers/request-helpers.js'; +import { + getAppearancePreferences, + startTestServer, + updateAppearancePreferences +} from '../../../helpers/request-helpers.js'; describe('Appearance API Tests', () => { beforeAll(() => { @@ -13,6 +16,7 @@ describe('Appearance API Tests', () => { expect(response.status).toBe(402); }); }); + describe('Update Appearance Preferences', () => { it('should return 402 status code as it is a PRO feature', async () => { const response = await updateAppearancePreferences({}); diff --git a/backend/tests/integration/api/global-preferences/security.test.ts b/backend/tests/integration/api/global-preferences/security.test.ts new file mode 100644 index 0000000..a7465ce --- /dev/null +++ b/backend/tests/integration/api/global-preferences/security.test.ts @@ -0,0 +1,229 @@ +import { afterEach, beforeAll, describe, expect, it } from '@jest/globals'; +import { expectValidationError } from '../../../helpers/assertion-helpers.js'; +import { + getSecurityPreferences, + startTestServer, + updateSecurityPreferences +} from '../../../helpers/request-helpers.js'; +import { AuthMode, AuthType } from '../../../../src/typings/ce/index.js'; + +const defaultPreferences = { + roomCreationPolicy: { + allowRoomCreation: true, + requireAuthentication: true + }, + authentication: { + authMode: AuthMode.NONE, + method: { + type: AuthType.SINGLE_USER + } + } +}; + +const restoreDefaultSecurityPreferences = async () => { + await updateSecurityPreferences(defaultPreferences); +}; + +describe('Security Preferences API Tests', () => { + beforeAll(() => { + startTestServer(); + }); + + afterEach(async () => { + await restoreDefaultSecurityPreferences(); + }); + + describe('Update security preferences', () => { + it('should update security preferences with valid complete data', async () => { + const validPreferences = { + roomCreationPolicy: { + allowRoomCreation: true, + requireAuthentication: true + }, + authentication: { + authMode: AuthMode.ALL_USERS, + method: { + type: AuthType.SINGLE_USER + } + } + }; + let response = await updateSecurityPreferences(validPreferences); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('Security preferences updated successfully'); + + response = await getSecurityPreferences(); + expect(response.status).toBe(200); + expect(response.body).toEqual(validPreferences); + }); + + it('should update security preferences with valid partial data (roomCreationPolicy)', async () => { + const validPreferences = { + roomCreationPolicy: { + allowRoomCreation: false, + requireAuthentication: true + } + }; + let response = await updateSecurityPreferences(validPreferences); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('Security preferences updated successfully'); + + response = await getSecurityPreferences(); + expect(response.status).toBe(200); + expect(response.body.roomCreationPolicy).toEqual(validPreferences.roomCreationPolicy); + expect(response.body.authentication).toEqual(defaultPreferences.authentication); + }); + + it('should update security preferences with valid partial data (authentication)', async () => { + const validPreferences = { + authentication: { + authMode: AuthMode.ALL_USERS, + method: { + type: AuthType.SINGLE_USER + } + } + }; + let response = await updateSecurityPreferences(validPreferences); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('Security preferences updated successfully'); + + response = await getSecurityPreferences(); + expect(response.status).toBe(200); + expect(response.body.authentication).toEqual(validPreferences.authentication); + expect(response.body.roomCreationPolicy).toEqual(defaultPreferences.roomCreationPolicy); + }); + }); + + describe('Update security preferences validation', () => { + it('should reject when allowRoomCreation is not a boolean', async () => { + const response = await updateSecurityPreferences({ + roomCreationPolicy: { + allowRoomCreation: 'invalid', + requireAuthentication: true + } + }); + + expectValidationError( + response, + 'roomCreationPolicy.allowRoomCreation', + 'Expected boolean, received string' + ); + }); + + it('should reject when requireAuthentication is not a boolean', async () => { + const response = await updateSecurityPreferences({ + roomCreationPolicy: { + allowRoomCreation: true, + requireAuthentication: 'invalid' + } + }); + + expectValidationError( + response, + 'roomCreationPolicy.requireAuthentication', + 'Expected boolean, received string' + ); + }); + + it('should reject when allowRoomCreation or requireAuthentication is not provided', async () => { + let response = await updateSecurityPreferences({ + roomCreationPolicy: { + allowRoomCreation: true + } + }); + expectValidationError(response, 'roomCreationPolicy.requireAuthentication', 'Required'); + + response = await updateSecurityPreferences({ + roomCreationPolicy: { + requireAuthentication: true + } + }); + expectValidationError(response, 'roomCreationPolicy.allowRoomCreation', 'Required'); + }); + + it('should reject when authMode is not a valid enum value', async () => { + const response = await updateSecurityPreferences({ + authentication: { + authMode: 'invalid', + method: { + type: AuthType.SINGLE_USER + } + } + }); + + expectValidationError( + response, + 'authentication.authMode', + "Invalid enum value. Expected 'none' | 'moderators_only' | 'all_users', received 'invalid'" + ); + }); + + it('should reject when authType is not a valid enum value', async () => { + const response = await updateSecurityPreferences({ + authentication: { + authMode: AuthMode.NONE, + method: { + type: 'invalid' + } + } + }); + + expectValidationError( + response, + 'authentication.method.type', + "Invalid enum value. Expected 'single-user', received 'invalid'" + ); + }); + + it('should reject when authMode or method.type is not provided', async () => { + let response = await updateSecurityPreferences({ + authentication: { + authMode: AuthMode.NONE + } + }); + expectValidationError(response, 'authentication.method', 'Required'); + + response = await updateSecurityPreferences({ + authentication: { + method: { + type: AuthType.SINGLE_USER + } + } + }); + expectValidationError(response, 'authentication.authMode', 'Required'); + }); + + it('should reject when roomCreationPolicy is not an object', async () => { + const response = await updateSecurityPreferences({ + roomCreationPolicy: 'invalid' + }); + + expectValidationError(response, 'roomCreationPolicy', 'Expected object, received string'); + }); + + it('should reject when authentication is not an object', async () => { + const response = await updateSecurityPreferences({ + authentication: 'invalid' + }); + + expectValidationError(response, 'authentication', 'Expected object, received string'); + }); + + it('should reject when both roomCreationPolicy and authentication are not provided', async () => { + const response = await updateSecurityPreferences({}); + + expectValidationError(response, '', 'At least one field must be provided for the update'); + }); + }); + + describe('Get security preferences', () => { + it('should return security preferences when authenticated as admin', async () => { + const response = await getSecurityPreferences(); + + expect(response.status).toBe(200); + expect(response.body).toEqual(defaultPreferences); + }); + }); +}); diff --git a/backend/tests/integration/api/global-preferences/webhook.test.ts b/backend/tests/integration/api/global-preferences/webhook.test.ts index 087e6f0..dffec93 100644 --- a/backend/tests/integration/api/global-preferences/webhook.test.ts +++ b/backend/tests/integration/api/global-preferences/webhook.test.ts @@ -1,11 +1,11 @@ import { afterEach, beforeAll, describe, expect, it } from '@jest/globals'; -import { - startTestServer, - updateWebbhookPreferences, - getWebbhookPreferences -} from '../../../helpers/request-helpers.js'; -import { expectValidationError } from '../../../helpers/assertion-helpers.js'; import { MEET_WEBHOOK_ENABLED, MEET_WEBHOOK_URL } from '../../../../src/environment.js'; +import { expectValidationError } from '../../../helpers/assertion-helpers.js'; +import { + getWebbhookPreferences, + startTestServer, + updateWebbhookPreferences +} from '../../../helpers/request-helpers.js'; const restoreDefaultWebhookPreferences = async () => { const defaultPreferences = {