From 6d6a90d458770289027e48aba220259964426bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20R=C3=A8gne?= Date: Wed, 11 Aug 2021 11:39:05 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20R=C3=A9activer=20le=20lien=20vers=20l'in?= =?UTF-8?q?terface=20Web=20de=20Kodi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/popup/script.js | 9 +++++++++ src/tools/ping.js | 27 +++++++++++++++++++++++++++ test/unit/tools/ping.js | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/tools/ping.js create mode 100644 test/unit/tools/ping.js diff --git a/src/popup/script.js b/src/popup/script.js index 770f9b68..df48cf9a 100644 --- a/src/popup/script.js +++ b/src/popup/script.js @@ -5,6 +5,7 @@ import { cast, kodi } from "../core/index.js"; import { complete } from "../core/labellers.js"; import { notify } from "../core/notify.js"; +import { ping } from "../tools/ping.js"; /** * La position de l'élément courant dans la liste de lecture ; ou @@ -859,6 +860,14 @@ const load = async function () { document.querySelector("#feedback").disabled = false; document.querySelector("#donate").disabled = false; document.querySelector("#rate").disabled = false; + + // Afficher le bouton vers l'interface Web de Kodi seulement si + // celle-ci est accessible. + const url = `http://${kodi.url.hostname}:8080`; + if (await ping(url)) { + document.querySelector("#web").dataset.url = url; + document.querySelector("#web").style.display = "block"; + } } catch (err) { splash(err); } diff --git a/src/tools/ping.js b/src/tools/ping.js new file mode 100644 index 00000000..f9d5aff8 --- /dev/null +++ b/src/tools/ping.js @@ -0,0 +1,27 @@ +/** + * @module + */ + +/** + * Teste si un lien est accessible. + * + * @param {string} url Le lien testé. + * @returns {Promise} Une promesse indiquant si le lien est accessible. + */ +export const ping = async function (url) { + try { + await fetch(url, { + method: "HEAD", + // Fournir des "identifiants" vides dans les entêtes pour que si la + // page demande une authentification : celle-ci échoue directement + // sans demander à l'utilisateur de saisir son identifiant et son + // mot de passe. + headers: { Authorization: "" }, + }); + return true; + } catch { + // Ignorer l'erreur si la requête échoue. Et indiquer que le lien est + // inaccessible. + return false; + } +}; diff --git a/test/unit/tools/ping.js b/test/unit/tools/ping.js new file mode 100644 index 00000000..c4acdc55 --- /dev/null +++ b/test/unit/tools/ping.js @@ -0,0 +1,37 @@ +import assert from "node:assert"; +import sinon from "sinon"; +import { ping } from "../../../src/tools/ping.js"; + +describe("tools/ping.js", function () { + describe("ping()", function () { + it("should return true", async function () { + const stub = sinon.stub(globalThis, "fetch").resolves(); + + const ok = await ping("http://foo.com/"); + assert.strictEqual(ok, true); + + assert.strictEqual(stub.callCount, 1); + assert.deepStrictEqual(stub.firstCall.args, ["http://foo.com/", { + method: "HEAD", + headers: { Authorization: "" }, + }]); + + stub.restore(); + }); + + it("should return false", async function () { + const stub = sinon.stub(globalThis, "fetch").rejects(); + + const ok = await ping("http://foo.com/"); + assert.strictEqual(ok, false); + + assert.strictEqual(stub.callCount, 1); + assert.deepStrictEqual(stub.firstCall.args, ["http://foo.com/", { + method: "HEAD", + headers: { Authorization: "" }, + }]); + + stub.restore(); + }); + }); +});