mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-04-15 11:56:50 +02:00
fixing tests
This commit is contained in:
parent
a47e613ca9
commit
74a56caf76
@ -312,6 +312,11 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
|||||||
await this.fillPreviewFromSubDir(connection, dir);
|
await this.fillPreviewFromSubDir(connection, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dir.metaFile) {
|
||||||
|
for (const item of dir.metaFile) {
|
||||||
|
item.directory = dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dir.directories) {
|
if (dir.directories) {
|
||||||
for (const item of dir.directories) {
|
for (const item of dir.directories) {
|
||||||
await this.fillPreviewForSubDir(connection, item);
|
await this.fillPreviewForSubDir(connection, item);
|
||||||
|
@ -37,6 +37,14 @@ import {FileEntity} from './enitites/FileEntity';
|
|||||||
|
|
||||||
export class SearchManager implements ISQLSearchManager {
|
export class SearchManager implements ISQLSearchManager {
|
||||||
|
|
||||||
|
// This trick enables us to list less rows as faces will be concatenated into one row
|
||||||
|
// Also typeorm does not support automatic mapping of nested foreign keys
|
||||||
|
// (i.e: leftJoinAndSelect('media.metadata.faces', 'faces') does not work)
|
||||||
|
private FACE_SELECT = Config.Server.Database.type === DatabaseType.mysql ?
|
||||||
|
'CONCAT(\'[\' , GROUP_CONCAT( \'{"name": "\' , person.name , \'", "box": {"top":\' , faces.box.top , \', "left":\' , faces.box.left , \', "height":\' , faces.box.height ,\', "width":\' , faces.box.width , \'}}\' ) ,\']\') as media_metadataFaces' :
|
||||||
|
'\'[\' || GROUP_CONCAT( \'{"name": "\' || person.name || \'", "box": {"top":\' || faces.box.top || \', "left":\' || faces.box.left || \', "height":\' || faces.box.height ||\', "width":\' || faces.box.width || \'}}\' ) ||\']\' as media_metadataFaces';
|
||||||
|
private DIRECTORY_SELECT = ['directory.id', 'directory.name', 'directory.path'];
|
||||||
|
|
||||||
private static autoCompleteItemsUnique(array: Array<AutoCompleteItem>): Array<AutoCompleteItem> {
|
private static autoCompleteItemsUnique(array: Array<AutoCompleteItem>): Array<AutoCompleteItem> {
|
||||||
const a = array.concat();
|
const a = array.concat();
|
||||||
for (let i = 0; i < a.length; ++i) {
|
for (let i = 0; i < a.length; ++i) {
|
||||||
@ -151,19 +159,11 @@ export class SearchManager implements ISQLSearchManager {
|
|||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// This trick enables us to list less rows as faces will be concatenated into one row
|
|
||||||
// Also typeorm does not support automatic mapping of nested foreign keys
|
|
||||||
// (i.e: leftJoinAndSelect('media.metadata.faces', 'faces') does not work)
|
|
||||||
const facesQuery = Config.Server.Database.type === DatabaseType.mysql ?
|
|
||||||
'CONCAT(\'[\' , GROUP_CONCAT( \'{"name": "\' , person.name , \'", "box": {"top":\' , faces.box.top , \', "left":\' , faces.box.left , \', "height":\' , faces.box.height ,\', "width":\' , faces.box.width , \'}}\' ) ,\']\') as media_metadataFaces' :
|
|
||||||
'\'[\' || GROUP_CONCAT( \'{"name": "\' || person.name || \'", "box": {"top":\' || faces.box.top || \', "left":\' || faces.box.left || \', "height":\' || faces.box.height ||\', "width":\' || faces.box.width || \'}}\' ) ||\']\' as media_metadataFaces';
|
|
||||||
const directorySelect = ['directory.id', 'directory.name', 'directory.path'];
|
|
||||||
|
|
||||||
|
|
||||||
const rawAndEntries = await connection
|
const rawAndEntries = await connection
|
||||||
.getRepository(MediaEntity)
|
.getRepository(MediaEntity)
|
||||||
.createQueryBuilder('media')
|
.createQueryBuilder('media')
|
||||||
.select(['media', ...directorySelect, facesQuery])
|
.select(['media', ...this.DIRECTORY_SELECT, this.FACE_SELECT])
|
||||||
.where(this.buildWhereQuery(query))
|
.where(this.buildWhereQuery(query))
|
||||||
.leftJoin('media.directory', 'directory')
|
.leftJoin('media.directory', 'directory')
|
||||||
.leftJoin('media.metadata.faces', 'faces')
|
.leftJoin('media.metadata.faces', 'faces')
|
||||||
@ -187,7 +187,7 @@ export class SearchManager implements ISQLSearchManager {
|
|||||||
if (Config.Client.Search.listMetafiles === true) {
|
if (Config.Client.Search.listMetafiles === true) {
|
||||||
result.metaFile = await connection.getRepository(FileEntity)
|
result.metaFile = await connection.getRepository(FileEntity)
|
||||||
.createQueryBuilder('file')
|
.createQueryBuilder('file')
|
||||||
.select(['file', ...directorySelect])
|
.select(['file', ...this.DIRECTORY_SELECT])
|
||||||
.innerJoin(q => q.from(MediaEntity, 'media')
|
.innerJoin(q => q.from(MediaEntity, 'media')
|
||||||
.select('distinct directory.id')
|
.select('distinct directory.id')
|
||||||
.where(this.buildWhereQuery(query))
|
.where(this.buildWhereQuery(query))
|
||||||
@ -229,7 +229,8 @@ export class SearchManager implements ISQLSearchManager {
|
|||||||
const sqlQuery: SelectQueryBuilder<PhotoEntity> = connection
|
const sqlQuery: SelectQueryBuilder<PhotoEntity> = connection
|
||||||
.getRepository(PhotoEntity)
|
.getRepository(PhotoEntity)
|
||||||
.createQueryBuilder('media')
|
.createQueryBuilder('media')
|
||||||
.innerJoinAndSelect('media.directory', 'directory')
|
.select(['media', ...this.DIRECTORY_SELECT])
|
||||||
|
.innerJoin('media.directory', 'directory')
|
||||||
.where(this.buildWhereQuery(query));
|
.where(this.buildWhereQuery(query));
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@ import {Connection} from 'typeorm';
|
|||||||
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||||
import {GPSMetadata, PhotoDTO, PhotoMetadata} from '../../../../../src/common/entities/PhotoDTO';
|
import {GPSMetadata, PhotoDTO, PhotoMetadata} from '../../../../../src/common/entities/PhotoDTO';
|
||||||
import {VideoDTO} from '../../../../../src/common/entities/VideoDTO';
|
import {VideoDTO} from '../../../../../src/common/entities/VideoDTO';
|
||||||
import {MediaDTO} from '../../../../../src/common/entities/MediaDTO';
|
|
||||||
import {AutoCompleteItem} from '../../../../../src/common/entities/AutoCompleteItem';
|
import {AutoCompleteItem} from '../../../../../src/common/entities/AutoCompleteItem';
|
||||||
import {Config} from '../../../../../src/common/config/private/Config';
|
import {Config} from '../../../../../src/common/config/private/Config';
|
||||||
import {SearchQueryParser} from '../../../../../src/common/SearchQueryParser';
|
import {SearchQueryParser} from '../../../../../src/common/SearchQueryParser';
|
||||||
|
import {FileDTO} from '../../../../../src/common/entities/FileDTO';
|
||||||
|
|
||||||
const deepEqualInAnyOrder = require('deep-equal-in-any-order');
|
const deepEqualInAnyOrder = require('deep-equal-in-any-order');
|
||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
@ -82,6 +82,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
* |- v
|
* |- v
|
||||||
* |- p
|
* |- p
|
||||||
* |- p2
|
* |- p2
|
||||||
|
* |- gpx
|
||||||
* |-> subDir
|
* |-> subDir
|
||||||
* |- pFaceLess
|
* |- pFaceLess
|
||||||
* |-> subDir2
|
* |-> subDir2
|
||||||
@ -96,6 +97,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
let p2: PhotoDTO;
|
let p2: PhotoDTO;
|
||||||
let pFaceLess: PhotoDTO;
|
let pFaceLess: PhotoDTO;
|
||||||
let p4: PhotoDTO;
|
let p4: PhotoDTO;
|
||||||
|
let gpx: FileDTO;
|
||||||
|
|
||||||
|
|
||||||
const setUpTestGallery = async (): Promise<void> => {
|
const setUpTestGallery = async (): Promise<void> => {
|
||||||
@ -104,16 +106,19 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
||||||
p = TestHelper.getPhotoEntry1(directory);
|
p = TestHelper.getPhotoEntry1(directory);
|
||||||
p2 = TestHelper.getPhotoEntry2(directory);
|
p2 = TestHelper.getPhotoEntry2(directory);
|
||||||
|
v = TestHelper.getVideoEntry1(directory);
|
||||||
|
gpx = TestHelper.getRandomizedGPXEntry(directory);
|
||||||
p4 = TestHelper.getPhotoEntry4(subDir2);
|
p4 = TestHelper.getPhotoEntry4(subDir2);
|
||||||
const pFaceLessTmp = TestHelper.getPhotoEntry3(subDir);
|
const pFaceLessTmp = TestHelper.getPhotoEntry3(subDir);
|
||||||
delete pFaceLessTmp.metadata.faces;
|
delete pFaceLessTmp.metadata.faces;
|
||||||
v = TestHelper.getVideoEntry1(directory);
|
|
||||||
|
|
||||||
dir = await DBTestHelper.persistTestDir(directory);
|
dir = await DBTestHelper.persistTestDir(directory);
|
||||||
|
|
||||||
subDir = dir.directories[0];
|
subDir = dir.directories[0];
|
||||||
subDir2 = dir.directories[1];
|
subDir2 = dir.directories[1];
|
||||||
p = (dir.media.filter(m => m.name === p.name)[0] as any);
|
p = (dir.media.filter(m => m.name === p.name)[0] as any);
|
||||||
p2 = (dir.media.filter(m => m.name === p2.name)[0] as any);
|
p2 = (dir.media.filter(m => m.name === p2.name)[0] as any);
|
||||||
|
gpx = (dir.metaFile[0] as any);
|
||||||
v = (dir.media.filter(m => m.name === v.name)[0] as any);
|
v = (dir.media.filter(m => m.name === v.name)[0] as any);
|
||||||
p4 = (dir.directories[1].media[0] as any);
|
p4 = (dir.directories[1].media[0] as any);
|
||||||
pFaceLess = (dir.directories[0].media[0] as any);
|
pFaceLess = (dir.directories[0].media[0] as any);
|
||||||
@ -129,12 +134,14 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
before(async () => {
|
before(async () => {
|
||||||
await setUpSqlDB();
|
await setUpSqlDB();
|
||||||
Config.Client.Search.listDirectories = true;
|
Config.Client.Search.listDirectories = true;
|
||||||
|
Config.Client.Search.listMetafiles = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
after(async () => {
|
after(async () => {
|
||||||
await sqlHelper.clearDB();
|
await sqlHelper.clearDB();
|
||||||
Config.Client.Search.listDirectories = false;
|
Config.Client.Search.listDirectories = false;
|
||||||
|
Config.Client.Search.listMetafiles = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get autocomplete', async () => {
|
it('should get autocomplete', async () => {
|
||||||
@ -190,7 +197,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchifyMedia = (m: MediaDTO): MediaDTO => {
|
const searchifyMedia = <T extends FileDTO | PhotoDTO>(m: T): T => {
|
||||||
const tmpM = m.directory.media;
|
const tmpM = m.directory.media;
|
||||||
const tmpD = m.directory.directories;
|
const tmpD = m.directory.directories;
|
||||||
const tmpP = m.directory.preview;
|
const tmpP = m.directory.preview;
|
||||||
@ -203,8 +210,9 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
delete ret.directory.lastScanned;
|
delete ret.directory.lastScanned;
|
||||||
delete ret.directory.lastModified;
|
delete ret.directory.lastModified;
|
||||||
delete ret.directory.mediaCount;
|
delete ret.directory.mediaCount;
|
||||||
if ((ret.metadata as PhotoMetadata).faces && !(ret.metadata as PhotoMetadata).faces.length) {
|
if ((ret as PhotoDTO).metadata &&
|
||||||
delete (ret.metadata as PhotoMetadata).faces;
|
((ret as PhotoDTO).metadata as PhotoMetadata).faces && !((ret as PhotoDTO).metadata as PhotoMetadata).faces.length) {
|
||||||
|
delete ((ret as PhotoDTO).metadata as PhotoMetadata).faces;
|
||||||
}
|
}
|
||||||
m.directory.directories = tmpD;
|
m.directory.directories = tmpD;
|
||||||
m.directory.media = tmpM;
|
m.directory.media = tmpM;
|
||||||
@ -233,11 +241,20 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
const removeDir = (result: SearchResultDTO) => {
|
const removeDir = (result: SearchResultDTO) => {
|
||||||
result.media = result.media.map(m => searchifyMedia(m));
|
result.media = result.media.map(m => searchifyMedia(m));
|
||||||
|
result.metaFile = result.metaFile.map(m => searchifyMedia(m));
|
||||||
result.directories = result.directories.map(m => searchifyDir(m));
|
result.directories = result.directories.map(m => searchifyDir(m));
|
||||||
return Utils.clone(result);
|
return Utils.clone(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('advanced search', async () => {
|
describe('advanced search', async () => {
|
||||||
|
afterEach(async () => {
|
||||||
|
Config.Client.Search.listDirectories = false;
|
||||||
|
Config.Client.Search.listMetafiles = false;
|
||||||
|
});
|
||||||
|
afterEach(async () => {
|
||||||
|
Config.Client.Search.listDirectories = false;
|
||||||
|
Config.Client.Search.listMetafiles = false;
|
||||||
|
});
|
||||||
|
|
||||||
it('should AND', async () => {
|
it('should AND', async () => {
|
||||||
const sm = new SearchManager();
|
const sm = new SearchManager();
|
||||||
@ -484,7 +501,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
expect(removeDir(await sm.search(query)))
|
expect(removeDir(await sm.search(query)))
|
||||||
.to.deep.equalInAnyOrder(removeDir({
|
.to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [dir, subDir, subDir2],
|
directories: [],
|
||||||
media: [],
|
media: [],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -505,7 +522,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
expect(removeDir(await sm.search(query)))
|
expect(removeDir(await sm.search(query)))
|
||||||
.to.deep.equalInAnyOrder(removeDir({
|
.to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [dir, subDir, subDir2],
|
directories: [],
|
||||||
media: [p2, pFaceLess, p4],
|
media: [p2, pFaceLess, p4],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -708,7 +725,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [subDir2],
|
directories: [],
|
||||||
media: [p4],
|
media: [p4],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -721,7 +738,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [dir, subDir, subDir2],
|
directories: [],
|
||||||
media: [p, p2, v, pFaceLess, p4],
|
media: [p, p2, v, pFaceLess, p4],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -740,7 +757,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
type: SearchQueryTypes.directory
|
type: SearchQueryTypes.directory
|
||||||
} as TextSearch))).to.deep.equalInAnyOrder(removeDir({
|
} as TextSearch))).to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [dir],
|
directories: [],
|
||||||
media: [p, p2, v],
|
media: [p, p2, v],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -755,7 +772,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [subDir2],
|
directories: [],
|
||||||
media: [p4],
|
media: [p4],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -769,7 +786,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
|
|
||||||
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
expect(removeDir(await sm.search(query))).to.deep.equalInAnyOrder(removeDir({
|
||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
directories: [subDir2],
|
directories: [],
|
||||||
media: [p4],
|
media: [p4],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
@ -1211,6 +1228,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
}) as any).timeout(40000);
|
}) as any).timeout(40000);
|
||||||
|
|
||||||
it('search result should return directory', async () => {
|
it('search result should return directory', async () => {
|
||||||
|
Config.Client.Search.listDirectories = true;
|
||||||
const sm = new SearchManager();
|
const sm = new SearchManager();
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
@ -1226,6 +1244,24 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
resultOverflow: false
|
resultOverflow: false
|
||||||
} as SearchResultDTO));
|
} as SearchResultDTO));
|
||||||
});
|
});
|
||||||
|
it('search result should return meta files', async () => {
|
||||||
|
Config.Client.Search.listMetafiles = true;
|
||||||
|
const sm = new SearchManager();
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
text: dir.name,
|
||||||
|
type: SearchQueryTypes.any_text,
|
||||||
|
matchType: TextSearchQueryMatchTypes.exact_match
|
||||||
|
} as TextSearch;
|
||||||
|
expect(removeDir(await sm.search(query)))
|
||||||
|
.to.deep.equalInAnyOrder(removeDir({
|
||||||
|
searchQuery: query,
|
||||||
|
directories: [],
|
||||||
|
media: [p, p2, v],
|
||||||
|
metaFile: [gpx],
|
||||||
|
resultOverflow: false
|
||||||
|
} as SearchResultDTO));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user