Skip to content

Commit

Permalink
feat(dictionaries): adds methods and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chloelbn committed Feb 17, 2021
1 parent 677e902 commit 8f648ad
Show file tree
Hide file tree
Showing 21 changed files with 585 additions and 0 deletions.
61 changes: 61 additions & 0 deletions packages/algoliasearch/src/builds/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
browseSynonyms,
ChunkedBatchResponse,
ChunkOptions,
clearDictionaryEntries,
clearObjects,
clearRules,
ClearRulesOptions,
Expand All @@ -60,13 +61,16 @@ import {
DeleteApiKeyResponse,
deleteBy,
DeleteByFiltersOptions,
deleteDictionaryEntries,
deleteIndex,
deleteObject,
deleteObjects,
DeleteResponse,
deleteRule,
deleteSynonym,
DeleteSynonymOptions,
DictionaryEntry,
DictionarySettings,
exists,
findAnswers,
FindAnswersOptions,
Expand All @@ -76,6 +80,9 @@ import {
FindObjectResponse,
getApiKey,
GetApiKeyResponse,
getDictionarySettings,
GetDictionarySettingsResponse,
getDictionaryTask,
getLogs,
GetLogsResponse,
getObject,
Expand Down Expand Up @@ -127,9 +134,13 @@ import {
ReplaceAllObjectsOptions,
replaceAllRules,
replaceAllSynonyms,
replaceDictionaryEntries,
restoreApiKey,
RestoreApiKeyResponse,
Rule,
saveDictionaryEntries,
SaveDictionaryEntriesOptions,
SaveDictionaryEntriesResponse,
saveObject,
SaveObjectResponse,
saveObjects,
Expand All @@ -146,6 +157,8 @@ import {
SaveSynonymsResponse,
search,
SearchClient as BaseSearchClient,
searchDictionaryEntries,
SearchDictionaryEntriesResponse,
searchForFacetValues,
SearchForFacetValuesQueryParams,
SearchForFacetValuesResponse,
Expand All @@ -160,14 +173,18 @@ import {
searchUserIDs,
SearchUserIDsOptions,
SearchUserIDsResponse,
setDictionarySettings,
SetDictionarySettingsResponse,
setSettings,
SetSettingsResponse,
Settings,
Synonym,
TaskStatusResponse,
updateApiKey,
UpdateApiKeyOptions,
UpdateApiKeyResponse,
UserIDResponse,
waitDictionaryTask,
waitTask,
} from '@algolia/client-search';
import { LogLevelEnum } from '@algolia/logger-common';
Expand Down Expand Up @@ -235,6 +252,15 @@ export default function algoliasearch(
getTopUserIDs,
removeUserID,
hasPendingMappings,
clearDictionaryEntries,
deleteDictionaryEntries,
getDictionarySettings,
getDictionaryTask,
replaceDictionaryEntries,
saveDictionaryEntries,
searchDictionaryEntries,
setDictionarySettings,
waitDictionaryTask,
initIndex: base => (indexName: string): SearchIndex => {
return initIndex(base)(indexName, {
methods: {
Expand Down Expand Up @@ -601,6 +627,41 @@ export type SearchClient = BaseSearchClient & {
readonly hasPendingMappings: (
requestOptions?: HasPendingMappingsOptions & RequestOptions
) => Readonly<Promise<HasPendingMappingsResponse>>;
readonly clearDictionaryEntries: (
dictionary: string,
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly deleteDictionaryEntries: (
dictionary: string,
objectIDs: readonly string[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly replaceDictionaryEntries: (
dictionary: string,
entries: readonly DictionaryEntry[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly saveDictionaryEntries: (
dictionary: string,
entries: readonly DictionaryEntry[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly searchDictionaryEntries: (
dictionary: string,
query: string,
requestOptions?: RequestOptions
) => Readonly<Promise<SearchDictionaryEntriesResponse>>;
readonly getDictionarySettings: (
requestOptions?: RequestOptions
) => Readonly<Promise<GetDictionarySettingsResponse>>;
readonly setDictionarySettings: (
settings: readonly DictionarySettings[],
requestOptions?: RequestOptions
) => Readonly<WaitablePromise<SetDictionarySettingsResponse>>;
readonly getDictionaryTask: (
taskID: number,
requestOptions?: RequestOptions
) => Readonly<Promise<TaskStatusResponse>>;
readonly initAnalytics: (options?: InitAnalyticsOptions) => AnalyticsClient;
readonly initRecommendation: (options?: InitRecommendationOptions) => RecommendationClient;
};
Expand Down
61 changes: 61 additions & 0 deletions packages/algoliasearch/src/builds/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
browseSynonyms,
ChunkedBatchResponse,
ChunkOptions,
clearDictionaryEntries,
clearObjects,
clearRules,
ClearRulesOptions,
Expand All @@ -59,13 +60,16 @@ import {
DeleteApiKeyResponse,
deleteBy,
DeleteByFiltersOptions,
deleteDictionaryEntries,
deleteIndex,
deleteObject,
deleteObjects,
DeleteResponse,
deleteRule,
deleteSynonym,
DeleteSynonymOptions,
DictionaryEntry,
DictionarySettings,
exists,
findAnswers,
FindAnswersOptions,
Expand All @@ -76,6 +80,9 @@ import {
generateSecuredApiKey,
getApiKey,
GetApiKeyResponse,
getDictionarySettings,
GetDictionarySettingsResponse,
getDictionaryTask,
getLogs,
GetLogsResponse,
getObject,
Expand Down Expand Up @@ -128,9 +135,13 @@ import {
ReplaceAllObjectsOptions,
replaceAllRules,
replaceAllSynonyms,
replaceDictionaryEntries,
restoreApiKey,
RestoreApiKeyResponse,
Rule,
saveDictionaryEntries,
SaveDictionaryEntriesOptions,
SaveDictionaryEntriesResponse,
saveObject,
SaveObjectResponse,
saveObjects,
Expand All @@ -147,6 +158,8 @@ import {
SaveSynonymsResponse,
search,
SearchClient as BaseSearchClient,
searchDictionaryEntries,
SearchDictionaryEntriesResponse,
searchForFacetValues,
SearchForFacetValuesQueryParams,
SearchForFacetValuesResponse,
Expand All @@ -162,14 +175,18 @@ import {
SearchUserIDsOptions,
SearchUserIDsResponse,
SecuredApiKeyRestrictions,
setDictionarySettings,
SetDictionarySettingsResponse,
setSettings,
SetSettingsResponse,
Settings,
Synonym,
TaskStatusResponse,
updateApiKey,
UpdateApiKeyOptions,
UpdateApiKeyResponse,
UserIDResponse,
waitDictionaryTask,
waitTask,
} from '@algolia/client-search';
import { createNullLogger } from '@algolia/logger-common';
Expand Down Expand Up @@ -238,6 +255,15 @@ export default function algoliasearch(
generateSecuredApiKey,
getSecuredApiKeyRemainingValidity,
destroy,
clearDictionaryEntries,
deleteDictionaryEntries,
getDictionarySettings,
getDictionaryTask,
replaceDictionaryEntries,
saveDictionaryEntries,
searchDictionaryEntries,
setDictionarySettings,
waitDictionaryTask,
initIndex: base => (indexName: string): SearchIndex => {
return initIndex(base)(indexName, {
methods: {
Expand Down Expand Up @@ -609,6 +635,41 @@ export type SearchClient = BaseSearchClient & {
restrictions: SecuredApiKeyRestrictions
) => string;
readonly getSecuredApiKeyRemainingValidity: (securedApiKey: string) => number;
readonly clearDictionaryEntries: (
dictionary: string,
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly deleteDictionaryEntries: (
dictionary: string,
objectIDs: readonly string[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly replaceDictionaryEntries: (
dictionary: string,
entries: readonly DictionaryEntry[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly saveDictionaryEntries: (
dictionary: string,
entries: readonly DictionaryEntry[],
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
) => Readonly<WaitablePromise<SaveDictionaryEntriesResponse>>;
readonly searchDictionaryEntries: (
dictionary: string,
query: string,
requestOptions?: RequestOptions
) => Readonly<Promise<SearchDictionaryEntriesResponse>>;
readonly getDictionarySettings: (
requestOptions?: RequestOptions
) => Readonly<Promise<GetDictionarySettingsResponse>>;
readonly setDictionarySettings: (
settings: readonly DictionarySettings[],
requestOptions?: RequestOptions
) => Readonly<WaitablePromise<SetDictionarySettingsResponse>>;
readonly getDictionaryTask: (
taskID: number,
requestOptions?: RequestOptions
) => Readonly<Promise<TaskStatusResponse>>;
readonly initAnalytics: (options?: InitAnalyticsOptions) => AnalyticsClient;
readonly initRecommendation: (options?: InitRecommendationOptions) => RecommendationClient;
} & Destroyable;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { TestSuite } from '../../../../client-common/src/__tests__/TestSuite';

const testSuite = new TestSuite('dictionary');

test(testSuite.testName, async () => {
const client = testSuite.makeSearchClient('ALGOLIA_APPLICATION_ID_2', 'ALGOLIA_ADMIN_KEY_2')

// Stopwords
const stopwordEntryId = Math.floor(Math.random() * 10000).toString();
expect(await client.searchDictionaryEntries('stopwords', stopwordEntryId).nbHits).toEqual(0);

const stopwordEntry = {
objectID: stopwordEntryId,
language: 'en',
word: 'down',
};

await client.saveDictionaryEntries('stopwords', [stopwordEntry]);

const stopwords = await client.searchDictionaryEntries('stopwords', stopwordEntryId);
expect(stopwords.nbHits).toEqual(1);
expect(stopwords.hits[0].objectID).toEqual(stopwordEntry.objectID);
expect(stopwords.hits[0].word).toEqual(stopwordEntry.word);

await client.deleteDictionaryEntries('stopwords', [stopwordEntryId]);
expect(await client.searchDictionaryEntries('stopwords', stopwordEntryId).nbHits).toEqual(0);

const oldDictionaryState = await client.searchDictionaryEntries('stopwords', '');
const oldDictionaryEntries = oldDictionaryState.hits.map(hit => {
delete hit.type;

return hit;
});

await client.saveDictionaryEntries('stopwords', [stopwordEntry]);
expect(await client.searchDictionaryEntries('stopwords', stopwordEntryId).nbHits).toEqual(1);

await client.replaceDictionaryEntries('stopwords', oldDictionaryEntries);
expect(await client.searchDictionaryEntries('stopwords', stopwordEntryId).nbHits).toEqual(0);

const stopwordsSettings = {
disableStandardEntries: {
stopwords: {
en: true,
},
},
};

await client.setDictionarySettings(stopwordsSettings);
expect(await client.getDictionarySettings()).toEqual(stopwordsSettings);

// Plurals
const pluralEntryId = Math.floor(Math.random() * 10000).toString();
expect(await client.searchDictionaryEntries('plurals', pluralEntryId).nbHits).toEqual(0);

const pluralEntry = {
objectID: pluralEntryId,
language: 'fr',
words: ['cheval', 'chevaux'],
};

await client.saveDictionaryEntries('plurals', [pluralEntry]);

const plurals = await client.searchDictionaryEntries('plurals', pluralEntryId);
expect(plurals.nbHits).toEqual(1);
expect(plurals.hits[0].objectID).toEqual(pluralEntry.objectID);
expect(plurals.hits[0].words).toEqual(pluralEntry.words);

await client.deleteDictionaryEntries('plurals', [pluralEntryId]);
expect(await client.searchDictionaryEntries('plurals', pluralEntryId).nbHits).toEqual(0);

// Compounds
const compoundEntryId = Math.floor(Math.random() * 10000).toString();
expect(await client.searchDictionaryEntries('plurals', compoundEntryId).nbHits).toEqual(0);

const compoundEntry = {
objectID: compoundEntryId,
language: 'fr',
word: 'kopfschmerztablette',
decomposition: ['kopf', 'schmerz', 'tablette'],
};

await client.saveDictionaryEntries('plurals', [compoundEntry]);

const compounds = await client.searchDictionaryEntries('plurals', compoundEntryId);
expect(compounds.nbHits).toEqual(1);
expect(compounds.hits[0].objectID).toEqual(compoundEntry.objectID);
expect(compounds.hits[0].word).toEqual(compoundEntry.word);
expect(compounds.hits[0].decomposition).toEqual(compoundEntry.decomposition);

await client.deleteDictionaryEntries('plurals', [compoundEntryId]);
expect(await client.searchDictionaryEntries('plurals', compoundEntryId).nbHits).toEqual(0);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { createWaitablePromise, encode, WaitablePromise } from '@algolia/client-common';
import { MethodEnum } from '@algolia/requester-common';
import { RequestOptions } from '@algolia/transporter';

import { SaveDictionaryEntriesOptions, SaveDictionaryEntriesResponse, SearchClient } from '../..';
import { waitDictionaryTask } from '.';

// TODO: fill in SaveDictionaryEntriesOptions type
export const clearDictionaryEntries = (base: SearchClient) => {
return (
dictionary: string,
requestOptions?: RequestOptions & SaveDictionaryEntriesOptions
): Readonly<WaitablePromise<SaveDictionaryEntriesResponse>> => {
return createWaitablePromise<SaveDictionaryEntriesResponse>(
base.transporter.write(
{
method: MethodEnum.Post,
path: encode('/1/dictionaries/%s/batch', dictionary),
data: {
clearExistingDictionaryEntries: true,
requests: { action: 'addEntry', body: [] },
},
},
requestOptions
),
(response, waitRequestOptions) =>
waitDictionaryTask(base)(response.taskID, waitRequestOptions)
);
};
};
Loading

0 comments on commit 8f648ad

Please sign in to comment.