mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
* refactor: asset media endpoints * refactor: mobile upload livePhoto as separate request * refactor: change mobile backup flow to use new asset upload endpoints * chore: format and analyze dart code * feat: mark motion as hidden when linked * feat: upload video portion of live photo before image portion * fix: incorrect assetApi calls in mobile code * fix: download asset --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Zack Pollard <zackpollard@ymail.com>
77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
import { AssetMediaResponseDto, LoginResponseDto } from '@immich/sdk';
|
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
import { errorDto } from 'src/responses';
|
|
import { app, tempDir, utils } from 'src/utils';
|
|
import request from 'supertest';
|
|
import { beforeAll, describe, expect, it } from 'vitest';
|
|
|
|
describe('/download', () => {
|
|
let admin: LoginResponseDto;
|
|
let asset1: AssetMediaResponseDto;
|
|
let asset2: AssetMediaResponseDto;
|
|
|
|
beforeAll(async () => {
|
|
await utils.resetDatabase();
|
|
admin = await utils.adminSetup();
|
|
[asset1, asset2] = await Promise.all([utils.createAsset(admin.accessToken), utils.createAsset(admin.accessToken)]);
|
|
});
|
|
|
|
describe('POST /download/info', () => {
|
|
it('should require authentication', async () => {
|
|
const { status, body } = await request(app)
|
|
.post(`/download/info`)
|
|
.send({ assetIds: [asset1.id] });
|
|
|
|
expect(status).toBe(401);
|
|
expect(body).toEqual(errorDto.unauthorized);
|
|
});
|
|
|
|
it('should download info', async () => {
|
|
const { status, body } = await request(app)
|
|
.post('/download/info')
|
|
.set('Authorization', `Bearer ${admin.accessToken}`)
|
|
.send({ assetIds: [asset1.id] });
|
|
|
|
expect(status).toBe(201);
|
|
expect(body).toEqual(
|
|
expect.objectContaining({
|
|
archives: [expect.objectContaining({ assetIds: [asset1.id] })],
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('POST /download/archive', () => {
|
|
it('should require authentication', async () => {
|
|
const { status, body } = await request(app)
|
|
.post(`/download/archive`)
|
|
.send({ assetIds: [asset1.id, asset2.id] });
|
|
|
|
expect(status).toBe(401);
|
|
expect(body).toEqual(errorDto.unauthorized);
|
|
});
|
|
|
|
it('should download an archive', async () => {
|
|
const { status, body } = await request(app)
|
|
.post('/download/archive')
|
|
.set('Authorization', `Bearer ${admin.accessToken}`)
|
|
.send({ assetIds: [asset1.id, asset2.id] });
|
|
|
|
expect(status).toBe(200);
|
|
expect(body instanceof Buffer).toBe(true);
|
|
|
|
await writeFile(`${tempDir}/archive.zip`, body);
|
|
await utils.unzip(`${tempDir}/archive.zip`, `${tempDir}/archive`);
|
|
const files = [
|
|
{ filename: 'example.png', id: asset1.id },
|
|
{ filename: 'example+1.png', id: asset2.id },
|
|
];
|
|
for (const { id, filename } of files) {
|
|
const bytes = await readFile(`${tempDir}/archive/${filename}`);
|
|
const asset = await utils.getAssetInfo(admin.accessToken, id);
|
|
expect(utils.sha1(bytes)).toBe(asset.checksum);
|
|
}
|
|
});
|
|
});
|
|
});
|