mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:39:37 -05:00 
			
		
		
		
	feat(server): deterministic download order (#7658)
This commit is contained in:
		
							parent
							
								
									8df63b7c94
								
							
						
					
					
						commit
						972d5a3411
					
				@ -90,7 +90,10 @@ describe(DownloadService.name, () => {
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1', 'asset-2']));
 | 
			
		||||
      assetMock.getByIds.mockResolvedValue([assetStub.noResizePath, assetStub.noWebpPath]);
 | 
			
		||||
      assetMock.getByIds.mockResolvedValue([
 | 
			
		||||
        { ...assetStub.noResizePath, id: 'asset-1' },
 | 
			
		||||
        { ...assetStub.noWebpPath, id: 'asset-2' },
 | 
			
		||||
      ]);
 | 
			
		||||
      storageMock.createZipStream.mockReturnValue(archiveMock);
 | 
			
		||||
 | 
			
		||||
      await expect(sut.downloadArchive(authStub.admin, { assetIds: ['asset-1', 'asset-2'] })).resolves.toEqual({
 | 
			
		||||
@ -110,7 +113,33 @@ describe(DownloadService.name, () => {
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1', 'asset-2']));
 | 
			
		||||
      assetMock.getByIds.mockResolvedValue([assetStub.noResizePath, assetStub.noResizePath]);
 | 
			
		||||
      assetMock.getByIds.mockResolvedValue([
 | 
			
		||||
        { ...assetStub.noResizePath, id: 'asset-1' },
 | 
			
		||||
        { ...assetStub.noResizePath, id: 'asset-2' },
 | 
			
		||||
      ]);
 | 
			
		||||
      storageMock.createZipStream.mockReturnValue(archiveMock);
 | 
			
		||||
 | 
			
		||||
      await expect(sut.downloadArchive(authStub.admin, { assetIds: ['asset-1', 'asset-2'] })).resolves.toEqual({
 | 
			
		||||
        stream: archiveMock.stream,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      expect(archiveMock.addFile).toHaveBeenCalledTimes(2);
 | 
			
		||||
      expect(archiveMock.addFile).toHaveBeenNthCalledWith(1, 'upload/library/IMG_123.jpg', 'IMG_123.jpg');
 | 
			
		||||
      expect(archiveMock.addFile).toHaveBeenNthCalledWith(2, 'upload/library/IMG_123.jpg', 'IMG_123+1.jpg');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should be deterministic', async () => {
 | 
			
		||||
      const archiveMock = {
 | 
			
		||||
        addFile: jest.fn(),
 | 
			
		||||
        finalize: jest.fn(),
 | 
			
		||||
        stream: new Readable(),
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1', 'asset-2']));
 | 
			
		||||
      assetMock.getByIds.mockResolvedValue([
 | 
			
		||||
        { ...assetStub.noResizePath, id: 'asset-2' },
 | 
			
		||||
        { ...assetStub.noResizePath, id: 'asset-1' },
 | 
			
		||||
      ]);
 | 
			
		||||
      storageMock.createZipStream.mockReturnValue(archiveMock);
 | 
			
		||||
 | 
			
		||||
      await expect(sut.downloadArchive(authStub.admin, { assetIds: ['asset-1', 'asset-2'] })).resolves.toEqual({
 | 
			
		||||
 | 
			
		||||
@ -81,9 +81,16 @@ export class DownloadService {
 | 
			
		||||
 | 
			
		||||
    const zip = this.storageRepository.createZipStream();
 | 
			
		||||
    const assets = await this.assetRepository.getByIds(dto.assetIds);
 | 
			
		||||
    const assetMap = new Map(assets.map((asset) => [asset.id, asset]));
 | 
			
		||||
    const paths: Record<string, number> = {};
 | 
			
		||||
 | 
			
		||||
    for (const { originalPath, originalFileName } of assets) {
 | 
			
		||||
    for (const assetId of dto.assetIds) {
 | 
			
		||||
      const asset = assetMap.get(assetId);
 | 
			
		||||
      if (!asset) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const { originalPath, originalFileName } = asset;
 | 
			
		||||
      const extension = extname(originalPath);
 | 
			
		||||
      let filename = `${originalFileName}${extension}`;
 | 
			
		||||
      const count = paths[filename] || 0;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user