Skip to content

Commit

Permalink
fix: empty and restore over 1,000 items
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 committed Sep 17, 2024
1 parent 7a755a0 commit e6870d0
Show file tree
Hide file tree
Showing 38 changed files with 513 additions and 142 deletions.
26 changes: 18 additions & 8 deletions e2e/src/api/specs/trash.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ describe('/trash', () => {
const before = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
expect(before).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: true }));

const { status } = await request(app).post('/trash/empty').set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(204);
const { status, body } = await request(app)
.post('/trash/empty')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body).toEqual({ count: 1 });

await utils.waitForWebsocketEvent({ event: 'assetDelete', id: assetId });

Expand All @@ -51,8 +54,11 @@ describe('/trash', () => {
const before = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
expect(before).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: true, isArchived: true }));

const { status } = await request(app).post('/trash/empty').set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(204);
const { status, body } = await request(app)
.post('/trash/empty')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body).toEqual({ count: 1 });

await utils.waitForWebsocketEvent({ event: 'assetDelete', id: assetId });

Expand All @@ -76,8 +82,11 @@ describe('/trash', () => {
const before = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
expect(before).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: true }));

const { status } = await request(app).post('/trash/restore').set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(204);
const { status, body } = await request(app)
.post('/trash/restore')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body).toEqual({ count: 3 });

Check failure on line 89 in e2e/src/api/specs/trash.e2e-spec.ts

View workflow job for this annotation

GitHub Actions / End-to-End Tests (Server & CLI)

src/api/specs/trash.e2e-spec.ts > /trash > POST /trash/restore > should restore all trashed assets

AssertionError: expected { count: 1 } to deeply equal { count: 3 } - Expected + Received Object { - "count": 3, + "count": 1, } ❯ src/api/specs/trash.e2e-spec.ts:89:20

const after = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
expect(after).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: false }));
Expand All @@ -99,11 +108,12 @@ describe('/trash', () => {
const before = await utils.getAssetInfo(admin.accessToken, assetId);
expect(before.isTrashed).toBe(true);

const { status } = await request(app)
const { status, body } = await request(app)
.post('/trash/restore/assets')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ ids: [assetId] });
expect(status).toBe(204);
expect(status).toBe(200);
expect(body).toEqual({ count: 1 });

const after = await utils.getAssetInfo(admin.accessToken, assetId);
expect(after.isTrashed).toBe(false);
Expand Down
1 change: 1 addition & 0 deletions mobile/openapi/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mobile/openapi/lib/api.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 27 additions & 3 deletions mobile/openapi/lib/api/trash_api.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions mobile/openapi/lib/api_client.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 98 additions & 0 deletions mobile/openapi/lib/model/trash_response_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 35 additions & 3 deletions open-api/immich-openapi-specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -6839,7 +6839,14 @@
"operationId": "emptyTrash",
"parameters": [],
"responses": {
"204": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrashResponseDto"
}
}
},
"description": ""
}
},
Expand All @@ -6864,7 +6871,14 @@
"operationId": "restoreTrash",
"parameters": [],
"responses": {
"204": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrashResponseDto"
}
}
},
"description": ""
}
},
Expand Down Expand Up @@ -6899,7 +6913,14 @@
"required": true
},
"responses": {
"204": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrashResponseDto"
}
}
},
"description": ""
}
},
Expand Down Expand Up @@ -12254,6 +12275,17 @@
],
"type": "string"
},
"TrashResponseDto": {
"properties": {
"count": {
"type": "integer"
}
},
"required": [
"count"
],
"type": "object"
},
"UpdateAlbumDto": {
"properties": {
"albumName": {
Expand Down
18 changes: 15 additions & 3 deletions open-api/typescript-sdk/src/fetch-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,9 @@ export type TimeBucketResponseDto = {
count: number;
timeBucket: string;
};
export type TrashResponseDto = {
count: number;
};
export type UserUpdateMeDto = {
email?: string;
name?: string;
Expand Down Expand Up @@ -3073,21 +3076,30 @@ export function getTimeBuckets({ albumId, isArchived, isFavorite, isTrashed, key
}));
}
export function emptyTrash(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/trash/empty", {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: TrashResponseDto;
}>("/trash/empty", {
...opts,
method: "POST"
}));
}
export function restoreTrash(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/trash/restore", {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: TrashResponseDto;
}>("/trash/restore", {
...opts,
method: "POST"
}));
}
export function restoreAssets({ bulkIdsDto }: {
bulkIdsDto: BulkIdsDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/trash/restore/assets", oazapfts.json({
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: TrashResponseDto;
}>("/trash/restore/assets", oazapfts.json({
...opts,
method: "POST",
body: bulkIdsDto
Expand Down
13 changes: 7 additions & 6 deletions server/src/controllers/trash.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { TrashResponseDto } from 'src/dtos/trash.dto';
import { Permission } from 'src/enum';
import { Auth, Authenticated } from 'src/middleware/auth.guard';
import { TrashService } from 'src/services/trash.service';
Expand All @@ -12,23 +13,23 @@ export class TrashController {
constructor(private service: TrashService) {}

@Post('empty')
@HttpCode(HttpStatus.NO_CONTENT)
@HttpCode(HttpStatus.OK)
@Authenticated({ permission: Permission.ASSET_DELETE })
emptyTrash(@Auth() auth: AuthDto): Promise<void> {
emptyTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
return this.service.empty(auth);
}

@Post('restore')
@HttpCode(HttpStatus.NO_CONTENT)
@HttpCode(HttpStatus.OK)
@Authenticated({ permission: Permission.ASSET_DELETE })
restoreTrash(@Auth() auth: AuthDto): Promise<void> {
restoreTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
return this.service.restore(auth);
}

@Post('restore/assets')
@HttpCode(HttpStatus.NO_CONTENT)
@HttpCode(HttpStatus.OK)
@Authenticated({ permission: Permission.ASSET_DELETE })
restoreAssets(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
restoreAssets(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<TrashResponseDto> {
return this.service.restoreAssets(auth, dto);
}
}
6 changes: 6 additions & 0 deletions server/src/dtos/trash.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';

export class TrashResponseDto {
@ApiProperty({ type: 'integer' })
count!: number;
}
Loading

0 comments on commit e6870d0

Please sign in to comment.