/* global fetchMock, process */ const restSearchClient = require( '../../../resources/src/mediawiki.skinning.typeaheadSearch/restSearchClient.js' ); const jestFetchMock = require( 'jest-fetch-mock' ); const urlGeneratorFn = require( '../../../resources/src/mediawiki.skinning.typeaheadSearch/urlGenerator.js' ); const scriptPath = '/w/index.php'; const urlGenerator = urlGeneratorFn( scriptPath ); const searchApiUrl = 'https://en.wikipedia.org/w/rest.php'; const recommendationApiUrl = 'https://en.wikipedia.org/w/api.php'; const mockedRequests = !process.env.TEST_LIVE_REQUESTS; describe( 'restApiSearchClient', () => { beforeAll( () => { jestFetchMock.enableFetchMocks(); } ); afterAll( () => { jestFetchMock.disableFetchMocks(); } ); beforeEach( () => { fetchMock.resetMocks(); if ( !mockedRequests ) { fetchMock.disableMocks(); } } ); test( '2 results', async () => { const thumbUrl = '//upload.wikimedia.org/wikipedia/commons/0/01/MediaWiki-smaller-logo.png'; const restResponse = { pages: [ { id: 37298, key: 'Media', label: 'Media', title: 'Media', description: 'Wikimedia disambiguation page', thumbnail: null, url: '/w/index.php?title=Special%3ASearch&search=Media', value: 37298 }, { id: 323710, key: 'MediaWiki', label: 'MediaWiki', title: 'MediaWiki', description: 'wiki software', thumbnail: { width: 200, height: 189, url: thumbUrl }, url: '/w/index.php?title=Special%3ASearch&search=MediaWiki', value: 323710 } ] }; fetchMock.mockOnce( JSON.stringify( restResponse ) ); const searchResult = await restSearchClient( searchApiUrl, urlGenerator, recommendationApiUrl ).fetchByTitle( 'media', 2 ).fetch; const controller = new AbortController(); expect( searchResult.query ).toStrictEqual( 'media' ); expect( searchResult.results ).toBeTruthy(); expect( searchResult.results.length ).toBe( 2 ); expect( searchResult.results[ 0 ] ).toStrictEqual( Object.assign( {}, restResponse.pages[ 0 ], { // thumbnail: null -> thumbnail: undefined thumbnail: undefined } ) ); expect( searchResult.results[ 1 ] ).toStrictEqual( restResponse.pages[ 1 ] ); if ( mockedRequests ) { expect( fetchMock ).toHaveBeenCalledTimes( 1 ); expect( fetchMock ).toHaveBeenCalledWith( 'https://en.wikipedia.org/w/rest.php/v1/search/title?q=media&limit=2', { headers: { accept: 'application/json' }, signal: controller.signal } ); } } ); test( '0 results', async () => { const restResponse = { pages: [] }; fetchMock.mockOnce( JSON.stringify( restResponse ) ); const searchResult = await restSearchClient( searchApiUrl, urlGenerator, recommendationApiUrl ).fetchByTitle( 'thereIsNothingLikeThis' ).fetch; const controller = new AbortController(); expect( searchResult.query ).toStrictEqual( 'thereIsNothingLikeThis' ); expect( searchResult.results ).toBeTruthy(); expect( searchResult.results.length ).toBe( 0 ); if ( mockedRequests ) { expect( fetchMock ).toHaveBeenCalledTimes( 1 ); expect( fetchMock ).toHaveBeenCalledWith( 'https://en.wikipedia.org/w/rest.php/v1/search/title?q=thereIsNothingLikeThis&limit=10', { headers: { accept: 'application/json' }, signal: controller.signal } ); } } ); test( 'no recommendations service', async () => { const client = await restSearchClient( searchApiUrl, urlGenerator ); expect( client.fetchRecommendationByTitle ).toBe( undefined ); } ); test( 'recommendations service', async () => { fetchMock.mockOnce( JSON.stringify( { pages: [ { id: 1, title: 'R' } ] } ) ); const searchResult = await restSearchClient( searchApiUrl, urlGenerator, recommendationApiUrl ) .fetchRecommendationByTitle( 'recommendMe' ).fetch; expect( searchResult.query ).toStrictEqual( '' ); expect( searchResult.results ).toBeTruthy(); expect( searchResult.results.length ).toBe( 1 ); expect( searchResult.results[ 0 ].title ).toBe( 'R' ); } ); if ( mockedRequests ) { test( 'network error', async () => { fetchMock.mockRejectOnce( new Error( 'failed' ) ); await expect( restSearchClient( searchApiUrl, urlGenerator, recommendationApiUrl ).fetchByTitle( 'anything' ).fetch ).rejects.toThrow( 'failed' ); } ); } } );