@@ -9,6 +9,7 @@ import type { NextRESTClient } from '../helpers/NextRESTClient.js'
99import { initPayloadInt } from '../helpers/initPayloadInt.js'
1010import {
1111 mediaSlug ,
12+ mediaWithDirectAccessSlug ,
1213 mediaWithDynamicPrefixSlug ,
1314 mediaWithPrefixSlug ,
1415 mediaWithSignedDownloadsSlug ,
@@ -121,6 +122,49 @@ describe('@payloadcms/storage-s3', () => {
121122 expect ( response . status ) . toBe ( 404 )
122123 } )
123124
125+ describe ( 'disablePayloadAccessControl' , ( ) => {
126+ it ( 'should return direct S3 URL with encoded filename when uploading file with spaces' , async ( ) => {
127+ const upload = await payload . create ( {
128+ collection : mediaWithDirectAccessSlug ,
129+ data : { } ,
130+ filePath : path . resolve ( dirname , '../uploads/image with spaces.png' ) ,
131+ } )
132+
133+ expect ( upload . id ) . toBeTruthy ( )
134+ expect ( upload . filename ) . toBe ( 'image with spaces.png' )
135+
136+ // When disablePayloadAccessControl is true, URL should point directly to S3
137+ // and the filename should be URL-encoded
138+ expect ( upload . url ) . toContain ( process . env . S3_ENDPOINT )
139+ expect ( upload . url ) . toContain ( TEST_BUCKET )
140+ expect ( upload . url ) . toContain ( 'image%20with%20spaces.png' )
141+
142+ // Verify the file can be fetched using the URL
143+ const response = await fetch ( upload . url )
144+ expect ( response . status ) . toBe ( 200 )
145+ expect ( response . headers . get ( 'Content-Type' ) ) . toBe ( 'image/png' )
146+ } )
147+
148+ it ( 'should return direct S3 URL without encoding issues for normal filenames' , async ( ) => {
149+ const upload = await payload . create ( {
150+ collection : mediaWithDirectAccessSlug ,
151+ data : { } ,
152+ filePath : path . resolve ( dirname , '../uploads/image.png' ) ,
153+ } )
154+
155+ expect ( upload . id ) . toBeTruthy ( )
156+
157+ // URL should point directly to S3
158+ expect ( upload . url ) . toContain ( process . env . S3_ENDPOINT )
159+ expect ( upload . url ) . toContain ( TEST_BUCKET )
160+ expect ( upload . url ) . toContain ( 'image.png' )
161+
162+ // Verify the file can be fetched
163+ const response = await fetch ( upload . url )
164+ expect ( response . status ) . toBe ( 200 )
165+ } )
166+ } )
167+
124168 describe ( 'R2' , ( ) => {
125169 it . todo ( 'can upload' )
126170 } )
0 commit comments