mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor: small test factories (#26862)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { Selectable } from 'kysely';
|
||||
import { ActivityTable } from 'src/schema/tables/activity.table';
|
||||
import { build } from 'test/factories/builder.factory';
|
||||
import { ActivityLike, FactoryBuilder, UserLike } from 'test/factories/types';
|
||||
import { UserFactory } from 'test/factories/user.factory';
|
||||
import { newDate, newUuid, newUuidV7 } from 'test/small.factory';
|
||||
|
||||
export class ActivityFactory {
|
||||
#user!: UserFactory;
|
||||
|
||||
private constructor(private value: Selectable<ActivityTable>) {}
|
||||
|
||||
static create(dto: ActivityLike = {}) {
|
||||
return ActivityFactory.from(dto).build();
|
||||
}
|
||||
|
||||
static from(dto: ActivityLike = {}) {
|
||||
const userId = dto.userId ?? newUuid();
|
||||
return new ActivityFactory({
|
||||
albumId: newUuid(),
|
||||
assetId: null,
|
||||
comment: null,
|
||||
createdAt: newDate(),
|
||||
id: newUuid(),
|
||||
isLiked: false,
|
||||
userId,
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
...dto,
|
||||
}).user({ id: userId });
|
||||
}
|
||||
|
||||
user(dto: UserLike = {}, builder?: FactoryBuilder<UserFactory>) {
|
||||
this.#user = build(UserFactory.from(dto), builder);
|
||||
this.value.userId = this.#user.build().id;
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return { ...this.value, user: this.#user.build() };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Selectable } from 'kysely';
|
||||
import { Permission } from 'src/enum';
|
||||
import { ApiKeyTable } from 'src/schema/tables/api-key.table';
|
||||
import { build } from 'test/factories/builder.factory';
|
||||
import { ApiKeyLike, FactoryBuilder, UserLike } from 'test/factories/types';
|
||||
import { UserFactory } from 'test/factories/user.factory';
|
||||
import { newDate, newUuid, newUuidV7 } from 'test/small.factory';
|
||||
|
||||
export class ApiKeyFactory {
|
||||
#user!: UserFactory;
|
||||
|
||||
private constructor(private value: Selectable<ApiKeyTable>) {}
|
||||
|
||||
static create(dto: ApiKeyLike = {}) {
|
||||
return ApiKeyFactory.from(dto).build();
|
||||
}
|
||||
|
||||
static from(dto: ApiKeyLike = {}) {
|
||||
const userId = dto.userId ?? newUuid();
|
||||
return new ApiKeyFactory({
|
||||
createdAt: newDate(),
|
||||
id: newUuid(),
|
||||
key: Buffer.from('api-key-buffer'),
|
||||
name: 'API Key',
|
||||
permissions: [Permission.All],
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
userId,
|
||||
...dto,
|
||||
}).user({ id: userId });
|
||||
}
|
||||
|
||||
user(dto: UserLike = {}, builder?: FactoryBuilder<UserFactory>) {
|
||||
this.#user = build(UserFactory.from(dto), builder);
|
||||
this.value.userId = this.#user.build().id;
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return { ...this.value, user: this.#user.build() };
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { ApiKeyFactory } from 'test/factories/api-key.factory';
|
||||
import { build } from 'test/factories/builder.factory';
|
||||
import { SharedLinkFactory } from 'test/factories/shared-link.factory';
|
||||
import { FactoryBuilder, SharedLinkLike, UserLike } from 'test/factories/types';
|
||||
import { ApiKeyLike, FactoryBuilder, SharedLinkLike, UserLike } from 'test/factories/types';
|
||||
import { UserFactory } from 'test/factories/user.factory';
|
||||
import { newUuid } from 'test/small.factory';
|
||||
|
||||
export class AuthFactory {
|
||||
#user: UserFactory;
|
||||
#sharedLink?: SharedLinkFactory;
|
||||
#apiKey?: ApiKeyFactory;
|
||||
#session?: AuthDto['session'];
|
||||
|
||||
private constructor(user: UserFactory) {
|
||||
this.#user = user;
|
||||
@@ -20,8 +24,8 @@ export class AuthFactory {
|
||||
return new AuthFactory(UserFactory.from(dto));
|
||||
}
|
||||
|
||||
apiKey() {
|
||||
// TODO
|
||||
apiKey(dto: ApiKeyLike = {}, builder?: FactoryBuilder<ApiKeyFactory>) {
|
||||
this.#apiKey = build(ApiKeyFactory.from(dto), builder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -30,6 +34,11 @@ export class AuthFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
session(dto: Partial<AuthDto['session']> = {}) {
|
||||
this.#session = { id: newUuid(), hasElevatedPermission: false, ...dto };
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): AuthDto {
|
||||
const { id, isAdmin, name, email, quotaUsageInBytes, quotaSizeInBytes } = this.#user.build();
|
||||
|
||||
@@ -43,6 +52,8 @@ export class AuthFactory {
|
||||
quotaSizeInBytes,
|
||||
},
|
||||
sharedLink: this.#sharedLink?.build(),
|
||||
apiKey: this.#apiKey?.build(),
|
||||
session: this.#session,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Selectable } from 'kysely';
|
||||
import { PartnerTable } from 'src/schema/tables/partner.table';
|
||||
import { build } from 'test/factories/builder.factory';
|
||||
import { FactoryBuilder, PartnerLike, UserLike } from 'test/factories/types';
|
||||
import { UserFactory } from 'test/factories/user.factory';
|
||||
import { newDate, newUuid, newUuidV7 } from 'test/small.factory';
|
||||
|
||||
export class PartnerFactory {
|
||||
#sharedWith!: UserFactory;
|
||||
#sharedBy!: UserFactory;
|
||||
|
||||
private constructor(private value: Selectable<PartnerTable>) {}
|
||||
|
||||
static create(dto: PartnerLike = {}) {
|
||||
return PartnerFactory.from(dto).build();
|
||||
}
|
||||
|
||||
static from(dto: PartnerLike = {}) {
|
||||
const sharedById = dto.sharedById ?? newUuid();
|
||||
const sharedWithId = dto.sharedWithId ?? newUuid();
|
||||
return new PartnerFactory({
|
||||
createdAt: newDate(),
|
||||
createId: newUuidV7(),
|
||||
inTimeline: true,
|
||||
sharedById,
|
||||
sharedWithId,
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
...dto,
|
||||
})
|
||||
.sharedBy({ id: sharedById })
|
||||
.sharedWith({ id: sharedWithId });
|
||||
}
|
||||
|
||||
sharedWith(dto: UserLike = {}, builder?: FactoryBuilder<UserFactory>) {
|
||||
this.#sharedWith = build(UserFactory.from(dto), builder);
|
||||
this.value.sharedWithId = this.#sharedWith.build().id;
|
||||
return this;
|
||||
}
|
||||
|
||||
sharedBy(dto: UserLike = {}, builder?: FactoryBuilder<UserFactory>) {
|
||||
this.#sharedBy = build(UserFactory.from(dto), builder);
|
||||
this.value.sharedById = this.#sharedBy.build().id;
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return { ...this.value, sharedWith: this.#sharedWith.build(), sharedBy: this.#sharedBy.build() };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Selectable } from 'kysely';
|
||||
import { SessionTable } from 'src/schema/tables/session.table';
|
||||
import { SessionLike } from 'test/factories/types';
|
||||
import { newDate, newUuid, newUuidV7 } from 'test/small.factory';
|
||||
|
||||
export class SessionFactory {
|
||||
private constructor(private value: Selectable<SessionTable>) {}
|
||||
|
||||
static create(dto: SessionLike = {}) {
|
||||
return SessionFactory.from(dto).build();
|
||||
}
|
||||
|
||||
static from(dto: SessionLike = {}) {
|
||||
return new SessionFactory({
|
||||
appVersion: null,
|
||||
createdAt: newDate(),
|
||||
deviceOS: 'android',
|
||||
deviceType: 'mobile',
|
||||
expiresAt: null,
|
||||
id: newUuid(),
|
||||
isPendingSyncReset: false,
|
||||
parentId: null,
|
||||
pinExpiresAt: null,
|
||||
token: Buffer.from('abc123'),
|
||||
updateId: newUuidV7(),
|
||||
updatedAt: newDate(),
|
||||
userId: newUuid(),
|
||||
...dto,
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
return { ...this.value };
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
import { Selectable } from 'kysely';
|
||||
import { ActivityTable } from 'src/schema/tables/activity.table';
|
||||
import { AlbumUserTable } from 'src/schema/tables/album-user.table';
|
||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||
import { ApiKeyTable } from 'src/schema/tables/api-key.table';
|
||||
import { AssetEditTable } from 'src/schema/tables/asset-edit.table';
|
||||
import { AssetExifTable } from 'src/schema/tables/asset-exif.table';
|
||||
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||
import { AssetFileTable } from 'src/schema/tables/asset-file.table';
|
||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||
import { MemoryTable } from 'src/schema/tables/memory.table';
|
||||
import { PartnerTable } from 'src/schema/tables/partner.table';
|
||||
import { PersonTable } from 'src/schema/tables/person.table';
|
||||
import { SessionTable } from 'src/schema/tables/session.table';
|
||||
import { SharedLinkTable } from 'src/schema/tables/shared-link.table';
|
||||
import { StackTable } from 'src/schema/tables/stack.table';
|
||||
import { UserTable } from 'src/schema/tables/user.table';
|
||||
@@ -26,3 +30,7 @@ export type AssetFaceLike = Partial<Selectable<AssetFaceTable>>;
|
||||
export type PersonLike = Partial<Selectable<PersonTable>>;
|
||||
export type StackLike = Partial<Selectable<StackTable>>;
|
||||
export type MemoryLike = Partial<Selectable<MemoryTable>>;
|
||||
export type PartnerLike = Partial<Selectable<PartnerTable>>;
|
||||
export type ActivityLike = Partial<Selectable<ActivityTable>>;
|
||||
export type ApiKeyLike = Partial<Selectable<ApiKeyTable>>;
|
||||
export type SessionLike = Partial<Selectable<SessionTable>>;
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
import { ShallowDehydrateObject } from 'kysely';
|
||||
import {
|
||||
Activity,
|
||||
Album,
|
||||
ApiKey,
|
||||
AuthApiKey,
|
||||
AuthSharedLink,
|
||||
AuthUser,
|
||||
Exif,
|
||||
Library,
|
||||
Partner,
|
||||
Person,
|
||||
Session,
|
||||
Tag,
|
||||
User,
|
||||
UserAdmin,
|
||||
} from 'src/database';
|
||||
import { AuthApiKey, AuthSharedLink, AuthUser, Exif, Library, UserAdmin } from 'src/database';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { AssetEditAction, AssetEditActionItem, MirrorAxis } from 'src/dtos/editing.dto';
|
||||
import { QueueStatisticsDto } from 'src/dtos/queue.dto';
|
||||
import { AssetFileType, AssetOrder, Permission, UserMetadataKey, UserStatus } from 'src/enum';
|
||||
import { UserMetadataItem } from 'src/types';
|
||||
import { UserFactory } from 'test/factories/user.factory';
|
||||
import { AssetFileType, Permission, UserStatus } from 'src/enum';
|
||||
import { v4, v7 } from 'uuid';
|
||||
|
||||
export const newUuid = () => v4();
|
||||
@@ -109,49 +90,6 @@ const authUserFactory = (authUser: Partial<AuthUser> = {}) => {
|
||||
return { id, isAdmin, name, email, quotaUsageInBytes, quotaSizeInBytes };
|
||||
};
|
||||
|
||||
const partnerFactory = ({
|
||||
sharedBy: sharedByProvided,
|
||||
sharedWith: sharedWithProvided,
|
||||
...partner
|
||||
}: Partial<Partner> = {}) => {
|
||||
const hydrateUser = (user: Partial<ShallowDehydrateObject<User>>) => ({
|
||||
...user,
|
||||
profileChangedAt: user.profileChangedAt ? new Date(user.profileChangedAt) : undefined,
|
||||
});
|
||||
const sharedBy = UserFactory.create(sharedByProvided ? hydrateUser(sharedByProvided) : {});
|
||||
const sharedWith = UserFactory.create(sharedWithProvided ? hydrateUser(sharedWithProvided) : {});
|
||||
|
||||
return {
|
||||
sharedById: sharedBy.id,
|
||||
sharedBy,
|
||||
sharedWithId: sharedWith.id,
|
||||
sharedWith,
|
||||
createId: newUuidV7(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
inTimeline: true,
|
||||
...partner,
|
||||
};
|
||||
};
|
||||
|
||||
const sessionFactory = (session: Partial<Session> = {}) => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
deviceOS: 'android',
|
||||
deviceType: 'mobile',
|
||||
token: Buffer.from('abc123'),
|
||||
parentId: null,
|
||||
expiresAt: null,
|
||||
userId: newUuid(),
|
||||
pinExpiresAt: newDate(),
|
||||
isPendingSyncReset: false,
|
||||
appVersion: session.appVersion ?? null,
|
||||
...session,
|
||||
});
|
||||
|
||||
const queueStatisticsFactory = (dto?: Partial<QueueStatisticsDto>) => ({
|
||||
active: 0,
|
||||
completed: 0,
|
||||
@@ -162,22 +100,6 @@ const queueStatisticsFactory = (dto?: Partial<QueueStatisticsDto>) => ({
|
||||
...dto,
|
||||
});
|
||||
|
||||
const userFactory = (user: Partial<User> = {}) => ({
|
||||
id: newUuid(),
|
||||
name: 'Test User',
|
||||
email: 'test@immich.cloud',
|
||||
avatarColor: null,
|
||||
profileImagePath: '',
|
||||
profileChangedAt: newDate(),
|
||||
metadata: [
|
||||
{
|
||||
key: UserMetadataKey.Onboarding,
|
||||
value: 'true',
|
||||
},
|
||||
] as UserMetadataItem[],
|
||||
...user,
|
||||
});
|
||||
|
||||
const userAdminFactory = (user: Partial<UserAdmin> = {}) => {
|
||||
const {
|
||||
id = newUuid(),
|
||||
@@ -219,34 +141,6 @@ const userAdminFactory = (user: Partial<UserAdmin> = {}) => {
|
||||
};
|
||||
};
|
||||
|
||||
const activityFactory = (activity: Omit<Partial<Activity>, 'user'> = {}) => {
|
||||
const userId = activity.userId || newUuid();
|
||||
return {
|
||||
id: newUuid(),
|
||||
comment: null,
|
||||
isLiked: false,
|
||||
userId,
|
||||
user: UserFactory.create({ id: userId }),
|
||||
assetId: newUuid(),
|
||||
albumId: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
...activity,
|
||||
};
|
||||
};
|
||||
|
||||
const apiKeyFactory = (apiKey: Partial<ApiKey> = {}) => ({
|
||||
id: newUuid(),
|
||||
userId: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
name: 'Api Key',
|
||||
permissions: [Permission.All],
|
||||
...apiKey,
|
||||
});
|
||||
|
||||
const libraryFactory = (library: Partial<Library> = {}) => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
@@ -328,88 +222,15 @@ const assetOcrFactory = (
|
||||
...ocr,
|
||||
});
|
||||
|
||||
const tagFactory = (tag: Partial<Tag>): Tag => ({
|
||||
id: newUuid(),
|
||||
color: null,
|
||||
createdAt: newDate(),
|
||||
parentId: null,
|
||||
updatedAt: newDate(),
|
||||
value: `tag-${newUuid()}`,
|
||||
...tag,
|
||||
});
|
||||
|
||||
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,
|
||||
});
|
||||
|
||||
const albumFactory = (album?: Partial<Omit<Album, 'assets'>>) => ({
|
||||
albumName: 'My Album',
|
||||
albumThumbnailAssetId: null,
|
||||
albumUsers: [],
|
||||
assets: [],
|
||||
createdAt: newDate(),
|
||||
deletedAt: null,
|
||||
description: 'Album description',
|
||||
id: newUuid(),
|
||||
isActivityEnabled: false,
|
||||
order: AssetOrder.Desc,
|
||||
ownerId: newUuid(),
|
||||
sharedLinks: [],
|
||||
updatedAt: newDate(),
|
||||
updateId: newUuidV7(),
|
||||
...album,
|
||||
});
|
||||
|
||||
export const factory = {
|
||||
activity: activityFactory,
|
||||
apiKey: apiKeyFactory,
|
||||
assetOcr: assetOcrFactory,
|
||||
auth: authFactory,
|
||||
authApiKey: authApiKeyFactory,
|
||||
authUser: authUserFactory,
|
||||
library: libraryFactory,
|
||||
partner: partnerFactory,
|
||||
queueStatistics: queueStatisticsFactory,
|
||||
session: sessionFactory,
|
||||
user: userFactory,
|
||||
userAdmin: userAdminFactory,
|
||||
versionHistory: versionHistoryFactory,
|
||||
jobAssets: {
|
||||
sidecarWrite: assetSidecarWriteFactory,
|
||||
},
|
||||
person: personFactory,
|
||||
assetEdit: assetEditFactory,
|
||||
tag: tagFactory,
|
||||
album: albumFactory,
|
||||
uuid: newUuid,
|
||||
buffer: () => Buffer.from('this is a fake buffer'),
|
||||
date: newDate,
|
||||
|
||||
Reference in New Issue
Block a user