const {test} = require("supertape") const {eventToMessage} = require("./event-to-message") const data = require("../../test/data") /** * @param {string} roomID * @param {string} eventID * @returns {(roomID: string, eventID: string) => Promise>} */ function mockGetEvent(t, roomID_in, eventID_in, outer) { return async function(roomID, eventID) { t.equal(roomID, roomID_in) t.equal(eventID, eventID_in) return new Promise(resolve => { setTimeout(() => { resolve({ event_id: eventID_in, room_id: roomID_in, origin_server_ts: 1680000000000, unsigned: { age: 2245, transaction_id: "$local.whatever" }, ...outer }) }) }) } } function sameFirstContentAndWhitespace(t, a, b) { const a2 = JSON.stringify(a[0].content) const b2 = JSON.stringify(b[0].content) t.equal(a2, b2) } test("event2message: body is used when there is no formatted_body", async t => { t.deepEqual( await eventToMessage({ content: { body: "testing plaintext", msgtype: "m.text" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "testing plaintext", avatar_url: undefined }] ) }) test("event2message: any markdown in body is escaped", async t => { t.deepEqual( await eventToMessage({ content: { body: "testing **special** ~~things~~ which _should_ *not* `trigger` @any ", msgtype: "m.text" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "testing \\*\\*special\\*\\* \\~\\~things\\~\\~ which \\_should\\_ \\*not\\* \\`trigger\\` @any ", avatar_url: undefined }] ) }) test("event2message: basic html is converted to markdown", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "this is a test of formatting" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "this **is** a **_test_** of ~~formatting~~", avatar_url: undefined }] ) }) test("event2message: markdown syntax is escaped", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "this **is** an extreme \\*test\\* of" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "this \\*\\*is\\*\\* an **_extreme_** \\\\\\*test\\\\\\* of", avatar_url: undefined }] ) }) test("event2message: html lines are bridged correctly", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "

paragraph one
line two
line three

paragraph two\nline two\nline three\n\nparagraph three

paragraph four\nline two
line three\nline four

paragraph five" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "paragraph one\nline _two_\nline three\n\nparagraph two\nline _two_\nline three\n\nparagraph three\n\nparagraph four\nline two\nline three\nline four\n\nparagraph five", avatar_url: undefined }] ) }) /*test("event2message: whitespace is retained", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "line one: test test
line two: test test
line three: test test
line four: test test
line five" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\n line five", avatar_url: undefined }] ) })*/ test("event2message: whitespace is collapsed", async t => { sameFirstContentAndWhitespace( t, await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "line one: test test
line two: test test
line three: test test
line four: test test
line five" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\nline five", avatar_url: undefined }] ) }) test("event2message: lists are bridged correctly", async t => { sameFirstContentAndWhitespace( t, await eventToMessage({ "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "* line one\n* line two\n* line three\n * nested one\n * nested two\n* line four", "format": "org.matrix.custom.html", "formatted_body": "
    \n
  • line one
  • \n
  • line two
  • \n
  • line three\n
      \n
    • nested one
    • \n
    • nested two
    • \n
    \n
  • \n
  • line four
  • \n
\n" }, "origin_server_ts": 1692967314062, "unsigned": { "age": 112, "transaction_id": "m1692967313951.441" }, "event_id": "$l-xQPY5vNJo3SNxU9d8aOWNVD1glMslMyrp4M_JEF70", "room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe" }), [{ username: "cadence", content: "* line one\n* line two\n* line three\n * nested one\n * nested two\n* line four", avatar_url: undefined }] ) }) test("event2message: long messages are split", async t => { t.deepEqual( await eventToMessage({ content: { body: ("a".repeat(130) + " ").repeat(19), msgtype: "m.text" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: (("a".repeat(130) + " ").repeat(15)).slice(0, -1), avatar_url: undefined }, { username: "cadence", content: (("a".repeat(130) + " ").repeat(4)).slice(0, -1), avatar_url: undefined }] ) }) test("event2message: code blocks work", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "

preceding

\n
code block\n
\n

following code is inline

\n" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "preceding\n\n```\ncode block\n```\n\nfollowing `code` is inline", avatar_url: undefined }] ) }) test("event2message: code block contents are formatted correctly and not escaped", async t => { t.deepEqual( await eventToMessage({ "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "wrong body", "format": "org.matrix.custom.html", "formatted_body": "
input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n_input_ = input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n
\n

input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,

\n" }, "origin_server_ts": 1693031482275, "unsigned": { "age": 99, "transaction_id": "m1693031482146.511" }, "event_id": "$pGkWQuGVmrPNByrFELxhzI6MCBgJecr5I2J3z88Gc2s", "room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe" }), [{ username: "cadence", content: "```\ninput = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n_input_ = input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,\n```\n\n`input = input.replace(/(<\\/?([^ >]+)[^>]*>)?\\n(<\\/?([^ >]+)[^>]*>)?/g,`", avatar_url: undefined }] ) }) test("event2message: quotes have an appropriate amount of whitespace", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.text", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "
Chancellor of Germany Angela Merkel, on March 17, 2017: they did not shake hands



🤨" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "> Chancellor of Germany Angela Merkel, on March 17, 2017: they did not shake hands\n🤨", avatar_url: undefined }] ) }) test("event2message: m.emote markdown syntax is escaped", async t => { t.deepEqual( await eventToMessage({ content: { msgtype: "m.emote", body: "wrong body", format: "org.matrix.custom.html", formatted_body: "shows you **her** extreme \\*test\\* of" }, event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU", origin_server_ts: 1688301929913, room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe", sender: "@cadence:cadence.moe", type: "m.room.message", unsigned: { age: 405299 } }), [{ username: "cadence", content: "\\* cadence shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of", avatar_url: undefined }] ) }) test("event2message: rich reply to a sim user", async t => { t.deepEqual( await eventToMessage({ "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "> <@_ooye_kyuugryphon:cadence.moe> Slow news day.\n\nTesting this reply, ignore", "format": "org.matrix.custom.html", "formatted_body": "
In reply to @_ooye_kyuugryphon:cadence.moe
Slow news day.
Testing this reply, ignore", "m.relates_to": { "m.in_reply_to": { "event_id": "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04" } } }, "origin_server_ts": 1693029683016, "unsigned": { "age": 91, "transaction_id": "m1693029682894.510" }, "event_id": "$v_Gtr-bzv9IVlSLBO5DstzwmiDd-GSFaNfHX66IupV8", "room_id": "!fGgIymcYWOqjbSRUdV:cadence.moe" }, data.guild.general, { api: { getEvent: mockGetEvent(t, "!fGgIymcYWOqjbSRUdV:cadence.moe", "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04", { type: "m.room.message", content: { msgtype: "m.text", body: "Slow news day." }, sender: "@_ooye_kyuugryphon:cadence.moe" }) } }), [{ username: "cadence", content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 <@111604486476181504>: Slow news day.\nTesting this reply, ignore", avatar_url: undefined }] ) }) test("event2message: rich reply to a matrix user's long message with formatting", async t => { t.deepEqual( await eventToMessage({ "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "> <@cadence:cadence.moe> ```\n> i should have a little happy test\n> ```\n> * list **bold** _em_ ~~strike~~\n> # heading 1\n> ## heading 2\n> ### heading 3\n> https://cadence.moe\n> [legit website](https://cadence.moe)\n\nno you can't!!!", "format": "org.matrix.custom.html", "formatted_body": "
In reply to @cadence:cadence.moe
i should have a little happy test\n
\n
    \n
  • list bold em ~~strike~~
  • \n
\n

heading 1

\n

heading 2

\n

heading 3

\n

https://cadence.moe
legit website

\n
no you can't!!!", "m.relates_to": { "m.in_reply_to": { "event_id": "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04" } } }, "origin_server_ts": 1693037401693, "unsigned": { "age": 381, "transaction_id": "m1693037401592.521" }, "event_id": "$v_Gtr-bzv9IVlSLBO5DstzwmiDd-GSFaNfHX66IupV8", "room_id": "!fGgIymcYWOqjbSRUdV:cadence.moe" }, data.guild.general, { api: { getEvent: mockGetEvent(t, "!fGgIymcYWOqjbSRUdV:cadence.moe", "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04", { "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "```\ni should have a little happy test\n```\n* list **bold** _em_ ~~strike~~\n# heading 1\n## heading 2\n### heading 3\nhttps://cadence.moe\n[legit website](https://cadence.moe)", "format": "org.matrix.custom.html", "formatted_body": "
i should have a little happy test\n
\n
    \n
  • list bold em ~~strike~~
  • \n
\n

heading 1

\n

heading 2

\n

heading 3

\n

https://cadence.moe
legit website

\n" } }) } }), [{ username: "cadence", content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 Ⓜ️**cadence**: i should have a little...\n**no you can't!!!**", avatar_url: undefined }] ) }) test("event2message: with layered rich replies, the preview should only be the real text", async t => { t.deepEqual( await eventToMessage({ type: "m.room.message", sender: "@cadence:cadence.moe", content: { msgtype: "m.text", body: "> <@cadence:cadence.moe> two\n\nthree", format: "org.matrix.custom.html", formatted_body: "
In reply to @cadence:cadence.moe
two
three", "m.relates_to": { "m.in_reply_to": { event_id: "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04" } } }, event_id: "$v_Gtr-bzv9IVlSLBO5DstzwmiDd-GSFaNfHX66IupV8", room_id: "!fGgIymcYWOqjbSRUdV:cadence.moe" }, data.guild.general, { api: { getEvent: mockGetEvent(t, "!fGgIymcYWOqjbSRUdV:cadence.moe", "$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04", { "type": "m.room.message", "sender": "@cadence:cadence.moe", "content": { "msgtype": "m.text", "body": "> <@cadence:cadence.moe> one\n\ntwo", "format": "org.matrix.custom.html", "formatted_body": "
In reply to @cadence:cadence.moe
one
two", "m.relates_to": { "m.in_reply_to": { "event_id": "$5UtboIC30EFlAYD_Oh0pSYVW8JqOp6GsDIJZHtT0Wls" } } } }) } }), [{ username: "cadence", content: "<:L1:1144820033948762203><:L2:1144820084079087647>https://discord.com/channels/112760669178241024/687028734322147344/1144865310588014633 Ⓜ️**cadence**: two\nthree", avatar_url: undefined }] ) })