diff --git a/src/MediaWiki.ts b/src/MediaWiki.ts index 1690a48e..30defed5 100644 --- a/src/MediaWiki.ts +++ b/src/MediaWiki.ts @@ -193,7 +193,11 @@ class MediaWiki { public async hasVisualEditorApi(): Promise { if (this.#hasVisualEditorApi === null) { this.visualEditorUrlDirector = new VisualEditorURLDirector(this.visualEditorApiUrl.href) - this.#hasVisualEditorApi = await checkApiAvailability(this.visualEditorUrlDirector.buildArticleURL(this.apiCheckArticleId)) + this.#hasVisualEditorApi = await checkApiAvailability( + this.visualEditorUrlDirector.buildArticleURL(this.apiCheckArticleId), + '' /* empty login cookie */, + this.visualEditorUrlDirector.validMimeTypes, + ) return this.#hasVisualEditorApi } return this.#hasVisualEditorApi diff --git a/src/util/builders/url/visual-editor.director.ts b/src/util/builders/url/visual-editor.director.ts index 660f1e1d..4daa74a8 100644 --- a/src/util/builders/url/visual-editor.director.ts +++ b/src/util/builders/url/visual-editor.director.ts @@ -13,4 +13,8 @@ export default class VisualEditorURLDirector { buildArticleURL(articleId: string) { return urlBuilder.setDomain(this.baseDomain).setQueryParams({ page: articleId }, '&').build() } + + get validMimeTypes() { + return ['application/json'] + } } diff --git a/src/util/mw-api.ts b/src/util/mw-api.ts index 5420eb61..ab453b39 100644 --- a/src/util/mw-api.ts +++ b/src/util/mw-api.ts @@ -258,7 +258,16 @@ export function mwRetToArticleDetail(obj: QueryMwRet): KVS { return ret } -export async function checkApiAvailability(url: string, loginCookie = ''): Promise { +/** + * Check for API availability at the given URL. + * + * @param url The URL to check. + * @param loginCookie A string representing a cookie for login, if necessary. + * @param allowedMimeTypes An array of allowed mime types for the response. If this is set, the check is only considered a + * success if the response has a mime type in this array. Set to null to disable this filter. + * @returns Promise resolving to true if the API is available. + */ +export async function checkApiAvailability(url: string, loginCookie = '', allowedMimeTypes = null): Promise { try { const resp = await axios.get(decodeURI(url), { maxRedirects: 0, headers: { cookie: loginCookie } }) @@ -268,7 +277,20 @@ export async function checkApiAvailability(url: string, loginCookie = ''): Promi // the 'mediawiki-api-error' === 'rest-permission-error' exception const isSuccess = resp.status === 200 && (!resp.headers['mediawiki-api-error'] || resp.headers['mediawiki-api-error'] === 'rest-permission-error') - return !isRedirectPage && isSuccess + let validMimeType = false + if (!allowedMimeTypes) { + // No MIME types to check, so consider the check passed. + validMimeType = true + } else { + for (const mimeType of allowedMimeTypes) { + if (resp.headers['content-type'].includes(mimeType)) { + validMimeType = true + break + } + } + } + + return !isRedirectPage && isSuccess && validMimeType } catch (err) { return false } diff --git a/test/unit/mwApiCapabilities.test.ts b/test/unit/mwApiCapabilities.test.ts index e25d840d..f6af020c 100644 --- a/test/unit/mwApiCapabilities.test.ts +++ b/test/unit/mwApiCapabilities.test.ts @@ -57,8 +57,7 @@ describe('Checking Mediawiki capabilities', () => { expect(await MediaWiki.hasVisualEditorApi()).toBe(true) }) - // https://github.com/openzim/mwoffliner/issues/2035 - test.skip('test capabilities of pokemon.fandom.com with default receipt', async () => { + test('test capabilities of pokemon.fandom.com with default receipt', async () => { MediaWiki.base = 'https://pokemon.fandom.com/' expect(await MediaWiki.hasWikimediaDesktopApi()).toBe(false) @@ -67,8 +66,7 @@ describe('Checking Mediawiki capabilities', () => { expect(await MediaWiki.hasVisualEditorApi()).toBe(false) }) - // https://github.com/openzim/mwoffliner/issues/2035 - test.skip('test capabilities of pokemon.fandom.com with RestApi receipt', async () => { + test('test capabilities of pokemon.fandom.com with RestApi receipt', async () => { MediaWiki.base = 'https://pokemon.fandom.com/' MediaWiki.wikiPath = '/' MediaWiki.restApiPath = 'rest.php'