From f47d54de814d95780bbcd53c0cf83beb5f206be8 Mon Sep 17 00:00:00 2001 From: Syndesi Date: Sun, 6 Oct 2024 11:12:32 +0200 Subject: [PATCH] Improved API Host Config Validation with Trailing Slash Removal ### Added - Print warning if trailing slashes in API host configuration are found, and automatically removes them, closes #92. ### Fixed - Fixed deprecated ts-jest configuration under globals keyword, "Define `ts-jest` config under `globals` is deprecated.". --- CHANGELOG.md | 4 + docs/type/assets/26e93147f10415a0ed4a.svg | 0 docs/type/assets/75c9471662e97ee24f29.svg | 0 docs/type/assets/db90e4df2373980c497d.svg | 0 docs/type/assets/hierarchy.css | 0 docs/type/assets/hierarchy.js | 0 docs/type/assets/style.css | 0 ...bSdkConfiguration.WebSdkConfiguration.html | 4 +- jest.config.ts | 9 +- src/Service/WebSdkConfiguration.ts | 9 +- test/Unit/Service/WebSdkConfiguration.test.ts | 109 ++++++++++++++++++ 11 files changed, 128 insertions(+), 7 deletions(-) mode change 100755 => 100644 docs/type/assets/26e93147f10415a0ed4a.svg mode change 100755 => 100644 docs/type/assets/75c9471662e97ee24f29.svg mode change 100755 => 100644 docs/type/assets/db90e4df2373980c497d.svg mode change 100755 => 100644 docs/type/assets/hierarchy.css mode change 100755 => 100644 docs/type/assets/hierarchy.js mode change 100755 => 100644 docs/type/assets/style.css create mode 100644 test/Unit/Service/WebSdkConfiguration.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 526a34a..eb29964 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +### Added +- Print warning if trailing slashes in API host configuration are found, and automatically removes them, closes #92. +### Fixed +- Fixed deprecated ts-jest configuration under globals keyword, "Define `ts-jest` config under `globals` is deprecated.". ## 0.0.62 - 2024-10-01 diff --git a/docs/type/assets/26e93147f10415a0ed4a.svg b/docs/type/assets/26e93147f10415a0ed4a.svg old mode 100755 new mode 100644 diff --git a/docs/type/assets/75c9471662e97ee24f29.svg b/docs/type/assets/75c9471662e97ee24f29.svg old mode 100755 new mode 100644 diff --git a/docs/type/assets/db90e4df2373980c497d.svg b/docs/type/assets/db90e4df2373980c497d.svg old mode 100755 new mode 100644 diff --git a/docs/type/assets/hierarchy.css b/docs/type/assets/hierarchy.css old mode 100755 new mode 100644 diff --git a/docs/type/assets/hierarchy.js b/docs/type/assets/hierarchy.js old mode 100755 new mode 100644 diff --git a/docs/type/assets/style.css b/docs/type/assets/style.css old mode 100755 new mode 100644 diff --git a/docs/type/classes/Service_WebSdkConfiguration.WebSdkConfiguration.html b/docs/type/classes/Service_WebSdkConfiguration.WebSdkConfiguration.html index f7c2672..70deee4 100644 --- a/docs/type/classes/Service_WebSdkConfiguration.WebSdkConfiguration.html +++ b/docs/type/classes/Service_WebSdkConfiguration.WebSdkConfiguration.html @@ -1,5 +1,5 @@ WebSdkConfiguration | @ember-nexus/web-sdk

Configuration handler.

-

Constructors

Constructors

Methods

  • Returns string

  • Returns number

  • Returns number

  • Returns number

  • Returns null | Token

  • Returns boolean

\ No newline at end of file +

Constructors

Methods

  • Returns string

  • Returns number

  • Returns number

  • Returns number

  • Returns null | Token

  • Returns boolean

\ No newline at end of file diff --git a/jest.config.ts b/jest.config.ts index 8eab5e1..f244217 100755 --- a/jest.config.ts +++ b/jest.config.ts @@ -101,9 +101,6 @@ const config: Config = { globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json' - } }, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader @@ -193,7 +190,11 @@ const config: Config = { // testRunner: "jest-circus/runner", // A map from regular expressions to paths to transformers - // transform: undefined, + transform: { + '^.+\\.ts$': ['ts-jest', { + tsconfig: 'tsconfig.test.json' + }] + }, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ diff --git a/src/Service/WebSdkConfiguration.ts b/src/Service/WebSdkConfiguration.ts index 0409fd9..879d0c6 100644 --- a/src/Service/WebSdkConfiguration.ts +++ b/src/Service/WebSdkConfiguration.ts @@ -1,5 +1,6 @@ import { Service } from 'typedi'; +import { Logger } from './Logger'; import { Token } from '../Type/Definition/index.js'; /** @@ -13,7 +14,7 @@ class WebSdkConfiguration { private collectionCacheMaxEntries: number; private collectionPageSize: number; - constructor() { + constructor(private logger: Logger) { this.token = null; this.apiHost = ''; this.elementCacheMaxEntries = 100; @@ -36,6 +37,12 @@ class WebSdkConfiguration { return this.apiHost; } setApiHost(apiHost: string): WebSdkConfiguration { + if (apiHost.endsWith('/')) { + this.logger.warn( + 'Removed trailing slash from API host configuration due to internal requirement. Please check if trailing slash can be directly removed.', + ); + apiHost = apiHost.replace(/\/+$/, ''); + } this.apiHost = apiHost; return this; } diff --git a/test/Unit/Service/WebSdkConfiguration.test.ts b/test/Unit/Service/WebSdkConfiguration.test.ts new file mode 100644 index 0000000..5c1e864 --- /dev/null +++ b/test/Unit/Service/WebSdkConfiguration.test.ts @@ -0,0 +1,109 @@ +import { expect } from 'chai'; +import { SinonSandbox, createSandbox } from 'sinon'; +import { Container } from 'typedi'; + +import { Logger, WebSdkConfiguration } from '../../../src/Service'; +import { validateTokenFromString } from '../../../src/Type/Definition'; +import { TestLogger } from '../TestLogger'; + +describe('WebSdkConfiguration tests', () => { + let sandbox: SinonSandbox; + let testLogger: TestLogger; + + beforeEach(() => { + sandbox = createSandbox(); + + testLogger = new TestLogger(); + Container.set(Logger, testLogger); + }); + + afterEach(() => { + sandbox.restore(); + Container.reset(); + }); + + it('should return default values', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + + expect(webSdkConfiguration.getToken()).to.be.null; + expect(webSdkConfiguration.getApiHost()).to.be.equal(''); + expect(webSdkConfiguration.getElementCacheMaxEntries()).to.be.equal(100); + expect(webSdkConfiguration.getCollectionCacheMaxEntries()).to.be.equal(50); + expect(webSdkConfiguration.getCollectionPageSize()).to.be.equal(25); + }); + + it('should correctly save the token', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const token = validateTokenFromString('secret-token:someToken'); + + expect(webSdkConfiguration.getToken()).to.be.null; + webSdkConfiguration.setToken(token); + expect(webSdkConfiguration.getToken()).to.be.equal(token); + }); + + it('should correctly save the api host', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const apiHost = 'https://localhost'; + + expect(webSdkConfiguration.getApiHost()).to.be.equal(''); + webSdkConfiguration.setApiHost(apiHost); + expect(webSdkConfiguration.getApiHost()).to.be.equal(apiHost); + }); + + it('should warn if the api host has a trailing slash', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const apiHost = 'https://localhost/'; + + expect(webSdkConfiguration.getApiHost()).to.be.equal(''); + webSdkConfiguration.setApiHost(apiHost); + expect(webSdkConfiguration.getApiHost()).to.not.be.equal(apiHost); + expect(webSdkConfiguration.getApiHost()).to.be.equal('https://localhost'); + expect( + testLogger.assertWarnHappened( + 'Removed trailing slash from API host configuration due to internal requirement. Please check if trailing slash can be directly removed.', + ), + ).to.be.true; + }); + + it('should warn if the api host has multiple trailing slashes', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const apiHost = 'https://localhost///'; + + expect(webSdkConfiguration.getApiHost()).to.be.equal(''); + webSdkConfiguration.setApiHost(apiHost); + expect(webSdkConfiguration.getApiHost()).to.not.be.equal(apiHost); + expect(webSdkConfiguration.getApiHost()).to.be.equal('https://localhost'); + expect( + testLogger.assertWarnHappened( + 'Removed trailing slash from API host configuration due to internal requirement. Please check if trailing slash can be directly removed.', + ), + ).to.be.true; + }); + + it('should correctly save the element cache max entries', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const elementCacheMaxEntries = 999; + + expect(webSdkConfiguration.getElementCacheMaxEntries()).to.be.equal(100); + webSdkConfiguration.setElementCacheMaxEntries(elementCacheMaxEntries); + expect(webSdkConfiguration.getElementCacheMaxEntries()).to.be.equal(elementCacheMaxEntries); + }); + + it('should correctly save the collection cache max entries', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const collectionCacheMaxEntries = 999; + + expect(webSdkConfiguration.getCollectionCacheMaxEntries()).to.be.equal(50); + webSdkConfiguration.setCollectionCacheMaxEntries(collectionCacheMaxEntries); + expect(webSdkConfiguration.getCollectionCacheMaxEntries()).to.be.equal(collectionCacheMaxEntries); + }); + + it('should correctly save the collection page size', async () => { + const webSdkConfiguration = Container.get(WebSdkConfiguration); + const collectionPageSize = 999; + + expect(webSdkConfiguration.getCollectionPageSize()).to.be.equal(25); + webSdkConfiguration.setCollectionPageSize(collectionPageSize); + expect(webSdkConfiguration.getCollectionPageSize()).to.be.equal(collectionPageSize); + }); +});