From de94e3efa5b40c6c0eedd4de8757739e842fbf66 Mon Sep 17 00:00:00 2001 From: Dong Nguyen Date: Tue, 7 May 2024 17:45:31 +0700 Subject: [PATCH] Add auto discovery support --- src/browser/linkedom.js | 1 + src/utils/autoDiscovery.js | 23 ++++++++++ src/utils/autoDiscovery.test.js | 53 +++++++++++++++++++++++ test-data/bitchute.html | 74 +++++++++++++++++++++++++++++++++ test-data/bitchute.json | 1 + 5 files changed, 152 insertions(+) create mode 100644 src/browser/linkedom.js create mode 100644 src/utils/autoDiscovery.js create mode 100644 src/utils/autoDiscovery.test.js create mode 100644 test-data/bitchute.html create mode 100644 test-data/bitchute.json diff --git a/src/browser/linkedom.js b/src/browser/linkedom.js new file mode 100644 index 0000000..6d5be04 --- /dev/null +++ b/src/browser/linkedom.js @@ -0,0 +1 @@ +export const DOMParser = window.DOMParser diff --git a/src/utils/autoDiscovery.js b/src/utils/autoDiscovery.js new file mode 100644 index 0000000..c080292 --- /dev/null +++ b/src/utils/autoDiscovery.js @@ -0,0 +1,23 @@ +// utils -> autoDiscovery.js + +import { DOMParser } from 'linkedom' + +import { getHtml, getJson } from './retrieve.js' + +export default async (url, params = {}, options = {}) => { + const html = await getHtml(url, options) + const doc = new DOMParser().parseFromString(html, 'text/html') + const elm = doc.querySelector('link[type="application/json+oembed"]') + const href = elm.getAttribute('href') + const q = new URL(href) + const { origin, pathname, searchParams } = q + Object.keys(params).forEach((key) => { + if (!searchParams.has(key)) { + searchParams.append(key, params[key]) + } + }) + const link = `${origin}${pathname}?${searchParams.toString()}` + const body = await getJson(link, options) + body.method = 'auto-discovery' + return body +} diff --git a/src/utils/autoDiscovery.test.js b/src/utils/autoDiscovery.test.js new file mode 100644 index 0000000..701ae69 --- /dev/null +++ b/src/utils/autoDiscovery.test.js @@ -0,0 +1,53 @@ +// autoDiscovery.test +/* eslint-env jest */ + +import nock from 'nock' + +import autoDiscovery from './autoDiscovery.js' + +const parseUrl = (url) => { + const re = new URL(url) + return { + baseUrl: `${re.protocol}//${re.host}`, + path: re.pathname, + } +} + +describe('test if autoDiscovery() works correctly', () => { + const url = 'https://www.bitchute.com/video/8hXWnkvA8Ao/' + test(`check fetchEmbed("${url}")`, async () => { + const htmlFile = './test-data/bitchute.html' + const jsonFile = './test-data/bitchute.json' + + const { baseUrl, path } = parseUrl(url) + const scope = nock(baseUrl) + scope.get(path) + .replyWithFile(200, htmlFile, { + 'Content-Type': 'text/html', + }) + + const endpoint = 'https://www.bitchute.com/oembed/' + const { baseUrl: endpointBaseUrl, path: endpointPath } = parseUrl(endpoint) + + const params = { + maxwidth: 600, + maxheight: 400, + } + + const jsonScope = nock(endpointBaseUrl, { encodedQueryParams: true }) + const queries = new URLSearchParams({ + url: 'https://www.bitchute.com/video/8hXWnkvA8Ao/', + format: 'json', + ...params, + }) + jsonScope.get(endpointPath) + .query(queries) + .replyWithFile(200, jsonFile, { + 'Content-Type': 'application/json', + }) + + const result = await autoDiscovery(url, params) + expect(result).toBeTruthy() + nock.cleanAll() + }) +}) diff --git a/test-data/bitchute.html b/test-data/bitchute.html new file mode 100644 index 0000000..0f7b80a --- /dev/null +++ b/test-data/bitchute.html @@ -0,0 +1,74 @@ + + + + + 2023 Praemium Imperiale White House Program + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-data/bitchute.json b/test-data/bitchute.json new file mode 100644 index 0000000..f5588ac --- /dev/null +++ b/test-data/bitchute.json @@ -0,0 +1 @@ +{"title": "2023 Praemium Imperiale White House Program", "provider_url": "https://www.bitchute.com/", "author_name": "TheWhiteHouse", "thumbnail_url": "https://static-3.bitchute.com/live/cover_images/zWsYVmCOu4JA/8hXWnkvA8Ao_320x180.jpg", "html": "", "author_url": "https://www.bitchute.com/channel/zWsYVmCOu4JA/", "height": "344", "thumbnail_height": "180", "version": "1.0", "type": "video", "thumbnail_width": "320", "provider_name": "BitChute", "width": "459"} \ No newline at end of file