2021-02-14 19:57:05 +08:00
|
|
|
import {expect} from 'chai';
|
|
|
|
import {
|
|
|
|
ANDSearchQuery,
|
2023-05-07 18:46:15 +08:00
|
|
|
DatePatternFrequency,
|
|
|
|
DatePatternSearch,
|
2021-02-14 19:57:05 +08:00
|
|
|
DistanceSearch,
|
|
|
|
FromDateSearch,
|
2023-08-02 04:57:36 +08:00
|
|
|
MaxPersonCountSearch,
|
2021-02-14 19:57:05 +08:00
|
|
|
MaxRatingSearch,
|
2023-08-02 04:57:36 +08:00
|
|
|
MaxResolutionSearch, MinPersonCountSearch,
|
2021-02-14 19:57:05 +08:00
|
|
|
MinRatingSearch,
|
|
|
|
MinResolutionSearch,
|
|
|
|
OrientationSearch,
|
|
|
|
ORSearchQuery,
|
2021-04-04 17:40:43 +08:00
|
|
|
RangeSearch,
|
2021-02-14 19:57:05 +08:00
|
|
|
SearchQueryDTO,
|
|
|
|
SearchQueryTypes,
|
|
|
|
SomeOfSearchQuery,
|
|
|
|
TextSearch,
|
2021-03-14 17:56:59 +08:00
|
|
|
TextSearchQueryMatchTypes,
|
2021-02-14 19:57:05 +08:00
|
|
|
ToDateSearch
|
|
|
|
} from '../../../src/common/entities/SearchQueryDTO';
|
2021-05-31 22:44:37 +08:00
|
|
|
import {defaultQueryKeywords, SearchQueryParser} from '../../../src/common/SearchQueryParser';
|
2021-02-14 19:57:05 +08:00
|
|
|
|
|
|
|
|
2021-05-10 19:03:22 +08:00
|
|
|
describe('SearchQueryParser', () => {
|
2021-02-14 19:57:05 +08:00
|
|
|
|
|
|
|
const check = (query: SearchQueryDTO) => {
|
2021-05-31 22:44:37 +08:00
|
|
|
const parser = new SearchQueryParser(defaultQueryKeywords);
|
2021-03-20 18:20:53 +08:00
|
|
|
expect(parser.parse(parser.stringify(query))).to.deep.equals(query, parser.stringify(query));
|
2021-02-14 19:57:05 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('should serialize and deserialize', () => {
|
|
|
|
it('Text search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.any_text, text: 'test'} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.person, text: 'person_test'} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.directory, text: 'directory'} as TextSearch);
|
2021-05-24 06:07:19 +08:00
|
|
|
check({type: SearchQueryTypes.directory, text: '2000.10.15 (Some event)'} as TextSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.directory,
|
|
|
|
text: '2000.10.15 (Some event)',
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match
|
|
|
|
} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.directory, text: '2000.10.15 (Some event) '} as TextSearch);
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.caption, text: 'caption'} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.file_name, text: 'filename'} as TextSearch);
|
|
|
|
check({type: SearchQueryTypes.position, text: 'New York'} as TextSearch);
|
|
|
|
check({
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.position,
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match,
|
|
|
|
text: 'New York'
|
2021-04-18 21:48:35 +08:00
|
|
|
} as TextSearch);
|
2021-05-23 23:56:58 +08:00
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.position,
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match,
|
|
|
|
negate: true,
|
|
|
|
text: 'New York'
|
|
|
|
} as TextSearch);
|
|
|
|
|
|
|
|
check({type: SearchQueryTypes.any_text, text: 'test', negate: true} as TextSearch);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
it('Date search', () => {
|
2021-05-28 05:15:00 +08:00
|
|
|
check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 10))} as FromDateSearch);
|
|
|
|
check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 1))} as FromDateSearch);
|
|
|
|
check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 20))} as ToDateSearch);
|
|
|
|
check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 1))} as ToDateSearch);
|
|
|
|
check({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 1)), negate: true} as FromDateSearch);
|
|
|
|
check({type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 1, 1)), negate: true} as ToDateSearch);
|
2021-04-04 17:40:43 +08:00
|
|
|
|
2021-05-31 22:44:37 +08:00
|
|
|
const parser = new SearchQueryParser(defaultQueryKeywords);
|
2022-04-26 01:23:03 +08:00
|
|
|
|
|
|
|
let query: RangeSearch = ({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 4))} as FromDateSearch);
|
|
|
|
expect(parser.parse(defaultQueryKeywords.from + ':' + '2020-02-04'))
|
|
|
|
.to.deep.equals(query, parser.stringify(query));
|
|
|
|
|
|
|
|
expect(parser.parse(defaultQueryKeywords.from + ':' + '2020-2-4'))
|
|
|
|
.to.deep.equals(query, parser.stringify(query));
|
|
|
|
|
|
|
|
query = ({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 1, 1))} as FromDateSearch);
|
|
|
|
expect(parser.parse(defaultQueryKeywords.from + ':' + (new Date(query.value)).getFullYear() + '-' + '02'))
|
|
|
|
.to.deep.equals(query, parser.stringify(query));
|
|
|
|
|
2021-04-04 17:40:43 +08:00
|
|
|
// test if date gets simplified on 1st of Jan.
|
2022-04-26 01:23:03 +08:00
|
|
|
query = {type: SearchQueryTypes.to_date, value: (Date.UTC(2020, 0, 1))} as ToDateSearch;
|
2021-05-31 22:44:37 +08:00
|
|
|
expect(parser.parse(defaultQueryKeywords.to + ':' + (new Date(query.value)).getFullYear()))
|
2021-04-04 17:40:43 +08:00
|
|
|
.to.deep.equals(query, parser.stringify(query));
|
|
|
|
|
2021-05-28 05:15:00 +08:00
|
|
|
query = ({type: SearchQueryTypes.from_date, value: (Date.UTC(2020, 0, 1))} as FromDateSearch);
|
2021-05-31 22:44:37 +08:00
|
|
|
expect(parser.parse(defaultQueryKeywords.from + ':' + (new Date(query.value)).getFullYear()))
|
2021-04-04 17:40:43 +08:00
|
|
|
.to.deep.equals(query, parser.stringify(query));
|
|
|
|
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
it('Rating search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.min_rating, value: 10} as MinRatingSearch);
|
|
|
|
check({type: SearchQueryTypes.max_rating, value: 1} as MaxRatingSearch);
|
2021-05-23 23:56:58 +08:00
|
|
|
check({type: SearchQueryTypes.min_rating, value: 10, negate: true} as MinRatingSearch);
|
|
|
|
check({type: SearchQueryTypes.max_rating, value: 1, negate: true} as MaxRatingSearch);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
2023-08-02 04:57:36 +08:00
|
|
|
it('Person count search', () => {
|
|
|
|
check({type: SearchQueryTypes.min_person_count, value: 10} as MinPersonCountSearch);
|
|
|
|
check({type: SearchQueryTypes.max_person_count, value: 1} as MaxPersonCountSearch);
|
|
|
|
check({type: SearchQueryTypes.min_person_count, value: 10, negate: true} as MinPersonCountSearch);
|
|
|
|
check({type: SearchQueryTypes.max_person_count, value: 1, negate: true} as MaxPersonCountSearch);
|
|
|
|
});
|
2021-02-14 19:57:05 +08:00
|
|
|
it('Resolution search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.min_resolution, value: 10} as MinResolutionSearch);
|
|
|
|
check({type: SearchQueryTypes.max_resolution, value: 5} as MaxResolutionSearch);
|
2021-05-23 23:56:58 +08:00
|
|
|
check({type: SearchQueryTypes.min_resolution, value: 10, negate: true} as MinResolutionSearch);
|
|
|
|
check({type: SearchQueryTypes.max_resolution, value: 5, negate: true} as MaxResolutionSearch);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
it('Distance search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.distance, distance: 10, from: {text: 'New York'}} as DistanceSearch);
|
2021-05-23 23:56:58 +08:00
|
|
|
check({type: SearchQueryTypes.distance, distance: 10, from: {text: 'New York'}, negate: true} as DistanceSearch);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
it('OrientationSearch search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({type: SearchQueryTypes.orientation, landscape: true} as OrientationSearch);
|
|
|
|
check({type: SearchQueryTypes.orientation, landscape: false} as OrientationSearch);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
2023-05-07 18:46:15 +08:00
|
|
|
it('Date patter search', () => {
|
|
|
|
for (let i = 0; i <= 10; ++i) {
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.every_week
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.every_month
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.every_year
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.days_ago,
|
|
|
|
agoNumber: 1
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.weeks_ago,
|
|
|
|
agoNumber: 1
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.months_ago,
|
|
|
|
agoNumber: 1
|
|
|
|
} as DatePatternSearch);
|
|
|
|
check({
|
|
|
|
type: SearchQueryTypes.date_pattern, daysLength: i,
|
|
|
|
frequency: DatePatternFrequency.years_ago,
|
|
|
|
agoNumber: 1
|
|
|
|
} as DatePatternSearch);
|
|
|
|
}
|
|
|
|
});
|
2021-05-24 00:05:12 +08:00
|
|
|
it('Default logical operator should be AND', () => {
|
|
|
|
|
2021-05-31 22:44:37 +08:00
|
|
|
const parser = new SearchQueryParser(defaultQueryKeywords);
|
2021-05-24 00:05:12 +08:00
|
|
|
expect(parser.parse('a b')).to.deep.equals({
|
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
|
|
|
{type: SearchQueryTypes.any_text, text: 'a'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.any_text, text: 'b'} as TextSearch
|
|
|
|
]
|
|
|
|
} as ANDSearchQuery);
|
|
|
|
});
|
2021-02-14 19:57:05 +08:00
|
|
|
it('And search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ANDSearchQuery);
|
2021-03-14 17:56:59 +08:00
|
|
|
|
2021-04-18 21:48:35 +08:00
|
|
|
check({
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.position,
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match,
|
|
|
|
text: 'New York'
|
2021-04-18 21:48:35 +08:00
|
|
|
} as TextSearch
|
2021-03-14 17:56:59 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ANDSearchQuery);
|
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
2021-05-06 03:20:12 +08:00
|
|
|
{type: SearchQueryTypes.caption, text: 'caption'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ANDSearchQuery);
|
|
|
|
check({
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.SOME_OF,
|
|
|
|
min: 2,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.caption, text: 'caption test'} as TextSearch
|
2021-03-14 17:56:59 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as SomeOfSearchQuery,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-03-14 17:56:59 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ANDSearchQuery);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
it('Or search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.OR,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ORSearchQuery);
|
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.OR,
|
|
|
|
list: [
|
2021-05-06 03:20:12 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.person, text: 'person_test'} as TextSearch,
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ORSearchQuery);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
it('Some of search', () => {
|
2021-04-18 21:48:35 +08:00
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.SOME_OF,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as SomeOfSearchQuery);
|
|
|
|
check({
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.SOME_OF,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.keyword,
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match,
|
|
|
|
text: 'big boom'
|
2021-04-18 21:48:35 +08:00
|
|
|
} as TextSearch,
|
|
|
|
{
|
2021-03-14 17:56:59 +08:00
|
|
|
type: SearchQueryTypes.position,
|
|
|
|
matchType: TextSearchQueryMatchTypes.exact_match,
|
|
|
|
text: 'New York'
|
2021-04-18 21:48:35 +08:00
|
|
|
} as TextSearch,
|
2021-03-14 17:56:59 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as SomeOfSearchQuery);
|
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.SOME_OF,
|
|
|
|
min: 2,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.caption, text: 'caption test'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as SomeOfSearchQuery);
|
|
|
|
check({
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.SOME_OF,
|
|
|
|
min: 2,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.keyword, text: 'big boom'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.person, text: 'person_test'} as TextSearch,
|
|
|
|
{
|
2021-02-14 19:57:05 +08:00
|
|
|
type: SearchQueryTypes.AND,
|
|
|
|
list: [
|
2021-04-18 21:48:35 +08:00
|
|
|
{type: SearchQueryTypes.caption, text: 'caption'} as TextSearch,
|
|
|
|
{type: SearchQueryTypes.position, text: 'New York'} as TextSearch
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as ANDSearchQuery
|
2021-02-14 19:57:05 +08:00
|
|
|
]
|
2021-04-18 21:48:35 +08:00
|
|
|
} as SomeOfSearchQuery);
|
2021-02-14 19:57:05 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
});
|