refactor(server): album count (#2746)

* refactor(server): album count

* chore: open api
This commit is contained in:
Jason Rasmussen 2023-06-16 11:48:48 -04:00 committed by GitHub
parent 441ee2ef90
commit 07f7fffae7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 100 additions and 95 deletions

View file

@ -95,9 +95,9 @@
]
}
},
"/album/count-by-user-id": {
"/album/count": {
"get": {
"operationId": "getAlbumCountByUserId",
"operationId": "getAlbumCount",
"parameters": [],
"responses": {
"200": {
@ -4530,14 +4530,14 @@
"shared": {
"type": "integer"
},
"sharing": {
"notShared": {
"type": "integer"
}
},
"required": [
"owned",
"shared",
"sharing"
"notShared"
]
},
"AlbumResponseDto": {

View file

@ -1,7 +1,7 @@
import { AlbumEntity } from '@app/infra/entities';
import { ApiProperty } from '@nestjs/swagger';
import { AssetResponseDto, mapAsset } from '../../asset';
import { mapUser, UserResponseDto } from '../../user';
import { AssetResponseDto, mapAsset } from '../asset';
import { mapUser, UserResponseDto } from '../user';
export class AlbumResponseDto {
id!: string;
@ -63,3 +63,14 @@ export function mapAlbumExcludeAssetInfo(entity: AlbumEntity): AlbumResponseDto
assetCount: entity.assets?.length || 0,
};
}
export class AlbumCountResponseDto {
@ApiProperty({ type: 'integer' })
owned!: number;
@ApiProperty({ type: 'integer' })
shared!: number;
@ApiProperty({ type: 'integer' })
notShared!: number;
}

View file

@ -35,6 +35,23 @@ describe(AlbumService.name, () => {
expect(sut).toBeDefined();
});
describe('getCount', () => {
it('should get the album count', async () => {
albumMock.getOwned.mockResolvedValue([]),
albumMock.getShared.mockResolvedValue([]),
albumMock.getNotShared.mockResolvedValue([]),
await expect(sut.getCount(authStub.admin)).resolves.toEqual({
owned: 0,
shared: 0,
notShared: 0,
});
expect(albumMock.getOwned).toHaveBeenCalledWith(authStub.admin.id);
expect(albumMock.getShared).toHaveBeenCalledWith(authStub.admin.id);
expect(albumMock.getNotShared).toHaveBeenCalledWith(authStub.admin.id);
});
});
describe('getAll', () => {
it('gets list of albums for auth user', async () => {
albumMock.getOwned.mockResolvedValue([albumStub.empty, albumStub.sharedWithUser]);

View file

@ -4,9 +4,9 @@ import { IAssetRepository, mapAsset } from '../asset';
import { AuthUserDto } from '../auth';
import { IJobRepository, JobName } from '../job';
import { IUserRepository } from '../user';
import { AlbumCountResponseDto, AlbumResponseDto, mapAlbum } from './album-response.dto';
import { IAlbumRepository } from './album.repository';
import { AddUsersDto, CreateAlbumDto, GetAlbumsDto, UpdateAlbumDto } from './dto';
import { AlbumResponseDto, mapAlbum } from './response-dto';
@Injectable()
export class AlbumService {
@ -17,6 +17,20 @@ export class AlbumService {
@Inject(IUserRepository) private userRepository: IUserRepository,
) {}
async getCount(authUser: AuthUserDto): Promise<AlbumCountResponseDto> {
const [owned, shared, notShared] = await Promise.all([
this.albumRepository.getOwned(authUser.id),
this.albumRepository.getShared(authUser.id),
this.albumRepository.getNotShared(authUser.id),
]);
return {
owned: owned.length,
shared: shared.length,
notShared: notShared.length,
};
}
async getAll({ id: ownerId }: AuthUserDto, { assetId, shared }: GetAlbumsDto): Promise<AlbumResponseDto[]> {
await this.updateInvalidThumbnails();

View file

@ -1,4 +1,4 @@
export * from './album-response.dto';
export * from './album.repository';
export * from './album.service';
export * from './dto';
export * from './response-dto';

View file

@ -1 +0,0 @@
export * from './album-response.dto';

View file

@ -5,7 +5,6 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AddAssetsDto } from './dto/add-assets.dto';
import { RemoveAssetsDto } from './dto/remove-assets.dto';
import { AlbumCountResponseDto } from './response-dto/album-count-response.dto';
import { AddAssetsResponseDto } from './response-dto/add-assets-response.dto';
export interface IAlbumRepository {
@ -13,7 +12,6 @@ export interface IAlbumRepository {
removeAssets(album: AlbumEntity, removeAssets: RemoveAssetsDto): Promise<number>;
addAssets(album: AlbumEntity, addAssetsDto: AddAssetsDto): Promise<AddAssetsResponseDto>;
updateThumbnails(): Promise<number | undefined>;
getCountByUserId(userId: string): Promise<AlbumCountResponseDto>;
getSharedWithUserAlbumCount(userId: string, assetId: string): Promise<number>;
}
@ -26,14 +24,6 @@ export class AlbumRepository implements IAlbumRepository {
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
) {}
async getCountByUserId(userId: string): Promise<AlbumCountResponseDto> {
const ownedAlbums = await this.albumRepository.find({ where: { ownerId: userId }, relations: ['sharedUsers'] });
const sharedAlbums = await this.albumRepository.count({ where: { sharedUsers: { id: userId } } });
const sharedAlbumCount = ownedAlbums.filter((album) => album.sharedUsers?.length > 0).length;
return new AlbumCountResponseDto(ownedAlbums.length, sharedAlbums, sharedAlbumCount);
}
async get(albumId: string): Promise<AlbumEntity | null> {
return this.albumRepository.findOne({
where: { id: albumId },

View file

@ -6,7 +6,6 @@ import { AddAssetsDto } from './dto/add-assets.dto';
import { RemoveAssetsDto } from './dto/remove-assets.dto';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { AlbumResponseDto } from '@app/domain';
import { AlbumCountResponseDto } from './response-dto/album-count-response.dto';
import { AddAssetsResponseDto } from './response-dto/add-assets-response.dto';
import { Response as Res } from 'express';
import { DownloadDto } from '../asset/dto/download-library.dto';
@ -22,11 +21,6 @@ import { handleDownload } from '../../app.utils';
export class AlbumController {
constructor(private readonly service: AlbumService) {}
@Get('count-by-user-id')
getAlbumCountByUserId(@GetAuthUser() authUser: AuthUserDto): Promise<AlbumCountResponseDto> {
return this.service.getCountByUserId(authUser);
}
@SharedLinkRoute()
@Put(':id/assets')
addAssetsToAlbum(

View file

@ -98,7 +98,6 @@ describe('Album service', () => {
get: jest.fn(),
removeAssets: jest.fn(),
updateThumbnails: jest.fn(),
getCountByUserId: jest.fn(),
getSharedWithUserAlbumCount: jest.fn(),
};

View file

@ -4,7 +4,6 @@ import { AlbumEntity, SharedLinkType } from '@app/infra/entities';
import { RemoveAssetsDto } from './dto/remove-assets.dto';
import { AlbumResponseDto, mapAlbum } from '@app/domain';
import { IAlbumRepository } from './album-repository';
import { AlbumCountResponseDto } from './response-dto/album-count-response.dto';
import { AddAssetsResponseDto } from './response-dto/add-assets-response.dto';
import { AddAssetsDto } from './dto/add-assets.dto';
import { DownloadService } from '../../modules/download/download.service';
@ -90,10 +89,6 @@ export class AlbumService {
};
}
async getCountByUserId(authUser: AuthUserDto): Promise<AlbumCountResponseDto> {
return this.albumRepository.getCountByUserId(authUser.id);
}
async downloadArchive(authUser: AuthUserDto, albumId: string, dto: DownloadDto) {
this.shareCore.checkDownloadAccess(authUser);

View file

@ -1,18 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class AlbumCountResponseDto {
@ApiProperty({ type: 'integer' })
owned!: number;
@ApiProperty({ type: 'integer' })
shared!: number;
@ApiProperty({ type: 'integer' })
sharing!: number;
constructor(owned: number, shared: number, sharing: number) {
this.owned = owned;
this.shared = shared;
this.sharing = sharing;
}
}

View file

@ -1,4 +1,11 @@
import { AddUsersDto, AlbumService, AuthUserDto, CreateAlbumDto, UpdateAlbumDto } from '@app/domain';
import {
AddUsersDto,
AlbumCountResponseDto,
AlbumService,
AuthUserDto,
CreateAlbumDto,
UpdateAlbumDto,
} from '@app/domain';
import { GetAlbumsDto } from '@app/domain/album/dto/get-albums.dto';
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
@ -15,6 +22,11 @@ import { UUIDParamDto } from './dto/uuid-param.dto';
export class AlbumController {
constructor(private service: AlbumService) {}
@Get('count')
getAlbumCount(@GetAuthUser() authUser: AuthUserDto): Promise<AlbumCountResponseDto> {
return this.service.getCount(authUser);
}
@Get()
getAllAlbums(@GetAuthUser() authUser: AuthUserDto, @Query() query: GetAlbumsDto) {
return this.service.getAll(authUser, query);