mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
160 lines
6.4 KiB
TypeScript
160 lines
6.4 KiB
TypeScript
import { BadRequestException } from '@nestjs/common';
|
|
import { Kysely } from 'kysely';
|
|
import { AssetVisibility } from 'src/enum';
|
|
import { AccessRepository } from 'src/repositories/access.repository';
|
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
|
import { DB } from 'src/schema';
|
|
import { TimelineService } from 'src/services/timeline.service';
|
|
import { newMediumService } from 'test/medium.factory';
|
|
import { factory } from 'test/small.factory';
|
|
import { getKyselyDB } from 'test/utils';
|
|
|
|
let defaultDatabase: Kysely<DB>;
|
|
|
|
const setup = (db?: Kysely<DB>) => {
|
|
return newMediumService(TimelineService, {
|
|
database: db || defaultDatabase,
|
|
real: [AssetRepository, AccessRepository],
|
|
mock: [LoggingRepository],
|
|
});
|
|
};
|
|
|
|
beforeAll(async () => {
|
|
defaultDatabase = await getKyselyDB();
|
|
});
|
|
|
|
describe(TimelineService.name, () => {
|
|
describe('getTimeBuckets', () => {
|
|
it('should get time buckets by month', async () => {
|
|
const { sut, ctx } = setup();
|
|
const { user } = await ctx.newUser();
|
|
const auth = factory.auth({ user });
|
|
const dates = [new Date('1970-01-01'), new Date('1970-02-10'), new Date('1970-02-11'), new Date('1970-02-11')];
|
|
for (const localDateTime of dates) {
|
|
const { asset } = await ctx.newAsset({ ownerId: user.id, localDateTime });
|
|
await ctx.newExif({ assetId: asset.id, make: 'Canon' });
|
|
}
|
|
|
|
const response = sut.getTimeBuckets(auth, {});
|
|
await expect(response).resolves.toEqual([
|
|
{ count: 3, timeBucket: '1970-02-01' },
|
|
{ count: 1, timeBucket: '1970-01-01' },
|
|
]);
|
|
});
|
|
|
|
it('should return error if time bucket is requested with partners asset and archived', async () => {
|
|
const { sut } = setup();
|
|
const auth = factory.auth();
|
|
const response1 = sut.getTimeBuckets(auth, { withPartners: true, visibility: AssetVisibility.ARCHIVE });
|
|
await expect(response1).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response1).rejects.toThrow(
|
|
'withPartners is only supported for non-archived, non-trashed, non-favorited assets',
|
|
);
|
|
|
|
const response2 = sut.getTimeBuckets(auth, { withPartners: true });
|
|
await expect(response2).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response2).rejects.toThrow(
|
|
'withPartners is only supported for non-archived, non-trashed, non-favorited assets',
|
|
);
|
|
});
|
|
|
|
it('should return error if time bucket is requested with partners asset and favorite', async () => {
|
|
const { sut } = setup();
|
|
const auth = factory.auth();
|
|
const response1 = sut.getTimeBuckets(auth, { withPartners: true, isFavorite: false });
|
|
await expect(response1).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response1).rejects.toThrow(
|
|
'withPartners is only supported for non-archived, non-trashed, non-favorited assets',
|
|
);
|
|
|
|
const response2 = sut.getTimeBuckets(auth, { withPartners: true, isFavorite: true });
|
|
await expect(response2).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response2).rejects.toThrow(
|
|
'withPartners is only supported for non-archived, non-trashed, non-favorited assets',
|
|
);
|
|
});
|
|
|
|
it('should return error if time bucket is requested with partners asset and trash', async () => {
|
|
const { sut } = setup();
|
|
const auth = factory.auth();
|
|
const response = sut.getTimeBuckets(auth, { withPartners: true, isTrashed: true });
|
|
await expect(response).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response).rejects.toThrow(
|
|
'withPartners is only supported for non-archived, non-trashed, non-favorited assets',
|
|
);
|
|
});
|
|
|
|
it('should not allow access for unrelated shared links', async () => {
|
|
const { sut } = setup();
|
|
const auth = factory.auth({ sharedLink: {} });
|
|
const response = sut.getTimeBuckets(auth, {});
|
|
await expect(response).rejects.toBeInstanceOf(BadRequestException);
|
|
await expect(response).rejects.toThrow('Not found or no timeline.read access');
|
|
});
|
|
});
|
|
|
|
describe('getTimeBucket', () => {
|
|
it('should return time bucket', async () => {
|
|
const { sut, ctx } = setup();
|
|
const { user } = await ctx.newUser();
|
|
const { asset } = await ctx.newAsset({
|
|
ownerId: user.id,
|
|
localDateTime: new Date('1970-02-12'),
|
|
deletedAt: new Date(),
|
|
});
|
|
await ctx.newExif({ assetId: asset.id, make: 'Canon' });
|
|
const auth = factory.auth({ user: { id: user.id } });
|
|
const rawResponse = await sut.getTimeBucket(auth, { timeBucket: '1970-02-01', isTrashed: true });
|
|
const response = JSON.parse(rawResponse);
|
|
expect(response).toEqual(expect.objectContaining({ isTrashed: [true] }));
|
|
});
|
|
|
|
it('should handle a bucket without any assets', async () => {
|
|
const { sut } = setup();
|
|
const rawResponse = await sut.getTimeBucket(factory.auth(), { timeBucket: '1970-02-01' });
|
|
const response = JSON.parse(rawResponse);
|
|
expect(response).toEqual({
|
|
city: [],
|
|
country: [],
|
|
duration: [],
|
|
id: [],
|
|
visibility: [],
|
|
isFavorite: [],
|
|
isImage: [],
|
|
isTrashed: [],
|
|
livePhotoVideoId: [],
|
|
fileCreatedAt: [],
|
|
localOffsetHours: [],
|
|
ownerId: [],
|
|
projectionType: [],
|
|
ratio: [],
|
|
status: [],
|
|
thumbhash: [],
|
|
});
|
|
});
|
|
|
|
it('should handle 5 digit years', async () => {
|
|
const { sut } = setup();
|
|
const rawResponse = await sut.getTimeBucket(factory.auth(), { timeBucket: '012345-01-01' });
|
|
const response = JSON.parse(rawResponse);
|
|
expect(response).toEqual(expect.objectContaining({ id: [] }));
|
|
});
|
|
|
|
it('should return time bucket in trash', async () => {
|
|
const { sut, ctx } = setup();
|
|
const { user } = await ctx.newUser();
|
|
const { asset } = await ctx.newAsset({
|
|
ownerId: user.id,
|
|
localDateTime: new Date('1970-02-12'),
|
|
deletedAt: new Date(),
|
|
});
|
|
await ctx.newExif({ assetId: asset.id, make: 'Canon' });
|
|
const auth = factory.auth({ user: { id: user.id } });
|
|
const rawResponse = await sut.getTimeBucket(auth, { timeBucket: '1970-02-01', isTrashed: true });
|
|
const response = JSON.parse(rawResponse);
|
|
expect(response).toEqual(expect.objectContaining({ isTrashed: [true] }));
|
|
});
|
|
});
|
|
});
|