2023-05-25 21:37:19 +02:00
|
|
|
import { BadRequestException, ForbiddenException } from '@nestjs/common';
|
2023-05-25 04:10:45 +02:00
|
|
|
import { albumStub, authStub, newAlbumRepositoryMock, newAssetRepositoryMock, newJobRepositoryMock } from '../../test';
|
2023-03-26 04:46:48 +02:00
|
|
|
import { IAssetRepository } from '../asset';
|
2023-05-25 04:10:45 +02:00
|
|
|
import { IJobRepository, JobName } from '../job';
|
2023-03-26 04:46:48 +02:00
|
|
|
import { IAlbumRepository } from './album.repository';
|
|
|
|
import { AlbumService } from './album.service';
|
|
|
|
|
|
|
|
describe(AlbumService.name, () => {
|
|
|
|
let sut: AlbumService;
|
|
|
|
let albumMock: jest.Mocked<IAlbumRepository>;
|
|
|
|
let assetMock: jest.Mocked<IAssetRepository>;
|
2023-05-25 04:10:45 +02:00
|
|
|
let jobMock: jest.Mocked<IJobRepository>;
|
2023-03-26 04:46:48 +02:00
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
albumMock = newAlbumRepositoryMock();
|
|
|
|
assetMock = newAssetRepositoryMock();
|
2023-05-25 04:10:45 +02:00
|
|
|
jobMock = newJobRepositoryMock();
|
2023-03-26 04:46:48 +02:00
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
sut = new AlbumService(albumMock, assetMock, jobMock);
|
2023-03-26 04:46:48 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should work', () => {
|
|
|
|
expect(sut).toBeDefined();
|
|
|
|
});
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
describe('getAll', () => {
|
2023-03-26 04:46:48 +02:00
|
|
|
it('gets list of albums for auth user', async () => {
|
|
|
|
albumMock.getOwned.mockResolvedValue([albumStub.empty, albumStub.sharedWithUser]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([
|
|
|
|
{ albumId: albumStub.empty.id, assetCount: 0 },
|
|
|
|
{ albumId: albumStub.sharedWithUser.id, assetCount: 0 },
|
|
|
|
]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, {});
|
2023-03-26 04:46:48 +02:00
|
|
|
expect(result).toHaveLength(2);
|
|
|
|
expect(result[0].id).toEqual(albumStub.empty.id);
|
|
|
|
expect(result[1].id).toEqual(albumStub.sharedWithUser.id);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets list of albums that have a specific asset', async () => {
|
|
|
|
albumMock.getByAssetId.mockResolvedValue([albumStub.oneAsset]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([{ albumId: albumStub.oneAsset.id, assetCount: 1 }]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, { assetId: albumStub.oneAsset.id });
|
2023-03-26 04:46:48 +02:00
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(result[0].id).toEqual(albumStub.oneAsset.id);
|
|
|
|
expect(albumMock.getByAssetId).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets list of albums that are shared', async () => {
|
|
|
|
albumMock.getShared.mockResolvedValue([albumStub.sharedWithUser]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([{ albumId: albumStub.sharedWithUser.id, assetCount: 0 }]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, { shared: true });
|
2023-03-26 04:46:48 +02:00
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(result[0].id).toEqual(albumStub.sharedWithUser.id);
|
|
|
|
expect(albumMock.getShared).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('gets list of albums that are NOT shared', async () => {
|
|
|
|
albumMock.getNotShared.mockResolvedValue([albumStub.empty]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([{ albumId: albumStub.empty.id, assetCount: 0 }]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, { shared: false });
|
2023-03-26 04:46:48 +02:00
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(result[0].id).toEqual(albumStub.empty.id);
|
|
|
|
expect(albumMock.getNotShared).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('counts assets correctly', async () => {
|
|
|
|
albumMock.getOwned.mockResolvedValue([albumStub.oneAsset]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([{ albumId: albumStub.oneAsset.id, assetCount: 1 }]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, {});
|
2023-03-26 04:46:48 +02:00
|
|
|
|
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(result[0].assetCount).toEqual(1);
|
|
|
|
expect(albumMock.getOwned).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('updates the album thumbnail by listing all albums', async () => {
|
|
|
|
albumMock.getOwned.mockResolvedValue([albumStub.oneAssetInvalidThumbnail]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([
|
|
|
|
{ albumId: albumStub.oneAssetInvalidThumbnail.id, assetCount: 1 },
|
|
|
|
]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([albumStub.oneAssetInvalidThumbnail.id]);
|
2023-05-25 21:37:19 +02:00
|
|
|
albumMock.update.mockResolvedValue(albumStub.oneAssetValidThumbnail);
|
2023-03-26 04:46:48 +02:00
|
|
|
assetMock.getFirstAssetForAlbumId.mockResolvedValue(albumStub.oneAssetInvalidThumbnail.assets[0]);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, {});
|
2023-03-26 04:46:48 +02:00
|
|
|
|
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(albumMock.getInvalidThumbnail).toHaveBeenCalledTimes(1);
|
2023-05-25 21:37:19 +02:00
|
|
|
expect(albumMock.update).toHaveBeenCalledTimes(1);
|
2023-03-26 04:46:48 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
it('removes the thumbnail for an empty album', async () => {
|
|
|
|
albumMock.getOwned.mockResolvedValue([albumStub.emptyWithInvalidThumbnail]);
|
|
|
|
albumMock.getAssetCountForIds.mockResolvedValue([
|
|
|
|
{ albumId: albumStub.emptyWithInvalidThumbnail.id, assetCount: 1 },
|
|
|
|
]);
|
|
|
|
albumMock.getInvalidThumbnail.mockResolvedValue([albumStub.emptyWithInvalidThumbnail.id]);
|
2023-05-25 21:37:19 +02:00
|
|
|
albumMock.update.mockResolvedValue(albumStub.emptyWithValidThumbnail);
|
2023-03-26 04:46:48 +02:00
|
|
|
assetMock.getFirstAssetForAlbumId.mockResolvedValue(null);
|
|
|
|
|
2023-05-25 04:10:45 +02:00
|
|
|
const result = await sut.getAll(authStub.admin, {});
|
2023-03-26 04:46:48 +02:00
|
|
|
|
|
|
|
expect(result).toHaveLength(1);
|
|
|
|
expect(albumMock.getInvalidThumbnail).toHaveBeenCalledTimes(1);
|
2023-05-25 21:37:19 +02:00
|
|
|
expect(albumMock.update).toHaveBeenCalledTimes(1);
|
2023-03-26 04:46:48 +02:00
|
|
|
});
|
2023-05-25 04:10:45 +02:00
|
|
|
|
|
|
|
describe('create', () => {
|
|
|
|
it('creates album', async () => {
|
|
|
|
albumMock.create.mockResolvedValue(albumStub.empty);
|
|
|
|
|
|
|
|
await expect(sut.create(authStub.admin, { albumName: 'Empty album' })).resolves.toEqual({
|
|
|
|
albumName: 'Empty album',
|
|
|
|
albumThumbnailAssetId: null,
|
|
|
|
assetCount: 0,
|
|
|
|
assets: [],
|
|
|
|
createdAt: expect.anything(),
|
|
|
|
id: 'album-1',
|
|
|
|
owner: {
|
|
|
|
createdAt: '2021-01-01',
|
|
|
|
email: 'admin@test.com',
|
|
|
|
firstName: 'admin_first_name',
|
|
|
|
id: 'admin_id',
|
|
|
|
isAdmin: true,
|
|
|
|
lastName: 'admin_last_name',
|
|
|
|
oauthId: '',
|
|
|
|
profileImagePath: '',
|
|
|
|
shouldChangePassword: false,
|
|
|
|
storageLabel: 'admin',
|
|
|
|
updatedAt: '2021-01-01',
|
|
|
|
},
|
|
|
|
ownerId: 'admin_id',
|
|
|
|
shared: false,
|
|
|
|
sharedUsers: [],
|
|
|
|
updatedAt: expect.anything(),
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(jobMock.queue).toHaveBeenCalledWith({
|
|
|
|
name: JobName.SEARCH_INDEX_ALBUM,
|
|
|
|
data: { ids: [albumStub.empty.id] },
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2023-05-25 21:37:19 +02:00
|
|
|
|
|
|
|
describe('update', () => {
|
|
|
|
it('should prevent updating an album that does not exist', async () => {
|
|
|
|
albumMock.getByIds.mockResolvedValue([]);
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
sut.update(authStub.user1, 'invalid-id', {
|
|
|
|
albumName: 'new album name',
|
|
|
|
}),
|
|
|
|
).rejects.toBeInstanceOf(BadRequestException);
|
|
|
|
|
|
|
|
expect(albumMock.update).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should prevent updating a not owned album (shared with auth user)', async () => {
|
|
|
|
albumMock.getByIds.mockResolvedValue([albumStub.sharedWithAdmin]);
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
sut.update(authStub.admin, albumStub.sharedWithAdmin.id, {
|
|
|
|
albumName: 'new album name',
|
|
|
|
}),
|
|
|
|
).rejects.toBeInstanceOf(ForbiddenException);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should all the owner to update the album', async () => {
|
|
|
|
albumMock.getByIds.mockResolvedValue([albumStub.oneAsset]);
|
|
|
|
albumMock.update.mockResolvedValue(albumStub.oneAsset);
|
|
|
|
|
|
|
|
await sut.update(authStub.admin, albumStub.oneAsset.id, {
|
|
|
|
albumName: 'new album name',
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(albumMock.update).toHaveBeenCalledTimes(1);
|
|
|
|
expect(albumMock.update).toHaveBeenCalledWith({
|
|
|
|
id: 'album-4',
|
|
|
|
albumName: 'new album name',
|
|
|
|
});
|
|
|
|
expect(jobMock.queue).toHaveBeenCalledWith({
|
|
|
|
name: JobName.SEARCH_INDEX_ALBUM,
|
|
|
|
data: { ids: [albumStub.oneAsset.id] },
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2023-03-26 04:46:48 +02:00
|
|
|
});
|