mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
fix: activity types (#15368)
This commit is contained in:
parent
0ce62d8efd
commit
6ce1533117
@ -20,14 +20,14 @@ import { ErrorInterceptor } from 'src/middleware/error.interceptor';
|
|||||||
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
||||||
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
|
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
|
||||||
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
|
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
|
||||||
import { repositories } from 'src/repositories';
|
import { providers, repositories } from 'src/repositories';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { teardownTelemetry } from 'src/repositories/telemetry.repository';
|
import { teardownTelemetry } from 'src/repositories/telemetry.repository';
|
||||||
import { services } from 'src/services';
|
import { services } from 'src/services';
|
||||||
import { CliService } from 'src/services/cli.service';
|
import { CliService } from 'src/services/cli.service';
|
||||||
import { DatabaseService } from 'src/services/database.service';
|
import { DatabaseService } from 'src/services/database.service';
|
||||||
|
|
||||||
const common = [...services, ...repositories];
|
const common = [...services, ...providers, ...repositories];
|
||||||
|
|
||||||
const middleware = [
|
const middleware = [
|
||||||
FileUploadInterceptor,
|
FileUploadInterceptor,
|
||||||
@ -73,7 +73,7 @@ class BaseModule implements OnModuleInit, OnModuleDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
this.telemetryRepository.setup({ repositories: repositories.map(({ useClass }) => useClass) });
|
this.telemetryRepository.setup({ repositories: [...providers.map(({ useClass }) => useClass), ...repositories] });
|
||||||
|
|
||||||
this.jobRepository.setup({ services });
|
this.jobRepository.setup({ services });
|
||||||
if (this.worker === ImmichWorker.MICROSERVICES) {
|
if (this.worker === ImmichWorker.MICROSERVICES) {
|
||||||
|
@ -12,7 +12,7 @@ import { format } from 'sql-formatter';
|
|||||||
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
||||||
import { entities } from 'src/entities';
|
import { entities } from 'src/entities';
|
||||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||||
import { repositories } from 'src/repositories';
|
import { providers, repositories } from 'src/repositories';
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { AuthService } from 'src/services/auth.service';
|
import { AuthService } from 'src/services/auth.service';
|
||||||
@ -43,7 +43,7 @@ export class SqlLogger implements Logger {
|
|||||||
|
|
||||||
const reflector = new Reflector();
|
const reflector = new Reflector();
|
||||||
|
|
||||||
type Repository = (typeof repositories)[0]['useClass'];
|
type Repository = (typeof providers)[0]['useClass'];
|
||||||
type Provider = { provide: any; useClass: Repository };
|
type Provider = { provide: any; useClass: Repository };
|
||||||
type SqlGeneratorOptions = { targetDir: string };
|
type SqlGeneratorOptions = { targetDir: string };
|
||||||
|
|
||||||
@ -57,7 +57,11 @@ class SqlGenerator {
|
|||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
await this.setup();
|
await this.setup();
|
||||||
for (const repository of repositories) {
|
const targets = [
|
||||||
|
...providers,
|
||||||
|
...repositories.map((repository) => ({ provide: repository, useClass: repository as any })),
|
||||||
|
];
|
||||||
|
for (const repository of targets) {
|
||||||
if (repository.provide === ILoggerRepository) {
|
if (repository.provide === ILoggerRepository) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -99,7 +103,7 @@ class SqlGenerator {
|
|||||||
TypeOrmModule.forFeature(entities),
|
TypeOrmModule.forFeature(entities),
|
||||||
OpenTelemetryModule.forRoot(otel),
|
OpenTelemetryModule.forRoot(otel),
|
||||||
],
|
],
|
||||||
providers: [...repositories, AuthService, SchedulerRegistry],
|
providers: [...providers, ...repositories, AuthService, SchedulerRegistry],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
this.app = await moduleFixture.createNestApplication().init();
|
this.app = await moduleFixture.createNestApplication().init();
|
||||||
|
3
server/src/database.ts
Normal file
3
server/src/database.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const columns = {
|
||||||
|
userDto: ['id', 'name', 'email', 'profileImagePath', 'profileChangedAt'],
|
||||||
|
} as const;
|
@ -1,7 +1,8 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNotEmpty, IsString, ValidateIf } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString, ValidateIf } from 'class-validator';
|
||||||
import { UserResponseDto, mapUser } from 'src/dtos/user.dto';
|
import { mapUser, UserResponseDto } from 'src/dtos/user.dto';
|
||||||
import { ActivityEntity } from 'src/entities/activity.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
|
import { ActivityItem } from 'src/types';
|
||||||
import { Optional, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export enum ReactionType {
|
export enum ReactionType {
|
||||||
@ -67,13 +68,13 @@ export class ActivityCreateDto extends ActivityDto {
|
|||||||
comment?: string;
|
comment?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapActivity(activity: ActivityEntity): ActivityResponseDto {
|
export const mapActivity = (activity: ActivityItem): ActivityResponseDto => {
|
||||||
return {
|
return {
|
||||||
id: activity.id,
|
id: activity.id,
|
||||||
assetId: activity.assetId,
|
assetId: activity.assetId,
|
||||||
createdAt: activity.createdAt,
|
createdAt: activity.createdAt,
|
||||||
comment: activity.comment,
|
comment: activity.comment,
|
||||||
type: activity.isLiked ? ReactionType.LIKE : ReactionType.COMMENT,
|
type: activity.isLiked ? ReactionType.LIKE : ReactionType.COMMENT,
|
||||||
user: mapUser(activity.user),
|
user: mapUser(activity.user as unknown as UserEntity),
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { Insertable } from 'kysely';
|
|
||||||
import { Activity } from 'src/db';
|
|
||||||
import { ActivityEntity } from 'src/entities/activity.entity';
|
|
||||||
import { ActivitySearch } from 'src/repositories/activity.repository';
|
|
||||||
|
|
||||||
export const IActivityRepository = 'IActivityRepository';
|
|
||||||
|
|
||||||
export interface IActivityRepository {
|
|
||||||
search(options: ActivitySearch): Promise<ActivityEntity[]>;
|
|
||||||
create(activity: Insertable<Activity>): Promise<ActivityEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
getStatistics(options: { albumId: string; assetId?: string }): Promise<number>;
|
|
||||||
}
|
|
@ -9,7 +9,11 @@ select
|
|||||||
from
|
from
|
||||||
(
|
(
|
||||||
select
|
select
|
||||||
*
|
"id",
|
||||||
|
"name",
|
||||||
|
"email",
|
||||||
|
"profileImagePath",
|
||||||
|
"profileChangedAt"
|
||||||
from
|
from
|
||||||
"users"
|
"users"
|
||||||
where
|
where
|
||||||
|
@ -2,10 +2,9 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { ExpressionBuilder, Insertable, Kysely } from 'kysely';
|
import { ExpressionBuilder, Insertable, Kysely } from 'kysely';
|
||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
|
import { columns } from 'src/database';
|
||||||
import { Activity, DB } from 'src/db';
|
import { Activity, DB } from 'src/db';
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { ActivityEntity } from 'src/entities/activity.entity';
|
|
||||||
import { IActivityRepository } from 'src/interfaces/activity.interface';
|
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
export interface ActivitySearch {
|
export interface ActivitySearch {
|
||||||
@ -19,18 +18,18 @@ const withUser = (eb: ExpressionBuilder<DB, 'activity'>) => {
|
|||||||
return jsonObjectFrom(
|
return jsonObjectFrom(
|
||||||
eb
|
eb
|
||||||
.selectFrom('users')
|
.selectFrom('users')
|
||||||
.selectAll()
|
.select(columns.userDto)
|
||||||
.whereRef('users.id', '=', 'activity.userId')
|
.whereRef('users.id', '=', 'activity.userId')
|
||||||
.where('users.deletedAt', 'is', null),
|
.where('users.deletedAt', 'is', null),
|
||||||
).as('user');
|
).as('user');
|
||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ActivityRepository implements IActivityRepository {
|
export class ActivityRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ albumId: DummyValue.UUID }] })
|
@GenerateSql({ params: [{ albumId: DummyValue.UUID }] })
|
||||||
search(options: ActivitySearch): Promise<ActivityEntity[]> {
|
search(options: ActivitySearch) {
|
||||||
const { userId, assetId, albumId, isLiked } = options;
|
const { userId, assetId, albumId, isLiked } = options;
|
||||||
|
|
||||||
return this.db
|
return this.db
|
||||||
@ -44,14 +43,14 @@ export class ActivityRepository implements IActivityRepository {
|
|||||||
.$if(!!albumId, (qb) => qb.where('activity.albumId', '=', albumId!))
|
.$if(!!albumId, (qb) => qb.where('activity.albumId', '=', albumId!))
|
||||||
.$if(isLiked !== undefined, (qb) => qb.where('activity.isLiked', '=', isLiked!))
|
.$if(isLiked !== undefined, (qb) => qb.where('activity.isLiked', '=', isLiked!))
|
||||||
.orderBy('activity.createdAt', 'asc')
|
.orderBy('activity.createdAt', 'asc')
|
||||||
.execute() as unknown as Promise<ActivityEntity[]>;
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(activity: Insertable<Activity>) {
|
async create(activity: Insertable<Activity>) {
|
||||||
return this.save(activity);
|
return this.save(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(id: string): Promise<void> {
|
async delete(id: string) {
|
||||||
await this.db.deleteFrom('activity').where('id', '=', asUuid(id)).execute();
|
await this.db.deleteFrom('activity').where('id', '=', asUuid(id)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +78,6 @@ export class ActivityRepository implements IActivityRepository {
|
|||||||
.selectAll('activity')
|
.selectAll('activity')
|
||||||
.select(withUser)
|
.select(withUser)
|
||||||
.where('activity.id', '=', asUuid(id))
|
.where('activity.id', '=', asUuid(id))
|
||||||
.executeTakeFirstOrThrow() as unknown as Promise<ActivityEntity>;
|
.executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { IAccessRepository } from 'src/interfaces/access.interface';
|
import { IAccessRepository } from 'src/interfaces/access.interface';
|
||||||
import { IActivityRepository } from 'src/interfaces/activity.interface';
|
|
||||||
import { IAlbumUserRepository } from 'src/interfaces/album-user.interface';
|
import { IAlbumUserRepository } from 'src/interfaces/album-user.interface';
|
||||||
import { IAlbumRepository } from 'src/interfaces/album.interface';
|
import { IAlbumRepository } from 'src/interfaces/album.interface';
|
||||||
import { IKeyRepository } from 'src/interfaces/api-key.interface';
|
import { IKeyRepository } from 'src/interfaces/api-key.interface';
|
||||||
@ -78,8 +77,12 @@ import { VersionHistoryRepository } from 'src/repositories/version-history.repos
|
|||||||
import { ViewRepository } from 'src/repositories/view-repository';
|
import { ViewRepository } from 'src/repositories/view-repository';
|
||||||
|
|
||||||
export const repositories = [
|
export const repositories = [
|
||||||
|
//
|
||||||
|
ActivityRepository,
|
||||||
|
];
|
||||||
|
|
||||||
|
export const providers = [
|
||||||
{ provide: IAccessRepository, useClass: AccessRepository },
|
{ provide: IAccessRepository, useClass: AccessRepository },
|
||||||
{ provide: IActivityRepository, useClass: ActivityRepository },
|
|
||||||
{ provide: IAlbumRepository, useClass: AlbumRepository },
|
{ provide: IAlbumRepository, useClass: AlbumRepository },
|
||||||
{ provide: IAlbumUserRepository, useClass: AlbumUserRepository },
|
{ provide: IAlbumUserRepository, useClass: AlbumUserRepository },
|
||||||
{ provide: IAssetRepository, useClass: AssetRepository },
|
{ provide: IAssetRepository, useClass: AssetRepository },
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
import { ReactionType } from 'src/dtos/activity.dto';
|
import { ReactionType } from 'src/dtos/activity.dto';
|
||||||
import { IActivityRepository } from 'src/interfaces/activity.interface';
|
|
||||||
import { ActivityService } from 'src/services/activity.service';
|
import { ActivityService } from 'src/services/activity.service';
|
||||||
|
import { IActivityRepository } from 'src/types';
|
||||||
import { activityStub } from 'test/fixtures/activity.stub';
|
import { activityStub } from 'test/fixtures/activity.stub';
|
||||||
import { authStub } from 'test/fixtures/auth.stub';
|
import { authStub } from 'test/fixtures/auth.stub';
|
||||||
import { IAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
import { IAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
||||||
|
@ -5,15 +5,15 @@ import {
|
|||||||
ActivityResponseDto,
|
ActivityResponseDto,
|
||||||
ActivitySearchDto,
|
ActivitySearchDto,
|
||||||
ActivityStatisticsResponseDto,
|
ActivityStatisticsResponseDto,
|
||||||
|
mapActivity,
|
||||||
MaybeDuplicate,
|
MaybeDuplicate,
|
||||||
ReactionLevel,
|
ReactionLevel,
|
||||||
ReactionType,
|
ReactionType,
|
||||||
mapActivity,
|
|
||||||
} from 'src/dtos/activity.dto';
|
} from 'src/dtos/activity.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ActivityEntity } from 'src/entities/activity.entity';
|
|
||||||
import { Permission } from 'src/enum';
|
import { Permission } from 'src/enum';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
|
import { ActivityItem } from 'src/types';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ActivityService extends BaseService {
|
export class ActivityService extends BaseService {
|
||||||
@ -43,7 +43,7 @@ export class ActivityService extends BaseService {
|
|||||||
albumId: dto.albumId,
|
albumId: dto.albumId,
|
||||||
};
|
};
|
||||||
|
|
||||||
let activity: ActivityEntity | null = null;
|
let activity: ActivityItem | undefined;
|
||||||
let duplicate = false;
|
let duplicate = false;
|
||||||
|
|
||||||
if (dto.type === ReactionType.LIKE) {
|
if (dto.type === ReactionType.LIKE) {
|
||||||
|
@ -7,7 +7,6 @@ import { StorageCore } from 'src/cores/storage.core';
|
|||||||
import { Users } from 'src/db';
|
import { Users } from 'src/db';
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { IAccessRepository } from 'src/interfaces/access.interface';
|
import { IAccessRepository } from 'src/interfaces/access.interface';
|
||||||
import { IActivityRepository } from 'src/interfaces/activity.interface';
|
|
||||||
import { IAlbumUserRepository } from 'src/interfaces/album-user.interface';
|
import { IAlbumUserRepository } from 'src/interfaces/album-user.interface';
|
||||||
import { IAlbumRepository } from 'src/interfaces/album.interface';
|
import { IAlbumRepository } from 'src/interfaces/album.interface';
|
||||||
import { IKeyRepository } from 'src/interfaces/api-key.interface';
|
import { IKeyRepository } from 'src/interfaces/api-key.interface';
|
||||||
@ -45,6 +44,7 @@ import { ITrashRepository } from 'src/interfaces/trash.interface';
|
|||||||
import { IUserRepository } from 'src/interfaces/user.interface';
|
import { IUserRepository } from 'src/interfaces/user.interface';
|
||||||
import { IVersionHistoryRepository } from 'src/interfaces/version-history.interface';
|
import { IVersionHistoryRepository } from 'src/interfaces/version-history.interface';
|
||||||
import { IViewRepository } from 'src/interfaces/view.interface';
|
import { IViewRepository } from 'src/interfaces/view.interface';
|
||||||
|
import { ActivityRepository } from 'src/repositories/activity.repository';
|
||||||
import { AccessRequest, checkAccess, requireAccess } from 'src/utils/access';
|
import { AccessRequest, checkAccess, requireAccess } from 'src/utils/access';
|
||||||
import { getConfig, updateConfig } from 'src/utils/config';
|
import { getConfig, updateConfig } from 'src/utils/config';
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ export class BaseService {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(ILoggerRepository) protected logger: ILoggerRepository,
|
@Inject(ILoggerRepository) protected logger: ILoggerRepository,
|
||||||
@Inject(IAccessRepository) protected accessRepository: IAccessRepository,
|
@Inject(IAccessRepository) protected accessRepository: IAccessRepository,
|
||||||
@Inject(IActivityRepository) protected activityRepository: IActivityRepository,
|
protected activityRepository: ActivityRepository,
|
||||||
@Inject(IAuditRepository) protected auditRepository: IAuditRepository,
|
@Inject(IAuditRepository) protected auditRepository: IAuditRepository,
|
||||||
@Inject(IAlbumRepository) protected albumRepository: IAlbumRepository,
|
@Inject(IAlbumRepository) protected albumRepository: IAlbumRepository,
|
||||||
@Inject(IAlbumUserRepository) protected albumUserRepository: IAlbumUserRepository,
|
@Inject(IAlbumUserRepository) protected albumUserRepository: IAlbumUserRepository,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { Permission } from 'src/enum';
|
import { Permission } from 'src/enum';
|
||||||
|
import { ActivityRepository } from 'src/repositories/activity.repository';
|
||||||
|
|
||||||
export type AuthApiKey = {
|
export type AuthApiKey = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -7,3 +8,11 @@ export type AuthApiKey = {
|
|||||||
user: UserEntity;
|
user: UserEntity;
|
||||||
permissions: Permission[];
|
permissions: Permission[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RepositoryInterface<T extends object> = Pick<T, keyof T>;
|
||||||
|
|
||||||
|
export type IActivityRepository = RepositoryInterface<ActivityRepository>;
|
||||||
|
|
||||||
|
export type ActivityItem =
|
||||||
|
| Awaited<ReturnType<IActivityRepository['create']>>
|
||||||
|
| Awaited<ReturnType<IActivityRepository['search']>>[0];
|
||||||
|
32
server/test/fixtures/activity.stub.ts
vendored
32
server/test/fixtures/activity.stub.ts
vendored
@ -1,33 +1,39 @@
|
|||||||
import { ActivityEntity } from 'src/entities/activity.entity';
|
import { ActivityItem } from 'src/types';
|
||||||
import { albumStub } from 'test/fixtures/album.stub';
|
import { albumStub } from 'test/fixtures/album.stub';
|
||||||
import { assetStub } from 'test/fixtures/asset.stub';
|
import { assetStub } from 'test/fixtures/asset.stub';
|
||||||
import { authStub } from 'test/fixtures/auth.stub';
|
|
||||||
import { userStub } from 'test/fixtures/user.stub';
|
|
||||||
|
|
||||||
export const activityStub = {
|
export const activityStub = {
|
||||||
oneComment: Object.freeze<ActivityEntity>({
|
oneComment: Object.freeze<ActivityItem>({
|
||||||
id: 'activity-1',
|
id: 'activity-1',
|
||||||
comment: 'comment',
|
comment: 'comment',
|
||||||
isLiked: false,
|
isLiked: false,
|
||||||
userId: authStub.admin.user.id,
|
userId: 'admin_id',
|
||||||
user: userStub.admin,
|
user: {
|
||||||
|
id: 'admin_id',
|
||||||
|
name: 'admin',
|
||||||
|
email: 'admin@test.com',
|
||||||
|
profileImagePath: '',
|
||||||
|
profileChangedAt: new Date('2021-01-01'),
|
||||||
|
},
|
||||||
assetId: assetStub.image.id,
|
assetId: assetStub.image.id,
|
||||||
asset: assetStub.image,
|
|
||||||
albumId: albumStub.oneAsset.id,
|
albumId: albumStub.oneAsset.id,
|
||||||
album: albumStub.oneAsset,
|
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
}),
|
}),
|
||||||
liked: Object.freeze<ActivityEntity>({
|
liked: Object.freeze<ActivityItem>({
|
||||||
id: 'activity-2',
|
id: 'activity-2',
|
||||||
comment: null,
|
comment: null,
|
||||||
isLiked: true,
|
isLiked: true,
|
||||||
userId: authStub.admin.user.id,
|
userId: 'admin_id',
|
||||||
user: userStub.admin,
|
user: {
|
||||||
|
id: 'admin_id',
|
||||||
|
name: 'admin',
|
||||||
|
email: 'admin@test.com',
|
||||||
|
profileImagePath: '',
|
||||||
|
profileChangedAt: new Date('2021-01-01'),
|
||||||
|
},
|
||||||
assetId: assetStub.image.id,
|
assetId: assetStub.image.id,
|
||||||
asset: assetStub.image,
|
|
||||||
albumId: albumStub.oneAsset.id,
|
albumId: albumStub.oneAsset.id,
|
||||||
album: albumStub.oneAsset,
|
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
}),
|
}),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IActivityRepository } from 'src/interfaces/activity.interface';
|
import { IActivityRepository } from 'src/types';
|
||||||
import { Mocked, vitest } from 'vitest';
|
import { Mocked, vitest } from 'vitest';
|
||||||
|
|
||||||
export const newActivityRepositoryMock = (): Mocked<IActivityRepository> => {
|
export const newActivityRepositoryMock = (): Mocked<IActivityRepository> => {
|
||||||
|
@ -3,7 +3,9 @@ import { Writable } from 'node:stream';
|
|||||||
import { PNG } from 'pngjs';
|
import { PNG } from 'pngjs';
|
||||||
import { ImmichWorker } from 'src/enum';
|
import { ImmichWorker } from 'src/enum';
|
||||||
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
|
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
|
||||||
|
import { ActivityRepository } from 'src/repositories/activity.repository';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
|
import { IActivityRepository } from 'src/types';
|
||||||
import { newAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
import { newAccessRepositoryMock } from 'test/repositories/access.repository.mock';
|
||||||
import { newActivityRepositoryMock } from 'test/repositories/activity.repository.mock';
|
import { newActivityRepositoryMock } from 'test/repositories/activity.repository.mock';
|
||||||
import { newAlbumUserRepositoryMock } from 'test/repositories/album-user.repository.mock';
|
import { newAlbumUserRepositoryMock } from 'test/repositories/album-user.repository.mock';
|
||||||
@ -104,7 +106,7 @@ export const newTestService = <T extends BaseService>(
|
|||||||
const sut = new Service(
|
const sut = new Service(
|
||||||
loggerMock,
|
loggerMock,
|
||||||
accessMock,
|
accessMock,
|
||||||
activityMock,
|
activityMock as IActivityRepository as ActivityRepository,
|
||||||
auditMock,
|
auditMock,
|
||||||
albumMock,
|
albumMock,
|
||||||
albumUserMock,
|
albumUserMock,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user