Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 6 additions & 6 deletions cli/src/commands/asset.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'node:path';
import { setTimeout as sleep } from 'node:timers/promises';
import { describe, expect, it, MockedFunction, vi } from 'vitest';

import { Action, checkBulkUpload, defaults, getSupportedMediaTypes, Reason } from '@immich/sdk';
import { AssetRejectReason, AssetUploadAction, checkBulkUpload, defaults, getSupportedMediaTypes } from '@immich/sdk';
import createFetchMock from 'vitest-fetch-mock';

import {
Expand Down Expand Up @@ -120,7 +120,7 @@ describe('checkForDuplicates', () => {
vi.mocked(checkBulkUpload).mockResolvedValue({
results: [
{
action: Action.Accept,
action: AssetUploadAction.Accept,
id: testFilePath,
},
],
Expand All @@ -144,10 +144,10 @@ describe('checkForDuplicates', () => {
vi.mocked(checkBulkUpload).mockResolvedValue({
results: [
{
action: Action.Reject,
action: AssetUploadAction.Reject,
id: testFilePath,
assetId: 'fc5621b1-86f6-44a1-9905-403e607df9f5',
reason: Reason.Duplicate,
reason: AssetRejectReason.Duplicate,
},
],
});
Expand All @@ -167,7 +167,7 @@ describe('checkForDuplicates', () => {
vi.mocked(checkBulkUpload).mockResolvedValue({
results: [
{
action: Action.Accept,
action: AssetUploadAction.Accept,
id: testFilePath,
},
],
Expand All @@ -187,7 +187,7 @@ describe('checkForDuplicates', () => {
mocked.mockResolvedValue({
results: [
{
action: Action.Accept,
action: AssetUploadAction.Accept,
id: testFilePath,
},
],
Expand Down
4 changes: 2 additions & 2 deletions cli/src/commands/asset.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
Action,
AssetBulkUploadCheckItem,
AssetBulkUploadCheckResult,
AssetMediaResponseDto,
AssetMediaStatus,
AssetUploadAction,
Permission,
addAssetsToAlbum,
checkBulkUpload,
Expand Down Expand Up @@ -234,7 +234,7 @@ export const checkForDuplicates = async (files: string[], { concurrency, skipHas
const results = response.results as AssetBulkUploadCheckResults;

for (const { id: filepath, assetId, action } of results) {
if (action === Action.Accept) {
if (action === AssetUploadAction.Accept) {
newFiles.push(filepath);
} else {
// rejects are always duplicates
Expand Down
7 changes: 4 additions & 3 deletions e2e/src/specs/server/api/asset.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ describe('/asset', () => {
utils.createAsset(user1.accessToken),
utils.createAsset(user1.accessToken, {
isFavorite: true,
fileCreatedAt: yesterday.toISO(),
fileModifiedAt: yesterday.toISO(),
fileCreatedAt: yesterday.toUTC().toISO(),
Comment thread
jrasm91 marked this conversation as resolved.
fileModifiedAt: yesterday.toUTC().toISO(),
assetData: { filename: 'example.mp4' },
}),
utils.createAsset(user1.accessToken),
Expand Down Expand Up @@ -435,7 +435,8 @@ describe('/asset', () => {
it('should require access', async () => {
const { status, body } = await request(app)
.put(`/assets/${user2Assets[0].id}`)
.set('Authorization', `Bearer ${user1.accessToken}`);
.set('Authorization', `Bearer ${user1.accessToken}`)
.send({});
expect(status).toBe(400);
expect(body).toEqual(errorDto.noPermission);
});
Expand Down
14 changes: 7 additions & 7 deletions e2e/src/specs/server/api/library.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe('/libraries', () => {
});

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(["All importPaths's elements must be unique"]));
expect(body).toEqual(errorDto.badRequest(['[importPaths] Array must have unique items']));
});

it('should not create an external library with duplicate exclusion patterns', async () => {
Expand All @@ -125,7 +125,7 @@ describe('/libraries', () => {
});

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(["All exclusionPatterns's elements must be unique"]));
expect(body).toEqual(errorDto.badRequest(['[exclusionPatterns] Array must have unique items']));
});
});

Expand Down Expand Up @@ -157,7 +157,7 @@ describe('/libraries', () => {
.send({ name: '' });

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['name should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[name] Too small: expected string to have >=1 characters']));
});

it('should change the import paths', async () => {
Expand All @@ -181,7 +181,7 @@ describe('/libraries', () => {
.send({ importPaths: [''] });

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['each value in importPaths should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[importPaths] Array items must not be empty']));
});

it('should reject duplicate import paths', async () => {
Expand All @@ -191,7 +191,7 @@ describe('/libraries', () => {
.send({ importPaths: ['/path', '/path'] });

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(["All importPaths's elements must be unique"]));
expect(body).toEqual(errorDto.badRequest(['[importPaths] Array must have unique items']));
});

it('should change the exclusion pattern', async () => {
Expand All @@ -215,7 +215,7 @@ describe('/libraries', () => {
.send({ exclusionPatterns: ['**/*.jpg', '**/*.jpg'] });

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(["All exclusionPatterns's elements must be unique"]));
expect(body).toEqual(errorDto.badRequest(['[exclusionPatterns] Array must have unique items']));
});

it('should reject an empty exclusion pattern', async () => {
Expand All @@ -225,7 +225,7 @@ describe('/libraries', () => {
.send({ exclusionPatterns: [''] });

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['each value in exclusionPatterns should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[exclusionPatterns] Array items must not be empty']));
});
});

Expand Down
8 changes: 4 additions & 4 deletions e2e/src/specs/server/api/map.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,31 +109,31 @@ describe('/map', () => {
.get('/map/reverse-geocode?lon=123')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['lat must be a number between -90 and 90']));
expect(body).toEqual(errorDto.badRequest(['[lat] Invalid input: expected number, received NaN']));
});

it('should throw an error if a lat is not a number', async () => {
const { status, body } = await request(app)
.get('/map/reverse-geocode?lat=abc&lon=123.456')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['lat must be a number between -90 and 90']));
expect(body).toEqual(errorDto.badRequest(['[lat] Invalid input: expected number, received NaN']));
});

it('should throw an error if a lat is out of range', async () => {
const { status, body } = await request(app)
.get('/map/reverse-geocode?lat=91&lon=123.456')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['lat must be a number between -90 and 90']));
expect(body).toEqual(errorDto.badRequest(['[lat] Too big: expected number to be <=90']));
});

it('should throw an error if a lon is not provided', async () => {
const { status, body } = await request(app)
.get('/map/reverse-geocode?lat=75')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['lon must be a number between -180 and 180']));
expect(body).toEqual(errorDto.badRequest(['[lon] Invalid input: expected number, received NaN']));
});

const reverseGeocodeTestCases = [
Expand Down
6 changes: 3 additions & 3 deletions e2e/src/specs/server/api/oauth.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe(`/oauth`, () => {
it(`should throw an error if a redirect uri is not provided`, async () => {
const { status, body } = await request(app).post('/oauth/authorize').send({});
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['redirectUri must be a string', 'redirectUri should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[redirectUri] Invalid input: expected string, received undefined']));
});

it('should return a redirect uri', async () => {
Expand All @@ -123,13 +123,13 @@ describe(`/oauth`, () => {
it(`should throw an error if a url is not provided`, async () => {
const { status, body } = await request(app).post('/oauth/callback').send({});
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['url must be a string', 'url should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[url] Invalid input: expected string, received undefined']));
});

it(`should throw an error if the url is empty`, async () => {
const { status, body } = await request(app).post('/oauth/callback').send({ url: '' });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['url should not be empty']));
expect(body).toEqual(errorDto.badRequest(['[url] Too small: expected string to have >=1 characters']));
});

it(`should throw an error if the state is not provided`, async () => {
Expand Down
4 changes: 2 additions & 2 deletions e2e/src/specs/server/api/tag.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ describe('/tags', () => {
.get(`/tags/${uuidDto.invalid}`)
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
expect(body).toEqual(errorDto.badRequest(['[id] Invalid UUID']));
});

it('should get tag details', async () => {
Expand Down Expand Up @@ -427,7 +427,7 @@ describe('/tags', () => {
.delete(`/tags/${uuidDto.invalid}`)
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
expect(body).toEqual(errorDto.badRequest(['[id] Invalid UUID']));
});

it('should delete a tag', async () => {
Expand Down
3 changes: 2 additions & 1 deletion e2e/src/specs/server/api/user-admin.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ describe('/admin/users', () => {
it('should delete user', async () => {
const { status, body } = await request(app)
.delete(`/admin/users/${userToDelete.userId}`)
.set('Authorization', `Bearer ${admin.accessToken}`);
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({});

expect(status).toBe(200);
expect(body).toMatchObject({
Expand Down
8 changes: 6 additions & 2 deletions e2e/src/specs/server/api/user.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ describe('/users', () => {
.set('Authorization', `Bearer ${admin.accessToken}`);

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['download.archiveSize must be an integer number']));
expect(body).toEqual(
errorDto.badRequest(['[download.archiveSize] Invalid input: expected int, received number']),
);
});

it('should update download archive size', async () => {
Expand All @@ -204,7 +206,9 @@ describe('/users', () => {
.set('Authorization', `Bearer ${admin.accessToken}`);

expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest(['download.includeEmbeddedVideos must be a boolean value']));
expect(body).toEqual(
errorDto.badRequest(['[download.includeEmbeddedVideos] Invalid input: expected boolean, received number']),
);
});

it('should update download include embedded videos', async () => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/src/ui/mock-network/broken-asset-network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const createMockStackAsset = (ownerId: string): AssetResponseDto => {
tags: [],
people: [],
unassignedFaces: [],
stack: null,
stack: undefined,
isOffline: false,
hasMetadata: true,
duplicateId: null,
Expand Down
14 changes: 8 additions & 6 deletions mobile/lib/domain/utils/migrate_cloud_ids.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ Future<void> _processCloudIdMappingsInBatches(
AssetMetadataBulkUpsertItemDto(
assetId: mapping.remoteAssetId,
key: kMobileMetadataKey,
value: RemoteAssetMobileAppMetadata(
cloudId: mapping.localAsset.cloudId,
createdAt: mapping.localAsset.createdAt.toIso8601String(),
adjustmentTime: mapping.localAsset.adjustmentTime?.toIso8601String(),
latitude: mapping.localAsset.latitude?.toString(),
longitude: mapping.localAsset.longitude?.toString(),
value: Map<String, Object>.from(
RemoteAssetMobileAppMetadata(
cloudId: mapping.localAsset.cloudId,
createdAt: mapping.localAsset.createdAt.toIso8601String(),
adjustmentTime: mapping.localAsset.adjustmentTime?.toIso8601String(),
latitude: mapping.localAsset.latitude?.toString(),
longitude: mapping.localAsset.longitude?.toString(),
).toJson(),
Comment thread
timonrieger marked this conversation as resolved.
),
),
);
Expand Down
2 changes: 1 addition & 1 deletion mobile/lib/repositories/album_api.repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class AlbumApiRepository extends ApiRepository {
for (final result in response) {
if (result.success) {
added.add(result.id);
} else if (result.error == BulkIdResponseDtoErrorEnum.duplicate) {
} else if (result.error == BulkIdErrorReason.duplicate) {
Comment thread
timonrieger marked this conversation as resolved.
duplicates.add(result.id);
}
}
Expand Down
14 changes: 7 additions & 7 deletions mobile/lib/utils/openapi_patching.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ dynamic upgradeDto(dynamic value, String targetType) {
case 'UserPreferencesResponseDto':
if (value is Map) {
addDefault(value, 'download.includeEmbeddedVideos', false);
addDefault(value, 'folders', FoldersResponse().toJson());
addDefault(value, 'memories', MemoriesResponse().toJson());
addDefault(value, 'ratings', RatingsResponse().toJson());
addDefault(value, 'people', PeopleResponse().toJson());
addDefault(value, 'tags', TagsResponse().toJson());
addDefault(value, 'sharedLinks', SharedLinksResponse().toJson());
addDefault(value, 'cast', CastResponse().toJson());
addDefault(value, 'folders', FoldersResponse(enabled: false, sidebarWeb: false).toJson());
addDefault(value, 'memories', MemoriesResponse(enabled: true, duration: 5).toJson());
addDefault(value, 'ratings', RatingsResponse(enabled: false).toJson());
addDefault(value, 'people', PeopleResponse(enabled: true, sidebarWeb: false).toJson());
addDefault(value, 'tags', TagsResponse(enabled: false, sidebarWeb: false).toJson());
addDefault(value, 'sharedLinks', SharedLinksResponse(enabled: true, sidebarWeb: false).toJson());
addDefault(value, 'cast', CastResponse(gCastEnabled: false).toJson());
addDefault(value, 'albums', {'defaultAssetOrder': 'desc'});
}
break;
Expand Down
8 changes: 7 additions & 1 deletion mobile/openapi/README.md

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

Loading
Loading