mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
refactor: repository mocks (#16785)
This commit is contained in:
parent
1b35400043
commit
1382b27349
@ -1,11 +1,12 @@
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { EmailRenderRequest, EmailTemplate, NotificationRepository } from 'src/repositories/notification.repository';
|
||||
import { newFakeLoggingRepository } from 'test/repositories/logger.repository.mock';
|
||||
import { automock } from 'test/utils';
|
||||
|
||||
describe(NotificationRepository.name, () => {
|
||||
let sut: NotificationRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
sut = new NotificationRepository(newFakeLoggingRepository());
|
||||
sut = new NotificationRepository(automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false }));
|
||||
});
|
||||
|
||||
describe('renderEmail', () => {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import mockfs from 'mock-fs';
|
||||
import { CrawlOptionsDto } from 'src/dtos/library.dto';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||
import { newFakeLoggingRepository } from 'test/repositories/logger.repository.mock';
|
||||
import { automock } from 'test/utils';
|
||||
|
||||
interface Test {
|
||||
test: string;
|
||||
@ -182,7 +183,7 @@ describe(StorageRepository.name, () => {
|
||||
let sut: StorageRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
sut = new StorageRepository(newFakeLoggingRepository());
|
||||
sut = new StorageRepository(automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false }));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -146,6 +146,7 @@ describe(ActivityService.name, () => {
|
||||
const activity = factory.activity();
|
||||
|
||||
mocks.access.activity.checkOwnerAccess.mockResolvedValue(new Set([activity.id]));
|
||||
mocks.activity.delete.mockResolvedValue();
|
||||
|
||||
await sut.delete(factory.auth(), activity.id);
|
||||
|
||||
@ -156,6 +157,7 @@ describe(ActivityService.name, () => {
|
||||
const activity = factory.activity();
|
||||
|
||||
mocks.access.activity.checkAlbumOwnerAccess.mockResolvedValue(new Set([activity.id]));
|
||||
mocks.activity.delete.mockResolvedValue();
|
||||
|
||||
await sut.delete(factory.auth(), activity.id);
|
||||
|
||||
|
@ -347,6 +347,7 @@ describe(AlbumService.name, () => {
|
||||
it('should remove a shared user from an owned album', async () => {
|
||||
mocks.access.album.checkOwnerAccess.mockResolvedValue(new Set([albumStub.sharedWithUser.id]));
|
||||
mocks.album.getById.mockResolvedValue(albumStub.sharedWithUser);
|
||||
mocks.albumUser.delete.mockResolvedValue();
|
||||
|
||||
await expect(
|
||||
sut.removeUser(authStub.admin, albumStub.sharedWithUser.id, userStub.user1.id),
|
||||
@ -376,6 +377,7 @@ describe(AlbumService.name, () => {
|
||||
|
||||
it('should allow a shared user to remove themselves', async () => {
|
||||
mocks.album.getById.mockResolvedValue(albumStub.sharedWithUser);
|
||||
mocks.albumUser.delete.mockResolvedValue();
|
||||
|
||||
await sut.removeUser(authStub.user1, albumStub.sharedWithUser.id, authStub.user1.user.id);
|
||||
|
||||
@ -388,6 +390,7 @@ describe(AlbumService.name, () => {
|
||||
|
||||
it('should allow a shared user to remove themselves using "me"', async () => {
|
||||
mocks.album.getById.mockResolvedValue(albumStub.sharedWithUser);
|
||||
mocks.albumUser.delete.mockResolvedValue();
|
||||
|
||||
await sut.removeUser(authStub.user1, albumStub.sharedWithUser.id, 'me');
|
||||
|
||||
@ -422,6 +425,8 @@ describe(AlbumService.name, () => {
|
||||
describe('updateUser', () => {
|
||||
it('should update user role', async () => {
|
||||
mocks.access.album.checkOwnerAccess.mockResolvedValue(new Set([albumStub.sharedWithAdmin.id]));
|
||||
mocks.albumUser.update.mockResolvedValue(null as any);
|
||||
|
||||
await sut.updateUser(authStub.user1, albumStub.sharedWithAdmin.id, userStub.admin.id, {
|
||||
role: AlbumUserRole.EDITOR,
|
||||
});
|
||||
|
@ -67,6 +67,8 @@ describe(ApiKeyService.name, () => {
|
||||
const id = newUuid();
|
||||
const auth = factory.auth();
|
||||
|
||||
mocks.apiKey.getById.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.update(auth, id, { name: 'New Name' })).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.apiKey.update).not.toHaveBeenCalledWith(id);
|
||||
@ -91,6 +93,8 @@ describe(ApiKeyService.name, () => {
|
||||
const auth = factory.auth();
|
||||
const id = newUuid();
|
||||
|
||||
mocks.apiKey.getById.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.delete(auth, id)).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.apiKey.delete).not.toHaveBeenCalledWith(id);
|
||||
@ -101,6 +105,7 @@ describe(ApiKeyService.name, () => {
|
||||
const apiKey = factory.apiKey({ userId: auth.user.id });
|
||||
|
||||
mocks.apiKey.getById.mockResolvedValue(apiKey);
|
||||
mocks.apiKey.delete.mockResolvedValue();
|
||||
|
||||
await sut.delete(auth, apiKey.id);
|
||||
|
||||
@ -113,6 +118,8 @@ describe(ApiKeyService.name, () => {
|
||||
const auth = factory.auth();
|
||||
const id = newUuid();
|
||||
|
||||
mocks.apiKey.getById.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.getById(auth, id)).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.apiKey.getById).toHaveBeenCalledWith(auth.user.id, id);
|
||||
|
@ -127,8 +127,11 @@ describe(AssetService.name, () => {
|
||||
|
||||
describe('getRandom', () => {
|
||||
it('should get own random assets', async () => {
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
mocks.asset.getRandom.mockResolvedValue([assetStub.image]);
|
||||
|
||||
await sut.getRandom(authStub.admin, 1);
|
||||
|
||||
expect(mocks.asset.getRandom).toHaveBeenCalledWith([authStub.admin.user.id], 1);
|
||||
});
|
||||
|
||||
@ -531,6 +534,7 @@ describe(AssetService.name, () => {
|
||||
});
|
||||
|
||||
it('should update stack primary asset if deleted asset was primary asset in a stack', async () => {
|
||||
mocks.stack.update.mockResolvedValue(factory.stack() as unknown as any);
|
||||
mocks.asset.getById.mockResolvedValue(assetStub.primaryImage as AssetEntity);
|
||||
|
||||
await sut.handleAssetDeletion({ id: assetStub.primaryImage.id, deleteOnDisk: true });
|
||||
@ -542,6 +546,7 @@ describe(AssetService.name, () => {
|
||||
});
|
||||
|
||||
it('should delete the entire stack if deleted asset was the primary asset and the stack would only contain one asset afterwards', async () => {
|
||||
mocks.stack.delete.mockResolvedValue();
|
||||
mocks.asset.getById.mockResolvedValue({
|
||||
...assetStub.primaryImage,
|
||||
stack: { ...assetStub.primaryImage.stack, assets: assetStub.primaryImage.stack!.assets.slice(0, 2) },
|
||||
|
@ -18,7 +18,10 @@ describe(AuditService.name, () => {
|
||||
|
||||
describe('handleCleanup', () => {
|
||||
it('should delete old audit entries', async () => {
|
||||
mocks.audit.removeBefore.mockResolvedValue();
|
||||
|
||||
await expect(sut.handleCleanup()).resolves.toBe(JobStatus.SUCCESS);
|
||||
|
||||
expect(mocks.audit.removeBefore).toHaveBeenCalledWith(expect.any(Date));
|
||||
});
|
||||
});
|
||||
|
@ -65,7 +65,10 @@ describe('AuthService', () => {
|
||||
|
||||
describe('onBootstrap', () => {
|
||||
it('should init the repo', () => {
|
||||
mocks.oauth.init.mockResolvedValue();
|
||||
|
||||
sut.onBootstrap();
|
||||
|
||||
expect(mocks.oauth.init).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@ -73,24 +76,30 @@ describe('AuthService', () => {
|
||||
describe('login', () => {
|
||||
it('should throw an error if password login is disabled', async () => {
|
||||
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.disabled);
|
||||
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
});
|
||||
|
||||
it('should check the user exists', async () => {
|
||||
mocks.user.getByEmail.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
|
||||
expect(mocks.user.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should check the user has a password', async () => {
|
||||
mocks.user.getByEmail.mockResolvedValue({} as UserEntity);
|
||||
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
|
||||
expect(mocks.user.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should successfully log the user in', async () => {
|
||||
mocks.user.getByEmail.mockResolvedValue(userStub.user1);
|
||||
mocks.session.create.mockResolvedValue(sessionStub.valid);
|
||||
|
||||
await expect(sut.login(fixtures.login, loginDetails)).resolves.toEqual({
|
||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||
userId: 'user-id',
|
||||
@ -100,6 +109,7 @@ describe('AuthService', () => {
|
||||
isAdmin: false,
|
||||
shouldChangePassword: false,
|
||||
});
|
||||
|
||||
expect(mocks.user.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
@ -159,8 +169,10 @@ describe('AuthService', () => {
|
||||
|
||||
describe('logout', () => {
|
||||
it('should return the end session endpoint', async () => {
|
||||
const auth = factory.auth();
|
||||
|
||||
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.enabled);
|
||||
const auth = { user: { id: '123' } } as AuthDto;
|
||||
|
||||
await expect(sut.logout(auth, AuthType.OAUTH)).resolves.toEqual({
|
||||
successful: true,
|
||||
redirectUri: 'http://end-session-endpoint',
|
||||
@ -168,7 +180,7 @@ describe('AuthService', () => {
|
||||
});
|
||||
|
||||
it('should return the default redirect', async () => {
|
||||
const auth = { user: { id: '123' } } as AuthDto;
|
||||
const auth = factory.auth();
|
||||
|
||||
await expect(sut.logout(auth, AuthType.PASSWORD)).resolves.toEqual({
|
||||
successful: true,
|
||||
@ -178,6 +190,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should delete the access token', async () => {
|
||||
const auth = { user: { id: '123' }, session: { id: 'token123' } } as AuthDto;
|
||||
mocks.session.delete.mockResolvedValue();
|
||||
|
||||
await expect(sut.logout(auth, AuthType.PASSWORD)).resolves.toEqual({
|
||||
successful: true,
|
||||
@ -203,7 +216,9 @@ describe('AuthService', () => {
|
||||
|
||||
it('should only allow one admin', async () => {
|
||||
mocks.user.getAdmin.mockResolvedValue({} as UserEntity);
|
||||
|
||||
await expect(sut.adminSignUp(dto)).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.user.getAdmin).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -215,6 +230,7 @@ describe('AuthService', () => {
|
||||
createdAt: new Date('2021-01-01'),
|
||||
metadata: [] as UserMetadataEntity[],
|
||||
} as UserEntity);
|
||||
|
||||
await expect(sut.adminSignUp(dto)).resolves.toMatchObject({
|
||||
avatarColor: expect.any(String),
|
||||
id: 'admin',
|
||||
@ -222,6 +238,7 @@ describe('AuthService', () => {
|
||||
email: 'test@immich.com',
|
||||
name: 'immich admin',
|
||||
});
|
||||
|
||||
expect(mocks.user.getAdmin).toHaveBeenCalled();
|
||||
expect(mocks.user.create).toHaveBeenCalled();
|
||||
});
|
||||
@ -241,6 +258,7 @@ describe('AuthService', () => {
|
||||
it('should validate using authorization header', async () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.user1);
|
||||
mocks.session.getByToken.mockResolvedValue(sessionStub.valid as any);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { authorization: 'Bearer auth_token' },
|
||||
@ -256,6 +274,8 @@ describe('AuthService', () => {
|
||||
|
||||
describe('validate - shared key', () => {
|
||||
it('should not accept a non-existent key', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(void 0);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': 'key' },
|
||||
@ -267,6 +287,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should not accept an expired key', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(sharedLinkStub.expired);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': 'key' },
|
||||
@ -278,6 +299,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should not accept a key on a non-shared route', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(sharedLinkStub.valid);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': 'key' },
|
||||
@ -290,6 +312,7 @@ describe('AuthService', () => {
|
||||
it('should not accept a key without a user', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(sharedLinkStub.expired);
|
||||
mocks.user.get.mockResolvedValue(void 0);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': 'key' },
|
||||
@ -302,6 +325,7 @@ describe('AuthService', () => {
|
||||
it('should accept a base64url key', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(sharedLinkStub.valid);
|
||||
mocks.user.get.mockResolvedValue(userStub.admin);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': sharedLinkStub.valid.key.toString('base64url') },
|
||||
@ -318,6 +342,7 @@ describe('AuthService', () => {
|
||||
it('should accept a hex key', async () => {
|
||||
mocks.sharedLink.getByKey.mockResolvedValue(sharedLinkStub.valid);
|
||||
mocks.user.get.mockResolvedValue(userStub.admin);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-share-key': sharedLinkStub.valid.key.toString('hex') },
|
||||
@ -335,6 +360,7 @@ describe('AuthService', () => {
|
||||
describe('validate - user token', () => {
|
||||
it('should throw if no token is found', async () => {
|
||||
mocks.session.getByToken.mockResolvedValue(void 0);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-immich-user-token': 'auth_token' },
|
||||
@ -346,6 +372,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should return an auth dto', async () => {
|
||||
mocks.session.getByToken.mockResolvedValue(sessionStub.valid as any);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { cookie: 'immich_access_token=auth_token' },
|
||||
@ -360,6 +387,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should throw if admin route and not an admin', async () => {
|
||||
mocks.session.getByToken.mockResolvedValue(sessionStub.valid as any);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { cookie: 'immich_access_token=auth_token' },
|
||||
@ -372,6 +400,7 @@ describe('AuthService', () => {
|
||||
it('should update when access time exceeds an hour', async () => {
|
||||
mocks.session.getByToken.mockResolvedValue(sessionStub.inactive as any);
|
||||
mocks.session.update.mockResolvedValue(sessionStub.valid);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { cookie: 'immich_access_token=auth_token' },
|
||||
@ -386,6 +415,7 @@ describe('AuthService', () => {
|
||||
describe('validate - api key', () => {
|
||||
it('should throw an error if no api key is found', async () => {
|
||||
mocks.apiKey.getKey.mockResolvedValue(void 0);
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-api-key': 'auth_token' },
|
||||
@ -401,6 +431,7 @@ describe('AuthService', () => {
|
||||
const authApiKey = factory.authApiKey({ permissions: [] });
|
||||
|
||||
mocks.apiKey.getKey.mockResolvedValue({ ...authApiKey, user: authUser });
|
||||
|
||||
await expect(
|
||||
sut.authenticate({
|
||||
headers: { 'x-api-key': 'auth_token' },
|
||||
@ -442,6 +473,7 @@ describe('AuthService', () => {
|
||||
describe('authorize', () => {
|
||||
it('should fail if oauth is disabled', async () => {
|
||||
mocks.systemMetadata.get.mockResolvedValue({ oauth: { enabled: false } });
|
||||
|
||||
await expect(sut.authorize({ redirectUri: 'https://demo.immich.app' })).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
@ -449,6 +481,7 @@ describe('AuthService', () => {
|
||||
|
||||
it('should authorize the user', async () => {
|
||||
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.oauthWithMobileOverride);
|
||||
|
||||
await sut.authorize({ redirectUri: 'https://demo.immich.app' });
|
||||
});
|
||||
});
|
||||
@ -461,9 +494,11 @@ describe('AuthService', () => {
|
||||
it('should not allow auto registering', async () => {
|
||||
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.oauthEnabled);
|
||||
mocks.user.getByEmail.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).rejects.toBeInstanceOf(
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
expect(mocks.user.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@ -540,6 +575,7 @@ describe('AuthService', () => {
|
||||
mocks.session.create.mockResolvedValue(sessionStub.valid);
|
||||
|
||||
await sut.callback({ url }, loginDetails);
|
||||
|
||||
expect(mocks.oauth.getProfile).toHaveBeenCalledWith(expect.objectContaining({}), url, 'http://mobile-redirect');
|
||||
});
|
||||
}
|
||||
@ -549,6 +585,7 @@ describe('AuthService', () => {
|
||||
mocks.user.getByEmail.mockResolvedValue(void 0);
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.user1);
|
||||
mocks.user.create.mockResolvedValue(userStub.user1);
|
||||
mocks.session.create.mockResolvedValue(factory.session());
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).resolves.toEqual(
|
||||
oauthResponse,
|
||||
@ -563,6 +600,7 @@ describe('AuthService', () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.user1);
|
||||
mocks.user.create.mockResolvedValue(userStub.user1);
|
||||
mocks.oauth.getProfile.mockResolvedValue({ sub, email, immich_quota: 'abc' });
|
||||
mocks.session.create.mockResolvedValue(factory.session());
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).resolves.toEqual(
|
||||
oauthResponse,
|
||||
@ -577,6 +615,7 @@ describe('AuthService', () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.user1);
|
||||
mocks.user.create.mockResolvedValue(userStub.user1);
|
||||
mocks.oauth.getProfile.mockResolvedValue({ sub, email, immich_quota: -5 });
|
||||
mocks.session.create.mockResolvedValue(factory.session());
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).resolves.toEqual(
|
||||
oauthResponse,
|
||||
@ -591,6 +630,7 @@ describe('AuthService', () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.user1);
|
||||
mocks.user.create.mockResolvedValue(userStub.user1);
|
||||
mocks.oauth.getProfile.mockResolvedValue({ sub, email, immich_quota: 0 });
|
||||
mocks.session.create.mockResolvedValue(factory.session());
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).resolves.toEqual(
|
||||
oauthResponse,
|
||||
@ -611,6 +651,7 @@ describe('AuthService', () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.user1);
|
||||
mocks.user.create.mockResolvedValue(userStub.user1);
|
||||
mocks.oauth.getProfile.mockResolvedValue({ sub, email, immich_quota: 5 });
|
||||
mocks.session.create.mockResolvedValue(factory.session());
|
||||
|
||||
await expect(sut.callback({ url: 'http://immich/auth/login?code=abc123' }, loginDetails)).resolves.toEqual(
|
||||
oauthResponse,
|
||||
|
@ -22,6 +22,7 @@ describe(BackupService.name, () => {
|
||||
describe('onBootstrapEvent', () => {
|
||||
it('should init cron job and handle config changes', async () => {
|
||||
mocks.database.tryLock.mockResolvedValue(true);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.backupEnabled as SystemConfig });
|
||||
|
||||
@ -47,10 +48,14 @@ describe(BackupService.name, () => {
|
||||
describe('onConfigUpdateEvent', () => {
|
||||
beforeEach(async () => {
|
||||
mocks.database.tryLock.mockResolvedValue(true);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: defaults });
|
||||
});
|
||||
|
||||
it('should update cron job if backup is enabled', () => {
|
||||
mocks.cron.update.mockResolvedValue();
|
||||
|
||||
sut.onConfigUpdate({
|
||||
oldConfig: defaults,
|
||||
newConfig: {
|
||||
|
@ -31,6 +31,8 @@ describe(CliService.name, () => {
|
||||
|
||||
it('should default to a random password', async () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.admin);
|
||||
mocks.user.update.mockResolvedValue(userStub.admin);
|
||||
|
||||
const ask = vitest.fn().mockImplementation(() => {});
|
||||
|
||||
const response = await sut.resetAdminPassword(ask);
|
||||
@ -45,6 +47,8 @@ describe(CliService.name, () => {
|
||||
|
||||
it('should use the supplied password', async () => {
|
||||
mocks.user.getAdmin.mockResolvedValue(userStub.admin);
|
||||
mocks.user.update.mockResolvedValue(userStub.admin);
|
||||
|
||||
const ask = vitest.fn().mockResolvedValue('new-password');
|
||||
|
||||
const response = await sut.resetAdminPassword(ask);
|
||||
|
@ -173,6 +173,7 @@ describe(DownloadService.name, () => {
|
||||
it('should return a list of archives (assetIds)', async () => {
|
||||
const assetIds = ['asset-1', 'asset-2'];
|
||||
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(assetIds));
|
||||
mocks.downloadRepository.downloadAssetIds.mockReturnValue(
|
||||
makeStream([
|
||||
@ -187,6 +188,7 @@ describe(DownloadService.name, () => {
|
||||
});
|
||||
|
||||
it('should return a list of archives (albumId)', async () => {
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.access.album.checkOwnerAccess.mockResolvedValue(new Set(['album-1']));
|
||||
mocks.downloadRepository.downloadAlbumId.mockReturnValue(
|
||||
makeStream([
|
||||
@ -202,6 +204,7 @@ describe(DownloadService.name, () => {
|
||||
});
|
||||
|
||||
it('should return a list of archives (userId)', async () => {
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.downloadRepository.downloadUserId.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-1', livePhotoVideoId: null, size: 100_000 },
|
||||
@ -217,6 +220,7 @@ describe(DownloadService.name, () => {
|
||||
});
|
||||
|
||||
it('should split archives by size', async () => {
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.downloadRepository.downloadUserId.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-1', livePhotoVideoId: null, size: 5000 },
|
||||
@ -244,13 +248,13 @@ describe(DownloadService.name, () => {
|
||||
const assetIds = ['asset-1', 'asset-2'];
|
||||
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(assetIds));
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.downloadRepository.downloadAssetIds.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-1', livePhotoVideoId: 'asset-3', size: 5000 },
|
||||
{ id: 'asset-2', livePhotoVideoId: 'asset-4', size: 100_000 },
|
||||
]),
|
||||
);
|
||||
|
||||
mocks.downloadRepository.downloadMotionAssetIds.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-3', livePhotoVideoId: null, size: 23_456, originalPath: '/path/to/file.mp4' },
|
||||
@ -271,11 +275,10 @@ describe(DownloadService.name, () => {
|
||||
const assetIds = ['asset-1'];
|
||||
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(assetIds));
|
||||
|
||||
mocks.user.getMetadata.mockResolvedValue([]);
|
||||
mocks.downloadRepository.downloadAssetIds.mockReturnValue(
|
||||
makeStream([{ id: 'asset-1', livePhotoVideoId: 'asset-3', size: 5000 }]),
|
||||
);
|
||||
|
||||
mocks.downloadRepository.downloadMotionAssetIds.mockReturnValue(
|
||||
makeStream([
|
||||
{ id: 'asset-2', livePhotoVideoId: null, size: 23_456, originalPath: 'upload/encoded-video/uuid-MP.mp4' },
|
||||
|
@ -36,6 +36,9 @@ describe(LibraryService.name, () => {
|
||||
|
||||
describe('onConfigInit', () => {
|
||||
it('should init cron job and handle config changes', async () => {
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
mocks.cron.update.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: defaults });
|
||||
|
||||
expect(mocks.cron.create).toHaveBeenCalled();
|
||||
@ -65,6 +68,7 @@ describe(LibraryService.name, () => {
|
||||
mocks.library.get.mockImplementation((id) =>
|
||||
Promise.resolve([library1, library2].find((library) => library.id === id)),
|
||||
);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
|
||||
@ -74,6 +78,8 @@ describe(LibraryService.name, () => {
|
||||
});
|
||||
|
||||
it('should not initialize watcher when watching is disabled', async () => {
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchDisabled as SystemConfig });
|
||||
|
||||
expect(mocks.storage.watch).not.toHaveBeenCalled();
|
||||
@ -99,6 +105,8 @@ describe(LibraryService.name, () => {
|
||||
describe('onConfigUpdateEvent', () => {
|
||||
beforeEach(async () => {
|
||||
mocks.database.tryLock.mockResolvedValue(true);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: defaults });
|
||||
});
|
||||
|
||||
@ -111,6 +119,9 @@ describe(LibraryService.name, () => {
|
||||
|
||||
it('should update cron job and enable watching', async () => {
|
||||
mocks.library.getAll.mockResolvedValue([]);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
mocks.cron.update.mockResolvedValue();
|
||||
|
||||
await sut.onConfigUpdate({
|
||||
newConfig: systemConfigStub.libraryScanAndWatch as SystemConfig,
|
||||
oldConfig: defaults,
|
||||
@ -125,6 +136,9 @@ describe(LibraryService.name, () => {
|
||||
|
||||
it('should update cron job and disable watching', async () => {
|
||||
mocks.library.getAll.mockResolvedValue([]);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
mocks.cron.update.mockResolvedValue();
|
||||
|
||||
await sut.onConfigUpdate({
|
||||
newConfig: systemConfigStub.libraryScanAndWatch as SystemConfig,
|
||||
oldConfig: defaults,
|
||||
@ -620,6 +634,7 @@ describe(LibraryService.name, () => {
|
||||
|
||||
const mockClose = vitest.fn();
|
||||
mocks.storage.watch.mockImplementation(makeMockWatcher({ close: mockClose }));
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
await sut.delete(library.id);
|
||||
@ -765,6 +780,7 @@ describe(LibraryService.name, () => {
|
||||
mocks.library.create.mockResolvedValue(library);
|
||||
mocks.library.get.mockResolvedValue(library);
|
||||
mocks.library.getAll.mockResolvedValue([]);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
await sut.create({ ownerId: authStub.admin.user.id, importPaths: library.importPaths });
|
||||
@ -832,6 +848,7 @@ describe(LibraryService.name, () => {
|
||||
describe('update', () => {
|
||||
beforeEach(async () => {
|
||||
mocks.library.getAll.mockResolvedValue([]);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
});
|
||||
@ -878,6 +895,8 @@ describe(LibraryService.name, () => {
|
||||
|
||||
describe('watching disabled', () => {
|
||||
beforeEach(async () => {
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchDisabled as SystemConfig });
|
||||
});
|
||||
|
||||
@ -895,6 +914,8 @@ describe(LibraryService.name, () => {
|
||||
describe('watching enabled', () => {
|
||||
beforeEach(async () => {
|
||||
mocks.library.getAll.mockResolvedValue([]);
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
});
|
||||
|
||||
@ -1067,6 +1088,7 @@ describe(LibraryService.name, () => {
|
||||
|
||||
const mockClose = vitest.fn();
|
||||
mocks.storage.watch.mockImplementation(makeMockWatcher({ close: mockClose }));
|
||||
mocks.cron.create.mockResolvedValue();
|
||||
|
||||
await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
|
||||
await sut.onShutdown();
|
||||
|
@ -33,6 +33,8 @@ describe(MemoryService.name, () => {
|
||||
});
|
||||
|
||||
it('should map ', async () => {
|
||||
mocks.memory.search.mockResolvedValue([]);
|
||||
|
||||
await expect(sut.search(factory.auth(), {})).resolves.toEqual([]);
|
||||
});
|
||||
});
|
||||
@ -46,6 +48,7 @@ describe(MemoryService.name, () => {
|
||||
const [memoryId] = newUuids();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memoryId]));
|
||||
mocks.memory.get.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.get(factory.auth(), memoryId)).rejects.toBeInstanceOf(BadRequestException);
|
||||
});
|
||||
@ -159,6 +162,7 @@ describe(MemoryService.name, () => {
|
||||
const memoryId = newUuid();
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memoryId]));
|
||||
mocks.memory.delete.mockResolvedValue();
|
||||
|
||||
await expect(sut.remove(factory.auth(), memoryId)).resolves.toBeUndefined();
|
||||
|
||||
@ -183,6 +187,7 @@ describe(MemoryService.name, () => {
|
||||
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set());
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memory.id, { ids: [assetId] })).resolves.toEqual([
|
||||
{ error: 'no_permission', id: assetId, success: false },
|
||||
@ -213,6 +218,9 @@ describe(MemoryService.name, () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([assetId]));
|
||||
mocks.memory.get.mockResolvedValue(memory);
|
||||
mocks.memory.update.mockResolvedValue(memory);
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set());
|
||||
mocks.memory.addAssetIds.mockResolvedValue();
|
||||
|
||||
await expect(sut.addAssets(factory.auth(), memory.id, { ids: [assetId] })).resolves.toEqual([
|
||||
{ id: assetId, success: true },
|
||||
@ -233,6 +241,7 @@ describe(MemoryService.name, () => {
|
||||
|
||||
it('should skip assets not in the memory', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set());
|
||||
|
||||
await expect(sut.removeAssets(factory.auth(), 'memory1', { ids: ['not-found'] })).resolves.toEqual([
|
||||
{ error: 'not_found', id: 'not-found', success: false },
|
||||
@ -242,15 +251,20 @@ describe(MemoryService.name, () => {
|
||||
});
|
||||
|
||||
it('should remove assets', async () => {
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set(['memory1']));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset1']));
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set(['asset1']));
|
||||
const memory = factory.memory();
|
||||
const asset = factory.asset();
|
||||
|
||||
await expect(sut.removeAssets(factory.auth(), 'memory1', { ids: ['asset1'] })).resolves.toEqual([
|
||||
{ id: 'asset1', success: true },
|
||||
mocks.access.memory.checkOwnerAccess.mockResolvedValue(new Set([memory.id]));
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset.id]));
|
||||
mocks.memory.getAssetIds.mockResolvedValue(new Set([asset.id]));
|
||||
mocks.memory.removeAssetIds.mockResolvedValue();
|
||||
mocks.memory.update.mockResolvedValue(memory);
|
||||
|
||||
await expect(sut.removeAssets(factory.auth(), memory.id, { ids: [asset.id] })).resolves.toEqual([
|
||||
{ id: asset.id, success: true },
|
||||
]);
|
||||
|
||||
expect(mocks.memory.removeAssetIds).toHaveBeenCalledWith('memory1', ['asset1']);
|
||||
expect(mocks.memory.removeAssetIds).toHaveBeenCalledWith(memory.id, [asset.id]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -52,6 +52,10 @@ describe(MetadataService.name, () => {
|
||||
|
||||
describe('onBootstrapEvent', () => {
|
||||
it('should pause and resume queue during init', async () => {
|
||||
mocks.job.pause.mockResolvedValue();
|
||||
mocks.map.init.mockResolvedValue();
|
||||
mocks.job.resume.mockResolvedValue();
|
||||
|
||||
await sut.onBootstrap();
|
||||
|
||||
expect(mocks.job.pause).toHaveBeenCalledTimes(1);
|
||||
|
@ -260,6 +260,7 @@ describe(NotificationService.name, () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.admin);
|
||||
mocks.notification.verifySmtp.mockResolvedValue(true);
|
||||
mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
|
||||
mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
|
||||
|
||||
await expect(sut.sendTestEmail('', configs.smtpTransport.notifications.smtp)).resolves.not.toThrow();
|
||||
expect(mocks.notification.renderEmail).toHaveBeenCalledWith({
|
||||
@ -279,6 +280,7 @@ describe(NotificationService.name, () => {
|
||||
mocks.notification.verifySmtp.mockResolvedValue(true);
|
||||
mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
|
||||
mocks.systemMetadata.get.mockResolvedValue({ server: { externalDomain: 'https://demo.immich.app' } });
|
||||
mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
|
||||
|
||||
await expect(sut.sendTestEmail('', configs.smtpTransport.notifications.smtp)).resolves.not.toThrow();
|
||||
expect(mocks.notification.renderEmail).toHaveBeenCalledWith({
|
||||
@ -297,6 +299,7 @@ describe(NotificationService.name, () => {
|
||||
mocks.user.get.mockResolvedValue(userStub.admin);
|
||||
mocks.notification.verifySmtp.mockResolvedValue(true);
|
||||
mocks.notification.renderEmail.mockResolvedValue({ html: '', text: '' });
|
||||
mocks.notification.sendEmail.mockResolvedValue({ messageId: 'message-1', response: '' });
|
||||
|
||||
await expect(
|
||||
sut.sendTestEmail('', { ...configs.smtpTransport.notifications.smtp, replyTo: 'demo@immich.app' }),
|
||||
|
@ -324,6 +324,10 @@ describe(PersonService.name, () => {
|
||||
mocks.person.getFacesByIds.mockResolvedValue([faceStub.face1]);
|
||||
mocks.person.reassignFace.mockResolvedValue(1);
|
||||
mocks.person.getRandomFace.mockResolvedValue(faceStub.primaryFace1);
|
||||
mocks.person.refreshFaces.mockResolvedValue();
|
||||
mocks.person.reassignFace.mockResolvedValue(5);
|
||||
mocks.person.update.mockResolvedValue(personStub.noName);
|
||||
|
||||
await expect(
|
||||
sut.reassignFaces(authStub.admin, personStub.noName.id, {
|
||||
data: [{ personId: personStub.withName.id, assetId: assetStub.image.id }],
|
||||
@ -515,6 +519,7 @@ describe(PersonService.name, () => {
|
||||
hasNextPage: false,
|
||||
});
|
||||
mocks.person.getAllWithoutFaces.mockResolvedValue([personStub.randomPerson]);
|
||||
mocks.person.deleteFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleQueueDetectFaces({ force: true });
|
||||
|
||||
@ -633,6 +638,7 @@ describe(PersonService.name, () => {
|
||||
mocks.person.getAll.mockReturnValue(makeStream());
|
||||
mocks.person.getAllFaces.mockReturnValue(makeStream([faceStub.face1]));
|
||||
mocks.person.getAllWithoutFaces.mockResolvedValue([]);
|
||||
mocks.person.unassignFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleQueueRecognizeFaces({ force: true, nightly: true });
|
||||
|
||||
@ -679,6 +685,7 @@ describe(PersonService.name, () => {
|
||||
mocks.person.getAll.mockReturnValue(makeStream([faceStub.face1.person, personStub.randomPerson]));
|
||||
mocks.person.getAllFaces.mockReturnValue(makeStream([faceStub.face1]));
|
||||
mocks.person.getAllWithoutFaces.mockResolvedValue([personStub.randomPerson]);
|
||||
mocks.person.unassignFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleQueueRecognizeFaces({ force: true });
|
||||
|
||||
@ -757,6 +764,7 @@ describe(PersonService.name, () => {
|
||||
mocks.machineLearning.detectFaces.mockResolvedValue(detectFaceMock);
|
||||
mocks.search.searchFaces.mockResolvedValue([{ ...faceStub.face1, distance: 0.7 }]);
|
||||
mocks.asset.getByIds.mockResolvedValue([assetStub.image]);
|
||||
mocks.person.refreshFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleDetectFaces({ id: assetStub.image.id });
|
||||
|
||||
@ -784,6 +792,7 @@ describe(PersonService.name, () => {
|
||||
it('should add new face and delete an existing face not among the new detected faces', async () => {
|
||||
mocks.machineLearning.detectFaces.mockResolvedValue(detectFaceMock);
|
||||
mocks.asset.getByIds.mockResolvedValue([{ ...assetStub.image, faces: [faceStub.primaryFace1] }]);
|
||||
mocks.person.refreshFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleDetectFaces({ id: assetStub.image.id });
|
||||
|
||||
@ -799,6 +808,7 @@ describe(PersonService.name, () => {
|
||||
it('should add embedding to matching metadata face', async () => {
|
||||
mocks.machineLearning.detectFaces.mockResolvedValue(detectFaceMock);
|
||||
mocks.asset.getByIds.mockResolvedValue([{ ...assetStub.image, faces: [faceStub.fromExif1] }]);
|
||||
mocks.person.refreshFaces.mockResolvedValue();
|
||||
|
||||
await sut.handleDetectFaces({ id: assetStub.image.id });
|
||||
|
||||
@ -1006,6 +1016,7 @@ describe(PersonService.name, () => {
|
||||
mocks.person.getById.mockResolvedValue({ ...personStub.primaryPerson, faceAssetId: faceStub.middle.assetId });
|
||||
mocks.person.getFaceByIdWithAssets.mockResolvedValue(faceStub.middle);
|
||||
mocks.asset.getById.mockResolvedValue(assetStub.primaryImage);
|
||||
mocks.media.generateThumbnail.mockResolvedValue();
|
||||
|
||||
await sut.handleGeneratePersonThumbnail({ id: personStub.primaryPerson.id });
|
||||
|
||||
@ -1038,6 +1049,7 @@ describe(PersonService.name, () => {
|
||||
mocks.person.getById.mockResolvedValue({ ...personStub.primaryPerson, faceAssetId: faceStub.start.assetId });
|
||||
mocks.person.getFaceByIdWithAssets.mockResolvedValue(faceStub.start);
|
||||
mocks.asset.getById.mockResolvedValue(assetStub.image);
|
||||
mocks.media.generateThumbnail.mockResolvedValue();
|
||||
|
||||
await sut.handleGeneratePersonThumbnail({ id: personStub.primaryPerson.id });
|
||||
|
||||
@ -1063,7 +1075,9 @@ describe(PersonService.name, () => {
|
||||
it('should generate a thumbnail without overflowing', async () => {
|
||||
mocks.person.getById.mockResolvedValue({ ...personStub.primaryPerson, faceAssetId: faceStub.end.assetId });
|
||||
mocks.person.getFaceByIdWithAssets.mockResolvedValue(faceStub.end);
|
||||
mocks.person.update.mockResolvedValue(personStub.primaryPerson);
|
||||
mocks.asset.getById.mockResolvedValue(assetStub.primaryImage);
|
||||
mocks.media.generateThumbnail.mockResolvedValue();
|
||||
|
||||
await sut.handleGeneratePersonThumbnail({ id: personStub.primaryPerson.id });
|
||||
|
||||
|
@ -57,6 +57,8 @@ describe(SearchService.name, () => {
|
||||
describe('getSearchSuggestions', () => {
|
||||
it('should return search suggestions for country', async () => {
|
||||
mocks.search.getCountries.mockResolvedValue(['USA']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: false, type: SearchSuggestionType.COUNTRY }),
|
||||
).resolves.toEqual(['USA']);
|
||||
@ -65,6 +67,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for country (including null)', async () => {
|
||||
mocks.search.getCountries.mockResolvedValue(['USA']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: true, type: SearchSuggestionType.COUNTRY }),
|
||||
).resolves.toEqual(['USA', null]);
|
||||
@ -73,6 +77,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for state', async () => {
|
||||
mocks.search.getStates.mockResolvedValue(['California']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: false, type: SearchSuggestionType.STATE }),
|
||||
).resolves.toEqual(['California']);
|
||||
@ -81,6 +87,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for state (including null)', async () => {
|
||||
mocks.search.getStates.mockResolvedValue(['California']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: true, type: SearchSuggestionType.STATE }),
|
||||
).resolves.toEqual(['California', null]);
|
||||
@ -89,6 +97,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for city', async () => {
|
||||
mocks.search.getCities.mockResolvedValue(['Denver']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: false, type: SearchSuggestionType.CITY }),
|
||||
).resolves.toEqual(['Denver']);
|
||||
@ -97,6 +107,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for city (including null)', async () => {
|
||||
mocks.search.getCities.mockResolvedValue(['Denver']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: true, type: SearchSuggestionType.CITY }),
|
||||
).resolves.toEqual(['Denver', null]);
|
||||
@ -105,6 +117,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for camera make', async () => {
|
||||
mocks.search.getCameraMakes.mockResolvedValue(['Nikon']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: false, type: SearchSuggestionType.CAMERA_MAKE }),
|
||||
).resolves.toEqual(['Nikon']);
|
||||
@ -113,6 +127,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for camera make (including null)', async () => {
|
||||
mocks.search.getCameraMakes.mockResolvedValue(['Nikon']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: true, type: SearchSuggestionType.CAMERA_MAKE }),
|
||||
).resolves.toEqual(['Nikon', null]);
|
||||
@ -121,6 +137,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for camera model', async () => {
|
||||
mocks.search.getCameraModels.mockResolvedValue(['Fujifilm X100VI']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: false, type: SearchSuggestionType.CAMERA_MODEL }),
|
||||
).resolves.toEqual(['Fujifilm X100VI']);
|
||||
@ -129,6 +147,8 @@ describe(SearchService.name, () => {
|
||||
|
||||
it('should return search suggestions for camera model (including null)', async () => {
|
||||
mocks.search.getCameraModels.mockResolvedValue(['Fujifilm X100VI']);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getSearchSuggestions(authStub.user1, { includeNull: true, type: SearchSuggestionType.CAMERA_MODEL }),
|
||||
).resolves.toEqual(['Fujifilm X100VI', null]);
|
||||
|
@ -36,6 +36,7 @@ describe('SessionService', () => {
|
||||
updateId: 'uuid-v7',
|
||||
},
|
||||
]);
|
||||
mocks.session.delete.mockResolvedValue();
|
||||
|
||||
await expect(sut.handleCleanup()).resolves.toEqual(JobStatus.SUCCESS);
|
||||
expect(mocks.session.delete).toHaveBeenCalledWith('123');
|
||||
@ -71,6 +72,7 @@ describe('SessionService', () => {
|
||||
describe('logoutDevices', () => {
|
||||
it('should logout all devices', async () => {
|
||||
mocks.session.getByUserId.mockResolvedValue([sessionStub.inactive, sessionStub.valid] as any[]);
|
||||
mocks.session.delete.mockResolvedValue();
|
||||
|
||||
await sut.deleteAll(authStub.user1);
|
||||
|
||||
@ -83,6 +85,7 @@ describe('SessionService', () => {
|
||||
describe('logoutDevice', () => {
|
||||
it('should logout the device', async () => {
|
||||
mocks.access.authDevice.checkOwnerAccess.mockResolvedValue(new Set(['token-1']));
|
||||
mocks.session.delete.mockResolvedValue();
|
||||
|
||||
await sut.delete(authStub.user1, 'token-1');
|
||||
|
||||
|
@ -71,7 +71,10 @@ describe(SharedLinkService.name, () => {
|
||||
|
||||
describe('get', () => {
|
||||
it('should throw an error for an invalid shared link', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.get(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.sharedLink.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
|
||||
expect(mocks.sharedLink.update).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -194,7 +197,10 @@ describe(SharedLinkService.name, () => {
|
||||
|
||||
describe('update', () => {
|
||||
it('should throw an error for an invalid shared link', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.update(authStub.user1, 'missing-id', {})).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.sharedLink.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
|
||||
expect(mocks.sharedLink.update).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -214,14 +220,20 @@ describe(SharedLinkService.name, () => {
|
||||
|
||||
describe('remove', () => {
|
||||
it('should throw an error for an invalid shared link', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.remove(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
expect(mocks.sharedLink.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
|
||||
expect(mocks.sharedLink.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should remove a key', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(sharedLinkStub.valid);
|
||||
mocks.sharedLink.remove.mockResolvedValue();
|
||||
|
||||
await sut.remove(authStub.user1, sharedLinkStub.valid.id);
|
||||
|
||||
expect(mocks.sharedLink.get).toHaveBeenCalledWith(authStub.user1.user.id, sharedLinkStub.valid.id);
|
||||
expect(mocks.sharedLink.remove).toHaveBeenCalledWith(sharedLinkStub.valid);
|
||||
});
|
||||
@ -238,6 +250,7 @@ describe(SharedLinkService.name, () => {
|
||||
it('should add assets to a shared link', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(_.cloneDeep(sharedLinkStub.individual));
|
||||
mocks.sharedLink.create.mockResolvedValue(sharedLinkStub.individual);
|
||||
mocks.sharedLink.update.mockResolvedValue(sharedLinkStub.individual);
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-3']));
|
||||
|
||||
await expect(
|
||||
@ -268,6 +281,7 @@ describe(SharedLinkService.name, () => {
|
||||
it('should remove assets from a shared link', async () => {
|
||||
mocks.sharedLink.get.mockResolvedValue(_.cloneDeep(sharedLinkStub.individual));
|
||||
mocks.sharedLink.create.mockResolvedValue(sharedLinkStub.individual);
|
||||
mocks.sharedLink.update.mockResolvedValue(sharedLinkStub.individual);
|
||||
|
||||
await expect(
|
||||
sut.removeAssets(authStub.admin, 'link-1', { assetIds: [assetStub.image.id, 'asset-2'] }),
|
||||
|
@ -155,6 +155,7 @@ describe(StackService.name, () => {
|
||||
|
||||
it('should delete stack', async () => {
|
||||
mocks.access.stack.checkOwnerAccess.mockResolvedValue(new Set(['stack-id']));
|
||||
mocks.stack.delete.mockResolvedValue();
|
||||
|
||||
await sut.delete(authStub.admin, 'stack-id');
|
||||
|
||||
@ -176,6 +177,7 @@ describe(StackService.name, () => {
|
||||
|
||||
it('should delete all stacks', async () => {
|
||||
mocks.access.stack.checkOwnerAccess.mockResolvedValue(new Set(['stack-id']));
|
||||
mocks.stack.deleteAll.mockResolvedValue();
|
||||
|
||||
await sut.deleteAll(authStub.admin, { ids: ['stack-id'] });
|
||||
|
||||
|
@ -93,7 +93,9 @@ describe(StorageTemplateService.name, () => {
|
||||
describe('handleMigrationSingle', () => {
|
||||
it('should skip when storage template is disabled', async () => {
|
||||
mocks.systemMetadata.get.mockResolvedValue({ storageTemplate: { enabled: false } });
|
||||
|
||||
await expect(sut.handleMigrationSingle({ id: testAsset.id })).resolves.toBe(JobStatus.SKIPPED);
|
||||
|
||||
expect(mocks.asset.getByIds).not.toHaveBeenCalled();
|
||||
expect(mocks.storage.checkFileExists).not.toHaveBeenCalled();
|
||||
expect(mocks.storage.rename).not.toHaveBeenCalled();
|
||||
|
@ -87,9 +87,12 @@ describe(TagService.name, () => {
|
||||
|
||||
it('should create a new tag with optional color', async () => {
|
||||
mocks.tag.create.mockResolvedValue(tagStub.colorCreate);
|
||||
mocks.tag.getByValue.mockResolvedValue(void 0);
|
||||
|
||||
await expect(sut.create(authStub.admin, { name: 'tag-1', color: '#000000' })).resolves.toEqual(
|
||||
tagResponseStub.color1,
|
||||
);
|
||||
|
||||
expect(mocks.tag.create).toHaveBeenCalledWith({
|
||||
userId: authStub.admin.user.id,
|
||||
value: 'tag-1',
|
||||
@ -168,6 +171,8 @@ describe(TagService.name, () => {
|
||||
|
||||
it('should remove a tag', async () => {
|
||||
mocks.tag.get.mockResolvedValue(tagStub.tag);
|
||||
mocks.tag.delete.mockResolvedValue();
|
||||
|
||||
await sut.remove(authStub.admin, 'tag-1');
|
||||
expect(mocks.tag.delete).toHaveBeenCalledWith('tag-1');
|
||||
});
|
||||
@ -223,6 +228,7 @@ describe(TagService.name, () => {
|
||||
it('should accept accept ids that are new and reject the rest', async () => {
|
||||
mocks.tag.get.mockResolvedValue(tagStub.tag);
|
||||
mocks.tag.getAssetIds.mockResolvedValue(new Set(['asset-1']));
|
||||
mocks.tag.addAssetIds.mockResolvedValue();
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-2']));
|
||||
|
||||
await expect(
|
||||
@ -242,6 +248,8 @@ describe(TagService.name, () => {
|
||||
describe('removeAssets', () => {
|
||||
it('should throw an error for an invalid id', async () => {
|
||||
mocks.tag.getAssetIds.mockResolvedValue(new Set());
|
||||
mocks.tag.removeAssetIds.mockResolvedValue();
|
||||
|
||||
await expect(sut.removeAssets(authStub.admin, 'tag-1', { ids: ['asset-1'] })).resolves.toEqual([
|
||||
{ id: 'asset-1', success: false, error: 'not_found' },
|
||||
]);
|
||||
@ -250,6 +258,7 @@ describe(TagService.name, () => {
|
||||
it('should accept accept ids that are tagged and reject the rest', async () => {
|
||||
mocks.tag.get.mockResolvedValue(tagStub.tag);
|
||||
mocks.tag.getAssetIds.mockResolvedValue(new Set(['asset-1']));
|
||||
mocks.tag.removeAssetIds.mockResolvedValue();
|
||||
|
||||
await expect(
|
||||
sut.removeAssets(authStub.admin, 'tag-1', {
|
||||
@ -267,7 +276,10 @@ describe(TagService.name, () => {
|
||||
|
||||
describe('handleTagCleanup', () => {
|
||||
it('should delete empty tags', async () => {
|
||||
mocks.tag.deleteEmptyTags.mockResolvedValue();
|
||||
|
||||
await expect(sut.handleTagCleanup()).resolves.toBe(JobStatus.SUCCESS);
|
||||
|
||||
expect(mocks.tag.deleteEmptyTags).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -70,6 +70,7 @@ describe(TimelineService.name, () => {
|
||||
|
||||
it('should include partner shared assets', async () => {
|
||||
mocks.asset.getTimeBucket.mockResolvedValue([assetStub.image]);
|
||||
mocks.partner.getAll.mockResolvedValue([]);
|
||||
|
||||
await expect(
|
||||
sut.getTimeBucket(authStub.admin, {
|
||||
|
@ -39,6 +39,7 @@ describe(TrashService.name, () => {
|
||||
|
||||
it('should restore a batch of assets', async () => {
|
||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset1', 'asset2']));
|
||||
mocks.trash.restoreAll.mockResolvedValue(0);
|
||||
|
||||
await sut.restoreAssets(authStub.user1, { ids: ['asset1', 'asset2'] });
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { serverVersion } from 'src/constants';
|
||||
import { ImmichEnvironment, JobName, JobStatus, SystemMetadataKey } from 'src/enum';
|
||||
import { VersionService } from 'src/services/version.service';
|
||||
import { mockEnvData } from 'test/repositories/config.repository.mock';
|
||||
import { factory } from 'test/small.factory';
|
||||
import { newTestService, ServiceMocks } from 'test/utils';
|
||||
|
||||
const mockRelease = (version: string) => ({
|
||||
@ -30,7 +31,12 @@ describe(VersionService.name, () => {
|
||||
|
||||
describe('onBootstrap', () => {
|
||||
it('should record a new version', async () => {
|
||||
mocks.versionHistory.getAll.mockResolvedValue([]);
|
||||
mocks.versionHistory.getLatest.mockResolvedValue(void 0);
|
||||
mocks.versionHistory.create.mockResolvedValue(factory.versionHistory());
|
||||
|
||||
await expect(sut.onBootstrap()).resolves.toBeUndefined();
|
||||
|
||||
expect(mocks.versionHistory.create).toHaveBeenCalledWith({ version: expect.any(String) });
|
||||
});
|
||||
|
||||
|
@ -34,9 +34,9 @@ import { TrashRepository } from 'src/repositories/trash.repository';
|
||||
import { UserRepository } from 'src/repositories/user.repository';
|
||||
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
||||
import { ViewRepository } from 'src/repositories/view-repository';
|
||||
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
|
||||
import { newTelemetryRepositoryMock } from 'test/repositories/telemetry.repository.mock';
|
||||
import { newUuid } from 'test/small.factory';
|
||||
import { automock } from 'test/utils';
|
||||
|
||||
class CustomWritable extends Writable {
|
||||
private data = '';
|
||||
@ -213,7 +213,7 @@ export class TestContext {
|
||||
view: ViewRepository;
|
||||
|
||||
private constructor(public db: Kysely<DB>) {
|
||||
const logger = newLoggingRepositoryMock() as unknown as LoggingRepository;
|
||||
const logger = automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false });
|
||||
const config = new ConfigRepository();
|
||||
|
||||
this.access = new AccessRepository(this.db);
|
||||
|
@ -3,12 +3,14 @@ import { writeFile } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { AssetEntity } from 'src/entities/asset.entity';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { MetadataRepository } from 'src/repositories/metadata.repository';
|
||||
import { MetadataService } from 'src/services/metadata.service';
|
||||
import { newFakeLoggingRepository } from 'test/repositories/logger.repository.mock';
|
||||
import { newRandomImage, newTestService, ServiceMocks } from 'test/utils';
|
||||
import { automock, newRandomImage, newTestService, ServiceMocks } from 'test/utils';
|
||||
|
||||
const metadataRepository = new MetadataRepository(newFakeLoggingRepository());
|
||||
const metadataRepository = new MetadataRepository(
|
||||
automock(LoggingRepository, { args: [, { getEnv: () => ({}) }], strict: false }),
|
||||
);
|
||||
|
||||
const createTestFile = async (exifData: Record<string, any>) => {
|
||||
const data = newRandomImage();
|
||||
|
@ -1,12 +0,0 @@
|
||||
import { ActivityRepository } from 'src/repositories/activity.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newActivityRepositoryMock = (): Mocked<RepositoryInterface<ActivityRepository>> => {
|
||||
return {
|
||||
search: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
getStatistics: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked } from 'vitest';
|
||||
|
||||
export const newAlbumUserRepositoryMock = (): Mocked<RepositoryInterface<AlbumUserRepository>> => {
|
||||
return {
|
||||
create: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
import { AlbumRepository } from 'src/repositories/album.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newAlbumRepositoryMock = (): Mocked<RepositoryInterface<AlbumRepository>> => {
|
||||
return {
|
||||
getById: vitest.fn(),
|
||||
getByAssetId: vitest.fn(),
|
||||
getMetadataForIds: vitest.fn(),
|
||||
getOwned: vitest.fn(),
|
||||
getShared: vitest.fn(),
|
||||
getNotShared: vitest.fn(),
|
||||
restoreAll: vitest.fn(),
|
||||
softDeleteAll: vitest.fn(),
|
||||
deleteAll: vitest.fn(),
|
||||
addAssetIds: vitest.fn(),
|
||||
removeAsset: vitest.fn(),
|
||||
removeAssetIds: vitest.fn(),
|
||||
getAssetIds: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
updateThumbnails: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newKeyRepositoryMock = (): Mocked<RepositoryInterface<ApiKeyRepository>> => {
|
||||
return {
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
getKey: vitest.fn(),
|
||||
getById: vitest.fn(),
|
||||
getByUserId: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
import { AuditRepository } from 'src/repositories/audit.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newAuditRepositoryMock = (): Mocked<RepositoryInterface<AuditRepository>> => {
|
||||
return {
|
||||
getAfter: vitest.fn(),
|
||||
removeBefore: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
import { CronRepository } from 'src/repositories/cron.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newCronRepositoryMock = (): Mocked<RepositoryInterface<CronRepository>> => {
|
||||
return {
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import { DownloadRepository } from 'src/repositories/download.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newDownloadRepositoryMock = (): Mocked<RepositoryInterface<DownloadRepository>> => {
|
||||
return {
|
||||
downloadAssetIds: vitest.fn(),
|
||||
downloadMotionAssetIds: vitest.fn(),
|
||||
downloadAlbumId: vitest.fn(),
|
||||
downloadUserId: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
import { EventRepository } from 'src/repositories/event.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newEventRepositoryMock = (): Mocked<RepositoryInterface<EventRepository>> => {
|
||||
return {
|
||||
setup: vitest.fn(),
|
||||
emit: vitest.fn() as any,
|
||||
clientSend: vitest.fn() as any,
|
||||
clientBroadcast: vitest.fn() as any,
|
||||
serverSend: vitest.fn(),
|
||||
afterInit: vitest.fn(),
|
||||
handleConnection: vitest.fn(),
|
||||
handleDisconnect: vitest.fn(),
|
||||
setAuthFn: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
import { LibraryRepository } from 'src/repositories/library.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newLibraryRepositoryMock = (): Mocked<RepositoryInterface<LibraryRepository>> => {
|
||||
return {
|
||||
get: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
softDelete: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
getStatistics: vitest.fn(),
|
||||
getAllDeleted: vitest.fn(),
|
||||
getAll: vitest.fn(),
|
||||
streamAssetIds: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newLoggingRepositoryMock = (): Mocked<RepositoryInterface<LoggingRepository>> => {
|
||||
return {
|
||||
setLogLevel: vitest.fn(),
|
||||
setContext: vitest.fn(),
|
||||
setAppName: vitest.fn(),
|
||||
isLevelEnabled: vitest.fn(),
|
||||
verbose: vitest.fn(),
|
||||
verboseFn: vitest.fn(),
|
||||
debug: vitest.fn(),
|
||||
debugFn: vitest.fn(),
|
||||
log: vitest.fn(),
|
||||
warn: vitest.fn(),
|
||||
error: vitest.fn(),
|
||||
fatal: vitest.fn(),
|
||||
};
|
||||
};
|
||||
|
||||
export const newFakeLoggingRepository = () =>
|
||||
newLoggingRepositoryMock() as RepositoryInterface<LoggingRepository> as LoggingRepository;
|
@ -1,11 +0,0 @@
|
||||
import { MachineLearningRepository } from 'src/repositories/machine-learning.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newMachineLearningRepositoryMock = (): Mocked<RepositoryInterface<MachineLearningRepository>> => {
|
||||
return {
|
||||
encodeImage: vitest.fn(),
|
||||
encodeText: vitest.fn(),
|
||||
detectFaces: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
import { MapRepository } from 'src/repositories/map.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked } from 'vitest';
|
||||
|
||||
export const newMapRepositoryMock = (): Mocked<RepositoryInterface<MapRepository>> => {
|
||||
return {
|
||||
init: vitest.fn(),
|
||||
reverseGeocode: vitest.fn(),
|
||||
getMapMarkers: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
import { MemoryRepository } from 'src/repositories/memory.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newMemoryRepositoryMock = (): Mocked<RepositoryInterface<MemoryRepository>> => {
|
||||
return {
|
||||
search: vitest.fn().mockResolvedValue([]),
|
||||
get: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
getAssetIds: vitest.fn().mockResolvedValue(new Set()),
|
||||
addAssetIds: vitest.fn(),
|
||||
removeAssetIds: vitest.fn(),
|
||||
cleanup: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { MoveRepository } from 'src/repositories/move.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newMoveRepositoryMock = (): Mocked<RepositoryInterface<MoveRepository>> => {
|
||||
return {
|
||||
create: vitest.fn(),
|
||||
getByEntity: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
cleanMoveHistory: vitest.fn(),
|
||||
cleanMoveHistorySingle: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
import { NotificationRepository } from 'src/repositories/notification.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked } from 'vitest';
|
||||
|
||||
export const newNotificationRepositoryMock = (): Mocked<RepositoryInterface<NotificationRepository>> => {
|
||||
return {
|
||||
renderEmail: vitest.fn(),
|
||||
sendEmail: vitest.fn().mockResolvedValue({ messageId: 'message-1' }),
|
||||
verifySmtp: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import { OAuthRepository } from 'src/repositories/oauth.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked } from 'vitest';
|
||||
|
||||
export const newOAuthRepositoryMock = (): Mocked<RepositoryInterface<OAuthRepository>> => {
|
||||
return {
|
||||
init: vitest.fn(),
|
||||
authorize: vitest.fn(),
|
||||
getLogoutEndpoint: vitest.fn(),
|
||||
getProfile: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
import { PartnerRepository } from 'src/repositories/partner.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newPartnerRepositoryMock = (): Mocked<RepositoryInterface<PartnerRepository>> => {
|
||||
return {
|
||||
create: vitest.fn(),
|
||||
remove: vitest.fn(),
|
||||
getAll: vitest.fn().mockResolvedValue([]),
|
||||
get: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
import { PersonRepository } from 'src/repositories/person.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newPersonRepositoryMock = (): Mocked<RepositoryInterface<PersonRepository>> => {
|
||||
return {
|
||||
getById: vitest.fn(),
|
||||
getAll: vitest.fn(),
|
||||
getAllForUser: vitest.fn(),
|
||||
getAllWithoutFaces: vitest.fn(),
|
||||
|
||||
getByName: vitest.fn(),
|
||||
getDistinctNames: vitest.fn(),
|
||||
|
||||
create: vitest.fn(),
|
||||
createAll: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
updateAll: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
deleteFaces: vitest.fn(),
|
||||
|
||||
getStatistics: vitest.fn(),
|
||||
getAllFaces: vitest.fn(),
|
||||
getFacesByIds: vitest.fn(),
|
||||
getRandomFace: vitest.fn(),
|
||||
|
||||
reassignFaces: vitest.fn(),
|
||||
unassignFaces: vitest.fn(),
|
||||
refreshFaces: vitest.fn(),
|
||||
getFaces: vitest.fn(),
|
||||
reassignFace: vitest.fn(),
|
||||
getFaceById: vitest.fn(),
|
||||
getFaceByIdWithAssets: vitest.fn(),
|
||||
getNumberOfPeople: vitest.fn(),
|
||||
getLatestFaceDate: vitest.fn(),
|
||||
|
||||
createAssetFace: vitest.fn(),
|
||||
deleteAssetFace: vitest.fn(),
|
||||
softDeleteAssetFaces: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,9 +0,0 @@
|
||||
import { ProcessRepository } from 'src/repositories/process.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newProcessRepositoryMock = (): Mocked<RepositoryInterface<ProcessRepository>> => {
|
||||
return {
|
||||
spawn: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
import { SearchRepository } from 'src/repositories/search.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newSearchRepositoryMock = (): Mocked<RepositoryInterface<SearchRepository>> => {
|
||||
return {
|
||||
searchMetadata: vitest.fn(),
|
||||
searchSmart: vitest.fn(),
|
||||
searchDuplicates: vitest.fn(),
|
||||
searchFaces: vitest.fn(),
|
||||
searchRandom: vitest.fn(),
|
||||
upsert: vitest.fn(),
|
||||
searchPlaces: vitest.fn(),
|
||||
getAssetsByCity: vitest.fn(),
|
||||
deleteAllSearchEmbeddings: vitest.fn(),
|
||||
getDimensionSize: vitest.fn(),
|
||||
setDimensionSize: vitest.fn(),
|
||||
getCameraMakes: vitest.fn(),
|
||||
getCameraModels: vitest.fn(),
|
||||
getCities: vitest.fn(),
|
||||
getCountries: vitest.fn(),
|
||||
getStates: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
import { ServerInfoRepository } from 'src/repositories/server-info.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newServerInfoRepositoryMock = (): Mocked<RepositoryInterface<ServerInfoRepository>> => {
|
||||
return {
|
||||
getGitHubRelease: vitest.fn(),
|
||||
getBuildVersions: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { SessionRepository } from 'src/repositories/session.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newSessionRepositoryMock = (): Mocked<RepositoryInterface<SessionRepository>> => {
|
||||
return {
|
||||
search: vitest.fn(),
|
||||
create: vitest.fn() as any,
|
||||
update: vitest.fn() as any,
|
||||
delete: vitest.fn(),
|
||||
getByToken: vitest.fn(),
|
||||
getByUserId: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { SharedLinkRepository } from 'src/repositories/shared-link.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newSharedLinkRepositoryMock = (): Mocked<RepositoryInterface<SharedLinkRepository>> => {
|
||||
return {
|
||||
getAll: vitest.fn(),
|
||||
get: vitest.fn(),
|
||||
getByKey: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
remove: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { StackRepository } from 'src/repositories/stack.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newStackRepositoryMock = (): Mocked<RepositoryInterface<StackRepository>> => {
|
||||
return {
|
||||
search: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
getById: vitest.fn(),
|
||||
deleteAll: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,21 +0,0 @@
|
||||
import { SyncRepository } from 'src/repositories/sync.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newSyncRepositoryMock = (): Mocked<RepositoryInterface<SyncRepository>> => {
|
||||
return {
|
||||
getCheckpoints: vitest.fn(),
|
||||
upsertCheckpoints: vitest.fn(),
|
||||
deleteCheckpoints: vitest.fn(),
|
||||
getUserUpserts: vitest.fn(),
|
||||
getUserDeletes: vitest.fn(),
|
||||
getPartnerUpserts: vitest.fn(),
|
||||
getPartnerDeletes: vitest.fn(),
|
||||
getPartnerAssetsUpserts: vitest.fn(),
|
||||
getPartnerAssetDeletes: vitest.fn(),
|
||||
getAssetDeletes: vitest.fn(),
|
||||
getAssetUpserts: vitest.fn(),
|
||||
getAssetExifsUpserts: vitest.fn(),
|
||||
getPartnerAssetExifsUpserts: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
import { TagRepository } from 'src/repositories/tag.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newTagRepositoryMock = (): Mocked<RepositoryInterface<TagRepository>> => {
|
||||
return {
|
||||
getAll: vitest.fn(),
|
||||
getByValue: vitest.fn(),
|
||||
upsertValue: vitest.fn(),
|
||||
replaceAssetTags: vitest.fn(),
|
||||
|
||||
get: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
|
||||
getAssetIds: vitest.fn(),
|
||||
addAssetIds: vitest.fn(),
|
||||
removeAssetIds: vitest.fn(),
|
||||
upsertAssetIds: vitest.fn(),
|
||||
deleteEmptyTags: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import { TrashRepository } from 'src/repositories/trash.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newTrashRepositoryMock = (): Mocked<RepositoryInterface<TrashRepository>> => {
|
||||
return {
|
||||
empty: vitest.fn(),
|
||||
restore: vitest.fn(),
|
||||
restoreAll: vitest.fn(),
|
||||
getDeletedIds: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,26 +0,0 @@
|
||||
import { UserRepository } from 'src/repositories/user.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newUserRepositoryMock = (): Mocked<RepositoryInterface<UserRepository>> => {
|
||||
return {
|
||||
get: vitest.fn(),
|
||||
getMetadata: vitest.fn().mockResolvedValue([]),
|
||||
getAdmin: vitest.fn(),
|
||||
getByEmail: vitest.fn(),
|
||||
getByStorageLabel: vitest.fn(),
|
||||
getByOAuthId: vitest.fn(),
|
||||
getUserStats: vitest.fn(),
|
||||
getList: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
update: vitest.fn(),
|
||||
delete: vitest.fn(),
|
||||
restore: vitest.fn(),
|
||||
getDeletedUsers: vitest.fn(),
|
||||
hasAdmin: vitest.fn(),
|
||||
updateUsage: vitest.fn(),
|
||||
syncUsage: vitest.fn(),
|
||||
upsertMetadata: vitest.fn(),
|
||||
deleteMetadata: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newVersionHistoryRepositoryMock = (): Mocked<RepositoryInterface<VersionHistoryRepository>> => {
|
||||
return {
|
||||
getAll: vitest.fn().mockResolvedValue([]),
|
||||
getLatest: vitest.fn(),
|
||||
create: vitest.fn(),
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
import { ViewRepository } from 'src/repositories/view-repository';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newViewRepositoryMock = (): Mocked<RepositoryInterface<ViewRepository>> => {
|
||||
return {
|
||||
getAssetsByOriginalPath: vitest.fn(),
|
||||
getUniqueOriginalPaths: vitest.fn(),
|
||||
};
|
||||
};
|
@ -42,6 +42,23 @@ const authUserFactory = (authUser: Partial<AuthUser> = {}) => ({
|
||||
...authUser,
|
||||
});
|
||||
|
||||
const sessionFactory = () => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
updatedAt: newDate(),
|
||||
updateId: newUpdateId(),
|
||||
deviceOS: 'android',
|
||||
deviceType: 'mobile',
|
||||
token: 'abc123',
|
||||
userId: newUuid(),
|
||||
});
|
||||
|
||||
const stackFactory = () => ({
|
||||
id: newUuid(),
|
||||
ownerId: newUuid(),
|
||||
primaryAssetId: newUuid(),
|
||||
});
|
||||
|
||||
const userFactory = (user: Partial<User> = {}) => ({
|
||||
id: newUuid(),
|
||||
name: 'Test User',
|
||||
@ -145,6 +162,12 @@ const memoryFactory = (memory: Partial<MemoryItem> = {}) => ({
|
||||
...memory,
|
||||
});
|
||||
|
||||
const versionHistoryFactory = () => ({
|
||||
id: newUuid(),
|
||||
createdAt: newDate(),
|
||||
version: '1.123.45',
|
||||
});
|
||||
|
||||
export const factory = {
|
||||
activity: activityFactory,
|
||||
apiKey: apiKeyFactory,
|
||||
@ -154,5 +177,8 @@ export const factory = {
|
||||
authUser: authUserFactory,
|
||||
library: libraryFactory,
|
||||
memory: memoryFactory,
|
||||
session: sessionFactory,
|
||||
stack: stackFactory,
|
||||
user: userFactory,
|
||||
versionHistory: versionHistoryFactory,
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ClassConstructor } from 'class-transformer';
|
||||
import { Kysely, sql } from 'kysely';
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import { ChildProcessWithoutNullStreams } from 'node:child_process';
|
||||
@ -50,48 +51,59 @@ import { ViewRepository } from 'src/repositories/view-repository';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
import { RepositoryInterface } from 'src/types';
|
||||
import { IAccessRepositoryMock, newAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
||||
import { newActivityRepositoryMock } from 'test/repositories/activity.repository.mock';
|
||||
import { newAlbumUserRepositoryMock } from 'test/repositories/album-user.repository.mock';
|
||||
import { newAlbumRepositoryMock } from 'test/repositories/album.repository.mock';
|
||||
import { newKeyRepositoryMock } from 'test/repositories/api-key.repository.mock';
|
||||
import { newAssetRepositoryMock } from 'test/repositories/asset.repository.mock';
|
||||
import { newAuditRepositoryMock } from 'test/repositories/audit.repository.mock';
|
||||
import { newConfigRepositoryMock } from 'test/repositories/config.repository.mock';
|
||||
import { newCronRepositoryMock } from 'test/repositories/cron.repository.mock';
|
||||
import { newCryptoRepositoryMock } from 'test/repositories/crypto.repository.mock';
|
||||
import { newDatabaseRepositoryMock } from 'test/repositories/database.repository.mock';
|
||||
import { newDownloadRepositoryMock } from 'test/repositories/download.repository.mock';
|
||||
import { newEventRepositoryMock } from 'test/repositories/event.repository.mock';
|
||||
import { newJobRepositoryMock } from 'test/repositories/job.repository.mock';
|
||||
import { newLibraryRepositoryMock } from 'test/repositories/library.repository.mock';
|
||||
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
|
||||
import { newMachineLearningRepositoryMock } from 'test/repositories/machine-learning.repository.mock';
|
||||
import { newMapRepositoryMock } from 'test/repositories/map.repository.mock';
|
||||
import { newMediaRepositoryMock } from 'test/repositories/media.repository.mock';
|
||||
import { newMemoryRepositoryMock } from 'test/repositories/memory.repository.mock';
|
||||
import { newMetadataRepositoryMock } from 'test/repositories/metadata.repository.mock';
|
||||
import { newMoveRepositoryMock } from 'test/repositories/move.repository.mock';
|
||||
import { newNotificationRepositoryMock } from 'test/repositories/notification.repository.mock';
|
||||
import { newOAuthRepositoryMock } from 'test/repositories/oauth.repository.mock';
|
||||
import { newPartnerRepositoryMock } from 'test/repositories/partner.repository.mock';
|
||||
import { newPersonRepositoryMock } from 'test/repositories/person.repository.mock';
|
||||
import { newProcessRepositoryMock } from 'test/repositories/process.repository.mock';
|
||||
import { newSearchRepositoryMock } from 'test/repositories/search.repository.mock';
|
||||
import { newServerInfoRepositoryMock } from 'test/repositories/server-info.repository.mock';
|
||||
import { newSessionRepositoryMock } from 'test/repositories/session.repository.mock';
|
||||
import { newSharedLinkRepositoryMock } from 'test/repositories/shared-link.repository.mock';
|
||||
import { newStackRepositoryMock } from 'test/repositories/stack.repository.mock';
|
||||
import { newStorageRepositoryMock } from 'test/repositories/storage.repository.mock';
|
||||
import { newSyncRepositoryMock } from 'test/repositories/sync.repository.mock';
|
||||
import { newSystemMetadataRepositoryMock } from 'test/repositories/system-metadata.repository.mock';
|
||||
import { newTagRepositoryMock } from 'test/repositories/tag.repository.mock';
|
||||
import { ITelemetryRepositoryMock, newTelemetryRepositoryMock } from 'test/repositories/telemetry.repository.mock';
|
||||
import { newTrashRepositoryMock } from 'test/repositories/trash.repository.mock';
|
||||
import { newUserRepositoryMock } from 'test/repositories/user.repository.mock';
|
||||
import { newVersionHistoryRepositoryMock } from 'test/repositories/version-history.repository.mock';
|
||||
import { newViewRepositoryMock } from 'test/repositories/view.repository.mock';
|
||||
import { Readable } from 'typeorm/platform/PlatformTools';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
import { assert, Mocked, vitest } from 'vitest';
|
||||
|
||||
const mockFn = (label: string, { strict }: { strict: boolean }) => {
|
||||
const message = `Called a mock function without a mock implementation (${label})`;
|
||||
return vitest.fn().mockImplementation(() => {
|
||||
if (strict) {
|
||||
assert.fail(message);
|
||||
} else {
|
||||
// console.warn(message);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const automock = <T>(
|
||||
Dependency: ClassConstructor<T>,
|
||||
options?: {
|
||||
args?: ConstructorParameters<ClassConstructor<T>>;
|
||||
strict?: boolean;
|
||||
},
|
||||
): Mocked<T> => {
|
||||
const mock: Record<string, unknown> = {};
|
||||
const strict = options?.strict ?? true;
|
||||
const args = options?.args ?? [];
|
||||
|
||||
const instance = new Dependency(...args);
|
||||
for (const property of Object.getOwnPropertyNames(Dependency.prototype)) {
|
||||
if (property === 'constructor') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const label = `${Dependency.name}.${property}`;
|
||||
// console.log(`Automocking ${label}`);
|
||||
|
||||
const target = instance[property as keyof T];
|
||||
if (typeof target === 'function') {
|
||||
mock[property] = mockFn(label, { strict });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return mock as Mocked<T>;
|
||||
};
|
||||
|
||||
export type ServiceOverrides = {
|
||||
access: AccessRepository;
|
||||
@ -153,48 +165,52 @@ export const newTestService = <T extends BaseService>(
|
||||
Service: Constructor<T, BaseServiceArgs>,
|
||||
overrides: Partial<ServiceOverrides> = {},
|
||||
) => {
|
||||
const loggerMock = { setContext: () => {} };
|
||||
const configMock = { getEnv: () => ({}) };
|
||||
|
||||
const mocks: ServiceMocks = {
|
||||
access: newAccessRepositoryMock(),
|
||||
logger: newLoggingRepositoryMock(),
|
||||
cron: newCronRepositoryMock(),
|
||||
logger: automock(LoggingRepository, { args: [, configMock], strict: false }),
|
||||
cron: automock(CronRepository, { args: [, loggerMock] }),
|
||||
crypto: newCryptoRepositoryMock(),
|
||||
activity: newActivityRepositoryMock(),
|
||||
audit: newAuditRepositoryMock(),
|
||||
album: newAlbumRepositoryMock(),
|
||||
albumUser: newAlbumUserRepositoryMock(),
|
||||
activity: automock(ActivityRepository),
|
||||
audit: automock(AuditRepository),
|
||||
album: automock(AlbumRepository, { strict: false }),
|
||||
albumUser: automock(AlbumUserRepository),
|
||||
asset: newAssetRepositoryMock(),
|
||||
config: newConfigRepositoryMock(),
|
||||
database: newDatabaseRepositoryMock(),
|
||||
downloadRepository: newDownloadRepositoryMock(),
|
||||
event: newEventRepositoryMock(),
|
||||
downloadRepository: automock(DownloadRepository, { strict: false }),
|
||||
event: automock(EventRepository, { args: [, , loggerMock], strict: false }),
|
||||
job: newJobRepositoryMock(),
|
||||
apiKey: newKeyRepositoryMock(),
|
||||
library: newLibraryRepositoryMock(),
|
||||
machineLearning: newMachineLearningRepositoryMock(),
|
||||
map: newMapRepositoryMock(),
|
||||
apiKey: automock(ApiKeyRepository),
|
||||
library: automock(LibraryRepository, { strict: false }),
|
||||
machineLearning: automock(MachineLearningRepository, { args: [loggerMock], strict: false }),
|
||||
map: automock(MapRepository, { args: [undefined, undefined, { setContext: () => {} }] }),
|
||||
media: newMediaRepositoryMock(),
|
||||
memory: newMemoryRepositoryMock(),
|
||||
memory: automock(MemoryRepository),
|
||||
metadata: newMetadataRepositoryMock(),
|
||||
move: newMoveRepositoryMock(),
|
||||
notification: newNotificationRepositoryMock(),
|
||||
oauth: newOAuthRepositoryMock(),
|
||||
partner: newPartnerRepositoryMock(),
|
||||
person: newPersonRepositoryMock(),
|
||||
process: newProcessRepositoryMock(),
|
||||
search: newSearchRepositoryMock(),
|
||||
serverInfo: newServerInfoRepositoryMock(),
|
||||
session: newSessionRepositoryMock(),
|
||||
sharedLink: newSharedLinkRepositoryMock(),
|
||||
stack: newStackRepositoryMock(),
|
||||
move: automock(MoveRepository, { strict: false }),
|
||||
notification: automock(NotificationRepository, { args: [loggerMock] }),
|
||||
oauth: automock(OAuthRepository, { args: [loggerMock] }),
|
||||
partner: automock(PartnerRepository, { strict: false }),
|
||||
person: automock(PersonRepository, { strict: false }),
|
||||
process: automock(ProcessRepository, { args: [loggerMock] }),
|
||||
search: automock(SearchRepository, { args: [loggerMock], strict: false }),
|
||||
serverInfo: automock(ServerInfoRepository, { args: [, loggerMock], strict: false }),
|
||||
session: automock(SessionRepository),
|
||||
sharedLink: automock(SharedLinkRepository),
|
||||
stack: automock(StackRepository),
|
||||
storage: newStorageRepositoryMock(),
|
||||
sync: newSyncRepositoryMock(),
|
||||
sync: automock(SyncRepository),
|
||||
systemMetadata: newSystemMetadataRepositoryMock(),
|
||||
tag: newTagRepositoryMock(),
|
||||
// systemMetadata: automock(SystemMetadataRepository, { strict: false }),
|
||||
tag: automock(TagRepository, { args: [, loggerMock], strict: false }),
|
||||
telemetry: newTelemetryRepositoryMock(),
|
||||
trash: newTrashRepositoryMock(),
|
||||
user: newUserRepositoryMock(),
|
||||
versionHistory: newVersionHistoryRepositoryMock(),
|
||||
view: newViewRepositoryMock(),
|
||||
trash: automock(TrashRepository),
|
||||
user: automock(UserRepository, { strict: false }),
|
||||
versionHistory: automock(VersionHistoryRepository),
|
||||
view: automock(ViewRepository),
|
||||
};
|
||||
|
||||
const sut = new Service(
|
||||
|
Loading…
x
Reference in New Issue
Block a user