@@ -47,6 +47,53 @@ describe('utils: transformReadyToAbsolute()', function () {
4747 transformReadyToAbsolute ( url , root )
4848 . should . equal ( 'https://not-transform-ready.com/my/file.png' ) ;
4949 } ) ;
50+
51+ it ( 'returns empty string for empty string input' , function ( ) {
52+ let url = '' ;
53+ let root = 'https://example.com' ;
54+
55+ transformReadyToAbsolute ( url , root )
56+ . should . equal ( '' ) ;
57+ } ) ;
58+
59+ it ( 'returns null for null input' , function ( ) {
60+ let url = null ;
61+ let root = 'https://example.com' ;
62+
63+ const result = transformReadyToAbsolute ( url , root ) ;
64+ should . equal ( result , null ) ;
65+ } ) ;
66+
67+ it ( 'returns empty string for undefined input' , function ( ) {
68+ let url = undefined ;
69+ let root = 'https://example.com' ;
70+
71+ transformReadyToAbsolute ( url , root )
72+ . should . equal ( '' ) ;
73+ } ) ;
74+
75+ it ( 'handles malformed URLs gracefully' , function ( ) {
76+ const root = 'https://example.com' ;
77+ let result ;
78+
79+ should . doesNotThrow ( function ( ) {
80+ result = transformReadyToAbsolute ( '__GHOST_URL__/content/images/invalid%20path%20with%20spaces.jpg' , root ) ;
81+ } ) ;
82+
83+ result . should . equal ( 'https://example.com/content/images/invalid%20path%20with%20spaces.jpg' ) ;
84+
85+ should . doesNotThrow ( function ( ) {
86+ result = transformReadyToAbsolute ( '__GHOST_URL__/content/images/../../etc/passwd' , root ) ;
87+ } ) ;
88+
89+ result . should . equal ( 'https://example.com/content/images/../../etc/passwd' ) ;
90+
91+ should . doesNotThrow ( function ( ) {
92+ result = transformReadyToAbsolute ( 'not-a-url' , root ) ;
93+ } ) ;
94+
95+ result . should . equal ( 'not-a-url' ) ;
96+ } ) ;
5097 } ) ;
5198
5299 describe ( 'cdn asset replacement' , function ( ) {
@@ -80,6 +127,44 @@ describe('utils: transformReadyToAbsolute()', function () {
80127
81128 result . should . equal ( 'https://site-base.com/content/media/video.mp4' ) ;
82129 } ) ;
130+
131+ it ( 'uses CDN for media and site URL for files when only media CDN is configured' , function ( ) {
132+ const options = {
133+ staticImageUrlPrefix : 'content/images' ,
134+ staticFilesUrlPrefix : 'content/files' ,
135+ staticMediaUrlPrefix : 'content/media' ,
136+ mediaBaseUrl : mediaCdn ,
137+ filesBaseUrl : null ,
138+ imageBaseUrl : null
139+ } ;
140+
141+ const mediaResult = transformReadyToAbsolute ( '__GHOST_URL__/content/media/video.mp4' , siteUrl , options ) ;
142+ const filesResult = transformReadyToAbsolute ( '__GHOST_URL__/content/files/doc.pdf' , siteUrl , options ) ;
143+ const imageResult = transformReadyToAbsolute ( '__GHOST_URL__/content/images/photo.jpg' , siteUrl , options ) ;
144+
145+ mediaResult . should . equal ( 'https://media-cdn.com/ns/content/media/video.mp4' ) ;
146+ filesResult . should . equal ( 'https://site-base.com/content/files/doc.pdf' ) ;
147+ imageResult . should . equal ( 'https://site-base.com/content/images/photo.jpg' ) ;
148+ } ) ;
149+
150+ it ( 'uses site URL for all assets when all CDN configs are null' , function ( ) {
151+ const options = {
152+ staticImageUrlPrefix : 'content/images' ,
153+ staticFilesUrlPrefix : 'content/files' ,
154+ staticMediaUrlPrefix : 'content/media' ,
155+ mediaBaseUrl : null ,
156+ filesBaseUrl : null ,
157+ imageBaseUrl : null
158+ } ;
159+
160+ const mediaResult = transformReadyToAbsolute ( '__GHOST_URL__/content/media/video.mp4' , siteUrl , options ) ;
161+ const filesResult = transformReadyToAbsolute ( '__GHOST_URL__/content/files/doc.pdf' , siteUrl , options ) ;
162+ const imageResult = transformReadyToAbsolute ( '__GHOST_URL__/content/images/photo.jpg' , siteUrl , options ) ;
163+
164+ mediaResult . should . equal ( 'https://site-base.com/content/media/video.mp4' ) ;
165+ filesResult . should . equal ( 'https://site-base.com/content/files/doc.pdf' ) ;
166+ imageResult . should . equal ( 'https://site-base.com/content/images/photo.jpg' ) ;
167+ } ) ;
83168 } ) ;
84169
85170 describe ( 'html' , function ( ) {
0 commit comments