mirror of
https://github.com/immich-app/immich.git
synced 2025-02-11 01:18:24 -05:00
refactor(server): view repository (#12755)
This commit is contained in:
parent
f53e4721cf
commit
1e6ef5c9e4
11 changed files with 159 additions and 166 deletions
|
@ -147,8 +147,6 @@ export type AssetPathEntity = Pick<AssetEntity, 'id' | 'originalPath' | 'isOffli
|
|||
export const IAssetRepository = 'IAssetRepository';
|
||||
|
||||
export interface IAssetRepository {
|
||||
getAssetsByOriginalPath(userId: string, partialPath: string): Promise<AssetEntity[]>;
|
||||
getUniqueOriginalPaths(userId: string): Promise<string[]>;
|
||||
create(asset: AssetCreate): Promise<AssetEntity>;
|
||||
getByIds(
|
||||
ids: string[],
|
||||
|
|
8
server/src/interfaces/view.interface.ts
Normal file
8
server/src/interfaces/view.interface.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { AssetEntity } from 'src/entities/asset.entity';
|
||||
|
||||
export const IViewRepository = 'IViewRepository';
|
||||
|
||||
export interface IViewRepository {
|
||||
getAssetsByOriginalPath(userId: string, partialPath: string): Promise<AssetEntity[]>;
|
||||
getUniqueOriginalPaths(userId: string): Promise<string[]>;
|
||||
}
|
|
@ -1134,109 +1134,6 @@ WHERE
|
|||
AND "asset"."ownerId" IN ($1)
|
||||
AND "asset"."updatedAt" > $2
|
||||
|
||||
-- AssetRepository.getAssetsByOriginalPath
|
||||
SELECT
|
||||
"asset"."id" AS "asset_id",
|
||||
"asset"."deviceAssetId" AS "asset_deviceAssetId",
|
||||
"asset"."ownerId" AS "asset_ownerId",
|
||||
"asset"."libraryId" AS "asset_libraryId",
|
||||
"asset"."deviceId" AS "asset_deviceId",
|
||||
"asset"."type" AS "asset_type",
|
||||
"asset"."originalPath" AS "asset_originalPath",
|
||||
"asset"."thumbhash" AS "asset_thumbhash",
|
||||
"asset"."encodedVideoPath" AS "asset_encodedVideoPath",
|
||||
"asset"."createdAt" AS "asset_createdAt",
|
||||
"asset"."updatedAt" AS "asset_updatedAt",
|
||||
"asset"."deletedAt" AS "asset_deletedAt",
|
||||
"asset"."fileCreatedAt" AS "asset_fileCreatedAt",
|
||||
"asset"."localDateTime" AS "asset_localDateTime",
|
||||
"asset"."fileModifiedAt" AS "asset_fileModifiedAt",
|
||||
"asset"."isFavorite" AS "asset_isFavorite",
|
||||
"asset"."isArchived" AS "asset_isArchived",
|
||||
"asset"."isExternal" AS "asset_isExternal",
|
||||
"asset"."isOffline" AS "asset_isOffline",
|
||||
"asset"."checksum" AS "asset_checksum",
|
||||
"asset"."duration" AS "asset_duration",
|
||||
"asset"."isVisible" AS "asset_isVisible",
|
||||
"asset"."livePhotoVideoId" AS "asset_livePhotoVideoId",
|
||||
"asset"."originalFileName" AS "asset_originalFileName",
|
||||
"asset"."sidecarPath" AS "asset_sidecarPath",
|
||||
"asset"."stackId" AS "asset_stackId",
|
||||
"asset"."duplicateId" AS "asset_duplicateId",
|
||||
"exifInfo"."assetId" AS "exifInfo_assetId",
|
||||
"exifInfo"."description" AS "exifInfo_description",
|
||||
"exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth",
|
||||
"exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight",
|
||||
"exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte",
|
||||
"exifInfo"."orientation" AS "exifInfo_orientation",
|
||||
"exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal",
|
||||
"exifInfo"."modifyDate" AS "exifInfo_modifyDate",
|
||||
"exifInfo"."timeZone" AS "exifInfo_timeZone",
|
||||
"exifInfo"."latitude" AS "exifInfo_latitude",
|
||||
"exifInfo"."longitude" AS "exifInfo_longitude",
|
||||
"exifInfo"."projectionType" AS "exifInfo_projectionType",
|
||||
"exifInfo"."city" AS "exifInfo_city",
|
||||
"exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID",
|
||||
"exifInfo"."autoStackId" AS "exifInfo_autoStackId",
|
||||
"exifInfo"."state" AS "exifInfo_state",
|
||||
"exifInfo"."country" AS "exifInfo_country",
|
||||
"exifInfo"."make" AS "exifInfo_make",
|
||||
"exifInfo"."model" AS "exifInfo_model",
|
||||
"exifInfo"."lensModel" AS "exifInfo_lensModel",
|
||||
"exifInfo"."fNumber" AS "exifInfo_fNumber",
|
||||
"exifInfo"."focalLength" AS "exifInfo_focalLength",
|
||||
"exifInfo"."iso" AS "exifInfo_iso",
|
||||
"exifInfo"."exposureTime" AS "exifInfo_exposureTime",
|
||||
"exifInfo"."profileDescription" AS "exifInfo_profileDescription",
|
||||
"exifInfo"."colorspace" AS "exifInfo_colorspace",
|
||||
"exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample",
|
||||
"exifInfo"."rating" AS "exifInfo_rating",
|
||||
"exifInfo"."fps" AS "exifInfo_fps",
|
||||
"stack"."id" AS "stack_id",
|
||||
"stack"."ownerId" AS "stack_ownerId",
|
||||
"stack"."primaryAssetId" AS "stack_primaryAssetId",
|
||||
"stackedAssets"."id" AS "stackedAssets_id",
|
||||
"stackedAssets"."deviceAssetId" AS "stackedAssets_deviceAssetId",
|
||||
"stackedAssets"."ownerId" AS "stackedAssets_ownerId",
|
||||
"stackedAssets"."libraryId" AS "stackedAssets_libraryId",
|
||||
"stackedAssets"."deviceId" AS "stackedAssets_deviceId",
|
||||
"stackedAssets"."type" AS "stackedAssets_type",
|
||||
"stackedAssets"."originalPath" AS "stackedAssets_originalPath",
|
||||
"stackedAssets"."thumbhash" AS "stackedAssets_thumbhash",
|
||||
"stackedAssets"."encodedVideoPath" AS "stackedAssets_encodedVideoPath",
|
||||
"stackedAssets"."createdAt" AS "stackedAssets_createdAt",
|
||||
"stackedAssets"."updatedAt" AS "stackedAssets_updatedAt",
|
||||
"stackedAssets"."deletedAt" AS "stackedAssets_deletedAt",
|
||||
"stackedAssets"."fileCreatedAt" AS "stackedAssets_fileCreatedAt",
|
||||
"stackedAssets"."localDateTime" AS "stackedAssets_localDateTime",
|
||||
"stackedAssets"."fileModifiedAt" AS "stackedAssets_fileModifiedAt",
|
||||
"stackedAssets"."isFavorite" AS "stackedAssets_isFavorite",
|
||||
"stackedAssets"."isArchived" AS "stackedAssets_isArchived",
|
||||
"stackedAssets"."isExternal" AS "stackedAssets_isExternal",
|
||||
"stackedAssets"."isOffline" AS "stackedAssets_isOffline",
|
||||
"stackedAssets"."checksum" AS "stackedAssets_checksum",
|
||||
"stackedAssets"."duration" AS "stackedAssets_duration",
|
||||
"stackedAssets"."isVisible" AS "stackedAssets_isVisible",
|
||||
"stackedAssets"."livePhotoVideoId" AS "stackedAssets_livePhotoVideoId",
|
||||
"stackedAssets"."originalFileName" AS "stackedAssets_originalFileName",
|
||||
"stackedAssets"."sidecarPath" AS "stackedAssets_sidecarPath",
|
||||
"stackedAssets"."stackId" AS "stackedAssets_stackId",
|
||||
"stackedAssets"."duplicateId" AS "stackedAssets_duplicateId"
|
||||
FROM
|
||||
"assets" "asset"
|
||||
LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "asset"."id"
|
||||
LEFT JOIN "asset_stack" "stack" ON "stack"."id" = "asset"."stackId"
|
||||
LEFT JOIN "assets" "stackedAssets" ON "stackedAssets"."stackId" = "stack"."id"
|
||||
AND ("stackedAssets"."deletedAt" IS NULL)
|
||||
WHERE
|
||||
"asset"."ownerId" = $1
|
||||
AND (
|
||||
"asset"."originalPath" LIKE $2
|
||||
AND "asset"."originalPath" NOT LIKE $3
|
||||
)
|
||||
ORDER BY
|
||||
regexp_replace("asset"."originalPath", '.*/(.+)', '\1') ASC
|
||||
|
||||
-- AssetRepository.upsertFile
|
||||
INSERT INTO
|
||||
"asset_files" (
|
||||
|
|
78
server/src/queries/view.repository.sql
Normal file
78
server/src/queries/view.repository.sql
Normal file
|
@ -0,0 +1,78 @@
|
|||
-- NOTE: This file is auto generated by ./sql-generator
|
||||
|
||||
-- ViewRepository.getAssetsByOriginalPath
|
||||
SELECT
|
||||
"asset"."id" AS "asset_id",
|
||||
"asset"."deviceAssetId" AS "asset_deviceAssetId",
|
||||
"asset"."ownerId" AS "asset_ownerId",
|
||||
"asset"."libraryId" AS "asset_libraryId",
|
||||
"asset"."deviceId" AS "asset_deviceId",
|
||||
"asset"."type" AS "asset_type",
|
||||
"asset"."originalPath" AS "asset_originalPath",
|
||||
"asset"."thumbhash" AS "asset_thumbhash",
|
||||
"asset"."encodedVideoPath" AS "asset_encodedVideoPath",
|
||||
"asset"."createdAt" AS "asset_createdAt",
|
||||
"asset"."updatedAt" AS "asset_updatedAt",
|
||||
"asset"."deletedAt" AS "asset_deletedAt",
|
||||
"asset"."fileCreatedAt" AS "asset_fileCreatedAt",
|
||||
"asset"."localDateTime" AS "asset_localDateTime",
|
||||
"asset"."fileModifiedAt" AS "asset_fileModifiedAt",
|
||||
"asset"."isFavorite" AS "asset_isFavorite",
|
||||
"asset"."isArchived" AS "asset_isArchived",
|
||||
"asset"."isExternal" AS "asset_isExternal",
|
||||
"asset"."isOffline" AS "asset_isOffline",
|
||||
"asset"."checksum" AS "asset_checksum",
|
||||
"asset"."duration" AS "asset_duration",
|
||||
"asset"."isVisible" AS "asset_isVisible",
|
||||
"asset"."livePhotoVideoId" AS "asset_livePhotoVideoId",
|
||||
"asset"."originalFileName" AS "asset_originalFileName",
|
||||
"asset"."sidecarPath" AS "asset_sidecarPath",
|
||||
"asset"."stackId" AS "asset_stackId",
|
||||
"asset"."duplicateId" AS "asset_duplicateId",
|
||||
"exifInfo"."assetId" AS "exifInfo_assetId",
|
||||
"exifInfo"."description" AS "exifInfo_description",
|
||||
"exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth",
|
||||
"exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight",
|
||||
"exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte",
|
||||
"exifInfo"."orientation" AS "exifInfo_orientation",
|
||||
"exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal",
|
||||
"exifInfo"."modifyDate" AS "exifInfo_modifyDate",
|
||||
"exifInfo"."timeZone" AS "exifInfo_timeZone",
|
||||
"exifInfo"."latitude" AS "exifInfo_latitude",
|
||||
"exifInfo"."longitude" AS "exifInfo_longitude",
|
||||
"exifInfo"."projectionType" AS "exifInfo_projectionType",
|
||||
"exifInfo"."city" AS "exifInfo_city",
|
||||
"exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID",
|
||||
"exifInfo"."autoStackId" AS "exifInfo_autoStackId",
|
||||
"exifInfo"."state" AS "exifInfo_state",
|
||||
"exifInfo"."country" AS "exifInfo_country",
|
||||
"exifInfo"."make" AS "exifInfo_make",
|
||||
"exifInfo"."model" AS "exifInfo_model",
|
||||
"exifInfo"."lensModel" AS "exifInfo_lensModel",
|
||||
"exifInfo"."fNumber" AS "exifInfo_fNumber",
|
||||
"exifInfo"."focalLength" AS "exifInfo_focalLength",
|
||||
"exifInfo"."iso" AS "exifInfo_iso",
|
||||
"exifInfo"."exposureTime" AS "exifInfo_exposureTime",
|
||||
"exifInfo"."profileDescription" AS "exifInfo_profileDescription",
|
||||
"exifInfo"."colorspace" AS "exifInfo_colorspace",
|
||||
"exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample",
|
||||
"exifInfo"."rating" AS "exifInfo_rating",
|
||||
"exifInfo"."fps" AS "exifInfo_fps"
|
||||
FROM
|
||||
"assets" "asset"
|
||||
LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "asset"."id"
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
"asset"."isVisible" = $1
|
||||
AND "asset"."isArchived" = $2
|
||||
AND "asset"."ownerId" = $3
|
||||
)
|
||||
AND (
|
||||
"asset"."originalPath" LIKE $4
|
||||
AND "asset"."originalPath" NOT LIKE $5
|
||||
)
|
||||
)
|
||||
AND ("asset"."deletedAt" IS NULL)
|
||||
ORDER BY
|
||||
regexp_replace("asset"."originalPath", '.*/(.+)', '\1') ASC
|
|
@ -836,50 +836,6 @@ export class AssetRepository implements IAssetRepository {
|
|||
return builder.getMany();
|
||||
}
|
||||
|
||||
async getUniqueOriginalPaths(userId: string): Promise<string[]> {
|
||||
const builder = this.getBuilder({
|
||||
userIds: [userId],
|
||||
exifInfo: false,
|
||||
withStacked: false,
|
||||
isArchived: false,
|
||||
isTrashed: false,
|
||||
});
|
||||
|
||||
const results = await builder
|
||||
.select("DISTINCT substring(asset.originalPath FROM '^(.*/)[^/]*$')", 'directoryPath')
|
||||
.getRawMany();
|
||||
|
||||
return results.map((row: { directoryPath: string }) => row.directoryPath.replaceAll(/^\/|\/$/g, ''));
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] })
|
||||
async getAssetsByOriginalPath(userId: string, partialPath: string): Promise<AssetEntity[]> {
|
||||
const normalizedPath = partialPath.replaceAll(/^\/|\/$/g, '');
|
||||
|
||||
const builder = this.getBuilder({
|
||||
userIds: [userId],
|
||||
exifInfo: true,
|
||||
withStacked: false,
|
||||
isArchived: false,
|
||||
isTrashed: false,
|
||||
});
|
||||
|
||||
const assets = await builder
|
||||
.where('asset.ownerId = :userId', { userId })
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where('asset.originalPath LIKE :likePath', { likePath: `%${normalizedPath}/%` }).andWhere(
|
||||
'asset.originalPath NOT LIKE :notLikePath',
|
||||
{ notLikePath: `%${normalizedPath}/%/%` },
|
||||
);
|
||||
}),
|
||||
)
|
||||
.orderBy(String.raw`regexp_replace(asset.originalPath, '.*/(.+)', '\1')`, 'ASC')
|
||||
.getMany();
|
||||
|
||||
return assets;
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [{ assetId: DummyValue.UUID, type: AssetFileType.PREVIEW, path: '/path/to/file' }] })
|
||||
async upsertFile({ assetId, type, path }: { assetId: string; type: AssetFileType; path: string }): Promise<void> {
|
||||
await this.fileRepository.upsert({ assetId, type, path }, { conflictPaths: ['assetId', 'type'] });
|
||||
|
|
|
@ -30,6 +30,7 @@ import { IStorageRepository } from 'src/interfaces/storage.interface';
|
|||
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
|
||||
import { ITagRepository } from 'src/interfaces/tag.interface';
|
||||
import { IUserRepository } from 'src/interfaces/user.interface';
|
||||
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||
import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { ActivityRepository } from 'src/repositories/activity.repository';
|
||||
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
||||
|
@ -62,6 +63,7 @@ import { StorageRepository } from 'src/repositories/storage.repository';
|
|||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||
import { TagRepository } from 'src/repositories/tag.repository';
|
||||
import { UserRepository } from 'src/repositories/user.repository';
|
||||
import { ViewRepository } from 'src/repositories/view-repository';
|
||||
|
||||
export const repositories = [
|
||||
{ provide: IAccessRepository, useClass: AccessRepository },
|
||||
|
@ -96,4 +98,5 @@ export const repositories = [
|
|||
{ provide: ISystemMetadataRepository, useClass: SystemMetadataRepository },
|
||||
{ provide: ITagRepository, useClass: TagRepository },
|
||||
{ provide: IUserRepository, useClass: UserRepository },
|
||||
{ provide: IViewRepository, useClass: ViewRepository },
|
||||
];
|
||||
|
|
48
server/src/repositories/view-repository.ts
Normal file
48
server/src/repositories/view-repository.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||
import { AssetEntity } from 'src/entities/asset.entity';
|
||||
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||
import { Brackets, Repository } from 'typeorm';
|
||||
|
||||
export class ViewRepository implements IViewRepository {
|
||||
constructor(@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>) {}
|
||||
|
||||
async getUniqueOriginalPaths(userId: string): Promise<string[]> {
|
||||
const results = await this.assetRepository
|
||||
.createQueryBuilder('asset')
|
||||
.where({
|
||||
isVisible: true,
|
||||
isArchived: false,
|
||||
ownerId: userId,
|
||||
})
|
||||
.select("DISTINCT substring(asset.originalPath FROM '^(.*/)[^/]*$')", 'directoryPath')
|
||||
.getRawMany();
|
||||
|
||||
return results.map((row: { directoryPath: string }) => row.directoryPath.replaceAll(/^\/|\/$/g, ''));
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] })
|
||||
async getAssetsByOriginalPath(userId: string, partialPath: string): Promise<AssetEntity[]> {
|
||||
const normalizedPath = partialPath.replaceAll(/^\/|\/$/g, '');
|
||||
const assets = await this.assetRepository
|
||||
.createQueryBuilder('asset')
|
||||
.where({
|
||||
isVisible: true,
|
||||
isArchived: false,
|
||||
ownerId: userId,
|
||||
})
|
||||
.leftJoinAndSelect('asset.exifInfo', 'exifInfo')
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where('asset.originalPath LIKE :likePath', { likePath: `%${normalizedPath}/%` }).andWhere(
|
||||
'asset.originalPath NOT LIKE :notLikePath',
|
||||
{ notLikePath: `%${normalizedPath}/%/%` },
|
||||
);
|
||||
}),
|
||||
)
|
||||
.orderBy(String.raw`regexp_replace(asset.originalPath, '.*/(.+)', '\1')`, 'ASC')
|
||||
.getMany();
|
||||
|
||||
return assets;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,20 @@
|
|||
import { mapAsset } from 'src/dtos/asset-response.dto';
|
||||
import { IAssetRepository } from 'src/interfaces/asset.interface';
|
||||
|
||||
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||
import { ViewService } from 'src/services/view.service';
|
||||
import { assetStub } from 'test/fixtures/asset.stub';
|
||||
import { authStub } from 'test/fixtures/auth.stub';
|
||||
import { newAssetRepositoryMock } from 'test/repositories/asset.repository.mock';
|
||||
import { newViewRepositoryMock } from 'test/repositories/view.repository.mock';
|
||||
|
||||
import { Mocked } from 'vitest';
|
||||
|
||||
describe(ViewService.name, () => {
|
||||
let sut: ViewService;
|
||||
let assetMock: Mocked<IAssetRepository>;
|
||||
let viewMock: Mocked<IViewRepository>;
|
||||
|
||||
beforeEach(() => {
|
||||
assetMock = newAssetRepositoryMock();
|
||||
viewMock = newViewRepositoryMock();
|
||||
|
||||
sut = new ViewService(assetMock);
|
||||
sut = new ViewService(viewMock);
|
||||
});
|
||||
|
||||
it('should work', () => {
|
||||
|
@ -25,12 +24,12 @@ describe(ViewService.name, () => {
|
|||
describe('getUniqueOriginalPaths', () => {
|
||||
it('should return unique original paths', async () => {
|
||||
const mockPaths = ['path1', 'path2', 'path3'];
|
||||
assetMock.getUniqueOriginalPaths.mockResolvedValue(mockPaths);
|
||||
viewMock.getUniqueOriginalPaths.mockResolvedValue(mockPaths);
|
||||
|
||||
const result = await sut.getUniqueOriginalPaths(authStub.admin);
|
||||
|
||||
expect(result).toEqual(mockPaths);
|
||||
expect(assetMock.getUniqueOriginalPaths).toHaveBeenCalledWith(authStub.admin.user.id);
|
||||
expect(viewMock.getUniqueOriginalPaths).toHaveBeenCalledWith(authStub.admin.user.id);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -45,11 +44,11 @@ describe(ViewService.name, () => {
|
|||
|
||||
const mockAssetReponseDto = mockAssets.map((a) => mapAsset(a, { auth: authStub.admin }));
|
||||
|
||||
assetMock.getAssetsByOriginalPath.mockResolvedValue(mockAssets);
|
||||
viewMock.getAssetsByOriginalPath.mockResolvedValue(mockAssets);
|
||||
|
||||
const result = await sut.getAssetsByOriginalPath(authStub.admin, path);
|
||||
expect(result).toEqual(mockAssetReponseDto);
|
||||
await expect(assetMock.getAssetsByOriginalPath(authStub.admin.user.id, path)).resolves.toEqual(mockAssets);
|
||||
await expect(viewMock.getAssetsByOriginalPath(authStub.admin.user.id, path)).resolves.toEqual(mockAssets);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import { Inject } from '@nestjs/common';
|
||||
import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { IAssetRepository } from 'src/interfaces/asset.interface';
|
||||
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||
|
||||
export class ViewService {
|
||||
constructor(@Inject(IAssetRepository) private assetRepository: IAssetRepository) {}
|
||||
constructor(@Inject(IViewRepository) private viewRepository: IViewRepository) {}
|
||||
|
||||
getUniqueOriginalPaths(auth: AuthDto): Promise<string[]> {
|
||||
return this.assetRepository.getUniqueOriginalPaths(auth.user.id);
|
||||
return this.viewRepository.getUniqueOriginalPaths(auth.user.id);
|
||||
}
|
||||
|
||||
async getAssetsByOriginalPath(auth: AuthDto, path: string): Promise<AssetResponseDto[]> {
|
||||
const assets = await this.assetRepository.getAssetsByOriginalPath(auth.user.id, path);
|
||||
|
||||
const assets = await this.viewRepository.getAssetsByOriginalPath(auth.user.id, path);
|
||||
return assets.map((asset) => mapAsset(asset, { auth }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,5 @@ export const newAssetRepositoryMock = (): Mocked<IAssetRepository> => {
|
|||
getChangedDeltaSync: vitest.fn(),
|
||||
getDuplicates: vitest.fn(),
|
||||
upsertFile: vitest.fn(),
|
||||
getAssetsByOriginalPath: vitest.fn(),
|
||||
getUniqueOriginalPaths: vitest.fn(),
|
||||
};
|
||||
};
|
||||
|
|
9
server/test/repositories/view.repository.mock.ts
Normal file
9
server/test/repositories/view.repository.mock.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||
import { Mocked, vitest } from 'vitest';
|
||||
|
||||
export const newViewRepositoryMock = (): Mocked<IViewRepository> => {
|
||||
return {
|
||||
getAssetsByOriginalPath: vitest.fn(),
|
||||
getUniqueOriginalPaths: vitest.fn(),
|
||||
};
|
||||
};
|
Loading…
Add table
Reference in a new issue