From 163e19ec2e0ac0d76a8a14f2f4648d768a6ca5bf Mon Sep 17 00:00:00 2001 From: Princi Vershwal Date: Wed, 26 Nov 2025 21:49:16 +0530 Subject: [PATCH 1/2] Added unit tests for transformReadyToAbsolute() --- .../utils/transform-ready-to-absolute.test.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js b/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js index d773db8d6..55ed14f8c 100644 --- a/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js +++ b/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js @@ -47,6 +47,30 @@ describe('utils: transformReadyToAbsolute()', function () { transformReadyToAbsolute(url, root) .should.equal('https://not-transform-ready.com/my/file.png'); }); + + it('returns empty string for empty string input', function () { + let url = ''; + let root = 'https://example.com'; + + transformReadyToAbsolute(url, root) + .should.equal(''); + }); + + it('returns null for null input', function () { + let url = null; + let root = 'https://example.com'; + + const result = transformReadyToAbsolute(url, root); + should.equal(result, null); + }); + + it('returns empty string for undefined input', function () { + let url = undefined; + let root = 'https://example.com'; + + transformReadyToAbsolute(url, root) + .should.equal(''); + }); }); describe('cdn asset replacement', function () { From cc7d18d3ec8385ef9c4ec8207df2a8eb384d5e5d Mon Sep 17 00:00:00 2001 From: Princi Vershwal Date: Wed, 26 Nov 2025 22:27:43 +0530 Subject: [PATCH 2/2] Added CDN tests for transformReadyToAbsolute() --- .../utils/transform-ready-to-absolute.test.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js b/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js index 55ed14f8c..41f5cdd57 100644 --- a/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js +++ b/packages/url-utils/test/unit/utils/transform-ready-to-absolute.test.js @@ -71,6 +71,29 @@ describe('utils: transformReadyToAbsolute()', function () { transformReadyToAbsolute(url, root) .should.equal(''); }); + + it('handles malformed URLs gracefully', function () { + const root = 'https://example.com'; + let result; + + should.doesNotThrow(function () { + result = transformReadyToAbsolute('__GHOST_URL__/content/images/invalid%20path%20with%20spaces.jpg', root); + }); + + result.should.equal('https://example.com/content/images/invalid%20path%20with%20spaces.jpg'); + + should.doesNotThrow(function () { + result = transformReadyToAbsolute('__GHOST_URL__/content/images/../../etc/passwd', root); + }); + + result.should.equal('https://example.com/content/images/../../etc/passwd'); + + should.doesNotThrow(function () { + result = transformReadyToAbsolute('not-a-url', root); + }); + + result.should.equal('not-a-url'); + }); }); describe('cdn asset replacement', function () { @@ -104,6 +127,44 @@ describe('utils: transformReadyToAbsolute()', function () { result.should.equal('https://site-base.com/content/media/video.mp4'); }); + + it('uses CDN for media and site URL for files when only media CDN is configured', function () { + const options = { + staticImageUrlPrefix: 'content/images', + staticFilesUrlPrefix: 'content/files', + staticMediaUrlPrefix: 'content/media', + mediaBaseUrl: mediaCdn, + filesBaseUrl: null, + imageBaseUrl: null + }; + + const mediaResult = transformReadyToAbsolute('__GHOST_URL__/content/media/video.mp4', siteUrl, options); + const filesResult = transformReadyToAbsolute('__GHOST_URL__/content/files/doc.pdf', siteUrl, options); + const imageResult = transformReadyToAbsolute('__GHOST_URL__/content/images/photo.jpg', siteUrl, options); + + mediaResult.should.equal('https://media-cdn.com/ns/content/media/video.mp4'); + filesResult.should.equal('https://site-base.com/content/files/doc.pdf'); + imageResult.should.equal('https://site-base.com/content/images/photo.jpg'); + }); + + it('uses site URL for all assets when all CDN configs are null', function () { + const options = { + staticImageUrlPrefix: 'content/images', + staticFilesUrlPrefix: 'content/files', + staticMediaUrlPrefix: 'content/media', + mediaBaseUrl: null, + filesBaseUrl: null, + imageBaseUrl: null + }; + + const mediaResult = transformReadyToAbsolute('__GHOST_URL__/content/media/video.mp4', siteUrl, options); + const filesResult = transformReadyToAbsolute('__GHOST_URL__/content/files/doc.pdf', siteUrl, options); + const imageResult = transformReadyToAbsolute('__GHOST_URL__/content/images/photo.jpg', siteUrl, options); + + mediaResult.should.equal('https://site-base.com/content/media/video.mp4'); + filesResult.should.equal('https://site-base.com/content/files/doc.pdf'); + imageResult.should.equal('https://site-base.com/content/images/photo.jpg'); + }); }); describe('html', function () {