Skip to content

Instantly share code, notes, and snippets.

@michaelbromley
Created June 18, 2020 14:19
Show Gist options
  • Save michaelbromley/40e89be0b00c36e2458c5d3138f4fb79 to your computer and use it in GitHub Desktop.
Save michaelbromley/40e89be0b00c36e2458c5d3138f4fb79 to your computer and use it in GitHub Desktop.
MeiliSearch Issue Jest tests
module.exports = {
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: __dirname,
testRegex: '.spec.ts$',
transform: {
'^.+\\.ts$': 'ts-jest',
},
testEnvironment: 'node',
globals: {
'ts-jest': {
tsConfig: '<rootDir>/e2e/config/tsconfig.e2e.json',
diagnostics: false,
isolatedModules: true,
},
},
};
import Meilisearch, { Index } from 'meilisearch';
import { awaitUpdate } from './src/common/meilisearch-utils';
describe('MeiliSearch facet handling', () => {
let index: Index;
beforeAll(async () => {
const meilisearch = new Meilisearch({
host: 'http://localhost:7700',
});
index = await meilisearch.getOrCreateIndex('facet-issue-test');
await awaitUpdate(index, index.deleteAllDocuments());
await awaitUpdate(
index,
index.updateSettings({
attributesForFaceting: ['genre'],
searchableAttributes: ['id', 'type', 'title', 'genre'],
displayedAttributes: ['id', 'type', 'title', 'genre'],
}),
);
const enqueuedUpdatePromise = index.addDocuments([
{
id: '1',
type: 'album',
title: 'Nevermind',
genre: ['grunge', 'alternative'],
},
{
id: '2',
type: 'album',
title: 'Mellon Collie and the Infinite Sadness',
genre: ['alternative', 'rock'],
},
{
id: '3',
type: 'album',
title: 'The Queen Is Dead',
genre: ['indie', 'rock'],
},
]);
await awaitUpdate(index, enqueuedUpdatePromise);
});
it('Facet distribution correct', async () => {
const result = await index.search('album', {
facetsDistribution: ['genre'],
});
expect(result.facetsDistribution).toEqual({
genre: {
grunge: 1,
alternative: 2,
rock: 2,
indie: 1,
},
});
});
it('Update facet', async () => {
const before = await index.getDocument('3');
expect(before.genre).toEqual(['indie', 'rock']);
const enqueuedUpdatePromise = index.updateDocuments([
{
id: '3',
title: 'The Queen Is Very Dead',
},
]);
await awaitUpdate(index, enqueuedUpdatePromise);
const after = await index.getDocument('3');
expect(after.genre).toEqual(['indie', 'rock']);
const result = await index.search('album', {
facetsDistribution: ['genre'],
});
expect(result.facetsDistribution).toEqual({
genre: {
grunge: 1,
alternative: 2,
rock: 2,
indie: 1,
},
});
});
});
import { EnqueuedUpdate, Index } from 'meilisearch';
import { Logger } from '@vendure/core';
import { loggerCtx } from '../../index';
/**
* Polls the enqueued update with an exponential backoff strategy until it is either
* processed or fails.
*/
export async function awaitUpdate(
index: Index,
enqueuedUpdatePromise: Promise<EnqueuedUpdate>,
): Promise<boolean> {
const maxAttempts = 50;
let attempts = 0;
let delay = 2;
const backoffFactor = 1.25;
const enqueuedUpdate = await enqueuedUpdatePromise;
while (attempts < maxAttempts) {
const update = await index.getUpdateStatus(enqueuedUpdate.updateId);
const debugMessage =
update.status === 'enqueued'
? `Polling update ${index.uid}-${enqueuedUpdate.updateId}, attempt ${attempts + 1}`
: `${update.status.toLocaleUpperCase()}: ${index.uid}-${
enqueuedUpdate.updateId
}${JSON.stringify(update.type)}, duration ${update.duration}`;
Logger.debug(debugMessage, loggerCtx);
if (update.status !== 'enqueued') {
if (update.status === 'failed') {
Logger.error(`${index.uid}: ${(update as any).error}`, loggerCtx);
Logger.error(JSON.stringify(update), loggerCtx);
return false;
} else {
return true;
}
}
attempts++;
await new Promise((resolve) => {
delay *= backoffFactor;
setTimeout(resolve, delay * backoffFactor);
});
}
Logger.error(
`Attempt to retrieve update status exceeded max attempts. UpdateId: ${enqueuedUpdate.updateId}`,
loggerCtx,
);
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment