backend: Updated configuration for backend unit testing
Sets up Jest with ts-jest for unit and integration tests. Includes configurations for: - ESM support - Module resolution - Path aliasing - Adds unit tests to validate path utilities
This commit is contained in:
parent
4e65ca2d04
commit
498e837c70
@ -3,28 +3,29 @@ import { createDefaultEsmPreset } from 'ts-jest';
|
||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
const jestConfig = {
|
||||
displayName: 'backend',
|
||||
...createDefaultEsmPreset({
|
||||
tsconfig: 'tsconfig.json'
|
||||
}),
|
||||
...createDefaultEsmPreset(),
|
||||
testTimeout: 60000,
|
||||
resolver: 'ts-jest-resolver',
|
||||
testMatch: ['**/?(*.)+(spec|test).[tj]s?(x)'],
|
||||
moduleFileExtensions: ['js', 'ts', 'json', 'node'],
|
||||
testEnvironment: 'node',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: 'tsconfig.json'
|
||||
}
|
||||
},
|
||||
extensionsToTreatAsEsm: ['.ts'],
|
||||
moduleNameMapper: {
|
||||
'^@openvidu-meet/typings$': '<rootDir>/../typings/src/index.ts'
|
||||
'^@openvidu-meet/typings$': '<rootDir>/../typings/src/index.ts',
|
||||
'^(\\.{1,2}/.*)\\.js$': '$1' // Permite importar .js que resuelven a .ts
|
||||
},
|
||||
// transform: {
|
||||
// '^.+\\.tsx?$': ['ts-jest', {
|
||||
// // Opcionalmente, especifica el archivo tsconfig si es necesario
|
||||
// tsconfig: 'tsconfig.json',
|
||||
// }],
|
||||
// },
|
||||
transform: {
|
||||
'^.+\\.tsx?$': ['ts-jest', {
|
||||
tsconfig: {
|
||||
module: 'esnext',
|
||||
moduleResolution: 'node16',
|
||||
esModuleInterop: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
isolatedModules: true
|
||||
},
|
||||
useESM: true
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
export default jestConfig;
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
"test:integration-participants": "node --experimental-vm-modules ../../node_modules/.bin/jest --runInBand --forceExit --testPathPattern \"tests/integration/api/participants\" --ci --reporters=default --reporters=jest-junit",
|
||||
"test:integration-meetings": "node --experimental-vm-modules ../../node_modules/.bin/jest --runInBand --forceExit --testPathPattern \"tests/integration/api/meetings\" --ci --reporters=default --reporters=jest-junit",
|
||||
"test:integration-users": "node --experimental-vm-modules ../../node_modules/.bin/jest --runInBand --forceExit --testPathPattern \"tests/integration/api/users\" --ci --reporters=default --reporters=jest-junit",
|
||||
"test:unit": "pnpm exec jest --runInBand --forceExit --testPathPattern \"tests/unit\" --ci --reporters=default --reporters=jest-junit",
|
||||
"test:unit": "node --experimental-vm-modules ../../node_modules/.bin/jest --runInBand --forceExit --testPathPattern \"tests/unit\" --ci --reporters=default --reporters=jest-junit",
|
||||
"lint:fix": "eslint src --fix",
|
||||
"format:code": "prettier --ignore-path .gitignore --write '**/*.{ts,js,json,md}'"
|
||||
},
|
||||
|
||||
190
meet-ce/backend/tests/unit/path.utils.spec.ts
Normal file
190
meet-ce/backend/tests/unit/path.utils.spec.ts
Normal file
@ -0,0 +1,190 @@
|
||||
import { describe, it, expect, beforeAll } from '@jest/globals';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import * as pathUtils from '../../src/utils/path.utils.js';
|
||||
|
||||
/**
|
||||
* Tests for path.utils - Ensure robust path resolution
|
||||
* across different execution scenarios.
|
||||
*
|
||||
* These tests verify the module resolves project paths correctly
|
||||
* regardless of the directory from which the process is executed.
|
||||
*
|
||||
* NOTE: Because the module initializes on import, these tests assert
|
||||
* the module behavior after it has been loaded and cannot mock initialization.
|
||||
*/
|
||||
describe('path.utils - Robust project path resolution', () => {
|
||||
beforeAll(() => {
|
||||
// Silence logs during tests
|
||||
process.env.NODE_ENV = 'test';
|
||||
});
|
||||
|
||||
describe('Scenario 1: Exported paths verification', () => {
|
||||
it('should export all required paths', () => {
|
||||
// Verify all exported paths exist as properties
|
||||
expect(pathUtils.publicDirectoryPath).toBeDefined();
|
||||
expect(pathUtils.frontendDirectoryPath).toBeDefined();
|
||||
expect(pathUtils.webcomponentBundlePath).toBeDefined();
|
||||
expect(pathUtils.frontendHtmlPath).toBeDefined();
|
||||
expect(pathUtils.publicApiHtmlFilePath).toBeDefined();
|
||||
expect(pathUtils.internalApiHtmlFilePath).toBeDefined();
|
||||
|
||||
// Verify the paths are non-empty strings
|
||||
expect(typeof pathUtils.publicDirectoryPath).toBe('string');
|
||||
expect(pathUtils.publicDirectoryPath.length).toBeGreaterThan(0);
|
||||
|
||||
expect(typeof pathUtils.frontendDirectoryPath).toBe('string');
|
||||
expect(pathUtils.frontendDirectoryPath.length).toBeGreaterThan(0);
|
||||
|
||||
expect(typeof pathUtils.webcomponentBundlePath).toBe('string');
|
||||
expect(pathUtils.webcomponentBundlePath.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should build coherent paths (frontend inside public)', () => {
|
||||
// frontendDirectoryPath should be a subdirectory of publicDirectoryPath
|
||||
expect(pathUtils.frontendDirectoryPath.startsWith(pathUtils.publicDirectoryPath)).toBe(true);
|
||||
|
||||
// Ensure it contains 'frontend'
|
||||
expect(pathUtils.frontendDirectoryPath).toContain('frontend');
|
||||
});
|
||||
|
||||
it('should build webcomponentBundlePath inside public', () => {
|
||||
// webcomponentBundlePath must be inside publicDirectoryPath
|
||||
expect(pathUtils.webcomponentBundlePath.startsWith(pathUtils.publicDirectoryPath)).toBe(true);
|
||||
|
||||
// Should end with the correct bundle name
|
||||
expect(pathUtils.webcomponentBundlePath).toContain('openvidu-meet.bundle.min.js');
|
||||
});
|
||||
|
||||
it('should build coherent HTML paths', () => {
|
||||
// frontendHtmlPath should be inside frontendDirectoryPath
|
||||
expect(pathUtils.frontendHtmlPath.startsWith(pathUtils.frontendDirectoryPath)).toBe(true);
|
||||
expect(pathUtils.frontendHtmlPath).toContain('index.html');
|
||||
|
||||
// OpenAPI paths should reference 'openapi'
|
||||
expect(pathUtils.publicApiHtmlFilePath).toContain('openapi');
|
||||
expect(pathUtils.publicApiHtmlFilePath).toContain('public.html');
|
||||
|
||||
expect(pathUtils.internalApiHtmlFilePath).toContain('openapi');
|
||||
expect(pathUtils.internalApiHtmlFilePath).toContain('internal.html');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Scenario 2: Directory structure validation', () => {
|
||||
it('should contain "backend" and "public" in publicDirectoryPath', () => {
|
||||
// Path should contain both segments
|
||||
expect(pathUtils.publicDirectoryPath).toContain('backend');
|
||||
expect(pathUtils.publicDirectoryPath).toContain('public');
|
||||
|
||||
// Verify backend appears before public
|
||||
const segments = pathUtils.publicDirectoryPath.split(path.sep);
|
||||
const backendIndex = segments.findIndex((s: string) => s === 'backend');
|
||||
const publicIndex = segments.findIndex((s: string) => s === 'public');
|
||||
|
||||
expect(backendIndex).toBeGreaterThanOrEqual(0);
|
||||
expect(publicIndex).toBeGreaterThan(backendIndex);
|
||||
});
|
||||
|
||||
it('should work for both meet-ce and meet-pro', () => {
|
||||
// Path may be identifiable as CE or PRO
|
||||
const isCE = pathUtils.publicDirectoryPath.includes('meet-ce');
|
||||
const isPRO = pathUtils.publicDirectoryPath.includes('meet-pro');
|
||||
|
||||
// The structure backend/public must exist
|
||||
expect(pathUtils.publicDirectoryPath).toMatch(/backend[\/\\]public$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Scenario 3: Path integrity validation', () => {
|
||||
it('should use correct path separators for the OS', () => {
|
||||
// Should not contain mixed separators
|
||||
const hasForwardSlash = pathUtils.publicDirectoryPath.includes('/');
|
||||
const hasBackslash = pathUtils.publicDirectoryPath.includes('\\');
|
||||
|
||||
// Must have at least one type of separator
|
||||
expect(hasForwardSlash || hasBackslash).toBe(true);
|
||||
|
||||
// Verify normalized consistency
|
||||
const normalized = path.normalize(pathUtils.publicDirectoryPath);
|
||||
expect(pathUtils.publicDirectoryPath).toBe(normalized);
|
||||
});
|
||||
|
||||
it('should produce absolute paths', () => {
|
||||
// All exported paths must be absolute
|
||||
expect(path.isAbsolute(pathUtils.publicDirectoryPath)).toBe(true);
|
||||
expect(path.isAbsolute(pathUtils.frontendDirectoryPath)).toBe(true);
|
||||
expect(path.isAbsolute(pathUtils.webcomponentBundlePath)).toBe(true);
|
||||
expect(path.isAbsolute(pathUtils.frontendHtmlPath)).toBe(true);
|
||||
expect(path.isAbsolute(pathUtils.publicApiHtmlFilePath)).toBe(true);
|
||||
expect(path.isAbsolute(pathUtils.internalApiHtmlFilePath)).toBe(true);
|
||||
});
|
||||
|
||||
it('should resolve normalized paths (no .. or . segments)', () => {
|
||||
// Paths must not contain relative segments
|
||||
expect(pathUtils.publicDirectoryPath).not.toContain('..');
|
||||
expect(pathUtils.publicDirectoryPath).not.toMatch(/\/\.\//);
|
||||
|
||||
expect(pathUtils.frontendDirectoryPath).not.toContain('..');
|
||||
expect(pathUtils.webcomponentBundlePath).not.toContain('..');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Scenario 4: Existence of critical directories', () => {
|
||||
it('should point to a public/ directory whose parent exists', () => {
|
||||
// public directory might not exist at test time,
|
||||
// but the path should be valid
|
||||
const publicDir = pathUtils.publicDirectoryPath;
|
||||
|
||||
// Parent directory must exist
|
||||
const parentDir = path.dirname(publicDir);
|
||||
expect(fs.existsSync(parentDir)).toBe(true);
|
||||
});
|
||||
|
||||
it('should have an accessible backend/ directory up the tree', () => {
|
||||
// Walk up from publicDirectoryPath to find backend/
|
||||
let currentPath = pathUtils.publicDirectoryPath;
|
||||
let foundBackend = false;
|
||||
|
||||
// Up to 10 levels
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (path.basename(currentPath) === 'backend') {
|
||||
foundBackend = true;
|
||||
// Ensure this backend dir contains src/
|
||||
const srcPath = path.join(currentPath, 'src');
|
||||
expect(fs.existsSync(srcPath)).toBe(true);
|
||||
break;
|
||||
}
|
||||
const parent = path.dirname(currentPath);
|
||||
if (parent === currentPath) break; // Reached root
|
||||
currentPath = parent;
|
||||
}
|
||||
|
||||
expect(foundBackend).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Scenario 5: Robustness and consistency', () => {
|
||||
it('should keep the same resolution across multiple accesses', () => {
|
||||
// Paths must be consistent
|
||||
const path1 = pathUtils.publicDirectoryPath;
|
||||
const path2 = pathUtils.publicDirectoryPath;
|
||||
|
||||
expect(path1).toBe(path2);
|
||||
expect(path1).toStrictEqual(path2);
|
||||
});
|
||||
|
||||
it('should use path.join correctly (structure verification)', () => {
|
||||
// frontendDirectoryPath should equal public + frontend
|
||||
const expectedFrontend = path.join(pathUtils.publicDirectoryPath, 'frontend');
|
||||
expect(pathUtils.frontendDirectoryPath).toBe(expectedFrontend);
|
||||
|
||||
// Verify webcomponent
|
||||
const expectedWebcomponent = path.join(
|
||||
pathUtils.publicDirectoryPath,
|
||||
'webcomponent',
|
||||
'openvidu-meet.bundle.min.js'
|
||||
);
|
||||
expect(pathUtils.webcomponentBundlePath).toBe(expectedWebcomponent);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user