From e41873532275579a87c2a9402db99b4b7d15a3c6 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Mon, 29 Sep 2025 22:03:47 +0200 Subject: [PATCH] test: update appearance config tests to include 'enabled' property and improve theme validation --- .../api/global-config/appearance.test.ts | 106 +++++++++++++++--- .../security/global-config-security.test.ts | 26 +---- 2 files changed, 95 insertions(+), 37 deletions(-) diff --git a/backend/tests/integration/api/global-config/appearance.test.ts b/backend/tests/integration/api/global-config/appearance.test.ts index efc7e74..0f709c0 100644 --- a/backend/tests/integration/api/global-config/appearance.test.ts +++ b/backend/tests/integration/api/global-config/appearance.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeAll, describe, expect, it } from '@jest/globals'; import { container } from '../../../../src/config/dependency-injector.config.js'; import { MeetStorageService } from '../../../../src/services/index.js'; -import { MeetRoomThemeMode } from '../../../../src/typings/ce/index.js'; +import { MeetAppearanceConfig, MeetRoomThemeMode } from '../../../../src/typings/ce/index.js'; import { expectValidationError } from '../../../helpers/assertion-helpers.js'; import { getRoomsAppearanceConfig, @@ -25,7 +25,8 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Custom Theme', + name: 'custom', + enabled: true, baseTheme: MeetRoomThemeMode.DARK, backgroundColor: '#121212', primaryColor: '#bb86fc', @@ -50,7 +51,8 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Minimal Theme', + name: 'default', + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT } ] @@ -71,9 +73,11 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Initial Theme', + name: 'initial', + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT, - primaryColor: '#1976d2' + primaryColor: '#1976d2', + backgroundColor: '#ffffff' } ] } @@ -86,11 +90,12 @@ describe('Rooms Appearance Config API Tests', () => { expect(response.status).toBe(200); expect(response.body).toEqual(initialConfig); - const newConfig = { + const newConfig: { appearance: MeetAppearanceConfig } = { appearance: { themes: [ { - name: 'New Theme', + name: 'new', + enabled: false, baseTheme: MeetRoomThemeMode.DARK, primaryColor: '#bb86fc' } @@ -103,6 +108,10 @@ describe('Rooms Appearance Config API Tests', () => { response = await getRoomsAppearanceConfig(); expect(response.status).toBe(200); + newConfig.appearance.themes[0] = { + ...newConfig.appearance.themes[0], + backgroundColor: '#ffffff' + }; expect(response.body).toEqual(newConfig); }); }); @@ -124,10 +133,12 @@ describe('Rooms Appearance Config API Tests', () => { themes: [ { name: 'Theme 1', + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT }, { name: 'Theme 2', + enabled: true, baseTheme: MeetRoomThemeMode.DARK } ] @@ -143,6 +154,7 @@ describe('Rooms Appearance Config API Tests', () => { themes: [ { name: '', + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT } ] @@ -157,7 +169,8 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'This is a very long theme name that exceeds fifty characters', + name: 'a'.repeat(51), + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT } ] @@ -167,6 +180,53 @@ describe('Rooms Appearance Config API Tests', () => { expectValidationError(response, 'appearance.themes.0.name', 'Theme name cannot exceed 50 characters'); }); + it('should reject when theme name has invalid characters', async () => { + const invalidNames = [ + 'Corporate Blue', // Uppercase and spaces + 'dark-mode-2024!', // Exclamation mark + 'theme.corporate', // Dot + 'Dark_Mode', // Uppercase + 'theme 1', // Space + 'thème-français' // Accents + ]; + + for (const name of invalidNames) { + const response = await updateRoomsAppearanceConfig({ + appearance: { + themes: [ + { + name: name, + enabled: true, + baseTheme: MeetRoomThemeMode.LIGHT + } + ] + } + }); + + expectValidationError( + response, + 'appearance.themes.0.name', + 'Theme name can only contain lowercase letters, numbers, hyphens and underscores' + ); + } + }); + + it('should reject when enabled is not a boolean', async () => { + const response = await updateRoomsAppearanceConfig({ + appearance: { + themes: [ + { + name: 'Valid Name', + enabled: 'yes', + baseTheme: MeetRoomThemeMode.LIGHT + } + ] + } + }); + + expectValidationError(response, 'appearance.themes.0.enabled', 'Expected boolean, received string'); + }); + it('should reject when baseTheme is not a valid enum value', async () => { const response = await updateRoomsAppearanceConfig({ appearance: { @@ -245,7 +305,8 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Short Hex Theme', + name: 'custom', + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT, backgroundColor: '#fff', primaryColor: '#000', @@ -259,11 +320,12 @@ describe('Rooms Appearance Config API Tests', () => { expect(response.status).toBe(200); }); - it('should reject when name or baseTheme are not provided', async () => { + it('should reject when name, enabled or baseTheme are not provided', async () => { let response = await updateRoomsAppearanceConfig({ appearance: { themes: [ { + enabled: true, baseTheme: MeetRoomThemeMode.LIGHT } ] @@ -275,7 +337,20 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Missing Base Theme' + name: 'Missing Enabled', + baseTheme: MeetRoomThemeMode.LIGHT + } + ] + } + }); + expectValidationError(response, 'appearance.themes.0.enabled', 'Required'); + + response = await updateRoomsAppearanceConfig({ + appearance: { + themes: [ + { + name: 'Missing Base Theme', + enabled: true } ] } @@ -303,11 +378,11 @@ describe('Rooms Appearance Config API Tests', () => { }); describe('Get rooms appearance config', () => { - it('should return 404 when no appearance config is set', async () => { + it('should return an empty array when no appearance config is set', async () => { const response = await getRoomsAppearanceConfig(); - expect(response.status).toBe(404); - expect(response.body.message).toBe('Rooms appearance config not defined'); + expect(response.status).toBe(200); + expect(response.body).toEqual({ appearance: { themes: [] } }); }); it('should return rooms appearance config when one is set', async () => { @@ -315,7 +390,8 @@ describe('Rooms Appearance Config API Tests', () => { appearance: { themes: [ { - name: 'Test Theme', + name: 'custom', + enabled: true, baseTheme: MeetRoomThemeMode.DARK, primaryColor: '#bb86fc' } diff --git a/backend/tests/integration/api/security/global-config-security.test.ts b/backend/tests/integration/api/security/global-config-security.test.ts index cd80f71..5043705 100644 --- a/backend/tests/integration/api/security/global-config-security.test.ts +++ b/backend/tests/integration/api/security/global-config-security.test.ts @@ -1,4 +1,4 @@ -import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; +import { beforeAll, describe, expect, it } from '@jest/globals'; import { Express } from 'express'; import request from 'supertest'; import { container } from '../../../../src/config/dependency-injector.config.js'; @@ -6,7 +6,7 @@ import INTERNAL_CONFIG from '../../../../src/config/internal-config.js'; import { MEET_INITIAL_API_KEY } from '../../../../src/environment.js'; import { MeetStorageService } from '../../../../src/services/index.js'; import { AuthMode, AuthType, MeetRoomThemeMode } from '../../../../src/typings/ce/index.js'; -import { loginUser, startTestServer, updateRoomsAppearanceConfig } from '../../../helpers/request-helpers.js'; +import { loginUser, startTestServer } from '../../../helpers/request-helpers.js'; const CONFIG_PATH = `${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config`; @@ -119,7 +119,8 @@ describe('Global Config API Security Tests', () => { appearance: { themes: [ { - name: 'Default Theme', + name: 'default', + enabled: true, baseTheme: MeetRoomThemeMode.DARK } ] @@ -151,25 +152,6 @@ describe('Global Config API Security Tests', () => { }); describe('Get Rooms Appearance Config Tests', () => { - const appearanceConfig = { - appearance: { - themes: [ - { - name: 'Default Theme', - baseTheme: MeetRoomThemeMode.DARK - } - ] - } - }; - - beforeAll(async () => { - await updateRoomsAppearanceConfig(appearanceConfig); - }); - - afterAll(async () => { - await restoreGlobalConfig(); - }); - it('should fail when request includes API key', async () => { const response = await request(app) .get(`${CONFIG_PATH}/rooms/appearance`)