tests: add tests for rooms appearance configuration endpoints

This commit is contained in:
juancarmore 2025-09-19 11:35:22 +02:00
parent 22a1f23639
commit 1f24c461b8
3 changed files with 387 additions and 30 deletions

View File

@ -77,23 +77,23 @@ export const getApiKeys = async () => {
return response;
};
export const getAppearanceConfig = async () => {
export const getRoomsAppearanceConfig = async () => {
checkAppIsRunning();
const adminCookie = await loginUser();
const response = await request(app)
.get(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config/appearance`)
.get(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config/rooms/appearance`)
.set('Cookie', adminCookie)
.send();
return response;
};
export const updateAppearanceConfig = async (config: any) => {
export const updateRoomsAppearanceConfig = async (config: any) => {
checkAppIsRunning();
const adminCookie = await loginUser();
const response = await request(app)
.put(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config/appearance`)
.put(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config/rooms/appearance`)
.set('Cookie', adminCookie)
.send(config);
return response;

View File

@ -1,22 +1,333 @@
import { beforeAll, describe, expect, it } from '@jest/globals';
import { getAppearanceConfig, startTestServer, updateAppearanceConfig } from '../../../helpers/request-helpers.js';
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 { expectValidationError } from '../../../helpers/assertion-helpers.js';
import {
getRoomsAppearanceConfig,
startTestServer,
updateRoomsAppearanceConfig
} from '../../../helpers/request-helpers.js';
describe('Appearance API Tests', () => {
beforeAll(() => {
describe('Rooms Appearance Config API Tests', () => {
beforeAll(async () => {
startTestServer();
});
describe('Get Appearance Config', () => {
it('should return 402 status code as it is a PRO feature', async () => {
const response = await getAppearanceConfig();
expect(response.status).toBe(402);
afterEach(async () => {
const storageService = container.get(MeetStorageService);
await storageService['initializeGlobalConfig']();
});
describe('Update rooms appearance config', () => {
it('should update rooms appearance config with valid complete data', async () => {
const validConfig = {
appearance: {
themes: [
{
name: 'Custom Theme',
baseTheme: MeetRoomThemeMode.DARK,
backgroundColor: '#121212',
primaryColor: '#bb86fc',
secondaryColor: '#03dac6',
surfaceColor: '#1f1f1f'
}
]
}
};
let response = await updateRoomsAppearanceConfig(validConfig);
expect(response.status).toBe(200);
expect(response.body.message).toBe('Rooms appearance config updated successfully');
response = await getRoomsAppearanceConfig();
expect(response.status).toBe(200);
expect(response.body).toEqual(validConfig);
});
it('should update rooms appearance config with minimal required data', async () => {
const validConfig = {
appearance: {
themes: [
{
name: 'Minimal Theme',
baseTheme: MeetRoomThemeMode.LIGHT
}
]
}
};
let response = await updateRoomsAppearanceConfig(validConfig);
expect(response.status).toBe(200);
expect(response.body.message).toBe('Rooms appearance config updated successfully');
response = await getRoomsAppearanceConfig();
expect(response.status).toBe(200);
expect(response.body).toEqual(validConfig);
});
it('should replace existing config when updating', async () => {
const initialConfig = {
appearance: {
themes: [
{
name: 'Initial Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
primaryColor: '#1976d2'
}
]
}
};
let response = await updateRoomsAppearanceConfig(initialConfig);
expect(response.status).toBe(200);
response = await getRoomsAppearanceConfig();
expect(response.status).toBe(200);
expect(response.body).toEqual(initialConfig);
const newConfig = {
appearance: {
themes: [
{
name: 'New Theme',
baseTheme: MeetRoomThemeMode.DARK,
primaryColor: '#bb86fc'
}
]
}
};
response = await updateRoomsAppearanceConfig(newConfig);
expect(response.status).toBe(200);
response = await getRoomsAppearanceConfig();
expect(response.status).toBe(200);
expect(response.body).toEqual(newConfig);
});
});
describe('Update Appearance Config', () => {
it('should return 402 status code as it is a PRO feature', async () => {
const response = await updateAppearanceConfig({});
expect(response.status).toBe(402);
describe('Update rooms appearance config validation', () => {
it('should reject when themes array is empty', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: []
}
});
expectValidationError(response, 'appearance.themes', 'There must be exactly one theme defined');
});
it('should reject when themes array has more than one theme', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Theme 1',
baseTheme: MeetRoomThemeMode.LIGHT
},
{
name: 'Theme 2',
baseTheme: MeetRoomThemeMode.DARK
}
]
}
});
expectValidationError(response, 'appearance.themes', 'There must be exactly one theme defined');
});
it('should reject when theme name is empty', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: '',
baseTheme: MeetRoomThemeMode.LIGHT
}
]
}
});
expectValidationError(response, 'appearance.themes.0.name', 'Theme name cannot be empty');
});
it('should reject when theme name exceeds 50 characters', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'This is a very long theme name that exceeds fifty characters',
baseTheme: MeetRoomThemeMode.LIGHT
}
]
}
});
expectValidationError(response, 'appearance.themes.0.name', 'Theme name cannot exceed 50 characters');
});
it('should reject when baseTheme is not a valid enum value', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Invalid Theme',
baseTheme: 'invalid'
}
]
}
});
expectValidationError(
response,
'appearance.themes.0.baseTheme',
"Invalid enum value. Expected 'light' | 'dark', received 'invalid'"
);
});
it('should reject when hex colors are invalid', async () => {
let response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Invalid Color Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
backgroundColor: 'not-a-color'
}
]
}
});
expectValidationError(response, 'appearance.themes.0.backgroundColor', 'Must be a valid hex color code');
response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Invalid Color Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
primaryColor: '#gggggg'
}
]
}
});
expectValidationError(response, 'appearance.themes.0.primaryColor', 'Must be a valid hex color code');
response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Invalid Color Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
secondaryColor: '#12345'
}
]
}
});
expectValidationError(response, 'appearance.themes.0.secondaryColor', 'Must be a valid hex color code');
response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Invalid Color Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
surfaceColor: 'rgb(255,255,255)'
}
]
}
});
expectValidationError(response, 'appearance.themes.0.surfaceColor', 'Must be a valid hex color code');
});
it('should accept valid 3-digit hex colors', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Short Hex Theme',
baseTheme: MeetRoomThemeMode.LIGHT,
backgroundColor: '#fff',
primaryColor: '#000',
secondaryColor: '#f0f',
surfaceColor: '#abc'
}
]
}
});
expect(response.status).toBe(200);
});
it('should reject when name or baseTheme are not provided', async () => {
let response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
baseTheme: MeetRoomThemeMode.LIGHT
}
]
}
});
expectValidationError(response, 'appearance.themes.0.name', 'Required');
response = await updateRoomsAppearanceConfig({
appearance: {
themes: [
{
name: 'Missing Base Theme'
}
]
}
});
expectValidationError(response, 'appearance.themes.0.baseTheme', 'Required');
});
it('should reject when appearance is not an object', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: 'invalid'
});
expectValidationError(response, 'appearance', 'Expected object, received string');
});
it('should reject when themes is not an array', async () => {
const response = await updateRoomsAppearanceConfig({
appearance: {
themes: 'invalid'
}
});
expectValidationError(response, 'appearance.themes', 'Expected array, received string');
});
});
describe('Get rooms appearance config', () => {
it('should return 404 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');
});
it('should return rooms appearance config when one is set', async () => {
const configToSet = {
appearance: {
themes: [
{
name: 'Test Theme',
baseTheme: MeetRoomThemeMode.DARK,
primaryColor: '#bb86fc'
}
]
}
};
let response = await updateRoomsAppearanceConfig(configToSet);
expect(response.status).toBe(200);
response = await getRoomsAppearanceConfig();
expect(response.status).toBe(200);
expect(response.body).toEqual(configToSet);
});
});
});

View File

@ -1,13 +1,20 @@
import { beforeAll, describe, expect, it } from '@jest/globals';
import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
import { Express } from 'express';
import request from 'supertest';
import { container } from '../../../../src/config/dependency-injector.config.js';
import INTERNAL_CONFIG from '../../../../src/config/internal-config.js';
import { MEET_INITIAL_API_KEY } from '../../../../src/environment.js';
import { AuthMode, AuthType } from '../../../../src/typings/ce/index.js';
import { loginUser, startTestServer } from '../../../helpers/request-helpers.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';
const CONFIG_PATH = `${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config`;
const restoreGlobalConfig = async () => {
const storageService = container.get(MeetStorageService);
await storageService['initializeGlobalConfig']();
};
describe('Global Config API Security Tests', () => {
let app: Express;
let adminCookie: string;
@ -37,6 +44,8 @@ describe('Global Config API Security Tests', () => {
.set('Cookie', adminCookie)
.send(webhookConfig);
expect(response.status).toBe(200);
await restoreGlobalConfig();
});
it('should fail when user is not authenticated', async () => {
@ -88,6 +97,8 @@ describe('Global Config API Security Tests', () => {
.set('Cookie', adminCookie)
.send(securityConfig);
expect(response.status).toBe(200);
await restoreGlobalConfig();
});
it('should fail when user is not authenticated', async () => {
@ -103,41 +114,76 @@ describe('Global Config API Security Tests', () => {
});
});
describe('Update Appearance Config Tests', () => {
describe('Update Rooms Appearance Config Tests', () => {
const appearanceConfig = {
appearance: {
themes: [
{
name: 'Default Theme',
baseTheme: MeetRoomThemeMode.DARK
}
]
}
};
it('should fail when request includes API key', async () => {
const response = await request(app)
.put(`${CONFIG_PATH}/appearance`)
.put(`${CONFIG_PATH}/rooms/appearance`)
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY)
.send({});
.send(appearanceConfig);
expect(response.status).toBe(401);
});
it('should succeed when user is authenticated as admin', async () => {
const response = await request(app).put(`${CONFIG_PATH}/appearance`).set('Cookie', adminCookie).send({});
expect(response.status).toBe(402); // Assuming 402 is the expected status code for this case
const response = await request(app)
.put(`${CONFIG_PATH}/rooms/appearance`)
.set('Cookie', adminCookie)
.send(appearanceConfig);
expect(response.status).toBe(200);
await restoreGlobalConfig();
});
it('should fail when user is not authenticated', async () => {
const response = await request(app).put(`${CONFIG_PATH}/appearance`).send({});
const response = await request(app).put(`${CONFIG_PATH}/rooms/appearance`).send(appearanceConfig);
expect(response.status).toBe(401);
});
});
describe('Get Appearance Config 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}/appearance`)
.get(`${CONFIG_PATH}/rooms/appearance`)
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY);
expect(response.status).toBe(401);
});
it('should succeed when user is authenticated as admin', async () => {
const response = await request(app).get(`${CONFIG_PATH}/appearance`).set('Cookie', adminCookie);
expect(response.status).toBe(402); // Assuming 402 is the expected status code for this case
const response = await request(app).get(`${CONFIG_PATH}/rooms/appearance`).set('Cookie', adminCookie);
expect(response.status).toBe(200);
});
it('should fail when user is not authenticated', async () => {
const response = await request(app).get(`${CONFIG_PATH}/appearance`);
const response = await request(app).get(`${CONFIG_PATH}/rooms/appearance`);
expect(response.status).toBe(401);
});
});