mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 01:22:54 +00:00
fix: tests
This commit is contained in:
@@ -56,7 +56,6 @@
|
||||
"devDependencies": {
|
||||
"@openstapps/es-mapping-generator": "workspace:*",
|
||||
"@openstapps/eslint-config": "workspace:*",
|
||||
"@openstapps/nyc-config": "workspace:*",
|
||||
"@openstapps/prettier-config": "workspace:*",
|
||||
"@openstapps/tsconfig": "workspace:*",
|
||||
"@testdeck/mocha": "0.3.3",
|
||||
@@ -91,7 +90,7 @@
|
||||
"sinon-express-mock": "2.2.1",
|
||||
"supertest": "6.3.3",
|
||||
"tsup": "6.7.0",
|
||||
"typescript": "4.6.4"
|
||||
"typescript": "4.8.4"
|
||||
},
|
||||
"tsup": {
|
||||
"entry": [
|
||||
|
||||
@@ -20,19 +20,18 @@ import {
|
||||
IndicesGetAliasResponse,
|
||||
SearchHit,
|
||||
SearchResponse,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {SCConfigFile, SCSearchQuery, SCSearchResponse, SCThings, SCUuid} from '@openstapps/core';
|
||||
import {Logger} from '@openstapps/logger';
|
||||
import {IndicesUpdateAliasesParamsAction, SearchResponse} from 'elasticsearch';
|
||||
import moment from 'moment';
|
||||
import {MailQueue} from '../../notification/mail-queue';
|
||||
import {Bulk} from '../bulk-storage';
|
||||
import {Database} from '../database';
|
||||
import {parseAggregations} from './aggregations';
|
||||
import * as Monitoring from './monitoring';
|
||||
import {buildQuery} from './query/query';
|
||||
import {buildSort} from './query/sort';
|
||||
import {aggregations, putTemplate} from './templating';
|
||||
import {MailQueue} from '../../notification/mail-queue.js';
|
||||
import {Bulk} from '../bulk-storage.js';
|
||||
import {Database} from '../database.js';
|
||||
import {parseAggregations} from './aggregations.js';
|
||||
import * as Monitoring from './monitoring.js';
|
||||
import {buildQuery} from './query/query.js';
|
||||
import {buildSort} from './query/sort.js';
|
||||
import {aggregations, putTemplate} from './templating.js';
|
||||
import {
|
||||
ElasticsearchConfig,
|
||||
ElasticsearchQueryDisMaxConfig,
|
||||
@@ -44,7 +43,7 @@ import {
|
||||
INACTIVE_INDICES_ALIAS,
|
||||
matchIndexByType,
|
||||
VALID_INDEX_REGEX,
|
||||
} from './util';
|
||||
} from './util/index.js';
|
||||
import {noUndefined} from './util/no-undefined.js';
|
||||
import {retryCatch, RetryOptions} from './util/retry.js';
|
||||
|
||||
@@ -170,7 +169,7 @@ export class Elasticsearch implements Database {
|
||||
return searchResponse.hits.hits[0];
|
||||
}
|
||||
|
||||
private async prepareBulkWrite(bulk: Bulk): Promise<string> {
|
||||
async prepareBulkWrite(bulk: Bulk): Promise<string> {
|
||||
if (!this.ready) {
|
||||
throw new Error('No connection to elasticsearch established yet.');
|
||||
}
|
||||
@@ -389,7 +388,7 @@ export class Elasticsearch implements Database {
|
||||
index: ACTIVE_INDICES_ALIAS,
|
||||
allow_no_indices: true,
|
||||
size: parameters.size,
|
||||
sort: typeof parameters.sort !== 'undefined' ? buildSort(parameters.sort) : undefined,
|
||||
sort: typeof parameters.sort === 'undefined' ? undefined : buildSort(parameters.sort),
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -401,9 +400,9 @@ export class Elasticsearch implements Database {
|
||||
})
|
||||
.filter(noUndefined),
|
||||
facets:
|
||||
typeof response.aggregations !== 'undefined'
|
||||
? parseAggregations(response.aggregations as Record<AggregateName, AggregationsMultiTermsBucket>)
|
||||
: [],
|
||||
typeof response.aggregations === 'undefined'
|
||||
? []
|
||||
: parseAggregations(response.aggregations as Record<AggregateName, AggregationsMultiTermsBucket>),
|
||||
pagination: {
|
||||
count: response.hits.hits.length,
|
||||
offset: typeof parameters.from === 'number' ? parameters.from : 0,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Client} from '@elastic/elasticsearch';
|
||||
import {SearchRequest} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {SearchRequest} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {
|
||||
SCMonitoringConfiguration,
|
||||
SCMonitoringLogAction,
|
||||
@@ -150,6 +150,3 @@ export async function setUp(
|
||||
|
||||
Logger.log(`Scheduled ${monitoringConfig.watchers.length} watches`);
|
||||
}
|
||||
|
||||
// do this for esm mocking
|
||||
export default {setUp};
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {QueryDslQueryContainer} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {QueryDslQueryContainer} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {SCConfigFile, SCSearchQuery} from '@openstapps/core';
|
||||
import {ElasticsearchConfig} from '../types/elasticsearch-config.js';
|
||||
import {buildFilter} from './filter.js';
|
||||
@@ -31,7 +31,7 @@ export const buildQuery = function buildQuery(
|
||||
defaultConfig: SCConfigFile,
|
||||
elasticsearchConfig: ElasticsearchConfig,
|
||||
): QueryDslQueryContainer {
|
||||
// if config provides an minMatch parameter we use query_string instead of match query
|
||||
// if config provides a minMatch parameter, we use query_string instead of a match query
|
||||
let query;
|
||||
if (typeof elasticsearchConfig.query === 'undefined') {
|
||||
query = {
|
||||
@@ -39,7 +39,7 @@ export const buildQuery = function buildQuery(
|
||||
analyzer: 'search_german',
|
||||
default_field: 'name',
|
||||
minimum_should_match: '90%',
|
||||
query: typeof parameters.query !== 'string' ? '*' : parameters.query,
|
||||
query: typeof parameters.query === 'string' ? parameters.query : '*',
|
||||
},
|
||||
};
|
||||
} else if (elasticsearchConfig.query.queryType === 'query_string') {
|
||||
@@ -48,7 +48,7 @@ export const buildQuery = function buildQuery(
|
||||
analyzer: 'search_german',
|
||||
default_field: 'name',
|
||||
minimum_should_match: elasticsearchConfig.query.minMatch,
|
||||
query: typeof parameters.query !== 'string' ? '*' : parameters.query,
|
||||
query: typeof parameters.query === 'string' ? parameters.query : '*',
|
||||
},
|
||||
};
|
||||
} else if (elasticsearchConfig.query.queryType === 'dis_max') {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Sort} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {Sort} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {SCSearchSort} from '@openstapps/core';
|
||||
import {buildDistanceSort} from './sort/distance.js';
|
||||
import {buildDucetSort} from './sort/ducet.js';
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {SortOptions} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {SCGenericSort} from '@openstapps/core';
|
||||
|
||||
/**
|
||||
* Converts a generic sort to elasticsearch syntax
|
||||
*
|
||||
* @param sort A sorting definition
|
||||
*/
|
||||
export function hashStringToInt(string_: string): number {
|
||||
return [...string_].reduce(
|
||||
(accumulator, current) =>
|
||||
(current.codePointAt(0) ?? 0) + (accumulator << 6) + (accumulator << 16) - accumulator,
|
||||
0,
|
||||
);
|
||||
export function buildGenericSort(sort: SCGenericSort): SortOptions {
|
||||
return {
|
||||
[sort.arguments.field]: sort.order,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,10 +24,11 @@ import {expect} from 'chai';
|
||||
import {bulk, DEFAULT_TEST_TIMEOUT} from '../common.js';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
import {v4} from 'uuid';
|
||||
|
||||
const book = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
|
||||
);
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.2.json', 'utf8'),
|
||||
).instance;
|
||||
|
||||
describe('Bulk routes', async function () {
|
||||
// increase timeout for the suite
|
||||
@@ -60,7 +61,7 @@ describe('Bulk routes', async function () {
|
||||
|
||||
it('should return (throw) error if a bulk with the provided UID cannot be found when adding to a bulk', async function () {
|
||||
await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request);
|
||||
const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid');
|
||||
const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', v4());
|
||||
|
||||
const {status} = await testApp
|
||||
.post(bulkAddRouteUrlPath)
|
||||
@@ -75,10 +76,10 @@ describe('Bulk routes', async function () {
|
||||
.post(bulkRoute.urlPath)
|
||||
.set('Content-Type', 'application/json')
|
||||
.send(request);
|
||||
const bulkAddRouteurlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', response.body.uid);
|
||||
const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', response.body.uid);
|
||||
|
||||
const {status, body} = await testApp
|
||||
.post(bulkAddRouteurlPath)
|
||||
.post(bulkAddRouteUrlPath)
|
||||
.set('Content-Type', 'application/json')
|
||||
.send(book);
|
||||
|
||||
@@ -88,10 +89,10 @@ describe('Bulk routes', async function () {
|
||||
|
||||
it('should return (throw) error if a bulk with the provided UID cannot be found when closing a bulk (done)', async function () {
|
||||
await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request);
|
||||
const bulkDoneRouteurlPath = bulkDoneRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid');
|
||||
const bulkDoneRouteUrlPath = bulkDoneRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid');
|
||||
|
||||
const {status} = await testApp
|
||||
.post(bulkDoneRouteurlPath)
|
||||
.post(bulkDoneRouteUrlPath)
|
||||
.set('Content-Type', 'application/json')
|
||||
.send({});
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ use(chaiAsPromised);
|
||||
|
||||
const book = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
|
||||
);
|
||||
).instance;
|
||||
|
||||
describe('Thing update route', async function () {
|
||||
// increase timeout for the suite
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {AggregateName, AggregationsMultiTermsBucket} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {AggregateName, AggregationsMultiTermsBucket} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {SCFacet, SCThingType} from '@openstapps/core';
|
||||
import {expect} from 'chai';
|
||||
import {parseAggregations} from '../../../src/storage/elasticsearch/aggregations.js';
|
||||
|
||||
@@ -15,13 +15,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Client, Diagnostic} from '@elastic/elasticsearch';
|
||||
import Indices from '@elastic/elasticsearch/lib/api/api/indices';
|
||||
import {
|
||||
CreateResponse,
|
||||
SearchHit,
|
||||
SearchResponse,
|
||||
SortCombinations,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import Indices from '@elastic/elasticsearch/lib/api/api/indices.js';
|
||||
import {CreateResponse, SearchHit, SearchResponse} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {
|
||||
SCBook,
|
||||
SCBulkResponse,
|
||||
@@ -36,27 +31,25 @@ import {expect, use} from 'chai';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {beforeEach} from 'mocha';
|
||||
import mockedEnv from 'mocked-env';
|
||||
import {
|
||||
ACTIVE_INDICES_ALIAS,
|
||||
INACTIVE_INDICES_ALIAS,
|
||||
parseIndexName,
|
||||
} from '../../../src/storage/elasticsearch/util.js';
|
||||
import * as queryModule from '../../../src/storage/elasticsearch/query/query.js';
|
||||
import * as sortModule from '../../../src/storage/elasticsearch/query/sort.js';
|
||||
import sinon, {SinonStub} from 'sinon';
|
||||
import {getIndexUID, getThingIndexName, INDEX_UID_LENGTH} from '../../../src/storage/elasticsearch/util.js';
|
||||
import * as utilModule from '../../../src/storage/elasticsearch/util.js';
|
||||
import {removeInvalidAliasChars} from '../../../src/storage/elasticsearch/util/alias.js';
|
||||
import {configFile} from '../../../src/common.js';
|
||||
import {MailQueue} from '../../../src/notification/mail-queue.js';
|
||||
import {aggregations} from '../../../src/storage/elasticsearch/templating.js';
|
||||
import {Elasticsearch} from '../../../src/storage/elasticsearch/elasticsearch.js';
|
||||
import * as Monitoring from '../../../src/storage/elasticsearch/monitoring.js';
|
||||
import * as templating from '../../../src/storage/elasticsearch/templating.js';
|
||||
import {bulk, DEFAULT_TEST_TIMEOUT, getTransport, getIndex} from '../../common.js';
|
||||
import fs from 'fs';
|
||||
import {backendConfig} from '../../../src/config.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
import {
|
||||
ACTIVE_INDICES_ALIAS,
|
||||
getIndexUID,
|
||||
getThingIndexName,
|
||||
INACTIVE_INDICES_ALIAS,
|
||||
INDEX_UID_LENGTH,
|
||||
parseIndexName,
|
||||
} from '../../../src/storage/elasticsearch/util/index.js';
|
||||
import cron from 'node-cron';
|
||||
import {query} from './query.js';
|
||||
|
||||
use(chaiAsPromised);
|
||||
|
||||
@@ -115,7 +108,7 @@ describe('Elasticsearch', function () {
|
||||
|
||||
describe('getAliasMap', function () {
|
||||
it('should fail after retries', async function () {
|
||||
const es = new Elasticsearch(configFile);
|
||||
const es = new Elasticsearch(backendConfig);
|
||||
sandbox.stub(es.client.indices, 'getAlias').throws();
|
||||
await expect(es.init({maxRetries: 1, retryInterval: 10})).to.be.rejected;
|
||||
});
|
||||
@@ -283,17 +276,24 @@ describe('Elasticsearch', function () {
|
||||
...backendConfig.internal,
|
||||
monitoring: {
|
||||
actions: [],
|
||||
watchers: [],
|
||||
watchers: [
|
||||
{
|
||||
triggers: [{executionTime: 'daily', name: 'trigger'}],
|
||||
name: 'watcher',
|
||||
actions: [],
|
||||
query: {},
|
||||
conditions: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const monitoringSetUpStub = sandbox.stub(Monitoring, 'setUp');
|
||||
const cronSetupStub = sandbox.stub(cron, 'schedule');
|
||||
|
||||
const es = new Elasticsearch(config, new MailQueue(getTransport(false) as unknown as SMTP));
|
||||
|
||||
es.init();
|
||||
|
||||
expect(monitoringSetUpStub.called).to.be.true;
|
||||
expect(cronSetupStub.called).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -308,14 +308,14 @@ describe('Elasticsearch', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox
|
||||
.stub(Indices.prototype, 'getAlias')
|
||||
.stub(Indices.default.prototype, 'getAlias')
|
||||
.resolves({[oldIndex]: {aliases: {[SCThingType.Book]: {}}}} as any);
|
||||
sandbox.stub(Indices.prototype, 'putTemplate').resolves({} as any);
|
||||
createStub = sandbox.stub(Indices.prototype, 'create').resolves({} as any);
|
||||
deleteStub = sandbox.stub(Indices.prototype, 'delete').resolves({} as any);
|
||||
refreshStub = sandbox.stub(Indices.prototype, 'refresh').resolves({} as any);
|
||||
updateAliasesStub = sandbox.stub(Indices.prototype, 'updateAliases').resolves({} as any);
|
||||
es = new Elasticsearch(configFile);
|
||||
sandbox.stub(Indices.default.prototype, 'putTemplate').resolves({} as any);
|
||||
createStub = sandbox.stub(Indices.default.prototype, 'create').resolves({} as any);
|
||||
deleteStub = sandbox.stub(Indices.default.prototype, 'delete').resolves({} as any);
|
||||
refreshStub = sandbox.stub(Indices.default.prototype, 'refresh').resolves({} as any);
|
||||
updateAliasesStub = sandbox.stub(Indices.default.prototype, 'updateAliases').resolves({} as any);
|
||||
es = new Elasticsearch(backendConfig);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@@ -329,21 +329,18 @@ describe('Elasticsearch', function () {
|
||||
|
||||
it('should reject (throw an error) if the index name is not valid', async function () {
|
||||
sandbox.createStubInstance(Client, {});
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(`invalid_${getIndex}`);
|
||||
const invalidBulk = {...bulk, source: '%#$^'};
|
||||
await es.init();
|
||||
|
||||
return expect(es.bulkCreated(bulk)).to.be.rejectedWith('Index');
|
||||
return expect(es.bulkCreated(invalidBulk)).to.be.rejectedWith('Index');
|
||||
});
|
||||
|
||||
it('should create a new index', async function () {
|
||||
const index = getIndex();
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(index);
|
||||
const putTemplateStub = sandbox.stub(templating, 'putTemplate');
|
||||
sandbox.stub(es, 'prepareBulkWrite').resolves(index);
|
||||
await es.init();
|
||||
|
||||
await es.bulkCreated(bulk);
|
||||
|
||||
expect(putTemplateStub.called).to.be.true;
|
||||
expect(createStub.calledWith({index, aliases: {[INACTIVE_INDICES_ALIAS]: {}}})).to.be.true;
|
||||
});
|
||||
});
|
||||
@@ -354,7 +351,7 @@ describe('Elasticsearch', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
it('should cleanup index in case of the expired bulk for bulk whose index is not in use', async function () {
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(getIndex());
|
||||
sandbox.stub(es, 'prepareBulkWrite').resolves(getIndex());
|
||||
|
||||
await es.init();
|
||||
await es.bulkExpired({...bulk, state: 'in progress'});
|
||||
@@ -363,7 +360,7 @@ describe('Elasticsearch', function () {
|
||||
});
|
||||
|
||||
it('should not cleanup index in case of the expired bulk for bulk whose index is in use', async function () {
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(getIndex());
|
||||
sandbox.stub(es, 'prepareBulkWrite').resolves(getIndex());
|
||||
|
||||
await es.init();
|
||||
await es.bulkExpired({...bulk, state: 'done'});
|
||||
@@ -378,11 +375,11 @@ describe('Elasticsearch', function () {
|
||||
});
|
||||
|
||||
it('should reject if the index name is not valid', async function () {
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(`invalid_${getIndex()}`);
|
||||
const invalidBulk = {...bulk, source: '%#$^'};
|
||||
sandbox.createStubInstance(Client, {});
|
||||
await es.init();
|
||||
|
||||
return expect(es.bulkUpdated(bulk)).to.be.rejectedWith('Index');
|
||||
return expect(es.bulkUpdated(invalidBulk)).to.be.rejectedWith('Index');
|
||||
});
|
||||
|
||||
it("should refuse to finalize bulk if index doesn't exist", async function () {
|
||||
@@ -411,10 +408,8 @@ describe('Elasticsearch', function () {
|
||||
remove_index: {index: oldIndex},
|
||||
},
|
||||
];
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(index);
|
||||
sandbox.stub(templating, 'putTemplate');
|
||||
sandbox.stub(es, 'prepareBulkWrite').resolves(index);
|
||||
await es.init();
|
||||
|
||||
await es.bulkUpdated(bulk);
|
||||
|
||||
expect(refreshStub.calledWith({index, allow_no_indices: false})).to.be.true;
|
||||
@@ -467,7 +462,7 @@ describe('Elasticsearch', function () {
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(Indices.prototype, 'getAlias').resolves({} as any);
|
||||
sandbox.stub(Indices.default.prototype, 'getAlias').resolves({} as any);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@@ -483,7 +478,7 @@ describe('Elasticsearch', function () {
|
||||
_source: message as SCMessage,
|
||||
};
|
||||
sandbox.stub(es.client, 'search').resolves(searchResponse<SCMessage>(object));
|
||||
sandbox.stub(utilModule, 'getThingIndexName').returns(index);
|
||||
sandbox.stub(es, 'prepareBulkWrite').resolves(index);
|
||||
|
||||
await es.init();
|
||||
return expect(es.post(object._source!, bulk)).to.be.rejectedWith('UID conflict');
|
||||
@@ -609,7 +604,7 @@ describe('Elasticsearch', function () {
|
||||
};
|
||||
let searchStub: sinon.SinonStub;
|
||||
before(function () {
|
||||
es = new Elasticsearch(configFile);
|
||||
es = new Elasticsearch(backendConfig);
|
||||
});
|
||||
beforeEach(function () {
|
||||
searchStub = sandbox.stub(es.client, 'search').resolves(fakeSearchResponse);
|
||||
@@ -680,18 +675,14 @@ describe('Elasticsearch', function () {
|
||||
},
|
||||
},
|
||||
};
|
||||
const fakeResponse = {foo: 'bar'} as SortCombinations;
|
||||
const fakeBuildSortResponse = [fakeResponse];
|
||||
// @ts-expect-error not assignable
|
||||
sandbox.stub(queryModule, 'buildQuery').returns(fakeResponse);
|
||||
sandbox.stub(sortModule, 'buildSort').returns(fakeBuildSortResponse);
|
||||
|
||||
await es.search(parameters);
|
||||
|
||||
sandbox.assert.calledWithMatch(searchStub, {
|
||||
expect(searchStub.firstCall.firstArg).to.be.deep.equal({
|
||||
aggs: aggregations,
|
||||
query: fakeResponse,
|
||||
sort: fakeBuildSortResponse,
|
||||
query,
|
||||
allow_no_indices: true,
|
||||
sort: [{'name.sort': 'desc'}],
|
||||
from: parameters.from,
|
||||
index: ACTIVE_INDICES_ALIAS,
|
||||
size: parameters.size,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {Client} from '@elastic/elasticsearch';
|
||||
import {SearchResponse} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {SearchResponse} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {
|
||||
SCMonitoringConfiguration,
|
||||
SCMonitoringLogAction,
|
||||
|
||||
@@ -31,7 +31,7 @@ import {buildQuery} from '../../../src/storage/elasticsearch/query/query.js';
|
||||
import {buildSort} from '../../../src/storage/elasticsearch/query/sort.js';
|
||||
import {ElasticsearchConfig} from '../../../src/storage/elasticsearch/types/elasticsearch-config.js';
|
||||
import {QueryDslSpecificQueryContainer} from '../../../src/storage/elasticsearch/types/util.js';
|
||||
import {SortCombinations} from '@elastic/elasticsearch/lib/api/types';
|
||||
import {SortCombinations} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
import {backendConfig} from '../../../src/config.js';
|
||||
|
||||
describe('Query', function () {
|
||||
|
||||
386
backend/backend/test/storage/elasticsearch/query.ts
Normal file
386
backend/backend/test/storage/elasticsearch/query.ts
Normal file
@@ -0,0 +1,386 @@
|
||||
import {QueryDslQueryContainer} from '@elastic/elasticsearch/lib/api/types.js';
|
||||
|
||||
export const query: QueryDslQueryContainer = {
|
||||
function_score: {
|
||||
functions: [
|
||||
{
|
||||
filter: {
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
weight: 1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'academicTerms.acronym.raw': 'SS 2023',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'academicTerms.acronym.raw': 'WS 2022/23',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.05,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'academicTerms.acronym.raw': 'SoSe 2023',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'academicTerms.acronym.raw': 'WiSe 2022/23',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.05,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
weight: 1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'course',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.08,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'integrated course',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.08,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'introductory class',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.05,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'lecture',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'seminar',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.01,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'academic event',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'tutorial',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.05,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
term: {
|
||||
type: 'building',
|
||||
},
|
||||
},
|
||||
weight: 1.6,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
term: {
|
||||
type: 'point of interest',
|
||||
},
|
||||
},
|
||||
weight: 1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'point of interest',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'cafe',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'point of interest',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'learn',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'point of interest',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'library',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.2,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'point of interest',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'restaurant',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 1.1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
term: {
|
||||
type: 'dish',
|
||||
},
|
||||
},
|
||||
weight: 1,
|
||||
},
|
||||
{
|
||||
filter: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: 'dish',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'categories.raw': 'main dish',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
weight: 2,
|
||||
},
|
||||
],
|
||||
query: {
|
||||
bool: {
|
||||
minimum_should_match: 0,
|
||||
must: [
|
||||
{
|
||||
dis_max: {
|
||||
boost: 1.2,
|
||||
queries: [
|
||||
{
|
||||
match: {
|
||||
name: {
|
||||
boost: 1.3,
|
||||
fuzziness: 'AUTO',
|
||||
query: 'mathematics',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
query_string: {
|
||||
default_field: 'name',
|
||||
minimum_should_match: '75%',
|
||||
query: 'mathematics',
|
||||
},
|
||||
},
|
||||
],
|
||||
tie_breaker: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
'type.raw': 'academic event',
|
||||
},
|
||||
},
|
||||
],
|
||||
should: [],
|
||||
},
|
||||
},
|
||||
score_mode: 'multiply',
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user