@@ -28,6 +28,7 @@ vi.mock('@/lib/uploads/core/setup.server', () => ({
2828
2929import { fileParseBodySchema } from '@/lib/api/contracts/storage-transfer'
3030import * as inputValidation from '@/lib/core/security/input-validation.server'
31+ import { textArrayLiteral } from '@/lib/db/arrays'
3132import { executeFileParserOperation } from '@/lib/internal/file/parser'
3233import {
3334 createKnowledgeAclFixtureIds ,
@@ -204,29 +205,34 @@ describe('workspace file names in PostgreSQL', () => {
204205 }
205206 } )
206207
208+ // Names stored before upload normalization: U+202F before AM/PM, doubled and edge whitespace,
209+ // a decomposed accent, a control character, and a BOM.
210+ const unnormalizedNames = [
211+ 'Screenshot 2026-01-15 at 9.41.07\u202fAM.png' ,
212+ 'Quarterly Report.pdf' ,
213+ ' padded.txt\t' ,
214+ 'Cafe\u0301 menu.png' ,
215+ 'ring\u0007ing.png' ,
216+ '\ufeffbom.md' ,
217+ ]
218+
219+ it ( 'normalizes a display name in SQL exactly as normalizeDisplaySegment does' , async ( ) => {
220+ const rows = await db . execute < { name : string ; key : string } > (
221+ sql `SELECT name, ${ displaySegmentKey ( sql `name` ) } AS key FROM unnest(${ textArrayLiteral ( unnormalizedNames ) } ) AS name`
222+ )
223+ expect ( rows ) . toHaveLength ( unnormalizedNames . length )
224+ for ( const row of rows ) expect ( row . key ) . toBe ( normalizeDisplaySegment ( row . name ) )
225+ } )
226+
207227 it ( 'resolves a stored name that differs from its VFS path through the display-name index' , async ( ) => {
208228 const fixture = await seedWorkspace ( )
209229 const folder = await createWorkspaceFileFolder ( {
210230 workspaceId : fixture . workspaceId ,
211231 userId : fixture . aliceId ,
212232 name : 'Reports' ,
213233 } )
214- // Names stored before upload normalization: U+202F before AM/PM, doubled and edge
215- // whitespace, a decomposed accent, a control character, and a BOM.
216- const storedNames = [
217- 'Screenshot 2026-01-15 at 9.41.07 AM.png' ,
218- 'Quarterly Report.pdf' ,
219- ' padded.txt\t' ,
220- 'Café menu.png' ,
221- 'ring\u0007ing.png' ,
222- 'bom.md' ,
223- ]
224- for ( const name of storedNames ) {
225- const [ row ] = await db . execute ( sql `SELECT ${ displaySegmentKey ( sql `${ name } ::text` ) } AS key` )
226- expect ( row . key ) . toBe ( normalizeDisplaySegment ( name ) )
227- }
228234
229- const files = storedNames . map ( ( name , n ) => ( {
235+ const files = unnormalizedNames . map ( ( name , n ) => ( {
230236 name,
231237 id : `wf_legacy_${ n } _${ fixture . workspaceId } ` ,
232238 folderId : n === 0 ? folder . id : null ,
0 commit comments