import { Kysely } from 'kysely'; import { AssetFileType } from 'src/enum'; import { AssetJobRepository } from 'src/repositories/asset-job.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { DB } from 'src/schema'; import { BaseService } from 'src/services/base.service'; import { newMediumService } from 'test/medium.factory'; import { getKyselyDB } from 'test/utils'; const consume = async (generator: AsyncIterableIterator) => { const values: T[] = []; for await (const value of generator) { values.push(value); } return values; }; let defaultDatabase: Kysely; const setup = (db?: Kysely) => { const { ctx } = newMediumService(BaseService, { database: db || defaultDatabase, real: [], mock: [LoggingRepository], }); return { ctx, sut: ctx.get(AssetJobRepository) }; }; beforeAll(async () => { defaultDatabase = await getKyselyDB(); }); describe(AssetJobRepository.name, () => { describe('streamForThumbnailJob', () => { it('should work', async () => { const { sut } = setup(); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: false }); await expect(stream.next()).resolves.toEqual({ done: true, value: undefined }); }); it('should queue an asset with missing thumbnails', async () => { const { ctx, sut } = setup(); const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id }); await ctx.newJobStatus({ assetId: asset.id, metadataExtractedAt: new Date() }); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: false }); await expect(consume(stream)).resolves.toEqual([expect.objectContaining({ id: asset.id })]); }); it('should skip assets without missing thumbnails', async () => { const { ctx, sut } = setup(); const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id, thumbhash: Buffer.from('fake-thumbhash-buffer') }); await ctx.newJobStatus({ assetId: asset.id, metadataExtractedAt: new Date() }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: 'thumbnail.jpg' }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: 'preview.jpg' }); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: false }); await expect(consume(stream)).resolves.not.toEqual( expect.arrayContaining([expect.objectContaining({ id: asset.id })]), ); }); it('should queue assets with a missing full size', async () => { const { ctx, sut } = setup(); const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id, thumbhash: Buffer.from('fake-thumbhash-buffer'), originalFileName: 'photo.cr2', }); await ctx.newJobStatus({ assetId: asset.id, metadataExtractedAt: new Date() }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: 'thumbnail.jpg' }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: 'preview.jpg' }); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: true }); await expect(consume(stream)).resolves.toEqual( expect.arrayContaining([expect.objectContaining({ id: asset.id })]), ); }); it('should skip assets with after they have full size previews', async () => { const { ctx, sut } = setup(); const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id, thumbhash: Buffer.from('fake-thumbhash-buffer') }); await ctx.newJobStatus({ assetId: asset.id, metadataExtractedAt: new Date() }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: 'thumbnail.jpg' }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: 'preview.jpg' }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.FullSize, path: 'fullsize.jpg' }); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: true }); await expect(consume(stream)).resolves.not.toEqual( expect.arrayContaining([expect.objectContaining({ id: asset.id })]), ); }); it('should skip assets with web-compatible originals', async () => { const { ctx, sut } = setup(); const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id, thumbhash: Buffer.from('fake-thumbhash-buffer'), originalFileName: 'photo.jpg', }); await ctx.newJobStatus({ assetId: asset.id, metadataExtractedAt: new Date() }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Thumbnail, path: 'thumbnail.jpg' }); await ctx.newAssetFile({ assetId: asset.id, type: AssetFileType.Preview, path: 'preview.jpg' }); const stream = sut.streamForThumbnailJob({ force: false, fullsizeEnabled: true }); await expect(consume(stream)).resolves.not.toEqual( expect.arrayContaining([expect.objectContaining({ id: asset.id })]), ); }); }); });