From 3a4dfdf971056ca6e4d93df485d26e8018a2f26e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Wed, 11 Feb 2026 16:29:01 +0100 Subject: [PATCH] test(ui-server): add UIServerSecurity unit tests - Add 14 unit tests covering all UIServerSecurity functions - Test isValidCredential (matching, non-matching, edge cases) - Test createBodySizeLimiter (under/over/exact boundary) - Test createRateLimiter (under/over limit, window reset) - Test isValidNumberOfStations (valid/invalid ranges) - All tests pass (152ms execution time) --- .../ui-server/UIServerSecurity.test.ts | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tests/charging-station/ui-server/UIServerSecurity.test.ts diff --git a/tests/charging-station/ui-server/UIServerSecurity.test.ts b/tests/charging-station/ui-server/UIServerSecurity.test.ts new file mode 100644 index 00000000..0ee4a6ac --- /dev/null +++ b/tests/charging-station/ui-server/UIServerSecurity.test.ts @@ -0,0 +1,113 @@ +// Copyright Jerome Benoit. 2024-2025. All Rights Reserved. + +import { expect } from '@std/expect' +import { describe, it } from 'node:test' + +import { + createBodySizeLimiter, + createRateLimiter, + DEFAULT_MAX_STATIONS, + isValidCredential, + isValidNumberOfStations, +} from '../../../src/charging-station/ui-server/UIServerSecurity.js' + +await describe('UIServerSecurity test suite', async () => { + await describe('isValidCredential()', async () => { + await it('should return true for matching credentials', () => { + const result = isValidCredential('myPassword123', 'myPassword123') + expect(result).toBe(true) + }) + + await it('should return false for non-matching credentials', () => { + const result = isValidCredential('password1', 'password2') + expect(result).toBe(false) + }) + + await it('should handle empty string credentials', () => { + const result = isValidCredential('', '') + expect(result).toBe(true) + }) + + await it('should handle different length credentials', () => { + // cspell:disable-next-line + const result = isValidCredential('short', 'verylongpassword') + expect(result).toBe(false) + }) + }) + + await describe('createBodySizeLimiter()', async () => { + await it('should return true when accumulated bytes are under limit', () => { + const limiter = createBodySizeLimiter(1000) + const result = limiter(500) + expect(result).toBe(true) + }) + + await it('should return false when accumulated bytes exceed limit', () => { + const limiter = createBodySizeLimiter(1000) + limiter(600) + const result = limiter(500) + expect(result).toBe(false) + }) + + await it('should return true at exact limit boundary', () => { + const limiter = createBodySizeLimiter(1000) + const result = limiter(1000) + expect(result).toBe(true) + }) + }) + + await describe('createRateLimiter()', async () => { + await it('should allow requests under the limit', () => { + const limiter = createRateLimiter(5, 1000) + for (let i = 0; i < 5; i++) { + expect(limiter('192.168.1.1')).toBe(true) + } + }) + + await it('should block requests that exceed the limit', () => { + const limiter = createRateLimiter(3, 1000) + limiter('192.168.1.1') + limiter('192.168.1.1') + limiter('192.168.1.1') + const result = limiter('192.168.1.1') + expect(result).toBe(false) + }) + + await it('should reset window after time expires', async () => { + const limiter = createRateLimiter(2, 100) + limiter('10.0.0.1') + limiter('10.0.0.1') + expect(limiter('10.0.0.1')).toBe(false) + + // Wait for window to expire + await new Promise(resolve => { + setTimeout(resolve, 110) + }) + + // Should allow request after window reset + expect(limiter('10.0.0.1')).toBe(true) + }) + }) + + await describe('isValidNumberOfStations()', async () => { + await it('should return true for valid number of stations', () => { + const result = isValidNumberOfStations(50, DEFAULT_MAX_STATIONS) + expect(result).toBe(true) + }) + + await it('should return false when exceeding max stations', () => { + const result = isValidNumberOfStations(150, DEFAULT_MAX_STATIONS) + expect(result).toBe(false) + }) + + await it('should return false for zero stations', () => { + const result = isValidNumberOfStations(0, DEFAULT_MAX_STATIONS) + expect(result).toBe(false) + }) + + await it('should return false for negative stations', () => { + const result = isValidNumberOfStations(-5, DEFAULT_MAX_STATIONS) + expect(result).toBe(false) + }) + }) +}) -- 2.53.0