diff --git a/.gitignore b/.gitignore index ebfcc07..9a310ad 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ config.js registration.yaml coverage db/ooye.db* -test/res/butterfly* diff --git a/m2d/converters/emoji-sheet.test.js b/m2d/converters/emoji-sheet.test.js index 026c53f..de3a2ab 100644 --- a/m2d/converters/emoji-sheet.test.js +++ b/m2d/converters/emoji-sheet.test.js @@ -1,7 +1,7 @@ const assert = require("assert").strict const {test} = require("supertape") const {_convertImageStream} = require("./emoji-sheet") -const fs = require("fs") +const fetch = require("node-fetch") const {Transform} = require("stream").Transform /* c8 ignore next 7 */ @@ -25,16 +25,18 @@ class Meter extends Transform { /** * @param {import("supertape").Test} t - * @param {string} path + * @param {string} url * @param {number} totalSize */ -async function runSingleTest(t, path, totalSize) { - const file = fs.createReadStream(path) +async function runSingleTest(t, url, totalSize) { + const abortController = new AbortController() + const res = await fetch("https://ezgif.com/images/format-demo/butterfly.png", {agent: false, signal: abortController.signal}) const meter = new Meter() - const p = file.pipe(meter) + const p = res.body.pipe(meter) const result = await _convertImageStream(p, () => { - file.pause() - file.emit("end") + abortController.abort() + res.body.pause() + res.body.emit("end") }) t.equal(result.subarray(1, 4).toString("ascii"), "PNG", `result was not a PNG file: ${result.toString("base64")}`) /* c8 ignore next 5 */ @@ -46,9 +48,9 @@ async function runSingleTest(t, path, totalSize) { } slow()("emoji-sheet: only partial file is read for APNG", async t => { - await runSingleTest(t, "test/res/butterfly.png", 2438998) + await runSingleTest(t, "https://ezgif.com/images/format-demo/butterfly.png", 2438998) }) slow()("emoji-sheet: only partial file is read for GIF", async t => { - await runSingleTest(t, "test/res/butterfly.gif", 781223) + await runSingleTest(t, "https://ezgif.com/images/format-demo/butterfly.gif", 781223) }) diff --git a/m2d/converters/event-to-message.js b/m2d/converters/event-to-message.js index 4ffe26e..8710531 100644 --- a/m2d/converters/event-to-message.js +++ b/m2d/converters/event-to-message.js @@ -209,19 +209,14 @@ function convertEmoji(mxcUrl, nameForGuess, allowSpriteSheetIndicator, allowLink // Get the known emoji from the database. let row if (mxcUrl) row = select("emoji", ["emoji_id", "name", "animated"], {mxc_url: mxcUrl}).get() - // Now we have to search all servers to see if we're able to send this emoji. - if (row) { - const found = [...discord.guilds.values()].find(g => g.emojis.find(e => e.id === row.id)) - if (!found) row = null - } - // Or, if we don't have an emoji right now, we search for the name instead. if (!row && nameForGuess) { + // We don't know the emoji, but we could guess a suitable emoji based on the name const nameForGuessLower = nameForGuess.toLowerCase() for (const guild of discord.guilds.values()) { /** @type {{name: string, id: string, animated: number}[]} */ // @ts-ignore const emojis = guild.emojis - const found = emojis.find(e => e.id === row?.id || e.name?.toLowerCase() === nameForGuessLower) + const found = emojis.find(e => e.name?.toLowerCase() === nameForGuessLower) if (found) { row = { animated: found.animated, @@ -648,6 +643,19 @@ async function eventToMessage(event, guild, di) { // input = input.replace(/ /g, " ") // There is also a corresponding test to uncomment, named "event2message: whitespace is retained" + // SPRITE SHEET EMOJIS FEATURE: Emojis at the end of the message that we don't know about will be reuploaded as a sprite sheet. + // First we need to determine which emojis are at the end. + endOfMessageEmojis = [] + let match + let last = input.length + while ((match = input.slice(0, last).match(/]*>\s*$/))) { + if (!match[0].includes("data-mx-emoticon")) break + const mxcUrl = match[0].match(/\bsrc="(mxc:\/\/[^"]+)"/) + if (mxcUrl) endOfMessageEmojis.unshift(mxcUrl[1]) + assert(typeof match.index === "number", "Your JavaScript implementation does not comply with TC39: https://tc39.es/ecma262/multipage/text-processing.html#sec-regexpbuiltinexec") + last = match.index + } + // Handling written @mentions: we need to look for candidate Discord members to join to the room // This shouldn't apply to code blocks, links, or inside attributes. So editing the HTML tree instead of regular expressions is a sensible choice here. // We're using the domino parser because Turndown uses the same and can reuse this tree. @@ -693,19 +701,6 @@ async function eventToMessage(event, guild, di) { } await forEachNode(root) - // SPRITE SHEET EMOJIS FEATURE: Emojis at the end of the message that we don't know about will be reuploaded as a sprite sheet. - // First we need to determine which emojis are at the end. - endOfMessageEmojis = [] - let match - let last = input.length - while ((match = input.slice(0, last).match(/]*>\s*$/))) { - if (!match[0].includes("data-mx-emoticon")) break - const mxcUrl = match[0].match(/\bsrc="(mxc:\/\/[^"]+)"/) - if (mxcUrl) endOfMessageEmojis.unshift(mxcUrl[1]) - assert(typeof match.index === "number", "Your JavaScript implementation does not comply with TC39: https://tc39.es/ecma262/multipage/text-processing.html#sec-regexpbuiltinexec") - last = match.index - } - // @ts-ignore bad type from turndown content = turndownService.turndown(root) diff --git a/package.json b/package.json index 3ecb7a8..658fa3a 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "scripts": { "addbot": "node addbot.js", "test": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap test/test.js | tap-dot", - "test-slow": "cross-env FORCE_COLOR=true SUPERTAPE_TIMEOUT=6000 supertape --no-check-assertions-count --format tap test/test.js -- --slow | tap-dot", + "test-slow": "cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap test/test.js -- --slow | tap-dot", "cover": "c8 --skip-full -x db/migrations -x matrix/file.js -x matrix/api.js -x matrix/mreq.js -r html -r text supertape --no-check-assertions-count --format fail test/test.js -- --slow" } } diff --git a/test/test.js b/test/test.js index 3e5ba72..263ccc7 100644 --- a/test/test.js +++ b/test/test.js @@ -7,9 +7,6 @@ const migrate = require("../db/migrate") const HeatSync = require("heatsync") const {test} = require("supertape") const data = require("./data") -/** @type {import("node-fetch").default} */ -// @ts-ignore -const fetch = require("node-fetch") const config = require("../config") const passthrough = require("../passthrough") @@ -63,27 +60,6 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not }) db.exec(fs.readFileSync(join(__dirname, "ooye-test-data.sql"), "utf8")) - - /* c8 ignore start - maybe download some more test files in slow mode */ - if (process.argv.includes("--slow")) { - test("test files: download", async t => { - function download(url, to) { - return new Promise(async resolve => { - if (fs.existsSync(to)) return resolve(null) - const res = await fetch(url) - res.body.pipe(fs.createWriteStream(to, {encoding: "binary"})) - res.body.once("finish", resolve) - }) - } - await Promise.all([ - download("https://ezgif.com/images/format-demo/butterfly.png", "test/res/butterfly.png"), - download("https://ezgif.com/images/format-demo/butterfly.gif", "test/res/butterfly.gif") - ]) - t.pass("downloaded") - }) - } - /* c8 ignore end */ - require("../db/orm.test") require("../discord/utils.test") require("../matrix/kstate.test")