From: Wouter Admiraal Date: Tue, 14 Jun 2022 09:38:48 +0000 (+0200) Subject: SONAR-16490 Embedded documentation throws exception when visited twice X-Git-Tag: 9.6.0.59041~363 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=95a251388ad0c6e4d077737fbcb8cd0a628745cd;p=sonarqube.git SONAR-16490 Embedded documentation throws exception when visited twice --- diff --git a/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx b/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx index c5395620f1a..784909c3e40 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx @@ -157,8 +157,14 @@ export function tokenContextPluginCallback(token: LunrToken, index: number, toke return token; } +let tokenContextPluginRegistered = false; + export function tokenContextPlugin(builder: LunrBuilder) { - (lunr as any).Pipeline.registerFunction(tokenContextPluginCallback, 'tokenContext'); + if (!tokenContextPluginRegistered) { + (lunr as any).Pipeline.registerFunction(tokenContextPluginCallback, 'tokenContext'); + tokenContextPluginRegistered = true; + } + builder.pipeline.before((lunr as any).stemmer, tokenContextPluginCallback); builder.metadataWhitelist.push('tokenContext'); } diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx index 40fd9ed3aae..d01e6646c76 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { shallow } from 'enzyme'; -import lunr, { LunrToken } from 'lunr'; +import lunr, { LunrBuilder, LunrToken } from 'lunr'; import * as React from 'react'; import { mockDocumentationEntry } from '../../../../helpers/testMocks'; import { getUrlsList } from '../../navTreeUtils'; @@ -30,8 +30,8 @@ jest.mock('../../navTreeUtils', () => ({ getUrlsList: jest.fn().mockReturnValue([]) })); -jest.mock('lunr', () => - jest.fn(() => ({ +jest.mock('lunr', () => { + const lunr = jest.fn(() => ({ search: jest.fn(() => [ { ref: 'lorem/origin', @@ -68,8 +68,14 @@ jest.mock('lunr', () => } } ]) - })) -); + })); + + (lunr as any).Pipeline = { + registerFunction: jest.fn() + }; + + return lunr; +}); it('should render correctly', () => { expect(shallowRender()).toMatchSnapshot('default'); @@ -164,10 +170,28 @@ describe('tokenContextPluginCallback', () => { } } + class LunrBuilderMock { + pipeline: { before: (stemmer: any, cb: Function) => void }; + metadataWhitelist: string[]; + + constructor() { + this.pipeline = { + before: () => { + /* noop */ + } + }; + this.metadataWhitelist = []; + } + } + function mockLunrToken(str: string): LunrToken { return new LunrTokenMock(str); } + function mockLunrBuilder(): LunrBuilder { + return new LunrBuilderMock(); + } + it('should correctly provide token context for text', () => { const tokens = [ mockLunrToken('this'), @@ -189,6 +213,12 @@ describe('tokenContextPluginCallback', () => { expect.objectContaining({ tokenContext: 'some text' }) ); }); + + it('should only register the plugin once', () => { + tokenContextPlugin(mockLunrBuilder()); + tokenContextPlugin(mockLunrBuilder()); + expect((lunr as any).Pipeline.registerFunction).toBeCalledTimes(1); + }); }); function shallowRender(props: Partial = {}) {