1- import { Readable } from 'node:stream'
2- import { storageServiceMock , storageServiceMockFns } from '@sim/testing'
1+ import { mkdirSync , mkdtempSync , writeFileSync } from 'node:fs'
2+ import { tmpdir } from 'node:os'
3+ import { dirname , join } from 'node:path'
34import {
45 createDelegatedPrincipal ,
56 createSessionPrincipal ,
67} from '@sim/testing/factories/principal.factory'
78import { fileReadReceiptMock } from '@sim/testing/mocks/file-read-receipt.mock'
9+ import { uploadsConfigMock , uploadsConfigMockFns } from '@sim/testing/mocks/uploads-config.mock'
10+ import { uploadsMetadataMock } from '@sim/testing/mocks/uploads-metadata.mock'
11+ import { setUploadDirServer , uploadsSetupMock } from '@sim/testing/mocks/uploads-setup.mock'
812import {
913 workspaceFileSecretProvenanceMock ,
1014 workspaceFileSecretProvenanceMockFns ,
@@ -22,60 +26,65 @@ vi.mock(
2226 '@/lib/uploads/contexts/workspace/file-secret-provenance' ,
2327 ( ) => workspaceFileSecretProvenanceMock
2428)
25- vi . mock ( '@/lib/uploads/core/storage-service' , ( ) => storageServiceMock )
29+ vi . mock ( '@/lib/uploads/config' , ( ) => uploadsConfigMock )
30+ vi . mock ( '@/lib/uploads/core/setup.server' , ( ) => uploadsSetupMock )
31+ vi . mock ( '@/lib/uploads/server/metadata' , ( ) => uploadsMetadataMock )
2632
2733import type { WorkspaceFileRecord } from '@/lib/uploads/contexts/workspace'
2834import { streamAuthorizedWorkspaceFile } from '@/lib/workspace-files/application/stream-authorized-workspace-file'
2935
36+ const CONTENT = Buffer . from ( '0123456789abcdefghij' )
37+
3038const file = {
3139 id : 'file-1' ,
3240 workspaceId : 'workspace-1' ,
3341 name : 'clip.mp4' ,
3442 key : 'workspace/workspace-1/clip.mp4' ,
3543 path : '/api/files/serve/workspace/workspace-1/clip.mp4' ,
36- size : 6 ,
44+ size : CONTENT . length ,
3745 type : 'video/mp4' ,
3846 uploadedBy : 'user-1' ,
3947 uploadedAt : new Date ( '2026-08-01T00:00:00Z' ) ,
4048 updatedAt : new Date ( '2026-08-01T00:00:00Z' ) ,
4149} satisfies WorkspaceFileRecord
4250
43- let source : Readable
44-
45- async function readAll ( stream : ReadableStream < Uint8Array > ) : Promise < string > {
46- return Buffer . from ( await new Response ( stream ) . arrayBuffer ( ) ) . toString ( )
51+ async function readAll ( stream : ReadableStream < Uint8Array > ) : Promise < Buffer > {
52+ return Buffer . from ( await new Response ( stream ) . arrayBuffer ( ) )
4753}
4854
4955describe ( 'streamAuthorizedWorkspaceFile' , ( ) => {
5056 beforeEach ( ( ) => {
51- source = Readable . from ( [ Buffer . from ( 'stream' ) ] )
52- storageServiceMockFns . mockDownloadFileStream . mockResolvedValue ( source )
57+ const uploads = mkdtempSync ( join ( tmpdir ( ) , 'stream-authorized-' ) )
58+ mkdirSync ( dirname ( join ( uploads , file . key ) ) , { recursive : true } )
59+ writeFileSync ( join ( uploads , file . key ) , CONTENT )
60+ setUploadDirServer ( uploads )
61+ uploadsConfigMockFns . mockGetStorageConfig . mockReturnValue ( { bucket : 'b' , region : 'r' } )
5362 } )
5463
55- it ( 'streams the stored bytes once access still holds after storage opens' , async ( ) => {
64+ it ( 'streams every stored byte once access still holds after storage opens' , async ( ) => {
5665 const stream = await streamAuthorizedWorkspaceFile ( {
5766 file,
5867 principal : createSessionPrincipal ( ) ,
5968 authorize : async ( ) => undefined ,
6069 } )
61- await expect ( readAll ( stream ) ) . resolves . toBe ( 'stream' )
70+
71+ expect ( await readAll ( stream ) ) . toEqual ( CONTENT )
6272 } )
6373
64- it ( 'reads only the requested span from storage ' , async ( ) => {
65- await streamAuthorizedWorkspaceFile ( {
74+ it ( 'reads exactly the requested inclusive span and nothing else ' , async ( ) => {
75+ const stream = await streamAuthorizedWorkspaceFile ( {
6676 file,
6777 principal : createSessionPrincipal ( ) ,
6878 authorize : async ( ) => undefined ,
69- range : { start : 2 , end : 4 } ,
70- } )
71- expect ( storageServiceMockFns . mockDownloadFileStream ) . toHaveBeenCalledWith ( {
72- key : file . key ,
73- context : 'workspace' ,
74- range : { start : 2 , end : 4 } ,
79+ range : { start : 5 , end : 9 } ,
7580 } )
81+
82+ expect ( ( await readAll ( stream ) ) . toString ( ) ) . toBe ( '56789' )
7683 } )
7784
7885 it ( 'disposes the opened stream when access is revoked before it is handed out' , async ( ) => {
86+ const cancel = vi . spyOn ( ReadableStream . prototype , 'cancel' )
87+
7988 await expect (
8089 streamAuthorizedWorkspaceFile ( {
8190 file,
@@ -85,7 +94,8 @@ describe('streamAuthorizedWorkspaceFile', () => {
8594 } ,
8695 } )
8796 ) . rejects . toThrow ( 'revoked' )
88- expect ( source . destroyed ) . toBe ( true )
97+ expect ( cancel ) . toHaveBeenCalled ( )
98+ cancel . mockRestore ( )
8999 } )
90100
91101 it ( 'refuses and disposes the stream when provenance changes after storage opens' , async ( ) => {
@@ -94,6 +104,7 @@ describe('streamAuthorizedWorkspaceFile', () => {
94104 { status : 'exact' , entries : [ ] }
95105 )
96106 vi . mocked ( recheckFileReadReceipt ) . mockResolvedValueOnce ( { status : 'unknown' } )
107+ const cancel = vi . spyOn ( ReadableStream . prototype , 'cancel' )
97108
98109 await expect (
99110 observeContentDelivery (
@@ -102,6 +113,7 @@ describe('streamAuthorizedWorkspaceFile', () => {
102113 streamAuthorizedWorkspaceFile ( { file, principal : chat , authorize : async ( ) => undefined } )
103114 )
104115 ) . rejects . toBeInstanceOf ( ContentRefusedError )
105- expect ( source . destroyed ) . toBe ( true )
116+ expect ( cancel ) . toHaveBeenCalled ( )
117+ cancel . mockRestore ( )
106118 } )
107119} )
0 commit comments