Rearrange code (self-review)
This commit is contained in:
parent
c5d6c5e4c7
commit
47ac49a855
16 changed files with 275 additions and 74 deletions
8
.c8rc.json
Normal file
8
.c8rc.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"watermarks": {
|
||||
"statements": [60, 100],
|
||||
"lines": [60, 100],
|
||||
"functions": [60, 100],
|
||||
"branches": [60, 100]
|
||||
}
|
||||
}
|
|
@ -93,7 +93,11 @@ async function editToChanges(message, guild, api) {
|
|||
// We can choose an existing event to promote. Bigger order is better.
|
||||
const order = e => 2*+(e.event_type === "m.room.message") + 1*+(e.event_subtype === "m.text")
|
||||
eventsToReplace.sort((a, b) => order(b) - order(a))
|
||||
promotions.push({column, eventID: eventsToReplace[0].old.event_id})
|
||||
if (column === "part") {
|
||||
promotions.push({column, eventID: eventsToReplace[0].old.event_id}) // part should be the first one
|
||||
} else {
|
||||
promotions.push({column, eventID: eventsToReplace[eventsToReplace.length - 1].old.event_id}) // reaction_part should be the last one
|
||||
}
|
||||
} else {
|
||||
// No existing events to promote, but new events are being sent. Whatever gets sent will be the next part = 0.
|
||||
promotions.push({column, nextEvent: true})
|
||||
|
|
|
@ -175,3 +175,63 @@ test("edit2changes: edit of reply to skull webp attachment with content", async
|
|||
}
|
||||
}])
|
||||
})
|
||||
|
||||
test("edit2changes: edits the text event when multiple rows have part = 0 (should never happen in real life, but make sure the safety net works)", async t => {
|
||||
const {eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.edited_content_with_sticker_and_attachments_but_all_parts_equal_0, data.guild.general, {})
|
||||
t.deepEqual(eventsToRedact, [])
|
||||
t.deepEqual(eventsToSend, [])
|
||||
t.deepEqual(eventsToReplace, [{
|
||||
oldID: "$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd999",
|
||||
newContent: {
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.text",
|
||||
body: "* only the content can be edited",
|
||||
"m.mentions": {},
|
||||
// *** Replaced With: ***
|
||||
"m.new_content": {
|
||||
msgtype: "m.text",
|
||||
body: "only the content can be edited",
|
||||
"m.mentions": {}
|
||||
},
|
||||
"m.relates_to": {
|
||||
rel_type: "m.replace",
|
||||
event_id: "$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd999"
|
||||
}
|
||||
}
|
||||
}])
|
||||
})
|
||||
|
||||
test("edit2changes: promotes the text event when multiple rows have part = 1 (should never happen in real life, but make sure the safety net works)", async t => {
|
||||
const {eventsToRedact, eventsToReplace, eventsToSend, promotions} = await editToChanges(data.message_update.edited_content_with_sticker_and_attachments_but_all_parts_equal_1, data.guild.general, {})
|
||||
t.deepEqual(eventsToRedact, [])
|
||||
t.deepEqual(eventsToSend, [])
|
||||
t.deepEqual(eventsToReplace, [{
|
||||
oldID: "$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd111",
|
||||
newContent: {
|
||||
$type: "m.room.message",
|
||||
msgtype: "m.text",
|
||||
body: "* only the content can be edited",
|
||||
"m.mentions": {},
|
||||
// *** Replaced With: ***
|
||||
"m.new_content": {
|
||||
msgtype: "m.text",
|
||||
body: "only the content can be edited",
|
||||
"m.mentions": {}
|
||||
},
|
||||
"m.relates_to": {
|
||||
rel_type: "m.replace",
|
||||
event_id: "$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd111"
|
||||
}
|
||||
}
|
||||
}])
|
||||
t.deepEqual(promotions, [
|
||||
{
|
||||
column: "part",
|
||||
eventID: "$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd111"
|
||||
},
|
||||
{
|
||||
column: "reaction_part",
|
||||
eventID: "$f9cjKiacXI9qPF_nUAckzbiKnJEi0LM399kOkhdd111"
|
||||
}
|
||||
])
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @ts-check
|
||||
|
||||
const assert = require("assert")
|
||||
const stream = require("stream")
|
||||
const {PNG} = require("pngjs")
|
||||
|
||||
|
@ -27,7 +28,7 @@ async function convert(text) {
|
|||
/** @type RlottieWasm */
|
||||
const rh = new r.RlottieWasm()
|
||||
const status = rh.load(text)
|
||||
if (!status) throw new Error(`Rlottie unable to load ${text.length} byte data file.`)
|
||||
assert(status, `Rlottie unable to load ${text.length} byte data file.`)
|
||||
const rendered = rh.render(0, SIZE, SIZE)
|
||||
let png = new PNG({
|
||||
width: SIZE,
|
||||
|
@ -38,11 +39,9 @@ async function convert(text) {
|
|||
inputHasAlpha: true,
|
||||
})
|
||||
png.data = Buffer.from(rendered)
|
||||
// The transform stream is necessary because PNG requires me to pipe it somewhere before this event loop ends
|
||||
const resultStream = png.pack()
|
||||
const p = new stream.PassThrough()
|
||||
resultStream.pipe(p)
|
||||
return p
|
||||
// png.pack() is a bad stream and will throw away any data it sends if it's not connected to a destination straight away.
|
||||
// We use Duplex.from to convert it into a good stream.
|
||||
return stream.Duplex.from(png.pack())
|
||||
}
|
||||
|
||||
module.exports.convert = convert
|
||||
|
|
|
@ -78,10 +78,14 @@ function getDiscordParseCallbacks(message, guild, useHTML) {
|
|||
return `@${role.name}:`
|
||||
}
|
||||
},
|
||||
everyone: node =>
|
||||
"@room",
|
||||
here: node =>
|
||||
"@here"
|
||||
everyone: () => {
|
||||
if (message.mention_everyone) return "@room"
|
||||
return "@everyone"
|
||||
},
|
||||
here: () => {
|
||||
if (message.mention_everyone) return "@room"
|
||||
return "@here"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,6 +203,7 @@ async function attachmentToEvent(mentions, attachment) {
|
|||
async function messageToEvent(message, guild, options = {}, di) {
|
||||
const events = []
|
||||
|
||||
/* c8 ignore next 7 */
|
||||
if (message.type === DiscordTypes.MessageType.ThreadCreated) {
|
||||
// This is the kind of message that appears when somebody makes a thread which isn't close enough to the message it's based off.
|
||||
// It lacks the lines and the pill, so it looks kind of like a member join message, and it says:
|
||||
|
|
|
@ -60,7 +60,7 @@ function userToSimName(user) {
|
|||
|
||||
// 1. Is sim user already registered?
|
||||
const existing = select("sim", "sim_name", {user_id: user.id}).pluck().get()
|
||||
if (existing) return existing
|
||||
assert.equal(existing, null, "Shouldn't try to create a new name for an existing sim")
|
||||
|
||||
// 2. Register based on username (could be new or old format)
|
||||
// (Unless it's a special user, in which case copy their provided mappings.)
|
||||
|
|
36
m2d/actions/emoji-sheet.js
Normal file
36
m2d/actions/emoji-sheet.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
// @ts-check
|
||||
|
||||
const assert = require("assert")
|
||||
const fetch = require("node-fetch").default
|
||||
|
||||
const utils = require("../converters/utils")
|
||||
const {sync} = require("../../passthrough")
|
||||
|
||||
/** @type {import("../converters/emoji-sheet")} */
|
||||
const emojiSheetConverter = sync.require("../converters/emoji-sheet")
|
||||
|
||||
/**
|
||||
* Downloads the emoji from the web and converts to uncompressed PNG data.
|
||||
* @param {string} mxc a single mxc:// URL
|
||||
* @returns {Promise<Buffer | undefined>} uncompressed PNG data, or undefined if the downloaded emoji is not valid
|
||||
*/
|
||||
async function getAndConvertEmoji(mxc) {
|
||||
const abortController = new AbortController()
|
||||
|
||||
const url = utils.getPublicUrlForMxc(mxc)
|
||||
assert(url)
|
||||
|
||||
/** @type {import("node-fetch").Response} */
|
||||
// If it turns out to be a GIF, we want to abandon the connection without downloading the whole thing.
|
||||
// If we were using connection pooling, we would be forced to download the entire GIF.
|
||||
// So we set no agent to ensure we are not connection pooling.
|
||||
// @ts-ignore the signal is slightly different from the type it wants (still works fine)
|
||||
const res = await fetch(url, {agent: false, signal: abortController.signal})
|
||||
return emojiSheetConverter.convertImageStream(res.body, () => {
|
||||
abortController.abort()
|
||||
res.body.pause()
|
||||
res.body.emit("end")
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.getAndConvertEmoji = getAndConvertEmoji
|
|
@ -17,8 +17,8 @@ const eventToMessage = sync.require("../converters/event-to-message")
|
|||
const api = sync.require("../../matrix/api")
|
||||
/** @type {import("../../d2m/actions/register-user")} */
|
||||
const registerUser = sync.require("../../d2m/actions/register-user")
|
||||
/** @type {import("../converters/emoji-sheet")} */
|
||||
const emojiSheet = sync.require("../converters/emoji-sheet")
|
||||
/** @type {import("../actions/emoji-sheet")} */
|
||||
const emojiSheet = sync.require("../actions/emoji-sheet")
|
||||
|
||||
/**
|
||||
* @param {DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer | Readable}[], pendingFiles?: ({name: string, url: string} | {name: string, url: string, key: string, iv: string} | {name: string, buffer: Buffer | Readable})[]}} message
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
// @ts-check
|
||||
|
||||
const assert = require("assert").strict
|
||||
const fs = require("fs")
|
||||
const {pipeline} = require("stream").promises
|
||||
const sharp = require("sharp")
|
||||
const {GIFrame} = require("giframe")
|
||||
const {PNG} = require("pngjs")
|
||||
const utils = require("./utils")
|
||||
const fetch = require("node-fetch").default
|
||||
const streamMimeType = require("stream-mime-type")
|
||||
|
||||
const SIZE = 48
|
||||
|
@ -50,49 +47,6 @@ async function compositeMatrixEmojis(mxcs, mxcDownloader) {
|
|||
return output.data
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the emoji from the web and converts to uncompressed PNG data.
|
||||
* @param {string} mxc a single mxc:// URL
|
||||
* @returns {Promise<Buffer | undefined>} uncompressed PNG data, or undefined if the downloaded emoji is not valid
|
||||
*/
|
||||
async function getAndConvertEmoji(mxc) {
|
||||
const abortController = new AbortController()
|
||||
|
||||
const url = utils.getPublicUrlForMxc(mxc)
|
||||
assert(url)
|
||||
|
||||
/** @type {import("node-fetch").Response} */
|
||||
// If it turns out to be a GIF, we want to abandon the connection without downloading the whole thing.
|
||||
// If we were using connection pooling, we would be forced to download the entire GIF.
|
||||
// So we set no agent to ensure we are not connection pooling.
|
||||
// @ts-ignore the signal is slightly different from the type it wants (still works fine)
|
||||
const res = await fetch(url, {agent: false, signal: abortController.signal})
|
||||
return convertImageStream(res.body, () => {
|
||||
abortController.abort()
|
||||
res.body.pause()
|
||||
res.body.emit("end")
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* MOCK: Gets the emoji from the filesystem and converts to uncompressed PNG data.
|
||||
* @param {string} mxc a single mxc:// URL
|
||||
* @returns {Promise<Buffer | undefined>} uncompressed PNG data, or undefined if the downloaded emoji is not valid
|
||||
*/
|
||||
async function _mockGetAndConvertEmoji(mxc) {
|
||||
const id = mxc.match(/\/([^./]*)$/)?.[1]
|
||||
let s
|
||||
if (fs.existsSync(`test/res/${id}.png`)) {
|
||||
s = fs.createReadStream(`test/res/${id}.png`)
|
||||
} else {
|
||||
s = fs.createReadStream(`test/res/${id}.gif`)
|
||||
}
|
||||
return convertImageStream(s, () => {
|
||||
s.pause()
|
||||
s.emit("end")
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("node-fetch").Response["body"]} streamIn
|
||||
* @param {() => any} stopStream
|
||||
|
@ -156,6 +110,4 @@ async function convertImageStream(streamIn, stopStream) {
|
|||
}
|
||||
|
||||
module.exports.compositeMatrixEmojis = compositeMatrixEmojis
|
||||
module.exports.getAndConvertEmoji = getAndConvertEmoji
|
||||
module.exports._mockGetAndConvertEmoji = _mockGetAndConvertEmoji
|
||||
module.exports._convertImageStream = convertImageStream
|
||||
module.exports.convertImageStream = convertImageStream
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const assert = require("assert").strict
|
||||
const {test} = require("supertape")
|
||||
const {_convertImageStream} = require("./emoji-sheet")
|
||||
const {convertImageStream} = require("./emoji-sheet")
|
||||
const fs = require("fs")
|
||||
const {Transform} = require("stream").Transform
|
||||
|
||||
|
@ -33,7 +32,7 @@ async function runSingleTest(t, path, totalSize, sizeCheck) {
|
|||
const file = fs.createReadStream(path)
|
||||
const meter = new Meter()
|
||||
const p = file.pipe(meter)
|
||||
const result = await _convertImageStream(p, () => {
|
||||
const result = await convertImageStream(p, () => {
|
||||
file.pause()
|
||||
file.emit("end")
|
||||
})
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
const assert = require("assert").strict
|
||||
const fs = require("fs")
|
||||
const {test} = require("supertape")
|
||||
const {eventToMessage} = require("./event-to-message")
|
||||
const {_mockGetAndConvertEmoji} = require("./emoji-sheet")
|
||||
const {convertImageStream} = require("./emoji-sheet")
|
||||
const data = require("../../test/data")
|
||||
const {MatrixServerError} = require("../../matrix/mreq")
|
||||
const {db, select, discord} = require("../../passthrough")
|
||||
const {select, discord} = require("../../passthrough")
|
||||
|
||||
/* c8 ignore next 7 */
|
||||
function slow() {
|
||||
|
@ -47,6 +48,25 @@ function sameFirstContentAndWhitespace(t, a, b) {
|
|||
t.equal(a2, b2)
|
||||
}
|
||||
|
||||
/**
|
||||
* MOCK: Gets the emoji from the filesystem and converts to uncompressed PNG data.
|
||||
* @param {string} mxc a single mxc:// URL
|
||||
* @returns {Promise<Buffer | undefined>} uncompressed PNG data, or undefined if the downloaded emoji is not valid
|
||||
*/
|
||||
async function mockGetAndConvertEmoji(mxc) {
|
||||
const id = mxc.match(/\/([^./]*)$/)?.[1]
|
||||
let s
|
||||
if (fs.existsSync(`test/res/${id}.png`)) {
|
||||
s = fs.createReadStream(`test/res/${id}.png`)
|
||||
} else {
|
||||
s = fs.createReadStream(`test/res/${id}.gif`)
|
||||
}
|
||||
return convertImageStream(s, () => {
|
||||
s.pause()
|
||||
s.emit("end")
|
||||
})
|
||||
}
|
||||
|
||||
test("event2message: body is used when there is no formatted_body", async t => {
|
||||
t.deepEqual(
|
||||
await eventToMessage({
|
||||
|
@ -3535,7 +3555,7 @@ slow()("event2message: unknown emoji at the end is reuploaded as a sprite sheet"
|
|||
},
|
||||
event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
|
||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||
}, {}, {mxcDownloader: _mockGetAndConvertEmoji})
|
||||
}, {}, {mxcDownloader: mockGetAndConvertEmoji})
|
||||
const testResult = {
|
||||
content: messages.messagesToSend[0].content,
|
||||
fileName: messages.messagesToSend[0].pendingFiles[0].name,
|
||||
|
@ -3560,7 +3580,7 @@ slow()("event2message: known emoji from an unreachable server at the end is reup
|
|||
},
|
||||
event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
|
||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||
}, {}, {mxcDownloader: _mockGetAndConvertEmoji})
|
||||
}, {}, {mxcDownloader: mockGetAndConvertEmoji})
|
||||
const testResult = {
|
||||
content: messages.messagesToSend[0].content,
|
||||
fileName: messages.messagesToSend[0].pendingFiles[0].name,
|
||||
|
@ -3585,7 +3605,7 @@ slow()("event2message: known and unknown emojis in the end are reuploaded as a s
|
|||
},
|
||||
event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
|
||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe"
|
||||
}, {}, {mxcDownloader: _mockGetAndConvertEmoji})
|
||||
}, {}, {mxcDownloader: mockGetAndConvertEmoji})
|
||||
const testResult = {
|
||||
content: messages.messagesToSend[0].content,
|
||||
fileName: messages.messagesToSend[0].pendingFiles[0].name,
|
||||
|
@ -3610,7 +3630,7 @@ slow()("event2message: all unknown chess emojis are reuploaded as a sprite sheet
|
|||
},
|
||||
event_id: "$Me6iE8C8CZyrDEOYYrXKSYRuuh_25Jj9kZaNrf7LKr4",
|
||||
room_id: "!maggESguZBqGBZtSnr:cadence.moe"
|
||||
}, {}, {mxcDownloader: _mockGetAndConvertEmoji})
|
||||
}, {}, {mxcDownloader: mockGetAndConvertEmoji})
|
||||
const testResult = {
|
||||
content: messages.messagesToSend[0].content,
|
||||
fileName: messages.messagesToSend[0].pendingFiles[0].name,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const assert = require("assert")
|
||||
const {kstateToState, stateToKState, diffKState, kstateStripConditionals} = require("./kstate")
|
||||
const {test} = require("supertape")
|
||||
|
||||
|
@ -162,3 +163,29 @@ test("diffKState: power levels are mixed together", t => {
|
|||
})
|
||||
t.notDeepEqual(original, result)
|
||||
})
|
||||
|
||||
test("diffKState: cannot merge power levels if original power levels are missing", t => {
|
||||
const original = {}
|
||||
assert.throws(() =>
|
||||
diffKState(original, {
|
||||
"m.room.power_levels/": {
|
||||
"events": {
|
||||
"m.room.avatar": 0
|
||||
}
|
||||
}
|
||||
})
|
||||
, /original power level data is missing/)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test("diffKState: kstate keys must contain a slash separator", t => {
|
||||
assert.throws(() =>
|
||||
diffKState({
|
||||
"m.room.name/": {name: "test name"},
|
||||
}, {
|
||||
"m.room.name/": {name: "test name"},
|
||||
"new": {a: 2}
|
||||
})
|
||||
, /does not contain a slash separator/)
|
||||
t.pass()
|
||||
})
|
||||
|
|
|
@ -54,6 +54,6 @@
|
|||
"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 --no-check-assertions-count --format tap --no-worker 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"
|
||||
"cover": "c8 --skip-full -x db/migrations -x matrix/file.js -x matrix/api.js -x matrix/mreq.js -x d2m/converters/rlottie-wasm.js -r html -r text supertape --no-check-assertions-count --format fail --no-worker test/test.js -- --slow"
|
||||
}
|
||||
}
|
||||
|
|
82
test/data.js
82
test/data.js
|
@ -2662,6 +2662,88 @@ module.exports = {
|
|||
name: "pomu puff"
|
||||
}]
|
||||
},
|
||||
edited_content_with_sticker_and_attachments_but_all_parts_equal_0: {
|
||||
id: "1106366167788044451",
|
||||
type: 0,
|
||||
content: "only the content can be edited",
|
||||
channel_id: "122155380120748034",
|
||||
author: {
|
||||
id: "113340068197859328",
|
||||
username: "Cookie 🍪",
|
||||
global_name: null,
|
||||
display_name: null,
|
||||
avatar: "b48302623a12bc7c59a71328f72ccb39",
|
||||
discriminator: "7766",
|
||||
public_flags: 128,
|
||||
avatar_decoration: null
|
||||
},
|
||||
attachments: [{
|
||||
id: "1106366167486038016",
|
||||
filename: "image.png",
|
||||
size: 127373,
|
||||
url: "https://cdn.discordapp.com/attachments/122155380120748034/1106366167486038016/image.png",
|
||||
proxy_url: "https://media.discordapp.net/attachments/122155380120748034/1106366167486038016/image.png",
|
||||
width: 333,
|
||||
height: 287,
|
||||
content_type: "image/png"
|
||||
}],
|
||||
embeds: [],
|
||||
mentions: [],
|
||||
mention_roles: [],
|
||||
pinned: false,
|
||||
mention_everyone: false,
|
||||
tts: false,
|
||||
timestamp: "2023-05-11T23:44:09.690000+00:00",
|
||||
edited_timestamp: "2023-05-11T23:44:19.690000+00:00",
|
||||
flags: 0,
|
||||
components: [],
|
||||
sticker_items: [{
|
||||
id: "1106323941183717586",
|
||||
format_type: 1,
|
||||
name: "pomu puff"
|
||||
}]
|
||||
},
|
||||
edited_content_with_sticker_and_attachments_but_all_parts_equal_1: {
|
||||
id: "1106366167788044452",
|
||||
type: 0,
|
||||
content: "only the content can be edited",
|
||||
channel_id: "122155380120748034",
|
||||
author: {
|
||||
id: "113340068197859328",
|
||||
username: "Cookie 🍪",
|
||||
global_name: null,
|
||||
display_name: null,
|
||||
avatar: "b48302623a12bc7c59a71328f72ccb39",
|
||||
discriminator: "7766",
|
||||
public_flags: 128,
|
||||
avatar_decoration: null
|
||||
},
|
||||
attachments: [{
|
||||
id: "1106366167486038016",
|
||||
filename: "image.png",
|
||||
size: 127373,
|
||||
url: "https://cdn.discordapp.com/attachments/122155380120748034/1106366167486038016/image.png",
|
||||
proxy_url: "https://media.discordapp.net/attachments/122155380120748034/1106366167486038016/image.png",
|
||||
width: 333,
|
||||
height: 287,
|
||||
content_type: "image/png"
|
||||
}],
|
||||
embeds: [],
|
||||
mentions: [],
|
||||
mention_roles: [],
|
||||
pinned: false,
|
||||
mention_everyone: false,
|
||||
tts: false,
|
||||
timestamp: "2023-05-11T23:44:09.690000+00:00",
|
||||
edited_timestamp: "2023-05-11T23:44:19.690000+00:00",
|
||||
flags: 0,
|
||||
components: [],
|
||||
sticker_items: [{
|
||||
id: "1106323941183717586",
|
||||
format_type: 1,
|
||||
name: "pomu puff"
|
||||
}]
|
||||
},
|
||||
edit_of_reply_to_skull_webp_attachment_with_content: {
|
||||
type: 19,
|
||||
tts: false,
|
||||
|
|
|
@ -33,6 +33,8 @@ INSERT INTO sim_member (mxid, room_id, hashed_profile_content) VALUES
|
|||
|
||||
INSERT INTO message_channel (message_id, channel_id) VALUES
|
||||
('1106366167788044450', '122155380120748034'),
|
||||
('1106366167788044451', '122155380120748034'),
|
||||
('1106366167788044452', '122155380120748034'),
|
||||
('1126786462646550579', '112760669178241024'),
|
||||
('1128084748338741392', '112760669178241024'),
|
||||
('1128084851279536279', '112760669178241024'),
|
||||
|
@ -68,6 +70,12 @@ INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part
|
|||
('$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4', 'm.room.message', 'm.text', '1106366167788044450', 0, 1, 1),
|
||||
('$Ijf1MFCD39ktrNHxrA-i2aKoRWNYdAV2ZXYQeiZIgEU', 'm.room.message', 'm.image', '1106366167788044450', 1, 1, 0),
|
||||
('$f9cjKiacXI9qPF_nUAckzbiKnJEi0LM399kOkhdd8f8', 'm.sticker', NULL, '1106366167788044450', 1, 0, 0),
|
||||
('$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd999', 'm.room.message', 'm.text', '1106366167788044451', 0, 0, 1),
|
||||
('$Ijf1MFCD39ktrNHxrA-i2aKoRWNYdAV2ZXYQeiZI999', 'm.room.message', 'm.image', '1106366167788044451', 0, 0, 1),
|
||||
('$f9cjKiacXI9qPF_nUAckzbiKnJEi0LM399kOkhdd999', 'm.sticker', NULL, '1106366167788044451', 0, 0, 1),
|
||||
('$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qd111', 'm.room.message', 'm.text', '1106366167788044452', 1, 1, 1),
|
||||
('$Ijf1MFCD39ktrNHxrA-i2aKoRWNYdAV2ZXYQeiZI111', 'm.room.message', 'm.image', '1106366167788044452', 1, 1, 1),
|
||||
('$f9cjKiacXI9qPF_nUAckzbiKnJEi0LM399kOkhdd111', 'm.sticker', NULL, '1106366167788044452', 1, 1, 1),
|
||||
('$Fxy8SMoJuTduwReVkHZ1uHif9EuvNx36Hg79cltiA04', 'm.room.message', 'm.text', '1144865310588014633', 0, 0, 1),
|
||||
('$v_Gtr-bzv9IVlSLBO5DstzwmiDd-GSFaNfHX66IupV8', 'm.room.message', 'm.text', '1144874214311067708', 0, 0, 0),
|
||||
('$7LIdiJCEqjcWUrpzWzS8TELOlFfBEe4ytgS7zn2lbSs', 'm.room.message', 'm.text', '1145688633186193479', 0, 0, 0),
|
||||
|
|
|
@ -49,6 +49,7 @@ passthrough.from = orm.from
|
|||
passthrough.select = orm.select
|
||||
|
||||
const file = sync.require("../matrix/file")
|
||||
/* c8 ignore next */
|
||||
file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not allowed to upload files during testing.\nURL: ${url}`) }
|
||||
|
||||
;(async () => {
|
||||
|
@ -88,7 +89,7 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
|||
{url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/AYPpqXzVJvZdzMQJGjioIQBZ", to: "test/res/AYPpqXzVJvZdzMQJGjioIQBZ.png"},
|
||||
{url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/UVuzvpVUhqjiueMxYXJiFEAj", to: "test/res/UVuzvpVUhqjiueMxYXJiFEAj.png"},
|
||||
{url: "https://ezgif.com/images/format-demo/butterfly.gif", to: "test/res/butterfly.gif"},
|
||||
{url: "https://ezgif.com/images/format-demo/butterfly.gif", to: "test/res/butterfly.png"},
|
||||
{url: "https://ezgif.com/images/format-demo/butterfly.png", to: "test/res/butterfly.png"},
|
||||
])
|
||||
}, {timeout: 60000})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue