mirror of
https://github.com/immich-app/immich.git
synced 2025-04-08 03:01:32 -05:00
refactor: memory stub (#16704)
This commit is contained in:
parent
b0bf4e4fff
commit
ce74f765b1
6 changed files with 218 additions and 116 deletions
|
@ -1,5 +1,5 @@
|
|||
import { sql } from 'kysely';
|
||||
import { Permission } from 'src/enum';
|
||||
import { AssetStatus, AssetType, Permission } from 'src/enum';
|
||||
|
||||
export type AuthUser = {
|
||||
id: string;
|
||||
|
@ -23,6 +23,38 @@ export type User = {
|
|||
profileChangedAt: Date;
|
||||
};
|
||||
|
||||
export type Asset = {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
deletedAt: Date | null;
|
||||
id: string;
|
||||
updateId: string;
|
||||
status: AssetStatus;
|
||||
checksum: Buffer<ArrayBufferLike>;
|
||||
deviceAssetId: string;
|
||||
deviceId: string;
|
||||
duplicateId: string | null;
|
||||
duration: string | null;
|
||||
encodedVideoPath: string | null;
|
||||
fileCreatedAt: Date | null;
|
||||
fileModifiedAt: Date | null;
|
||||
isArchived: boolean;
|
||||
isExternal: boolean;
|
||||
isFavorite: boolean;
|
||||
isOffline: boolean;
|
||||
isVisible: boolean;
|
||||
libraryId: string | null;
|
||||
livePhotoVideoId: string | null;
|
||||
localDateTime: Date | null;
|
||||
originalFileName: string;
|
||||
originalPath: string;
|
||||
ownerId: string;
|
||||
sidecarPath: string | null;
|
||||
stackId: string | null;
|
||||
thumbhash: Buffer<ArrayBufferLike> | null;
|
||||
type: AssetType;
|
||||
};
|
||||
|
||||
export type AuthSharedLink = {
|
||||
id: string;
|
||||
expiresAt: Date | null;
|
||||
|
|
7
server/src/db.d.ts
vendored
7
server/src/db.d.ts
vendored
|
@ -4,7 +4,8 @@
|
|||
*/
|
||||
|
||||
import type { ColumnType } from 'kysely';
|
||||
import { AssetType, Permission, SyncEntityType } from 'src/enum';
|
||||
import { OnThisDayData } from 'src/entities/memory.entity';
|
||||
import { AssetType, MemoryType, Permission, SyncEntityType } from 'src/enum';
|
||||
|
||||
export type ArrayType<T> = ArrayTypeImpl<T> extends (infer U)[] ? U[] : ArrayTypeImpl<T>;
|
||||
|
||||
|
@ -231,7 +232,7 @@ export interface Libraries {
|
|||
|
||||
export interface Memories {
|
||||
createdAt: Generated<Timestamp>;
|
||||
data: Json;
|
||||
data: OnThisDayData;
|
||||
deletedAt: Timestamp | null;
|
||||
hideAt: Timestamp | null;
|
||||
id: Generated<string>;
|
||||
|
@ -240,7 +241,7 @@ export interface Memories {
|
|||
ownerId: string;
|
||||
seenAt: Timestamp | null;
|
||||
showAt: Timestamp | null;
|
||||
type: string;
|
||||
type: MemoryType;
|
||||
updatedAt: Generated<Timestamp>;
|
||||
updateId: Generated<string>;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import { BadRequestException } from '@nestjs/common';
|
||||
import { MemoryType } from 'src/enum';
|
||||
import { MemoryService } from 'src/services/memory.service';
|
||||
import { authStub } from 'test/fixtures/auth.stub';
|
||||
import { memoryStub } from 'test/fixtures/memory.stub';
|
||||
import { userStub } from 'test/fixtures/user.stub';
|
||||
import { factory, newUuid, newUuids } from 'test/small.factory';
|
||||
import { newTestService, ServiceMocks } from 'test/utils';
|
||||
|
||||
describe(MemoryService.name, () => {
|
||||
|
@ -20,174 +17,227 @@ describe(MemoryService.name, () => {
|
|||
|
||||
describe('search', () => {
|
||||
it('should search memories', async () => {
|
||||
mocks.memory.search.mockResolvedValue([memoryStub.memory1, memoryStub.empty]);
|
||||
await expect(sut.search(authStub.admin, {})).resolves.toEqual(
|
||||
const [userId] = newUuids();
|
||||
const asset = factory.asset();
|
||||
const memory1 = factory.memory({ ownerId: userId, assets: [asset] });
|
||||
const memory2 = factory.memory({ ownerId: userId });
|
||||
|
||||
mocks.memory.search.mockResolvedValue([memory1, memory2]);
|
||||
|
||||
await expect(sut.search(factory.auth({ id: userId }), {})).resolves.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: 'memory1', assets: expect.any(Array) }),
|
||||
expect.objectContaining({ id: 'memoryEmpty', assets: [] }),
|
||||
expect.objectContaining({ id: memory1.id, assets: [expect.objectContaining({ id: asset.id })] }),
|
||||
expect.objectContaining({ id: memory2.id, assets: [] }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should map ', async () => {
|
||||
await expect(sut.search(authStub.admin, {})).resolves.toEqual([]);
|
||||
await expect(sut.search(factory.auth(), {})).resolves.toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
it('should throw an error when no access', async () => {
|
||||
await expect(sut.get(authStub.admin, 'not-found')).rejects.toBeInstanceOf(BadRequestException);
|
||||
await expect(sut.get(factory.auth(), 'not-found')).rejects.toBeInstanceOf(BadRequestException);
|
||||
});
|
||||
|
||||
it('should throw an error when the memory is not found', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['race-condition']));
|
||||
await expect(sut.get(authStub.admin, 'race-condition')).rejects.toBeInstanceOf(BadRequestException);
|
||||
const [memoryId] = newUuids();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memoryId]));
|
||||
|
||||
await expect(sut.get(factory.auth(), memoryId)).rejects.toBeInstanceOf(BadRequestException);
|
||||
});
|
||||
|
||||
it('should get a memory by id', async () => {
|
||||
mocks.memory.get.mockResolvedValue(memoryStub.memory1);
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
await expect(sut.get(authStub.admin, 'memory1')).resolves.toMatchObject({ id: 'memory1' });
|
||||
expect(mocks.memory.get).toHaveBeenCalledWith('memory1');
|
||||
expect(mocks.access.memory.checkOwnerAccess).toHaveBeenCalledWith(userStub.admin.id, new Set(['memory1']));
|
||||
const userId = newUuid();
|
||||
const memory = factory.memory({ ownerId: userId });
|
||||
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
|
||||
await expect(sut.get(factory.auth({ id: userId }), memory.id)).resolves.toMatchObject({ id: memory.id });
|
||||
|
||||
expect(mocks.memory.get).toHaveBeenCalledWith(memory.id);
|
||||
expect(mocks.access.memory.checkOwnerAccess).toHaveBeenCalledWith(memory.ownerId, new Set([memory.id]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should skip assets the user does not have access to', async () => {
|
||||
mocks.memory.create.mockResolvedValue(memoryStub.empty);
|
||||
const [assetId, userId] = newUuids();
|
||||
const memory = factory.memory({ ownerId: userId });
|
||||
|
||||
mocks.memory.create.mockResolvedValue(memory);
|
||||
|
||||
await expect(
|
||||
sut.create(authStub.admin, {
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 },
|
||||
assetIds: ['not-mine'],
|
||||
memoryAt: new Date(2024),
|
||||
sut.create(factory.auth({ id: userId }), {
|
||||
type: memory.type,
|
||||
data: memory.data,
|
||||
memoryAt: memory.memoryAt,
|
||||
isSaved: memory.isSaved,
|
||||
assetIds: [assetId],
|
||||
}),
|
||||
).resolves.toMatchObject({ assets: [] });
|
||||
|
||||
expect(mocks.memory.create).toHaveBeenCalledWith(
|
||||
{
|
||||
ownerId: 'admin_id',
|
||||
memoryAt: expect.any(Date),
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
isSaved: undefined,
|
||||
sendAt: undefined,
|
||||
data: { year: 2024 },
|
||||
type: memory.type,
|
||||
data: memory.data,
|
||||
ownerId: memory.ownerId,
|
||||
memoryAt: memory.memoryAt,
|
||||
isSaved: memory.isSaved,
|
||||
},
|
||||
new Set(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should create a memory', async () => {
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset1']));
|
||||
mocks.memory.create.mockResolvedValue(memoryStub.memory1);
|
||||
const [assetId, userId] = newUuids();
|
||||
const asset = factory.asset({ id: assetId, ownerId: userId });
|
||||
const memory = factory.memory({ assets: [asset] });
|
||||
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset.id]));
|
||||
mocks.memory.create.mockResolvedValue(memory);
|
||||
|
||||
await expect(
|
||||
sut.create(authStub.admin, {
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 },
|
||||
assetIds: ['asset1'],
|
||||
memoryAt: new Date(2024, 0, 1),
|
||||
sut.create(factory.auth({ id: userId }), {
|
||||
type: memory.type,
|
||||
data: memory.data,
|
||||
assetIds: memory.assets.map((asset) => asset.id),
|
||||
memoryAt: memory.memoryAt,
|
||||
}),
|
||||
).resolves.toBeDefined();
|
||||
|
||||
expect(mocks.memory.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
ownerId: userStub.admin.id,
|
||||
}),
|
||||
new Set(['asset1']),
|
||||
expect.objectContaining({ ownerId: userId }),
|
||||
new Set([assetId]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should create a memory without assets', async () => {
|
||||
mocks.memory.create.mockResolvedValue(memoryStub.memory1);
|
||||
const memory = factory.memory();
|
||||
|
||||
mocks.memory.create.mockResolvedValue(memory);
|
||||
|
||||
await expect(
|
||||
sut.create(authStub.admin, {
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 },
|
||||
memoryAt: new Date(2024),
|
||||
}),
|
||||
sut.create(factory.auth(), { type: memory.type, data: memory.data, memoryAt: memory.memoryAt }),
|
||||
).resolves.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should require access', async () => {
|
||||
await expect(sut.update(authStub.admin, 'not-found', { isSaved: true })).rejects.toBeInstanceOf(
|
||||
await expect(sut.update(factory.auth(), 'not-found', { isSaved: true })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
expect(mocks.memory.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update a memory', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.memory.update.mockResolvedValue(memoryStub.memory1);
|
||||
await expect(sut.update(authStub.admin, 'memory1', { isSaved: true })).resolves.toBeDefined();
|
||||
expect(mocks.memory.update).toHaveBeenCalledWith('memory1', expect.objectContaining({ isSaved: true }));
|
||||
const memory = factory.memory();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.memory.update.mockResolvedValue(memory);
|
||||
|
||||
await expect(sut.update(factory.auth(), memory.id, { isSaved: true })).resolves.toBeDefined();
|
||||
|
||||
expect(mocks.memory.update).toHaveBeenCalledWith(memory.id, expect.objectContaining({ isSaved: true }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should require access', async () => {
|
||||
await expect(sut.remove(authStub.admin, 'not-found')).rejects.toBeInstanceOf(BadRequestException);
|
||||
await expect(sut.remove(factory.auth(), newUuid())).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.memory.delete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should delete a memory', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
await expect(sut.remove(authStub.admin, 'memory1')).resolves.toBeUndefined();
|
||||
expect(mocks.memory.delete).toHaveBeenCalledWith('memory1');
|
||||
const memoryId = newUuid();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memoryId]));
|
||||
|
||||
await expect(sut.remove(factory.auth(), memoryId)).resolves.toBeUndefined();
|
||||
|
||||
expect(mocks.memory.delete).toHaveBeenCalledWith(memoryId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addAssets', () => {
|
||||
it('should require memory access', async () => {
|
||||
await expect(sut.addAssets(authStub.admin, 'not-found', { ids: ['asset1'] })).rejects.toBeInstanceOf(
|
||||
const [memoryId, assetId] = newUuids();
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memoryId, { ids: [assetId] })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
expect(mocks.memory.addAssetIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should require asset access', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.memory.get.mockResolvedValue(memoryStub.memory1);
|
||||
await expect(sut.addAssets(authStub.admin, 'memory1', { ids: ['not-found'] })).resolves.toEqual([
|
||||
{ error: 'no_permission', id: 'not-found', success: false },
|
||||
const assetId = newUuid();
|
||||
const memory = factory.memory();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memory.id, { ids: [assetId] })).resolves.toEqual([
|
||||
{ error: 'no_permission', id: assetId, success: false },
|
||||
]);
|
||||
|
||||
expect(mocks.memory.addAssetIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should skip assets already in the memory', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.memory.get.mockResolvedValue(memoryStub.memory1);
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set(['asset1']));
|
||||
await expect(sut.addAssets(authStub.admin, 'memory1', { ids: ['asset1'] })).resolves.toEqual([
|
||||
{ error: 'duplicate', id: 'asset1', success: false },
|
||||
const asset = factory.asset();
|
||||
const memory = factory.memory({ assets: [asset] });
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set([asset.id]));
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memory.id, { ids: [asset.id] })).resolves.toEqual([
|
||||
{ error: 'duplicate', id: asset.id, success: false },
|
||||
]);
|
||||
|
||||
expect(mocks.memory.addAssetIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should add assets', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset1']));
|
||||
mocks.memory.get.mockResolvedValue(memoryStub.memory1);
|
||||
await expect(sut.addAssets(authStub.admin, 'memory1', { ids: ['asset1'] })).resolves.toEqual([
|
||||
{ id: 'asset1', success: true },
|
||||
const assetId = newUuid();
|
||||
const memory = factory.memory();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([assetId]));
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memory.id, { ids: [assetId] })).resolves.toEqual([
|
||||
{ id: assetId, success: true },
|
||||
]);
|
||||
expect(mocks.memory.addAssetIds).toHaveBeenCalledWith('memory1', ['asset1']);
|
||||
|
||||
expect(mocks.memory.addAssetIds).toHaveBeenCalledWith(memory.id, [assetId]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeAssets', () => {
|
||||
it('should require memory access', async () => {
|
||||
await expect(sut.removeAssets(authStub.admin, 'not-found', { ids: ['asset1'] })).rejects.toBeInstanceOf(
|
||||
await expect(sut.removeAssets(factory.auth(), 'not-found', { ids: ['asset1'] })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
expect(mocks.memory.removeAssetIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should skip assets not in the memory', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
await expect(sut.removeAssets(authStub.admin, 'memory1', { ids: ['not-found'] })).resolves.toEqual([
|
||||
|
||||
await expect(sut.removeAssets(factory.auth(), 'memory1', { ids: ['not-found'] })).resolves.toEqual([
|
||||
{ error: 'not_found', id: 'not-found', success: false },
|
||||
]);
|
||||
|
||||
expect(mocks.memory.removeAssetIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -195,9 +245,11 @@ describe(MemoryService.name, () => {
|
|||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset1']));
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set(['asset1']));
|
||||
await expect(sut.removeAssets(authStub.admin, 'memory1', { ids: ['asset1'] })).resolves.toEqual([
|
||||
|
||||
await expect(sut.removeAssets(factory.auth(), 'memory1', { ids: ['asset1'] })).resolves.toEqual([
|
||||
{ id: 'asset1', success: true },
|
||||
]);
|
||||
|
||||
expect(mocks.memory.removeAssetIds).toHaveBeenCalledWith('memory1', ['asset1']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { DateTime } from 'luxon';
|
||||
import { JsonObject } from 'src/db';
|
||||
import { OnJob } from 'src/decorators';
|
||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
|
@ -97,7 +96,7 @@ export class MemoryService extends BaseService {
|
|||
{
|
||||
ownerId: auth.user.id,
|
||||
type: dto.type,
|
||||
data: dto.data as unknown as JsonObject,
|
||||
data: dto.data,
|
||||
isSaved: dto.isSaved,
|
||||
memoryAt: dto.memoryAt,
|
||||
seenAt: dto.seenAt,
|
||||
|
|
34
server/test/fixtures/memory.stub.ts
vendored
34
server/test/fixtures/memory.stub.ts
vendored
|
@ -1,34 +0,0 @@
|
|||
import { MemoryType } from 'src/enum';
|
||||
import { assetStub } from 'test/fixtures/asset.stub';
|
||||
import { userStub } from 'test/fixtures/user.stub';
|
||||
|
||||
export const memoryStub = {
|
||||
empty: {
|
||||
id: 'memoryEmpty',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
memoryAt: new Date(2024),
|
||||
ownerId: userStub.admin.id,
|
||||
owner: userStub.admin,
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 },
|
||||
isSaved: false,
|
||||
assets: [],
|
||||
deletedAt: null,
|
||||
seenAt: null,
|
||||
} as unknown as any,
|
||||
memory1: {
|
||||
id: 'memory1',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
memoryAt: new Date(2024),
|
||||
ownerId: userStub.admin.id,
|
||||
owner: userStub.admin,
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 },
|
||||
isSaved: false,
|
||||
assets: [assetStub.image1],
|
||||
deletedAt: null,
|
||||
seenAt: null,
|
||||
} as unknown as any,
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
import { randomUUID } from 'node:crypto';
|
||||
import { AuthUser, User } from 'src/database';
|
||||
import { ActivityItem } from 'src/types';
|
||||
import { Asset, AuthUser, User } from 'src/database';
|
||||
import { OnThisDayData } from 'src/entities/memory.entity';
|
||||
import { AssetStatus, AssetType, MemoryType } from 'src/enum';
|
||||
import { ActivityItem, MemoryItem } from 'src/types';
|
||||
|
||||
export const newUuid = () => randomUUID() as string;
|
||||
export const newUuids = () =>
|
||||
|
@ -9,6 +11,7 @@ export const newUuids = () =>
|
|||
.map(() => newUuid());
|
||||
export const newDate = () => new Date();
|
||||
export const newUpdateId = () => 'uuid-v7';
|
||||
export const newSha1 = () => Buffer.from('this is a fake hash');
|
||||
|
||||
const authUser = (authUser: Partial<AuthUser>) => ({
|
||||
id: newUuid(),
|
||||
|
@ -35,6 +38,38 @@ export const factory = {
|
|||
}),
|
||||
authUser,
|
||||
user,
|
||||
asset: (asset: Partial<Asset> = {}) => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
deletedAt: null,
|
||||
updateId: newUpdateId(),
|
||||
status: AssetStatus.ACTIVE,
|
||||
checksum: newSha1(),
|
||||
deviceAssetId: '',
|
||||
deviceId: '',
|
||||
duplicateId: null,
|
||||
duration: null,
|
||||
encodedVideoPath: null,
|
||||
fileCreatedAt: newDate(),
|
||||
fileModifiedAt: newDate(),
|
||||
isArchived: false,
|
||||
isExternal: false,
|
||||
isFavorite: false,
|
||||
isOffline: false,
|
||||
isVisible: true,
|
||||
libraryId: null,
|
||||
livePhotoVideoId: null,
|
||||
localDateTime: newDate(),
|
||||
originalFileName: 'IMG_123.jpg',
|
||||
originalPath: `upload/12/34/IMG_123.jpg`,
|
||||
ownerId: newUuid(),
|
||||
sidecarPath: null,
|
||||
stackId: null,
|
||||
thumbhash: null,
|
||||
type: AssetType.IMAGE,
|
||||
...asset,
|
||||
}),
|
||||
activity: (activity: Partial<ActivityItem> = {}) => {
|
||||
const userId = activity.userId || newUuid();
|
||||
return {
|
||||
|
@ -51,4 +86,21 @@ export const factory = {
|
|||
...activity,
|
||||
};
|
||||
},
|
||||
memory: (memory: Partial<MemoryItem> = {}) => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUpdateId(),
|
||||
deletedAt: null,
|
||||
ownerId: newUuid(),
|
||||
type: MemoryType.ON_THIS_DAY,
|
||||
data: { year: 2024 } as OnThisDayData,
|
||||
isSaved: false,
|
||||
memoryAt: newDate(),
|
||||
seenAt: null,
|
||||
showAt: newDate(),
|
||||
hideAt: newDate(),
|
||||
assets: [],
|
||||
...memory,
|
||||
}),
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue