2018-03-31 03:30:30 +08:00
|
|
|
import {expect} from 'chai';
|
|
|
|
import * as fs from 'fs';
|
|
|
|
import * as path from 'path';
|
|
|
|
import {Config} from '../../../../../common/config/private/Config';
|
|
|
|
import {DatabaseType} from '../../../../../common/config/private/IPrivateConfig';
|
|
|
|
import {SQLConnection} from '../../../../../backend/model/sql/SQLConnection';
|
2018-01-31 09:01:16 +08:00
|
|
|
import {
|
|
|
|
CameraMetadataEntity,
|
|
|
|
GPSMetadataEntity,
|
|
|
|
ImageSizeEntity,
|
|
|
|
PhotoEntity,
|
|
|
|
PhotoMetadataEntity,
|
|
|
|
PositionMetaDataEntity
|
2018-03-31 03:30:30 +08:00
|
|
|
} from '../../../../../backend/model/sql/enitites/PhotoEntity';
|
|
|
|
import {SearchManager} from '../../../../../backend/model/sql/SearchManager';
|
|
|
|
import {AutoCompleteItem, SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
|
|
|
|
import {SearchResultDTO} from '../../../../../common/entities/SearchResultDTO';
|
|
|
|
import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity';
|
2018-01-31 09:01:16 +08:00
|
|
|
|
|
|
|
describe('SearchManager', () => {
|
|
|
|
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
const tempDir = path.join(__dirname, '../../tmp');
|
|
|
|
const dbPath = path.join(tempDir, 'test.db');
|
2018-01-31 09:01:16 +08:00
|
|
|
|
|
|
|
const dir = new DirectoryEntity();
|
2018-03-31 03:30:30 +08:00
|
|
|
dir.name = 'wars dir';
|
|
|
|
dir.path = '.';
|
2018-01-31 09:01:16 +08:00
|
|
|
dir.lastModified = Date.now();
|
|
|
|
dir.lastScanned = null;
|
|
|
|
|
|
|
|
const getPhoto = () => {
|
|
|
|
const sd = new ImageSizeEntity();
|
|
|
|
sd.height = 200;
|
|
|
|
sd.width = 200;
|
|
|
|
const gps = new GPSMetadataEntity();
|
|
|
|
/* gps.altitude = 1;
|
|
|
|
gps.latitude = 1;
|
|
|
|
gps.longitude = 1;*/
|
|
|
|
const pd = new PositionMetaDataEntity();
|
|
|
|
/* pd.city = "New York";
|
|
|
|
pd.country = "Alderan";
|
|
|
|
pd.state = "Death star";*/
|
|
|
|
pd.GPSData = gps;
|
|
|
|
const cd = new CameraMetadataEntity();
|
|
|
|
/* cd.ISO = 100;
|
|
|
|
cd.model = "60D";
|
|
|
|
cd.maker = "Canon";
|
|
|
|
cd.fStop = 1;
|
|
|
|
cd.exposure = 1;
|
|
|
|
cd.focalLength = 1;*/
|
2018-03-31 03:30:30 +08:00
|
|
|
cd.lens = 'Lens';
|
2018-01-31 09:01:16 +08:00
|
|
|
const m = new PhotoMetadataEntity();
|
2018-03-31 03:30:30 +08:00
|
|
|
m.keywords = ['apple'];
|
2018-01-31 09:01:16 +08:00
|
|
|
m.cameraData = cd;
|
|
|
|
m.positionData = pd;
|
|
|
|
m.size = sd;
|
|
|
|
m.creationDate = Date.now();
|
|
|
|
m.fileSize = 123456789;
|
|
|
|
|
|
|
|
|
|
|
|
const d = new PhotoEntity();
|
2018-03-31 03:30:30 +08:00
|
|
|
d.name = 'test photo.jpg';
|
2018-01-31 09:01:16 +08:00
|
|
|
d.directory = dir;
|
|
|
|
d.metadata = m;
|
|
|
|
return d;
|
|
|
|
};
|
|
|
|
|
|
|
|
let p = getPhoto();
|
2018-03-31 03:30:30 +08:00
|
|
|
p.metadata.keywords = ['Boba Fett', 'star wars', 'Anakin', 'death star'];
|
|
|
|
p.metadata.positionData.city = 'Mos Eisley';
|
|
|
|
p.metadata.positionData.country = 'Tatooine';
|
|
|
|
p.name = 'sw1';
|
2018-01-31 09:01:16 +08:00
|
|
|
|
|
|
|
let p2 = getPhoto();
|
2018-03-31 03:30:30 +08:00
|
|
|
p2.metadata.keywords = ['Padmé Amidala', 'star wars', 'Natalie Portman', 'death star'];
|
|
|
|
p2.metadata.positionData.city = 'Derem City';
|
|
|
|
p2.metadata.positionData.state = 'Research City';
|
|
|
|
p2.metadata.positionData.country = 'Kamino';
|
|
|
|
p2.name = 'sw2';
|
2018-01-31 09:01:16 +08:00
|
|
|
|
|
|
|
const setUpSqlDB = async () => {
|
|
|
|
if (fs.existsSync(dbPath)) {
|
|
|
|
fs.unlinkSync(dbPath);
|
|
|
|
}
|
|
|
|
if (!fs.existsSync(tempDir)) {
|
|
|
|
fs.mkdirSync(tempDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
Config.Server.database.type = DatabaseType.sqlite;
|
|
|
|
Config.Server.database.sqlite.storage = dbPath;
|
|
|
|
|
|
|
|
const conn = await SQLConnection.getConnection();
|
|
|
|
|
|
|
|
const pr = conn.getRepository(PhotoEntity);
|
|
|
|
|
|
|
|
await conn.getRepository(DirectoryEntity).save(p.directory);
|
|
|
|
await pr.save(p);
|
|
|
|
await pr.save(p2);
|
|
|
|
|
|
|
|
await SQLConnection.close();
|
|
|
|
};
|
|
|
|
|
2018-03-30 08:30:23 +08:00
|
|
|
const tearDownSqlDB = async () => {
|
2018-01-31 09:01:16 +08:00
|
|
|
await SQLConnection.close();
|
|
|
|
if (fs.existsSync(dbPath)) {
|
|
|
|
fs.unlinkSync(dbPath);
|
|
|
|
}
|
|
|
|
if (fs.existsSync(tempDir)) {
|
|
|
|
fs.rmdirSync(tempDir);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
await setUpSqlDB();
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(async () => {
|
2018-03-30 08:30:23 +08:00
|
|
|
await tearDownSqlDB();
|
2018-01-31 09:01:16 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should get autocomplete', async () => {
|
|
|
|
let sm = new SearchManager();
|
|
|
|
|
|
|
|
const cmp = (a: AutoCompleteItem, b: AutoCompleteItem) => {
|
|
|
|
return a.text.localeCompare(b.text);
|
|
|
|
};
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.autocomplete('tat'))).to.deep.equal([new AutoCompleteItem('Tatooine', SearchTypes.position)]);
|
|
|
|
expect((await sm.autocomplete('star'))).to.deep.equal([new AutoCompleteItem('star wars', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('death star', SearchTypes.keyword)]);
|
|
|
|
|
|
|
|
expect((await sm.autocomplete('wars'))).to.deep.equal([new AutoCompleteItem('star wars', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('wars dir', SearchTypes.directory)]);
|
|
|
|
|
|
|
|
expect((await sm.autocomplete('arch'))).eql([new AutoCompleteItem('Research City', SearchTypes.position)]);
|
|
|
|
expect((await sm.autocomplete('a')).sort(cmp)).eql([
|
|
|
|
new AutoCompleteItem('Boba Fett', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('star wars', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('Anakin', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('death star', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('Padmé Amidala', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('Natalie Portman', SearchTypes.keyword),
|
|
|
|
new AutoCompleteItem('Kamino', SearchTypes.position),
|
|
|
|
new AutoCompleteItem('Tatooine', SearchTypes.position),
|
|
|
|
new AutoCompleteItem('wars dir', SearchTypes.directory),
|
|
|
|
new AutoCompleteItem('Research City', SearchTypes.position)].sort(cmp));
|
|
|
|
|
|
|
|
expect((await sm.autocomplete('sw')).sort(cmp)).to.deep.equal([new AutoCompleteItem('sw1', SearchTypes.image),
|
|
|
|
new AutoCompleteItem('sw2', SearchTypes.image)].sort(cmp));
|
2018-01-31 09:01:16 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should search', async () => {
|
|
|
|
let sm = new SearchManager();
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.search('sw', null))).to.deep.equal(<SearchResultDTO>{
|
|
|
|
searchText: 'sw',
|
2018-01-31 09:01:16 +08:00
|
|
|
searchType: null,
|
|
|
|
directories: [],
|
|
|
|
photos: [p, p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.search('Tatooine', SearchTypes.position))).to.deep.equal(<SearchResultDTO>{
|
|
|
|
searchText: 'Tatooine',
|
2018-01-31 09:01:16 +08:00
|
|
|
searchType: SearchTypes.position,
|
|
|
|
directories: [],
|
|
|
|
photos: [p],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal(<SearchResultDTO>{
|
|
|
|
searchText: 'ortm',
|
2018-01-31 09:01:16 +08:00
|
|
|
searchType: SearchTypes.keyword,
|
|
|
|
directories: [],
|
|
|
|
photos: [p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal(<SearchResultDTO>{
|
|
|
|
searchText: 'ortm',
|
2018-01-31 09:01:16 +08:00
|
|
|
searchType: SearchTypes.keyword,
|
|
|
|
directories: [],
|
|
|
|
photos: [p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.search('wa', SearchTypes.keyword))).to.deep.equal(<SearchResultDTO>{
|
|
|
|
searchText: 'wa',
|
2018-01-31 09:01:16 +08:00
|
|
|
searchType: SearchTypes.keyword,
|
|
|
|
directories: [dir],
|
|
|
|
photos: [p, p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should instant search', async () => {
|
|
|
|
let sm = new SearchManager();
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.instantSearch('sw'))).to.deep.equal({
|
|
|
|
searchText: 'sw',
|
2018-01-31 09:01:16 +08:00
|
|
|
directories: [],
|
|
|
|
photos: [p, p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.instantSearch('Tatooine'))).to.deep.equal({
|
|
|
|
searchText: 'Tatooine',
|
2018-01-31 09:01:16 +08:00
|
|
|
directories: [],
|
|
|
|
photos: [p],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.instantSearch('ortm'))).to.deep.equal({
|
|
|
|
searchText: 'ortm',
|
2018-01-31 09:01:16 +08:00
|
|
|
directories: [],
|
|
|
|
photos: [p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.instantSearch('ortm'))).to.deep.equal({
|
|
|
|
searchText: 'ortm',
|
2018-01-31 09:01:16 +08:00
|
|
|
directories: [],
|
|
|
|
photos: [p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
expect((await sm.instantSearch('wa'))).to.deep.equal({
|
|
|
|
searchText: 'wa',
|
2018-01-31 09:01:16 +08:00
|
|
|
directories: [dir],
|
|
|
|
photos: [p, p2],
|
|
|
|
resultOverflow: false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
});
|