Improve test coverage
This commit is contained in:
parent
69922c4a14
commit
c7fb6fd52e
10 changed files with 374 additions and 33 deletions
|
@ -257,6 +257,15 @@ async function messageToEvent(message, guild, options = {}, di) {
|
||||||
if (match) {
|
if (match) {
|
||||||
const row = from("event_message").join("message_channel", "message_id").join("channel_room", "channel_id").select("event_id", "room_id", "source").and("WHERE message_id = ? AND part = 0").get(match[1])
|
const row = from("event_message").join("message_channel", "message_id").join("channel_room", "channel_id").select("event_id", "room_id", "source").and("WHERE message_id = ? AND part = 0").get(match[1])
|
||||||
if (row) {
|
if (row) {
|
||||||
|
/*
|
||||||
|
we generate a partial referenced_message based on what PK provided. we don't need everything, since this will only be used for further message-to-event converting.
|
||||||
|
the following properties are necessary:
|
||||||
|
- content: used for generating the reply fallback
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
message.referenced_message = {
|
||||||
|
content: message.embeds[0].description.replace(/^.*?\)\*\*\s*/, "")
|
||||||
|
}
|
||||||
message.embeds.shift()
|
message.embeds.shift()
|
||||||
repliedToEventRow = row
|
repliedToEventRow = row
|
||||||
}
|
}
|
||||||
|
|
64
d2m/converters/message-to-event.pk.test.js
Normal file
64
d2m/converters/message-to-event.pk.test.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
const {test} = require("supertape")
|
||||||
|
const {messageToEvent} = require("./message-to-event")
|
||||||
|
const data = require("../../test/data")
|
||||||
|
const Ty = require("../../types")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} roomID
|
||||||
|
* @param {string} eventID
|
||||||
|
* @returns {(roomID: string, eventID: string) => Promise<Ty.Event.Outer<Ty.Event.M_Room_Message>>}
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("message2event: pk reply is converted to native matrix reply", async t => {
|
||||||
|
const events = await messageToEvent(data.pk_message.pk_reply, {}, {}, {
|
||||||
|
api: {
|
||||||
|
getEvent: mockGetEvent(t, "!TqlyQmifxGUggEmdBN:cadence.moe", "$NB6nPgO2tfXyIwwDSF0Ga0BUrsgX1S-0Xl-jAvI8ucU", {
|
||||||
|
type: "m.room.message",
|
||||||
|
sender: "@cadence:cadence.moe",
|
||||||
|
content: {
|
||||||
|
msgtype: "m.text",
|
||||||
|
body: "now for my next experiment:"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.deepEqual(events, [{
|
||||||
|
$type: "m.room.message",
|
||||||
|
"m.mentions": {
|
||||||
|
user_ids: [
|
||||||
|
"@cadence:cadence.moe"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
msgtype: "m.text",
|
||||||
|
body: "> cadence: now for my next experiment:\n\nthis is a reply",
|
||||||
|
format: "org.matrix.custom.html",
|
||||||
|
formatted_body: '<mx-reply><blockquote><a href="https://matrix.to/#/!TqlyQmifxGUggEmdBN:cadence.moe/$NB6nPgO2tfXyIwwDSF0Ga0BUrsgX1S-0Xl-jAvI8ucU">In reply to</a> <a href="https://matrix.to/#/@cadence:cadence.moe">cadence</a><br>'
|
||||||
|
+ "now for my next experiment:</blockquote></mx-reply>"
|
||||||
|
+ "this is a reply",
|
||||||
|
"m.relates_to": {
|
||||||
|
"m.in_reply_to": {
|
||||||
|
event_id: "$NB6nPgO2tfXyIwwDSF0Ga0BUrsgX1S-0Xl-jAvI8ucU"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
})
|
|
@ -397,6 +397,46 @@ test("message2event: reply with a video", async t => {
|
||||||
}])
|
}])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("message2event: voice message", async t => {
|
||||||
|
const events = await messageToEvent(data.message.voice_message)
|
||||||
|
t.deepEqual(events, [{
|
||||||
|
$type: "m.room.message",
|
||||||
|
body: "voice-message.ogg",
|
||||||
|
external_url: "https://cdn.discordapp.com/attachments/1099031887500034088/1112476845502365786/voice-message.ogg?ex=65c92d4c&is=65b6b84c&hm=0654bab5027474cbe23875954fa117cf44d8914c144cd151879590fa1baf8b1c&",
|
||||||
|
filename: "voice-message.ogg",
|
||||||
|
info: {
|
||||||
|
duration: 3960.0000381469727,
|
||||||
|
mimetype: "audio/ogg",
|
||||||
|
size: 10584,
|
||||||
|
},
|
||||||
|
"m.mentions": {},
|
||||||
|
msgtype: "m.audio",
|
||||||
|
url: "mxc://cadence.moe/MRRPDggXQMYkrUjTpxQbmcxB"
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("message2event: misc file", async t => {
|
||||||
|
const events = await messageToEvent(data.message.misc_file)
|
||||||
|
t.deepEqual(events, [{
|
||||||
|
$type: "m.room.message",
|
||||||
|
msgtype: "m.text",
|
||||||
|
body: "final final final revised draft",
|
||||||
|
"m.mentions": {}
|
||||||
|
}, {
|
||||||
|
$type: "m.room.message",
|
||||||
|
body: "the.yml",
|
||||||
|
external_url: "https://cdn.discordapp.com/attachments/122155380120748034/1174514575220158545/the.yml?ex=65cd6270&is=65baed70&hm=8c5f1b571784e3c7f99628492298815884e351ae0dc7c2ae40dd22d97caf27d9&",
|
||||||
|
filename: "the.yml",
|
||||||
|
info: {
|
||||||
|
mimetype: "text/plain; charset=utf-8",
|
||||||
|
size: 2274
|
||||||
|
},
|
||||||
|
"m.mentions": {},
|
||||||
|
msgtype: "m.file",
|
||||||
|
url: "mxc://cadence.moe/HnQIYQmmlIKwOQsbFsIGpzPP"
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
|
||||||
test("message2event: simple reply in thread to a matrix user's reply", async t => {
|
test("message2event: simple reply in thread to a matrix user's reply", async t => {
|
||||||
const events = await messageToEvent(data.message.simple_reply_to_reply_in_thread, data.guild.general, {}, {
|
const events = await messageToEvent(data.message.simple_reply_to_reply_in_thread, data.guild.general, {}, {
|
||||||
api: {
|
api: {
|
||||||
|
|
|
@ -16,7 +16,6 @@ async function migrate(db) {
|
||||||
let migrationRan = false
|
let migrationRan = false
|
||||||
|
|
||||||
for (const filename of files) {
|
for (const filename of files) {
|
||||||
/* c8 ignore next - we can't unit test this, but it's run on every real world bridge startup */
|
|
||||||
if (progress >= filename) continue
|
if (progress >= filename) continue
|
||||||
console.log(`Applying database migration ${filename}`)
|
console.log(`Applying database migration ${filename}`)
|
||||||
if (filename.endsWith(".sql")) {
|
if (filename.endsWith(".sql")) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ async function runSingleTest(t, url, totalSize) {
|
||||||
res.body.emit("end")
|
res.body.emit("end")
|
||||||
})
|
})
|
||||||
t.equal(result.subarray(1, 4).toString("ascii"), "PNG", `result was not a PNG file: ${result.toString("base64")}`)
|
t.equal(result.subarray(1, 4).toString("ascii"), "PNG", `result was not a PNG file: ${result.toString("base64")}`)
|
||||||
|
/* c8 ignore next 5 */
|
||||||
if (meter.bytes < totalSize / 4) { // should download less than 25% of each file
|
if (meter.bytes < totalSize / 4) { // should download less than 25% of each file
|
||||||
t.pass("intentionally read partial file")
|
t.pass("intentionally read partial file")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,6 +5,7 @@ const DiscordTypes = require("discord-api-types/v10")
|
||||||
const {Readable} = require("stream")
|
const {Readable} = require("stream")
|
||||||
const chunk = require("chunk-text")
|
const chunk = require("chunk-text")
|
||||||
const TurndownService = require("turndown")
|
const TurndownService = require("turndown")
|
||||||
|
const domino = require("domino")
|
||||||
const assert = require("assert").strict
|
const assert = require("assert").strict
|
||||||
const entities = require("entities")
|
const entities = require("entities")
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ const turndownService = new TurndownService({
|
||||||
hr: "----",
|
hr: "----",
|
||||||
headingStyle: "atx",
|
headingStyle: "atx",
|
||||||
preformattedCode: true,
|
preformattedCode: true,
|
||||||
codeBlockStyle: "fenced",
|
codeBlockStyle: "fenced"
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -339,6 +340,33 @@ async function handleRoomOrMessageLinks(input, di) {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} content
|
||||||
|
* @param {DiscordTypes.APIGuild} guild
|
||||||
|
* @param {{api: import("../../matrix/api"), snow: import("snowtransfer").SnowTransfer, fetch: import("node-fetch")["default"]}} di
|
||||||
|
*/
|
||||||
|
async function checkWrittenMentions(content, guild, di) {
|
||||||
|
let writtenMentionMatch = content.match(/(?:^|[^"[<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/d) // /d flag for indices requires node.js 16+
|
||||||
|
if (writtenMentionMatch) {
|
||||||
|
const results = await di.snow.guild.searchGuildMembers(guild.id, {query: writtenMentionMatch[1]})
|
||||||
|
if (results[0]) {
|
||||||
|
assert(results[0].user)
|
||||||
|
return {
|
||||||
|
// @ts-ignore - typescript doesn't know about indices yet
|
||||||
|
content: content.slice(0, writtenMentionMatch.indices[1][0]-1) + `<@${results[0].user.id}>` + content.slice(writtenMentionMatch.indices[1][1]),
|
||||||
|
ensureJoined: results[0].user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachmentEmojis = new Map([
|
||||||
|
["m.image", "🖼️"],
|
||||||
|
["m.video", "🎞️"],
|
||||||
|
["m.audio", "🎶"],
|
||||||
|
["m.file", "📄"]
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Ty.Event.Outer_M_Room_Message | Ty.Event.Outer_M_Room_Message_File | Ty.Event.Outer_M_Sticker | Ty.Event.Outer_M_Room_Message_Encrypted_File} event
|
* @param {Ty.Event.Outer_M_Room_Message | Ty.Event.Outer_M_Room_Message_File | Ty.Event.Outer_M_Sticker | Ty.Event.Outer_M_Room_Message_Encrypted_File} event
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
* @param {import("discord-api-types/v10").APIGuild} guild
|
||||||
|
@ -380,12 +408,10 @@ async function eventToMessage(event, guild, di) {
|
||||||
// Handling edits. If the edit was an edit of a reply, edits do not include the reply reference, so we need to fetch up to 2 more events.
|
// Handling edits. If the edit was an edit of a reply, edits do not include the reply reference, so we need to fetch up to 2 more events.
|
||||||
// this event ---is an edit of--> original event ---is a reply to--> past event
|
// this event ---is an edit of--> original event ---is a reply to--> past event
|
||||||
await (async () => {
|
await (async () => {
|
||||||
if (!event.content["m.new_content"]) return
|
// Check if there is an edit
|
||||||
const relatesTo = event.content["m.relates_to"]
|
const relatesTo = event.content["m.relates_to"]
|
||||||
if (!relatesTo) return
|
if (!event.content["m.new_content"] || !relatesTo || relatesTo.rel_type !== "m.replace") return
|
||||||
// Check if we have a pointer to what was edited
|
// Check if we have a pointer to what was edited
|
||||||
const relType = relatesTo.rel_type
|
|
||||||
if (relType !== "m.replace") return
|
|
||||||
const originalEventId = relatesTo.event_id
|
const originalEventId = relatesTo.event_id
|
||||||
if (!originalEventId) return
|
if (!originalEventId) return
|
||||||
messageIDsToEdit = select("event_message", "message_id", {event_id: originalEventId}, "ORDER BY part").pluck().all()
|
messageIDsToEdit = select("event_message", "message_id", {event_id: originalEventId}, "ORDER BY part").pluck().all()
|
||||||
|
@ -480,12 +506,7 @@ async function eventToMessage(event, guild, di) {
|
||||||
repliedToEvent.content = repliedToEvent.content["m.new_content"]
|
repliedToEvent.content = repliedToEvent.content["m.new_content"]
|
||||||
}
|
}
|
||||||
let contentPreview
|
let contentPreview
|
||||||
const fileReplyContentAlternative =
|
const fileReplyContentAlternative = attachmentEmojis.get(repliedToEvent.content.msgtype)
|
||||||
( repliedToEvent.content.msgtype === "m.image" ? "🖼️"
|
|
||||||
: repliedToEvent.content.msgtype === "m.video" ? "🎞️"
|
|
||||||
: repliedToEvent.content.msgtype === "m.audio" ? "🎶"
|
|
||||||
: repliedToEvent.content.msgtype === "m.file" ? "📄"
|
|
||||||
: null)
|
|
||||||
if (fileReplyContentAlternative) {
|
if (fileReplyContentAlternative) {
|
||||||
contentPreview = " " + fileReplyContentAlternative
|
contentPreview = " " + fileReplyContentAlternative
|
||||||
} else {
|
} else {
|
||||||
|
@ -574,8 +595,35 @@ async function eventToMessage(event, guild, di) {
|
||||||
last = match.index
|
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.
|
||||||
|
const doc = domino.createDocument(
|
||||||
|
// DOM parsers arrange elements in the <head> and <body>. Wrapping in a custom element ensures elements are reliably arranged in a single element.
|
||||||
|
'<x-turndown id="turndown-root">' + input + '</x-turndown>'
|
||||||
|
);
|
||||||
|
const root = doc.getElementById("turndown-root");
|
||||||
|
async function forEachNode(node) {
|
||||||
|
for (; node; node = node.nextSibling) {
|
||||||
|
if (node.nodeType === 3 && node.nodeValue.includes("@")) {
|
||||||
|
const result = await checkWrittenMentions(node.nodeValue, guild, di)
|
||||||
|
if (result) {
|
||||||
|
node.nodeValue = result.content
|
||||||
|
ensureJoined.push(result.ensureJoined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.nodeType === 1 && ["CODE", "PRE", "A"].includes(node.tagName)) {
|
||||||
|
// don't recurse into code or links
|
||||||
|
} else {
|
||||||
|
// do recurse into everything else
|
||||||
|
await forEachNode(node.firstChild)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await forEachNode(root)
|
||||||
|
|
||||||
// @ts-ignore bad type from turndown
|
// @ts-ignore bad type from turndown
|
||||||
content = turndownService.turndown(input)
|
content = turndownService.turndown(root)
|
||||||
|
|
||||||
// It's designed for commonmark, we need to replace the space-space-newline with just newline
|
// It's designed for commonmark, we need to replace the space-space-newline with just newline
|
||||||
content = content.replace(/ \n/g, "\n")
|
content = content.replace(/ \n/g, "\n")
|
||||||
|
@ -592,6 +640,12 @@ async function eventToMessage(event, guild, di) {
|
||||||
|
|
||||||
content = await handleRoomOrMessageLinks(content, di)
|
content = await handleRoomOrMessageLinks(content, di)
|
||||||
|
|
||||||
|
const result = await checkWrittenMentions(content, guild, di)
|
||||||
|
if (result) {
|
||||||
|
content = result.content
|
||||||
|
ensureJoined.push(result.ensureJoined)
|
||||||
|
}
|
||||||
|
|
||||||
// Markdown needs to be escaped, though take care not to escape the middle of links
|
// Markdown needs to be escaped, though take care not to escape the middle of links
|
||||||
// @ts-ignore bad type from turndown
|
// @ts-ignore bad type from turndown
|
||||||
content = turndownService.escape(content)
|
content = turndownService.escape(content)
|
||||||
|
@ -640,18 +694,6 @@ async function eventToMessage(event, guild, di) {
|
||||||
|
|
||||||
content = displayNameRunoff + replyLine + content
|
content = displayNameRunoff + replyLine + content
|
||||||
|
|
||||||
// Handling written @mentions: we need to look for candidate Discord members to join to the room
|
|
||||||
let writtenMentionMatch = content.match(/(?:^|[^"[<>/A-Za-z0-9])@([A-Za-z][A-Za-z0-9._\[\]\(\)-]+):?/d) // /d flag for indices requires node.js 16+
|
|
||||||
if (writtenMentionMatch) {
|
|
||||||
const results = await di.snow.guild.searchGuildMembers(guild.id, {query: writtenMentionMatch[1]})
|
|
||||||
if (results[0]) {
|
|
||||||
assert(results[0].user)
|
|
||||||
// @ts-ignore - typescript doesn't know about indices yet
|
|
||||||
content = content.slice(0, writtenMentionMatch.indices[1][0]-1) + `<@${results[0].user.id}>` + content.slice(writtenMentionMatch.indices[1][1])
|
|
||||||
ensureJoined.push(results[0].user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split into 2000 character chunks
|
// Split into 2000 character chunks
|
||||||
const chunks = chunk(content, 2000)
|
const chunks = chunk(content, 2000)
|
||||||
messages = messages.concat(chunks.map(content => ({
|
messages = messages.concat(chunks.map(content => ({
|
||||||
|
|
|
@ -1924,7 +1924,7 @@ test("event2message: mentioning PK discord users works", async t => {
|
||||||
messagesToEdit: [],
|
messagesToEdit: [],
|
||||||
messagesToSend: [{
|
messagesToSend: [{
|
||||||
username: "cadence [they]",
|
username: "cadence [they]",
|
||||||
content: "I'm just <@196188877885538304> testing mentions",
|
content: "I'm just **@Azalea &flwr; 🌺** (<@196188877885538304>) testing mentions",
|
||||||
avatar_url: undefined
|
avatar_url: undefined
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
@ -2845,7 +2845,7 @@ test("event2message: unknown emojis in the middle are linked", async t => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("event2message: guessed @mentions may join members to mention", async t => {
|
test("event2message: guessed @mentions in plaintext may join members to mention", async t => {
|
||||||
let called = 0
|
let called = 0
|
||||||
const subtext = {
|
const subtext = {
|
||||||
user: {
|
user: {
|
||||||
|
@ -2893,6 +2893,56 @@ test("event2message: guessed @mentions may join members to mention", async t =>
|
||||||
t.equal(called, 1, "searchGuildMembers should be called once")
|
t.equal(called, 1, "searchGuildMembers should be called once")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("event2message: guessed @mentions in formatted body may join members to mention", async t => {
|
||||||
|
let called = 0
|
||||||
|
const subtext = {
|
||||||
|
user: {
|
||||||
|
id: "321876634777218072",
|
||||||
|
username: "subtextual",
|
||||||
|
global_name: "subtext",
|
||||||
|
discriminator: "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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: "<strong><em>HEY @SUBTEXT, WHAT FOOD WOULD YOU LIKE TO ORDER??</em></strong>"
|
||||||
|
},
|
||||||
|
event_id: "$u5gSwSzv_ZQS3eM00mnTBCor8nx_A_AwuQz7e59PZk8",
|
||||||
|
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||||
|
}, {
|
||||||
|
id: "112760669178241024"
|
||||||
|
}, {
|
||||||
|
snow: {
|
||||||
|
guild: {
|
||||||
|
async searchGuildMembers(guildID, options) {
|
||||||
|
called++
|
||||||
|
t.equal(guildID, "112760669178241024")
|
||||||
|
t.deepEqual(options, {query: "SUBTEXT"})
|
||||||
|
return [subtext]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
messagesToDelete: [],
|
||||||
|
messagesToEdit: [],
|
||||||
|
messagesToSend: [{
|
||||||
|
username: "cadence [they]",
|
||||||
|
content: "**_HEY <@321876634777218072>, WHAT FOOD WOULD YOU LIKE TO ORDER??_**",
|
||||||
|
avatar_url: undefined
|
||||||
|
}],
|
||||||
|
ensureJoined: [subtext.user]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
t.equal(called, 1, "searchGuildMembers should be called once")
|
||||||
|
})
|
||||||
|
|
||||||
test("event2message: guessed @mentions work with other matrix bridge old users", async t => {
|
test("event2message: guessed @mentions work with other matrix bridge old users", async t => {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
await eventToMessage({
|
await eventToMessage({
|
||||||
|
|
124
test/data.js
124
test/data.js
|
@ -1340,6 +1340,89 @@ module.exports = {
|
||||||
components: []
|
components: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
voice_message: {
|
||||||
|
id: "1112476845783388160",
|
||||||
|
type: 0,
|
||||||
|
content: "",
|
||||||
|
channel_id: "1099031887500034088",
|
||||||
|
author: {
|
||||||
|
id: "113340068197859328",
|
||||||
|
username: "kumaccino",
|
||||||
|
avatar: "b48302623a12bc7c59a71328f72ccb39",
|
||||||
|
discriminator: "0",
|
||||||
|
public_flags: 128,
|
||||||
|
premium_type: 0,
|
||||||
|
flags: 128,
|
||||||
|
banner: null,
|
||||||
|
accent_color: null,
|
||||||
|
global_name: "kumaccino",
|
||||||
|
avatar_decoration_data: null,
|
||||||
|
banner_color: null
|
||||||
|
},
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
id: "1112476845502365786",
|
||||||
|
filename: "voice-message.ogg",
|
||||||
|
size: 10584,
|
||||||
|
url: "https://cdn.discordapp.com/attachments/1099031887500034088/1112476845502365786/voice-message.ogg?ex=65c92d4c&is=65b6b84c&hm=0654bab5027474cbe23875954fa117cf44d8914c144cd151879590fa1baf8b1c&",
|
||||||
|
proxy_url: "https://media.discordapp.net/attachments/1099031887500034088/1112476845502365786/voice-message.ogg?ex=65c92d4c&is=65b6b84c&hm=0654bab5027474cbe23875954fa117cf44d8914c144cd151879590fa1baf8b1c&",
|
||||||
|
duration_secs: 3.9600000381469727,
|
||||||
|
waveform: "AAgXAAwAPBsCAAAAInEDFwAAAAAbMwATEBAAAAAAAAAAAAAAAA==",
|
||||||
|
content_type: "audio/ogg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
embeds: [],
|
||||||
|
mentions: [],
|
||||||
|
mention_roles: [],
|
||||||
|
pinned: false,
|
||||||
|
mention_everyone: false,
|
||||||
|
tts: false,
|
||||||
|
timestamp: "2023-05-28T20:25:48.855000+00:00",
|
||||||
|
edited_timestamp: null,
|
||||||
|
flags: 8192,
|
||||||
|
components: []
|
||||||
|
},
|
||||||
|
misc_file: {
|
||||||
|
id: "1174514575819931718",
|
||||||
|
type: 0,
|
||||||
|
content: "final final final revised draft",
|
||||||
|
channel_id: "122155380120748034",
|
||||||
|
author: {
|
||||||
|
id: "142843483923677184",
|
||||||
|
username: "huck",
|
||||||
|
avatar: "a_1c7fda09a242d714570b4c828ef07504",
|
||||||
|
discriminator: "0",
|
||||||
|
public_flags: 512,
|
||||||
|
premium_type: 2,
|
||||||
|
flags: 512,
|
||||||
|
banner: null,
|
||||||
|
accent_color: null,
|
||||||
|
global_name: null,
|
||||||
|
avatar_decoration_data: null,
|
||||||
|
banner_color: null
|
||||||
|
},
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
id: "1174514575220158545",
|
||||||
|
filename: "the.yml",
|
||||||
|
size: 2274,
|
||||||
|
url: "https://cdn.discordapp.com/attachments/122155380120748034/1174514575220158545/the.yml?ex=65cd6270&is=65baed70&hm=8c5f1b571784e3c7f99628492298815884e351ae0dc7c2ae40dd22d97caf27d9&",
|
||||||
|
proxy_url: "https://media.discordapp.net/attachments/122155380120748034/1174514575220158545/the.yml?ex=65cd6270&is=65baed70&hm=8c5f1b571784e3c7f99628492298815884e351ae0dc7c2ae40dd22d97caf27d9&",
|
||||||
|
content_type: "text/plain; charset=utf-8",
|
||||||
|
content_scan_version: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
embeds: [],
|
||||||
|
mentions: [],
|
||||||
|
mention_roles: [],
|
||||||
|
pinned: false,
|
||||||
|
mention_everyone: false,
|
||||||
|
tts: false,
|
||||||
|
timestamp: "2023-11-16T01:01:36.301000+00:00",
|
||||||
|
edited_timestamp: null,
|
||||||
|
flags: 0,
|
||||||
|
components: []
|
||||||
|
},
|
||||||
simple_reply_to_reply_in_thread: {
|
simple_reply_to_reply_in_thread: {
|
||||||
type: 19,
|
type: 19,
|
||||||
tts: false,
|
tts: false,
|
||||||
|
@ -1681,6 +1764,47 @@ module.exports = {
|
||||||
components: []
|
components: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
pk_message: {
|
||||||
|
pk_reply: {
|
||||||
|
id: "1202543812644306965",
|
||||||
|
type: 0,
|
||||||
|
content: "this is a reply",
|
||||||
|
channel_id: "1160894080998461480",
|
||||||
|
author: {
|
||||||
|
id: "1195662438662680720",
|
||||||
|
username: "special name",
|
||||||
|
avatar: "6b44a106659e78a2550474c61889194d",
|
||||||
|
discriminator: "0000",
|
||||||
|
public_flags: 0,
|
||||||
|
flags: 0,
|
||||||
|
bot: true,
|
||||||
|
global_name: null
|
||||||
|
},
|
||||||
|
attachments: [],
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
type: "rich",
|
||||||
|
description: "**[Reply to:](https://discord.com/channels/1160893336324931584/1160894080998461480/1202543413652881428)** now for my next experiment:",
|
||||||
|
author: {
|
||||||
|
name: "cadence [they] ↩️",
|
||||||
|
icon_url: "https://cdn.discordapp.com/avatars/1162510387057545227/af0ead3b92cf6e448fdad80b4e7fc9e5.png",
|
||||||
|
proxy_icon_url: "https://images-ext-1.discordapp.net/external/wWslraV-s-bLDwphL64YxeDm30M7PIhQQy0EQa8jpDc/https/cdn.discordapp.com/avatars/1162510387057545227/af0ead3b92cf6e448fdad80b4e7fc9e5.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
mentions: [],
|
||||||
|
mention_roles: [],
|
||||||
|
pinned: false,
|
||||||
|
mention_everyone: false,
|
||||||
|
tts: false,
|
||||||
|
timestamp: "2024-02-01T09:19:47.118000+00:00",
|
||||||
|
edited_timestamp: null,
|
||||||
|
flags: 0,
|
||||||
|
components: [],
|
||||||
|
application_id: "466378653216014359",
|
||||||
|
webhook_id: "1195662438662680720"
|
||||||
|
}
|
||||||
|
},
|
||||||
message_with_embeds: {
|
message_with_embeds: {
|
||||||
nothing_but_a_field: {
|
nothing_but_a_field: {
|
||||||
guild_id: "497159726455455754",
|
guild_id: "497159726455455754",
|
||||||
|
|
|
@ -12,7 +12,8 @@ INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent, custom
|
||||||
('297272183716052993', '!rEOspnYqdOalaIFniV:cadence.moe', 'general', NULL, NULL, NULL),
|
('297272183716052993', '!rEOspnYqdOalaIFniV:cadence.moe', 'general', NULL, NULL, NULL),
|
||||||
('122155380120748034', '!cqeGDbPiMFAhLsqqqq:cadence.moe', 'cadences-mind', 'coding', NULL, NULL),
|
('122155380120748034', '!cqeGDbPiMFAhLsqqqq:cadence.moe', 'cadences-mind', 'coding', NULL, NULL),
|
||||||
('176333891320283136', '!qzDBLKlildpzrrOnFZ:cadence.moe', '🌈丨davids-horse_she-took-the-kids', 'wonderland', NULL, 'mxc://cadence.moe/EVvrSkKIRONHjtRJsMLmHWLS'),
|
('176333891320283136', '!qzDBLKlildpzrrOnFZ:cadence.moe', '🌈丨davids-horse_she-took-the-kids', 'wonderland', NULL, 'mxc://cadence.moe/EVvrSkKIRONHjtRJsMLmHWLS'),
|
||||||
('489237891895768942', '!tnedrGVYKFNUdnegvf:tchncs.de', 'ex-room-doesnt-exist-any-more', NULL, NULL, NULL);
|
('489237891895768942', '!tnedrGVYKFNUdnegvf:tchncs.de', 'ex-room-doesnt-exist-any-more', NULL, NULL, NULL),
|
||||||
|
('1160894080998461480', '!TqlyQmifxGUggEmdBN:cadence.moe', 'ooyexperiment', NULL, NULL, NULL);
|
||||||
|
|
||||||
INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES
|
INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES
|
||||||
('0', 'bot', '_ooye_bot', '@_ooye_bot:cadence.moe'),
|
('0', 'bot', '_ooye_bot', '@_ooye_bot:cadence.moe'),
|
||||||
|
@ -24,8 +25,8 @@ INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES
|
||||||
('1109360903096369153', 'amanda', '_ooye_amanda', '@_ooye_amanda:cadence.moe'),
|
('1109360903096369153', 'amanda', '_ooye_amanda', '@_ooye_amanda:cadence.moe'),
|
||||||
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '_pk_zoego', '_ooye__pk_zoego', '@_ooye__pk_zoego:cadence.moe');
|
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '_pk_zoego', '_ooye__pk_zoego', '@_ooye__pk_zoego:cadence.moe');
|
||||||
|
|
||||||
INSERT INTO sim_proxy (user_id, proxy_owner_id) VALUES
|
INSERT INTO sim_proxy (user_id, proxy_owner_id, displayname) VALUES
|
||||||
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '196188877885538304');
|
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '196188877885538304', 'Azalea &flwr; 🌺');
|
||||||
|
|
||||||
INSERT INTO sim_member (mxid, room_id, hashed_profile_content) VALUES
|
INSERT INTO sim_member (mxid, room_id, hashed_profile_content) VALUES
|
||||||
('@_ooye_bojack_horseman:cadence.moe', '!hYnGGlPHlbujVVfktC:cadence.moe', NULL);
|
('@_ooye_bojack_horseman:cadence.moe', '!hYnGGlPHlbujVVfktC:cadence.moe', NULL);
|
||||||
|
@ -48,7 +49,8 @@ INSERT INTO message_channel (message_id, channel_id) VALUES
|
||||||
('1162005526675193909', '1162005314908999790'),
|
('1162005526675193909', '1162005314908999790'),
|
||||||
('1162625810109317170', '497161350934560778'),
|
('1162625810109317170', '497161350934560778'),
|
||||||
('1158842413025071135', '176333891320283136'),
|
('1158842413025071135', '176333891320283136'),
|
||||||
('1197612733600895076', '112760669178241024');
|
('1197612733600895076', '112760669178241024'),
|
||||||
|
('1202543413652881428', '1160894080998461480');
|
||||||
|
|
||||||
INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, reaction_part, source) VALUES
|
INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, reaction_part, source) VALUES
|
||||||
('$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg', 'm.room.message', 'm.text', '1126786462646550579', 0, 0, 1),
|
('$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg', 'm.room.message', 'm.text', '1126786462646550579', 0, 0, 1),
|
||||||
|
@ -74,7 +76,8 @@ INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part
|
||||||
('$0wEdIP8fhTq-P68xwo_gyUw-Zv0KA2aS2tfhdFSrLZc', 'm.room.message', 'm.text', '1162625810109317170', 1, 1, 1),
|
('$0wEdIP8fhTq-P68xwo_gyUw-Zv0KA2aS2tfhdFSrLZc', 'm.room.message', 'm.text', '1162625810109317170', 1, 1, 1),
|
||||||
('$zJFjTvNn1w_YqpR4o4ISKUFisNRgZcu1KSMI_LADPVQ', 'm.room.message', 'm.notice', '1162625810109317170', 1, 0, 1),
|
('$zJFjTvNn1w_YqpR4o4ISKUFisNRgZcu1KSMI_LADPVQ', 'm.room.message', 'm.notice', '1162625810109317170', 1, 0, 1),
|
||||||
('$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo', 'm.room.message', 'm.text', '1158842413025071135', 0, 0, 1),
|
('$dVCLyj6kxb3DaAWDtjcv2kdSny8JMMHdDhCMz8mDxVo', 'm.room.message', 'm.text', '1158842413025071135', 0, 0, 1),
|
||||||
('$7tJoMw1h44n2gxgLUE1T_YinGrLbK0x-TDY1z6M7GBw', 'm.room.message', 'm.text', '1197612733600895076', 0, 0, 1);
|
('$7tJoMw1h44n2gxgLUE1T_YinGrLbK0x-TDY1z6M7GBw', 'm.room.message', 'm.text', '1197612733600895076', 0, 0, 1),
|
||||||
|
('$NB6nPgO2tfXyIwwDSF0Ga0BUrsgX1S-0Xl-jAvI8ucU', 'm.room.message', 'm.text', '1202543413652881428', 0, 0, 0);
|
||||||
|
|
||||||
INSERT INTO file (discord_url, mxc_url) VALUES
|
INSERT INTO file (discord_url, mxc_url) VALUES
|
||||||
('https://cdn.discordapp.com/attachments/497161332244742154/1124628646431297546/image.png', 'mxc://cadence.moe/qXoZktDqNtEGuOCZEADAMvhM'),
|
('https://cdn.discordapp.com/attachments/497161332244742154/1124628646431297546/image.png', 'mxc://cadence.moe/qXoZktDqNtEGuOCZEADAMvhM'),
|
||||||
|
@ -92,7 +95,9 @@ INSERT INTO file (discord_url, mxc_url) VALUES
|
||||||
('https://cdn.discordapp.com/emojis/1125827250609201255.png', 'mxc://cadence.moe/pgdGTxAyEltccRgZKxdqzHHP'),
|
('https://cdn.discordapp.com/emojis/1125827250609201255.png', 'mxc://cadence.moe/pgdGTxAyEltccRgZKxdqzHHP'),
|
||||||
('https://cdn.discordapp.com/avatars/320067006521147393/5fc4ad85c1ea876709e9a7d3374a78a1.png?size=1024', 'mxc://cadence.moe/JPzSmALLirnIprlSMKohSSoX'),
|
('https://cdn.discordapp.com/avatars/320067006521147393/5fc4ad85c1ea876709e9a7d3374a78a1.png?size=1024', 'mxc://cadence.moe/JPzSmALLirnIprlSMKohSSoX'),
|
||||||
('https://cdn.discordapp.com/emojis/288858540888686602.png', 'mxc://cadence.moe/mwZaCtRGAQQyOItagDeCocEO'),
|
('https://cdn.discordapp.com/emojis/288858540888686602.png', 'mxc://cadence.moe/mwZaCtRGAQQyOItagDeCocEO'),
|
||||||
('https://cdn.discordapp.com/attachments/112760669178241024/1197621094786531358/Ins_1960637570.mp4', 'mxc://cadence.moe/kMqLycqMURhVpwleWkmASpnU');
|
('https://cdn.discordapp.com/attachments/112760669178241024/1197621094786531358/Ins_1960637570.mp4', 'mxc://cadence.moe/kMqLycqMURhVpwleWkmASpnU'),
|
||||||
|
('https://cdn.discordapp.com/attachments/1099031887500034088/1112476845502365786/voice-message.ogg', 'mxc://cadence.moe/MRRPDggXQMYkrUjTpxQbmcxB'),
|
||||||
|
('https://cdn.discordapp.com/attachments/122155380120748034/1174514575220158545/the.yml', 'mxc://cadence.moe/HnQIYQmmlIKwOQsbFsIGpzPP');
|
||||||
|
|
||||||
INSERT INTO emoji (emoji_id, name, animated, mxc_url) VALUES
|
INSERT INTO emoji (emoji_id, name, animated, mxc_url) VALUES
|
||||||
('230201364309868544', 'hippo', 0, 'mxc://cadence.moe/qWmbXeRspZRLPcjseyLmeyXC'),
|
('230201364309868544', 'hippo', 0, 'mxc://cadence.moe/qWmbXeRspZRLPcjseyLmeyXC'),
|
||||||
|
|
|
@ -48,6 +48,12 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
||||||
t.pass("it did not throw an error")
|
t.pass("it did not throw an error")
|
||||||
})
|
})
|
||||||
await p
|
await p
|
||||||
|
|
||||||
|
test("migrate: migration works the second time", async t => {
|
||||||
|
await migrate.migrate(db)
|
||||||
|
t.pass("it did not throw an error")
|
||||||
|
})
|
||||||
|
|
||||||
db.exec(fs.readFileSync(join(__dirname, "ooye-test-data.sql"), "utf8"))
|
db.exec(fs.readFileSync(join(__dirname, "ooye-test-data.sql"), "utf8"))
|
||||||
require("../db/orm.test")
|
require("../db/orm.test")
|
||||||
require("../discord/utils.test")
|
require("../discord/utils.test")
|
||||||
|
@ -63,6 +69,7 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
||||||
require("../d2m/converters/lottie.test")
|
require("../d2m/converters/lottie.test")
|
||||||
require("../d2m/converters/message-to-event.test")
|
require("../d2m/converters/message-to-event.test")
|
||||||
require("../d2m/converters/message-to-event.embeds.test")
|
require("../d2m/converters/message-to-event.embeds.test")
|
||||||
|
require("../d2m/converters/message-to-event.pk.test")
|
||||||
require("../d2m/converters/pins-to-list.test")
|
require("../d2m/converters/pins-to-list.test")
|
||||||
require("../d2m/converters/remove-reaction.test")
|
require("../d2m/converters/remove-reaction.test")
|
||||||
require("../d2m/converters/thread-to-announcement.test")
|
require("../d2m/converters/thread-to-announcement.test")
|
||||||
|
|
Loading…
Reference in a new issue