mirror of
https://github.com/immich-app/immich.git
synced 2026-03-01 18:19:10 +03:00
feat: more factories for small tests (#25396)
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
|||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { ConcurrentQueueName, FullsizeImageOptions, ImageOptions } from 'src/types';
|
import { ConcurrentQueueName, FullsizeImageOptions, ImageOptions } from 'src/types';
|
||||||
|
|
||||||
export interface SystemConfig {
|
export type SystemConfig = {
|
||||||
backup: {
|
backup: {
|
||||||
database: {
|
database: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -187,7 +187,7 @@ export interface SystemConfig {
|
|||||||
user: {
|
user: {
|
||||||
deleteDelay: number;
|
deleteDelay: number;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export type MachineLearningConfig = SystemConfig['machineLearning'];
|
export type MachineLearningConfig = SystemConfig['machineLearning'];
|
||||||
|
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract tags from TagsList', async () => {
|
it('should extract tags from TagsList', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Parent'] }) });
|
||||||
mockReadTags({ TagsList: ['Parent'] });
|
mockReadTags({ TagsList: ['Parent'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract hierarchy from TagsList', async () => {
|
it('should extract hierarchy from TagsList', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent/Child'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Parent/Child'] }) });
|
||||||
mockReadTags({ TagsList: ['Parent/Child'] });
|
mockReadTags({ TagsList: ['Parent/Child'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
||||||
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert);
|
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert);
|
||||||
@@ -419,7 +419,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract tags from Keywords as a string', async () => {
|
it('should extract tags from Keywords as a string', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Parent'] }) });
|
||||||
mockReadTags({ Keywords: 'Parent' });
|
mockReadTags({ Keywords: 'Parent' });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -430,7 +430,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract tags from Keywords as a list', async () => {
|
it('should extract tags from Keywords as a list', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Parent'] }) });
|
||||||
mockReadTags({ Keywords: ['Parent'] });
|
mockReadTags({ Keywords: ['Parent'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -441,7 +441,10 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract tags from Keywords as a list with a number', async () => {
|
it('should extract tags from Keywords as a list with a number', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent', '2024'] } } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
exifInfo: factory.exif({ tags: ['Parent', '2024'] }),
|
||||||
|
});
|
||||||
mockReadTags({ Keywords: ['Parent', 2024] });
|
mockReadTags({ Keywords: ['Parent', 2024] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -453,7 +456,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract hierarchal tags from Keywords', async () => {
|
it('should extract hierarchal tags from Keywords', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent/Child'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Parent/Child'] }) });
|
||||||
mockReadTags({ Keywords: 'Parent/Child' });
|
mockReadTags({ Keywords: 'Parent/Child' });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -473,7 +476,10 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should ignore Keywords when TagsList is present', async () => {
|
it('should ignore Keywords when TagsList is present', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent/Child', 'Child'] } } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
exifInfo: factory.exif({ tags: ['Parent/Child', 'Child'] }),
|
||||||
|
});
|
||||||
mockReadTags({ Keywords: 'Child', TagsList: ['Parent/Child'] });
|
mockReadTags({ Keywords: 'Child', TagsList: ['Parent/Child'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -493,7 +499,10 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract hierarchy from HierarchicalSubject', async () => {
|
it('should extract hierarchy from HierarchicalSubject', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent/Child', 'TagA'] } } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
exifInfo: factory.exif({ tags: ['Parent/Child', 'TagA'] }),
|
||||||
|
});
|
||||||
mockReadTags({ HierarchicalSubject: ['Parent|Child', 'TagA'] });
|
mockReadTags({ HierarchicalSubject: ['Parent|Child', 'TagA'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
||||||
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert);
|
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.childUpsert);
|
||||||
@@ -515,7 +524,10 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract tags from HierarchicalSubject as a list with a number', async () => {
|
it('should extract tags from HierarchicalSubject as a list with a number', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(removeNonSidecarFiles(assetStub.image));
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent', '2024'] } } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
exifInfo: factory.exif({ tags: ['Parent', '2024'] }),
|
||||||
|
});
|
||||||
mockReadTags({ HierarchicalSubject: ['Parent', 2024] });
|
mockReadTags({ HierarchicalSubject: ['Parent', 2024] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -527,7 +539,7 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should extract ignore / characters in a HierarchicalSubject tag', async () => {
|
it('should extract ignore / characters in a HierarchicalSubject tag', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image);
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image);
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Mom|Dad'] } } as any);
|
mocks.asset.getById.mockResolvedValue({ ...factory.asset(), exifInfo: factory.exif({ tags: ['Mom|Dad'] }) });
|
||||||
mockReadTags({ HierarchicalSubject: ['Mom/Dad'] });
|
mockReadTags({ HierarchicalSubject: ['Mom/Dad'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValueOnce(tagStub.parentUpsert);
|
||||||
|
|
||||||
@@ -542,7 +554,10 @@ describe(MetadataService.name, () => {
|
|||||||
|
|
||||||
it('should ignore HierarchicalSubject when TagsList is present', async () => {
|
it('should ignore HierarchicalSubject when TagsList is present', async () => {
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image);
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(assetStub.image);
|
||||||
mocks.asset.getById.mockResolvedValue({ exifInfo: { tags: ['Parent/Child', 'Parent2/Child2'] } } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
exifInfo: factory.exif({ tags: ['Parent/Child', 'Parent2/Child2'] }),
|
||||||
|
});
|
||||||
mockReadTags({ HierarchicalSubject: ['Parent2|Child2'], TagsList: ['Parent/Child'] });
|
mockReadTags({ HierarchicalSubject: ['Parent2|Child2'], TagsList: ['Parent/Child'] });
|
||||||
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
mocks.tag.upsertValue.mockResolvedValue(tagStub.parentUpsert);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { JobStatus } from 'src/enum';
|
|||||||
import { TagService } from 'src/services/tag.service';
|
import { TagService } from 'src/services/tag.service';
|
||||||
import { authStub } from 'test/fixtures/auth.stub';
|
import { authStub } from 'test/fixtures/auth.stub';
|
||||||
import { tagResponseStub, tagStub } from 'test/fixtures/tag.stub';
|
import { tagResponseStub, tagStub } from 'test/fixtures/tag.stub';
|
||||||
|
import { factory } from 'test/small.factory';
|
||||||
import { newTestService, ServiceMocks } from 'test/utils';
|
import { newTestService, ServiceMocks } from 'test/utils';
|
||||||
|
|
||||||
describe(TagService.name, () => {
|
describe(TagService.name, () => {
|
||||||
@@ -191,7 +192,10 @@ describe(TagService.name, () => {
|
|||||||
it('should upsert records', async () => {
|
it('should upsert records', async () => {
|
||||||
mocks.access.tag.checkOwnerAccess.mockResolvedValue(new Set(['tag-1', 'tag-2']));
|
mocks.access.tag.checkOwnerAccess.mockResolvedValue(new Set(['tag-1', 'tag-2']));
|
||||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1', 'asset-2', 'asset-3']));
|
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1', 'asset-2', 'asset-3']));
|
||||||
mocks.asset.getById.mockResolvedValue({ tags: [{ value: 'tag-1' }, { value: 'tag-2' }] } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
tags: [factory.tag({ value: 'tag-1' }), factory.tag({ value: 'tag-2' })],
|
||||||
|
});
|
||||||
mocks.tag.upsertAssetIds.mockResolvedValue([
|
mocks.tag.upsertAssetIds.mockResolvedValue([
|
||||||
{ tagId: 'tag-1', assetId: 'asset-1' },
|
{ tagId: 'tag-1', assetId: 'asset-1' },
|
||||||
{ tagId: 'tag-1', assetId: 'asset-2' },
|
{ tagId: 'tag-1', assetId: 'asset-2' },
|
||||||
@@ -242,7 +246,10 @@ describe(TagService.name, () => {
|
|||||||
mocks.tag.get.mockResolvedValue(tagStub.tag);
|
mocks.tag.get.mockResolvedValue(tagStub.tag);
|
||||||
mocks.tag.getAssetIds.mockResolvedValue(new Set(['asset-1']));
|
mocks.tag.getAssetIds.mockResolvedValue(new Set(['asset-1']));
|
||||||
mocks.tag.addAssetIds.mockResolvedValue();
|
mocks.tag.addAssetIds.mockResolvedValue();
|
||||||
mocks.asset.getById.mockResolvedValue({ tags: [{ value: 'tag-1' }] } as any);
|
mocks.asset.getById.mockResolvedValue({
|
||||||
|
...factory.asset(),
|
||||||
|
tags: [factory.tag({ value: 'tag-1' })],
|
||||||
|
});
|
||||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-2']));
|
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-2']));
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
|
|||||||
@@ -23,34 +23,39 @@ import {
|
|||||||
VideoCodec,
|
VideoCodec,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
|
|
||||||
export type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T;
|
export type DeepPartial<T> =
|
||||||
|
T extends Record<string, unknown>
|
||||||
|
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||||
|
: T extends Array<infer R>
|
||||||
|
? DeepPartial<R>[]
|
||||||
|
: T;
|
||||||
|
|
||||||
export type RepositoryInterface<T extends object> = Pick<T, keyof T>;
|
export type RepositoryInterface<T extends object> = Pick<T, keyof T>;
|
||||||
|
|
||||||
export interface FullsizeImageOptions {
|
export type FullsizeImageOptions = {
|
||||||
format: ImageFormat;
|
format: ImageFormat;
|
||||||
quality: number;
|
quality: number;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface ImageOptions {
|
export type ImageOptions = {
|
||||||
format: ImageFormat;
|
format: ImageFormat;
|
||||||
quality: number;
|
quality: number;
|
||||||
size: number;
|
size: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface RawImageInfo {
|
export type RawImageInfo = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
channels: 1 | 2 | 3 | 4;
|
channels: 1 | 2 | 3 | 4;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface DecodeImageOptions {
|
type DecodeImageOptions = {
|
||||||
colorspace: string;
|
colorspace: string;
|
||||||
processInvalidImages: boolean;
|
processInvalidImages: boolean;
|
||||||
raw?: RawImageInfo;
|
raw?: RawImageInfo;
|
||||||
edits?: AssetEditActionItem[];
|
edits?: AssetEditActionItem[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface DecodeToBufferOptions extends DecodeImageOptions {
|
export interface DecodeToBufferOptions extends DecodeImageOptions {
|
||||||
size?: number;
|
size?: number;
|
||||||
@@ -504,7 +509,7 @@ export interface SystemMetadata extends Record<SystemMetadataKey, Record<string,
|
|||||||
[SystemMetadataKey.MemoriesState]: MemoriesState;
|
[SystemMetadataKey.MemoriesState]: MemoriesState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserPreferences {
|
export type UserPreferences = {
|
||||||
albums: {
|
albums: {
|
||||||
defaultAssetOrder: AssetOrder;
|
defaultAssetOrder: AssetOrder;
|
||||||
};
|
};
|
||||||
@@ -547,7 +552,7 @@ export interface UserPreferences {
|
|||||||
cast: {
|
cast: {
|
||||||
gCastEnabled: boolean;
|
gCastEnabled: boolean;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserMetadataItem<T extends keyof UserMetadata = UserMetadataKey> = {
|
export type UserMetadataItem<T extends keyof UserMetadata = UserMetadataKey> = {
|
||||||
key: T;
|
key: T;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
Activity,
|
Activity,
|
||||||
ApiKey,
|
ApiKey,
|
||||||
|
AssetFace,
|
||||||
AssetFile,
|
AssetFile,
|
||||||
AuthApiKey,
|
AuthApiKey,
|
||||||
AuthSharedLink,
|
AuthSharedLink,
|
||||||
@@ -9,12 +10,16 @@ import {
|
|||||||
Library,
|
Library,
|
||||||
Memory,
|
Memory,
|
||||||
Partner,
|
Partner,
|
||||||
|
Person,
|
||||||
Session,
|
Session,
|
||||||
|
Stack,
|
||||||
|
Tag,
|
||||||
User,
|
User,
|
||||||
UserAdmin,
|
UserAdmin,
|
||||||
} from 'src/database';
|
} from 'src/database';
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
|
import { AssetEditAction, AssetEditActionItem, MirrorAxis } from 'src/dtos/editing.dto';
|
||||||
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
||||||
import {
|
import {
|
||||||
AssetFileType,
|
AssetFileType,
|
||||||
@@ -23,10 +28,11 @@ import {
|
|||||||
AssetVisibility,
|
AssetVisibility,
|
||||||
MemoryType,
|
MemoryType,
|
||||||
Permission,
|
Permission,
|
||||||
|
SourceType,
|
||||||
UserMetadataKey,
|
UserMetadataKey,
|
||||||
UserStatus,
|
UserStatus,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { OnThisDayData, UserMetadataItem } from 'src/types';
|
import { DeepPartial, OnThisDayData, UserMetadataItem } from 'src/types';
|
||||||
import { v4, v7 } from 'uuid';
|
import { v4, v7 } from 'uuid';
|
||||||
|
|
||||||
export const newUuid = () => v4();
|
export const newUuid = () => v4();
|
||||||
@@ -160,11 +166,18 @@ const queueStatisticsFactory = (dto?: Partial<QueueStatisticsDto>) => ({
|
|||||||
...dto,
|
...dto,
|
||||||
});
|
});
|
||||||
|
|
||||||
const stackFactory = () => ({
|
const stackFactory = ({ owner, assets, ...stack }: DeepPartial<Stack> = {}): Stack => {
|
||||||
id: newUuid(),
|
const ownerId = newUuid();
|
||||||
ownerId: newUuid(),
|
|
||||||
primaryAssetId: newUuid(),
|
return {
|
||||||
});
|
id: newUuid(),
|
||||||
|
primaryAssetId: assets?.[0].id ?? newUuid(),
|
||||||
|
ownerId,
|
||||||
|
owner: userFactory(owner ?? { id: ownerId }),
|
||||||
|
assets: assets?.map((asset) => assetFactory(asset)) ?? [],
|
||||||
|
...stack,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const userFactory = (user: Partial<User> = {}) => ({
|
const userFactory = (user: Partial<User> = {}) => ({
|
||||||
id: newUuid(),
|
id: newUuid(),
|
||||||
@@ -223,39 +236,43 @@ const userAdminFactory = (user: Partial<UserAdmin> = {}) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const assetFactory = (asset: Partial<MapAsset> = {}) => ({
|
const assetFactory = (
|
||||||
id: newUuid(),
|
asset: Omit<DeepPartial<MapAsset>, 'exifInfo' | 'owner' | 'stack' | 'tags' | 'faces' | 'files' | 'edits'> = {},
|
||||||
createdAt: newDate(),
|
) => {
|
||||||
updatedAt: newDate(),
|
return {
|
||||||
deletedAt: null,
|
id: newUuid(),
|
||||||
updateId: newUuidV7(),
|
createdAt: newDate(),
|
||||||
status: AssetStatus.Active,
|
updatedAt: newDate(),
|
||||||
checksum: newSha1(),
|
deletedAt: null,
|
||||||
deviceAssetId: '',
|
updateId: newUuidV7(),
|
||||||
deviceId: '',
|
status: AssetStatus.Active,
|
||||||
duplicateId: null,
|
checksum: newSha1(),
|
||||||
duration: null,
|
deviceAssetId: '',
|
||||||
encodedVideoPath: null,
|
deviceId: '',
|
||||||
fileCreatedAt: newDate(),
|
duplicateId: null,
|
||||||
fileModifiedAt: newDate(),
|
duration: null,
|
||||||
isExternal: false,
|
encodedVideoPath: null,
|
||||||
isFavorite: false,
|
fileCreatedAt: newDate(),
|
||||||
isOffline: false,
|
fileModifiedAt: newDate(),
|
||||||
libraryId: null,
|
isExternal: false,
|
||||||
livePhotoVideoId: null,
|
isFavorite: false,
|
||||||
localDateTime: newDate(),
|
isOffline: false,
|
||||||
originalFileName: 'IMG_123.jpg',
|
libraryId: null,
|
||||||
originalPath: `/data/12/34/IMG_123.jpg`,
|
livePhotoVideoId: null,
|
||||||
ownerId: newUuid(),
|
localDateTime: newDate(),
|
||||||
stackId: null,
|
originalFileName: 'IMG_123.jpg',
|
||||||
thumbhash: null,
|
originalPath: `/data/12/34/IMG_123.jpg`,
|
||||||
type: AssetType.Image,
|
ownerId: newUuid(),
|
||||||
visibility: AssetVisibility.Timeline,
|
stackId: null,
|
||||||
width: null,
|
thumbhash: null,
|
||||||
height: null,
|
type: AssetType.Image,
|
||||||
isEdited: false,
|
visibility: AssetVisibility.Timeline,
|
||||||
...asset,
|
width: null,
|
||||||
});
|
height: null,
|
||||||
|
isEdited: false,
|
||||||
|
...asset,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const activityFactory = (activity: Partial<Activity> = {}) => {
|
const activityFactory = (activity: Partial<Activity> = {}) => {
|
||||||
const userId = activity.userId || newUuid();
|
const userId = activity.userId || newUuid();
|
||||||
@@ -391,6 +408,102 @@ const assetFileFactory = (file: Partial<AssetFile> = {}): AssetFile => ({
|
|||||||
...file,
|
...file,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const exifFactory = (exif: Partial<Exif> = {}) => ({
|
||||||
|
assetId: newUuid(),
|
||||||
|
autoStackId: null,
|
||||||
|
bitsPerSample: null,
|
||||||
|
city: 'Austin',
|
||||||
|
colorspace: null,
|
||||||
|
country: 'United States of America',
|
||||||
|
dateTimeOriginal: newDate(),
|
||||||
|
description: '',
|
||||||
|
exifImageHeight: 420,
|
||||||
|
exifImageWidth: 42,
|
||||||
|
exposureTime: null,
|
||||||
|
fileSizeInByte: 69,
|
||||||
|
fNumber: 1.7,
|
||||||
|
focalLength: 4.38,
|
||||||
|
fps: null,
|
||||||
|
iso: 947,
|
||||||
|
latitude: 30.267_334_570_570_195,
|
||||||
|
longitude: -97.789_833_534_282_07,
|
||||||
|
lensModel: null,
|
||||||
|
livePhotoCID: null,
|
||||||
|
make: 'Google',
|
||||||
|
model: 'Pixel 7',
|
||||||
|
modifyDate: newDate(),
|
||||||
|
orientation: '1',
|
||||||
|
profileDescription: null,
|
||||||
|
projectionType: null,
|
||||||
|
rating: 4,
|
||||||
|
state: 'Texas',
|
||||||
|
tags: ['parent/child'],
|
||||||
|
timeZone: 'UTC-6',
|
||||||
|
...exif,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tagFactory = (tag: Partial<Tag>): Tag => ({
|
||||||
|
id: newUuid(),
|
||||||
|
color: null,
|
||||||
|
createdAt: newDate(),
|
||||||
|
parentId: null,
|
||||||
|
updatedAt: newDate(),
|
||||||
|
value: `tag-${newUuid()}`,
|
||||||
|
...tag,
|
||||||
|
});
|
||||||
|
|
||||||
|
const faceFactory = ({ person, ...face }: DeepPartial<AssetFace> = {}): AssetFace => ({
|
||||||
|
assetId: newUuid(),
|
||||||
|
boundingBoxX1: 1,
|
||||||
|
boundingBoxX2: 2,
|
||||||
|
boundingBoxY1: 1,
|
||||||
|
boundingBoxY2: 2,
|
||||||
|
deletedAt: null,
|
||||||
|
id: newUuid(),
|
||||||
|
imageHeight: 420,
|
||||||
|
imageWidth: 42,
|
||||||
|
isVisible: true,
|
||||||
|
personId: null,
|
||||||
|
sourceType: SourceType.MachineLearning,
|
||||||
|
updatedAt: newDate(),
|
||||||
|
updateId: newUuidV7(),
|
||||||
|
person: person === null ? null : personFactory(person),
|
||||||
|
...face,
|
||||||
|
});
|
||||||
|
|
||||||
|
const assetEditFactory = (edit?: Partial<AssetEditActionItem>): AssetEditActionItem => {
|
||||||
|
switch (edit?.action) {
|
||||||
|
case AssetEditAction.Crop: {
|
||||||
|
return { action: AssetEditAction.Crop, parameters: { height: 42, width: 42, x: 0, y: 10 }, ...edit };
|
||||||
|
}
|
||||||
|
case AssetEditAction.Mirror: {
|
||||||
|
return { action: AssetEditAction.Mirror, parameters: { axis: MirrorAxis.Horizontal }, ...edit };
|
||||||
|
}
|
||||||
|
case AssetEditAction.Rotate: {
|
||||||
|
return { action: AssetEditAction.Rotate, parameters: { angle: 90 }, ...edit };
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return { action: AssetEditAction.Mirror, parameters: { axis: MirrorAxis.Vertical } };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const personFactory = (person?: Partial<Person>): Person => ({
|
||||||
|
birthDate: newDate(),
|
||||||
|
color: null,
|
||||||
|
createdAt: newDate(),
|
||||||
|
faceAssetId: null,
|
||||||
|
id: newUuid(),
|
||||||
|
isFavorite: false,
|
||||||
|
isHidden: false,
|
||||||
|
name: 'person',
|
||||||
|
ownerId: newUuid(),
|
||||||
|
thumbnailPath: '/path/to/person/thumbnail.jpg',
|
||||||
|
updatedAt: newDate(),
|
||||||
|
updateId: newUuidV7(),
|
||||||
|
...person,
|
||||||
|
});
|
||||||
|
|
||||||
export const factory = {
|
export const factory = {
|
||||||
activity: activityFactory,
|
activity: activityFactory,
|
||||||
apiKey: apiKeyFactory,
|
apiKey: apiKeyFactory,
|
||||||
@@ -412,6 +525,11 @@ export const factory = {
|
|||||||
jobAssets: {
|
jobAssets: {
|
||||||
sidecarWrite: assetSidecarWriteFactory,
|
sidecarWrite: assetSidecarWriteFactory,
|
||||||
},
|
},
|
||||||
|
exif: exifFactory,
|
||||||
|
face: faceFactory,
|
||||||
|
person: personFactory,
|
||||||
|
assetEdit: assetEditFactory,
|
||||||
|
tag: tagFactory,
|
||||||
uuid: newUuid,
|
uuid: newUuid,
|
||||||
date: newDate,
|
date: newDate,
|
||||||
responses: {
|
responses: {
|
||||||
|
|||||||
Reference in New Issue
Block a user