2024-01-05 16:43:24 +02:00
|
|
|
import { ModelType } from '../../BaseModel';
|
|
|
|
import Note from '../../models/Note';
|
2023-12-13 21:24:58 +02:00
|
|
|
import Resource from '../../models/Resource';
|
2024-01-05 16:43:24 +02:00
|
|
|
import shim from '../../shim';
|
|
|
|
import { db, msleep, newOcrService, ocrSampleDir, resourceService, setupDatabaseAndSynchronizer, switchClient } from '../../testing/test-utils';
|
2023-12-13 21:24:58 +02:00
|
|
|
import { ResourceOcrStatus } from '../database/types';
|
|
|
|
import SearchEngine from './SearchEngine';
|
|
|
|
|
|
|
|
const newSearchEngine = () => {
|
|
|
|
const engine = new SearchEngine();
|
|
|
|
engine.setDb(db());
|
|
|
|
return engine;
|
|
|
|
};
|
|
|
|
|
2024-03-02 16:25:27 +02:00
|
|
|
const createNoteAndResource = async () => {
|
|
|
|
const note = await Note.save({});
|
|
|
|
await Note.save({});
|
|
|
|
await shim.attachFileToNote(note, `${ocrSampleDir}/testocr.png`);
|
|
|
|
const resource = (await Resource.all())[0];
|
|
|
|
|
|
|
|
await resourceService().indexNoteResources();
|
|
|
|
|
|
|
|
return { note, resource };
|
|
|
|
};
|
|
|
|
|
2023-12-13 21:24:58 +02:00
|
|
|
describe('SearchEngine.resources', () => {
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
global.console = require('console');
|
|
|
|
await setupDatabaseAndSynchronizer(1);
|
|
|
|
await switchClient(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should index resources', async () => {
|
|
|
|
const engine = newSearchEngine();
|
|
|
|
|
|
|
|
await Resource.save({
|
|
|
|
id: '00000000000000000000000000000001',
|
|
|
|
mime: 'image/jpeg',
|
|
|
|
title: 'Bonjour ça va ?',
|
|
|
|
ocr_status: ResourceOcrStatus.Done,
|
|
|
|
ocr_text: 'héllô, hôw äre yoù ?',
|
|
|
|
}, { isNew: true });
|
|
|
|
|
|
|
|
await engine.syncTables();
|
|
|
|
|
|
|
|
const normalized = await db().selectAll('select * from items_normalized');
|
|
|
|
expect(normalized[0].title).toBe('bonjour ca va ?');
|
|
|
|
expect(normalized[0].body).toBe('hello, how are you ?');
|
|
|
|
});
|
|
|
|
|
2024-01-05 16:43:24 +02:00
|
|
|
it('should return notes associated with indexed resources', (async () => {
|
2024-03-02 16:25:27 +02:00
|
|
|
const { note, resource } = await createNoteAndResource();
|
2024-01-05 16:43:24 +02:00
|
|
|
|
|
|
|
const ocrService = newOcrService();
|
|
|
|
await ocrService.processResources();
|
|
|
|
|
|
|
|
const searchEngine = newSearchEngine();
|
|
|
|
await searchEngine.syncTables();
|
|
|
|
|
|
|
|
const results = await searchEngine.search('lazy fox');
|
|
|
|
expect(results.length).toBe(1);
|
2024-03-02 16:25:27 +02:00
|
|
|
expect(results[0].id).toBe(note.id);
|
2024-01-05 16:43:24 +02:00
|
|
|
expect(results[0].item_id).toBe(resource.id);
|
|
|
|
expect(results[0].item_type).toBe(ModelType.Resource);
|
2024-01-05 20:16:09 +02:00
|
|
|
|
|
|
|
await ocrService.dispose();
|
2024-01-05 16:43:24 +02:00
|
|
|
}));
|
|
|
|
|
2024-03-02 16:25:27 +02:00
|
|
|
it('should not return resources associated with deleted notes', (async () => {
|
|
|
|
const { note } = await createNoteAndResource();
|
|
|
|
const note2 = await Note.save({ body: 'lazy fox' });
|
|
|
|
await Note.delete(note.id, { toTrash: true });
|
|
|
|
|
|
|
|
const ocrService = newOcrService();
|
|
|
|
await ocrService.processResources();
|
|
|
|
|
|
|
|
const searchEngine = newSearchEngine();
|
|
|
|
await searchEngine.syncTables();
|
|
|
|
|
|
|
|
const results = await searchEngine.search('lazy fox');
|
|
|
|
expect(results.length).toBe(1);
|
|
|
|
expect(results[0].id).toBe(note2.id);
|
|
|
|
}));
|
|
|
|
|
2023-12-13 21:24:58 +02:00
|
|
|
it('should delete normalized data when a resource is deleted', async () => {
|
|
|
|
const engine = newSearchEngine();
|
|
|
|
|
|
|
|
const resource = await Resource.save({
|
|
|
|
id: '00000000000000000000000000000001',
|
|
|
|
mime: 'image/jpeg',
|
|
|
|
title: 'hello',
|
|
|
|
ocr_status: ResourceOcrStatus.Done,
|
|
|
|
ocr_text: 'hi',
|
|
|
|
}, { isNew: true });
|
|
|
|
|
|
|
|
await engine.syncTables();
|
|
|
|
|
|
|
|
expect((await db().selectAll('select * from items_normalized')).length).toBe(1);
|
|
|
|
|
|
|
|
await Resource.delete(resource.id);
|
|
|
|
|
|
|
|
expect((await db().selectAll('select * from items_normalized')).length).toBe(0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should sort resources', async () => {
|
|
|
|
const engine = newSearchEngine();
|
|
|
|
|
|
|
|
const resourceData = [
|
|
|
|
['abcd abcd abcd', 'efgh'],
|
|
|
|
['abcd', 'ijkl'],
|
|
|
|
['ijkl', 'mnop'],
|
|
|
|
];
|
|
|
|
|
|
|
|
for (const [title, body] of resourceData) {
|
|
|
|
await Resource.save({
|
|
|
|
mime: 'image/jpeg',
|
|
|
|
title,
|
|
|
|
ocr_status: ResourceOcrStatus.Done,
|
|
|
|
ocr_text: body,
|
|
|
|
});
|
|
|
|
await msleep(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
await engine.syncTables();
|
|
|
|
|
|
|
|
const results = await engine.search('abcd', { includeOrphanedResources: true });
|
|
|
|
expect(results[0].title).toBe('abcd abcd abcd');
|
|
|
|
expect(results[1].title).toBe('abcd');
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|