Skip to content

Commit

Permalink
Added test for retrieveAutoCompleteInfo
Browse files Browse the repository at this point in the history
Signed-off-by: kishor82 <kishorrathva8298@gmail.com>
  • Loading branch information
kishor82 committed Dec 4, 2023
1 parent 9700f54 commit 0fb9107
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,14 @@
* GitHub history for details.
*/

import {
HttpFetchError,
HttpFetchOptionsWithPath,
HttpResponse,
HttpSetup,
} from '../../../../../../core/public';
import { HttpFetchError, HttpSetup } from '../../../../../../core/public';
import { OpenSearchRequestArgs, sendRequestToOpenSearch } from './send_request_to_opensearch';
import * as opensearch from '../../../lib/opensearch/opensearch';
import {
createMockHttpResponse,
createMockResponse,
} from '../../../lib/opensearch/http_response.mock';

const createMockResponse = (
statusCode: number,
statusText: string,
headers: Array<[string, string]>
): Response => {
return {
// headers: {} as Headers,
headers: new Headers(headers),
ok: true,
redirected: false,
status: statusCode,
statusText,
type: 'basic',
url: '',
clone: jest.fn(),
body: (jest.fn() as unknown) as ReadableStream,
bodyUsed: true,
arrayBuffer: jest.fn(),
blob: jest.fn(),
text: jest.fn(),
formData: jest.fn(),
json: jest.fn(),
};
};

const createMockHttpResponse = (
statusCode: number,
statusText: string,
headers: Array<[string, string]>,
body: any
): HttpResponse<any> => {
return {
fetchOptions: (jest.fn() as unknown) as Readonly<HttpFetchOptionsWithPath>,
request: (jest.fn() as unknown) as Readonly<Request>,
response: createMockResponse(statusCode, statusText, headers),
body,
};
};
const dummyArgs: OpenSearchRequestArgs = {
http: ({
post: jest.fn(),
Expand Down
81 changes: 81 additions & 0 deletions src/plugins/console/public/lib/mappings/__tests__/mapping.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@

import { Field } from '../mappings';
import '../../../application/models/sense_editor/sense_editor.test.mocks';
import * as opensearch from '../../opensearch/opensearch';
import * as mappings from '../mappings';
import { createMockHttpResponse } from '../../opensearch/http_response.mock';
import { serviceContextMock } from '../../../application/contexts/services_context.mock';

describe('Mappings', () => {
beforeEach(() => {
Expand Down Expand Up @@ -291,3 +294,81 @@ describe('Mappings', () => {
expect(mappings.getTypes()).toEqual(['properties']);
});
});
const tick = () => new Promise((res) => setImmediate(res));

export const advanceTimersByTime = async (time: number) =>
jest.advanceTimersByTime(time) && (await tick());

export const runOnlyPendingTimers = async () => jest.runOnlyPendingTimers() && (await tick());

export const runAllTimers = async () => jest.runAllTimers() && (await tick());

describe('Auto Complete Info', () => {
let response = {};

beforeEach(() => {
mappings.clear();
response = {
body: {
'sample-ecommerce': {
mappings: {
properties: {
timestamp: {
type: 'date',
},
},
},
},
},
};
jest.resetAllMocks();
jest.useFakeTimers(); // Enable automatic mocking of timers
});

afterEach(() => {
jest.clearAllMocks();
jest.useRealTimers();
});

test('Retrieve AutoComplete Info for Mappings, Aliases and Templates', async () => {
jest.useFakeTimers(); // Ensure fake timers are used

const mockHttpResponse = createMockHttpResponse(
200,
'ok',
[['Content-Type', 'application/json, utf-8']],
response
);

const dataSourceId = 'mock-data-source-id';
const sendSpy = jest.spyOn(opensearch, 'send').mockResolvedValue(mockHttpResponse);

const {
services: { http, settings: settingsService },
} = serviceContextMock.create();

mappings.retrieveAutoCompleteInfo(
http,
settingsService,
{
fields: true,
indices: true,
templates: true,
},
dataSourceId
);

// Fast-forward until all timers have been executed
jest.runAllTimers();

// Resolve the promise chain
await Promise.resolve();

expect(sendSpy).toHaveBeenCalledTimes(3);

// Ensure send is called with different arguments
expect(sendSpy).toHaveBeenCalledWith(http, 'GET', '_mapping', null, dataSourceId);
expect(sendSpy).toHaveBeenCalledWith(http, 'GET', '_aliases', null, dataSourceId);
expect(sendSpy).toHaveBeenCalledWith(http, 'GET', '_template', null, dataSourceId);
});
});
24 changes: 12 additions & 12 deletions src/plugins/console/public/lib/mappings/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ interface IndexAliases {

type IndicesOrAliases = string | string[] | null;

interface SettingKeyToPathMap {
fields: '_mapping';
indices: '_aliases';
templates: '_template';
}

// NOTE: If this value ever changes to be a few seconds or less, it might introduce flakiness
// due to timing issues in our app.js tests.
const POLL_INTERVAL = 60000;
export const POLL_INTERVAL = 60000;
let pollTimeoutId: NodeJS.Timeout | null;

let perIndexTypes: { [index: string]: { [type: string]: Field[] } } = {};
Expand Down Expand Up @@ -316,11 +322,11 @@ export function clear() {

function retrieveSettings(
http: HttpSetup,
settingsKey: string,
settingsKey: keyof SettingKeyToPathMap,
settingsToRetrieve: any,
dataSourceId: string
): Promise<HttpResponse<any>> | Promise<void> | Promise<{}> {
const settingKeyToPathMap: { [settingsKey: string]: string } = {
const settingKeyToPathMap: SettingKeyToPathMap = {
fields: '_mapping',
indices: '_aliases',
templates: '_template',
Expand All @@ -330,13 +336,8 @@ function retrieveSettings(
if (settingsToRetrieve[settingsKey] === true) {
return opensearch.send(http, 'GET', settingKeyToPathMap[settingsKey], null, dataSourceId);
} else {
if (settingsToRetrieve[settingsKey] === false) {
// If the user doesn't want autocomplete suggestions, then clear any that exist
return Promise.resolve({});
} else {
// If the user doesn't want autocomplete suggestions, then clear any that exist
return Promise.resolve();
}
// If the user doesn't want autocomplete suggestions, then clear any that exist
return Promise.resolve();
}
}

Expand Down Expand Up @@ -418,12 +419,11 @@ export function retrieveAutoCompleteInfo(
dataSourceId: string
) {
clearSubscriptions();

Promise.allSettled([
retrieveMappings(http, settingsToRetrieve, dataSourceId),
retrieveAliases(http, settingsToRetrieve, dataSourceId),
retrieveTemplates(http, settingsToRetrieve, dataSourceId),
]).then(() => {
]).then((res) => {
// Schedule next request.
pollTimeoutId = setTimeout(() => {
// This looks strange/inefficient, but it ensures correct behavior because we don't want to send
Expand Down
45 changes: 45 additions & 0 deletions src/plugins/console/public/lib/opensearch/http_response.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { HttpFetchOptionsWithPath, HttpResponse } from '../../../../../core/public';

export const createMockResponse = (
statusCode: number,
statusText: string,
headers: Array<[string, string]>
): Response => {
return {
// headers: {} as Headers,
headers: new Headers(headers),
ok: true,
redirected: false,
status: statusCode,
statusText,
type: 'basic',
url: '',
clone: jest.fn(),
body: (jest.fn() as unknown) as ReadableStream,
bodyUsed: true,
arrayBuffer: jest.fn(),
blob: jest.fn(),
text: jest.fn(),
formData: jest.fn(),
json: jest.fn(),
};
};

export const createMockHttpResponse = (
statusCode: number,
statusText: string,
headers: Array<[string, string]>,
body: any
): HttpResponse<any> => {
return {
fetchOptions: (jest.fn() as unknown) as Readonly<HttpFetchOptionsWithPath>,
request: (jest.fn() as unknown) as Readonly<Request>,
response: createMockResponse(statusCode, statusText, headers),
body,
};
};

0 comments on commit 0fb9107

Please sign in to comment.