const {test} = require("supertape")
const {messageToEvent} = require("./message-to-event")
const {MatrixServerError} = require("../../matrix/mreq")
const data = require("../../../test/data")
const {mockGetEffectivePower} = require("../../matrix/utils.test")
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: simple plaintext", async t => {
	const events = await messageToEvent(data.message.simple_plaintext, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "ayy lmao"
	}])
})

test("message2event: simple plaintext with quotes", async t => {
	const events = await messageToEvent(data.message.simple_plaintext_with_quotes, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: `then he said, "you and her aren't allowed in here!"`
	}])
})

test("message2event: simple user mention", async t => {
	const events = await messageToEvent(data.message.simple_user_mention, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "@crunch god: Tell me about Phil, renowned martial arts master and creator of the Chin Trick",
		format: "org.matrix.custom.html",
		formatted_body: '<a href="https://matrix.to/#/@_ooye_crunch_god:cadence.moe">@crunch god</a> Tell me about Phil, renowned martial arts master and creator of the Chin Trick'
	}])
})

test("message2event: simple room mention", async t => {
	let called = 0
	const events = await messageToEvent(data.message.simple_room_mention, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!BnKuBPCvyfOkhcUjEu:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "#worm-farm",
		format: "org.matrix.custom.html",
		formatted_body: '<a href="https://matrix.to/#/!BnKuBPCvyfOkhcUjEu:cadence.moe?via=cadence.moe&via=matrix.org">#worm-farm</a>'
	}])
	t.equal(called, 1, "should call getJoinedMembers")
})

test("message2event: simple room link", async t => {
	let called = 0
	const events = await messageToEvent(data.message.simple_room_link, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!BnKuBPCvyfOkhcUjEu:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "#worm-farm",
		format: "org.matrix.custom.html",
		formatted_body: '<a href="https://matrix.to/#/!BnKuBPCvyfOkhcUjEu:cadence.moe?via=cadence.moe&via=matrix.org">#worm-farm</a>'
	}])
	t.equal(called, 1, "should call getJoinedMembers once")
})

test("message2event: nicked room mention", async t => {
	let called = 0
	const events = await messageToEvent(data.message.nicked_room_mention, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "#main",
		format: "org.matrix.custom.html",
		formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org">#main</a>'
	}])
	t.equal(called, 1, "should call getJoinedMembers once")
})

test("message2event: unknown room mention", async t => {
	const events = await messageToEvent(data.message.unknown_room_mention, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "#unknown-channel [channel from an unbridged server]"
	}])
})

test("message2event: unbridged room mention", async t => {
	const events = await messageToEvent(data.message.unbridged_room_mention, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "#bad-boots-prison [channel not bridged]"
	}])
})

test("message2event: simple role mentions", async t => {
	const events = await messageToEvent(data.message.simple_role_mentions, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "I'm just @!!DLCS!!: testing a few role pings @Master Wonder Mage: don't mind me",
		format: "org.matrix.custom.html",
		formatted_body: `I'm just <font color="#a901ff">@!!DLCS!!</font> testing a few role pings <span data-mx-color="#ffffff" data-mx-bg-color="#414eef">@Master Wonder Mage</span> don't mind me`
	}])
})

test("message2event: manually constructed unknown roles should use fallback", async t => {
	const events = await messageToEvent(data.message.unknown_role, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "I'm just @&4 testing a few role pings <@&B> don't mind me",
		format: "org.matrix.custom.html",
		formatted_body: "I'm just @&4 testing a few role pings &lt;@&amp;B&gt; don't mind me"
	}])
})

test("message2event: simple message link", async t => {
	let called = 0
	const events = await messageToEvent(data.message.simple_message_link, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:super.invalid": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&via=super.invalid",
		format: "org.matrix.custom.html",
		formatted_body: '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&amp;via=super.invalid">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg?via=cadence.moe&amp;via=super.invalid</a>'
	}])
	t.equal(called, 1, "should call getJoinedMembers once")
})

test("message2event: message link that OOYE doesn't know about", async t => {
	let called = 0
	const events = await messageToEvent(data.message.message_link_to_before_ooye, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getEventForTimestamp(roomID, ts) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return {
					event_id: "$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U",
					origin_server_ts: 1613287812754
				}
			},
			async getJoinedMembers(roomID) { // for ?via calculation
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "Me: I'll scroll up to find a certain message I'll send\n_scrolls up and clicks message links for god knows how long_\n_completely forgets what they were looking for and simply begins scrolling up to find some fun moments_\n_stumbles upon:_ "
			+ "https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?via=cadence.moe&via=matrix.org",
		format: "org.matrix.custom.html",
		formatted_body: "Me: I'll scroll up to find a certain message I'll send<br><em>scrolls up and clicks message links for god knows how long</em><br><em>completely forgets what they were looking for and simply begins scrolling up to find some fun moments</em><br><em>stumbles upon:</em> "
			+ '<a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?via=cadence.moe&amp;via=matrix.org">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe/$E8IQDGFqYzOU7BwY5Z74Bg-cwaU9OthXSroaWtgYc7U?via=cadence.moe&amp;via=matrix.org</a>'
	}])
	t.equal(called, 2, "getEventForTimestamp and getJoinedMembers should be called once each")
})

test("message2event: message timestamp failed to fetch", async t => {
	let called = 0
	const events = await messageToEvent(data.message.message_link_to_before_ooye, data.guild.general, {}, {
		api: {
			async getEventForTimestamp(roomID, ts) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				throw new MatrixServerError({
					errcode: "M_NOT_FOUND",
					error: "Unable to find event from 1726762095974 in direction Direction.FORWARDS"
				}, {})
			},
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers(roomID) { // for ?via calculation
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "Me: I'll scroll up to find a certain message I'll send\n_scrolls up and clicks message links for god knows how long_\n_completely forgets what they were looking for and simply begins scrolling up to find some fun moments_\n_stumbles upon:_ "
			+ "[unknown event in https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&via=matrix.org]",
		format: "org.matrix.custom.html",
		formatted_body: "Me: I'll scroll up to find a certain message I'll send<br><em>scrolls up and clicks message links for god knows how long</em><br><em>completely forgets what they were looking for and simply begins scrolling up to find some fun moments</em><br><em>stumbles upon:</em> "
			+ '[unknown event in <a href="https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org">https://matrix.to/#/!kLRqKKUQXcibIMtOpl:cadence.moe?via=cadence.moe&amp;via=matrix.org</a>]'
	}])
	t.equal(called, 2, "getEventForTimestamp and getJoinedMembers should be called once each")
})

test("message2event: message link from another server", async t => {
	const events = await messageToEvent(data.message.message_link_from_another_server, data.guild.general)
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "Neither of these servers are known to OOYE: https://discord.com/channels/111/222/333 [event is from another server] https://canary.discordapp.com/channels/444/555/666 [event is from another server]",
		format: "org.matrix.custom.html",
		formatted_body: 'Neither of these servers are known to OOYE: <a href="https://discord.com/channels/111/222/333">https://discord.com/channels/111/222/333</a> [event is from another server]'
			+ ' <a href="https://canary.discordapp.com/channels/444/555/666">https://canary.discordapp.com/channels/444/555/666</a> [event is from another server]'
	}])
})

test("message2event: attachment with no content", async t => {
	const events = await messageToEvent(data.message.attachment_no_content, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.image",
		url: "mxc://cadence.moe/qXoZktDqNtEGuOCZEADAMvhM",
		body: "image.png",
		external_url: "https://bridge.example.org/download/discordcdn/497161332244742154/1124628646431297546/image.png",
		filename: "image.png",
		info: {
			mimetype: "image/png",
			w: 466,
			h: 85,
			size: 12919,
		},
	}])
})

test("message2event: spoiler attachment", async t => {
	const events = await messageToEvent(data.message.spoiler_attachment, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "📄 Uploaded SPOILER file: https://bridge.example.org/download/discordcdn/1100319550446252084/1147465564307079258/SPOILER_69-GNDP-CADENCE.nfs.gci (74 KB)",
		format: "org.matrix.custom.html",
		formatted_body: "<blockquote>📄 Uploaded SPOILER file: <a href=\"https://bridge.example.org/download/discordcdn/1100319550446252084/1147465564307079258/SPOILER_69-GNDP-CADENCE.nfs.gci\">https://bridge.example.org/download/discordcdn/1100319550446252084/1147465564307079258/SPOILER_69-GNDP-CADENCE.nfs.gci</a> (74 KB)</blockquote>"
	}])
})

test("message2event: stickers", async t => {
	const events = await messageToEvent(data.message.sticker, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "can have attachments too"
	}, {
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.image",
		url: "mxc://cadence.moe/ZDCNYnkPszxGKgObUIFmvjus",
		body: "image.png",
		external_url: "https://bridge.example.org/download/discordcdn/122155380120748034/1106366167486038016/image.png",
		filename: "image.png",
		info: {
			mimetype: "image/png",
			w: 333,
			h: 287,
			size: 127373,
		},
	}, {
		$type: "m.sticker",
		"m.mentions": {},
		body: "pomu puff - damn that tiny lil bitch really chuffing. puffing that fat ass dart",
		info: {
			mimetype: "image/png"
			// thumbnail_url
			// thumbnail_info
		},
		url: "mxc://cadence.moe/UuUaLwXhkxFRwwWCXipDlBHn"
	}])
})

test("message2event: lottie sticker", async t => {
	const events = await messageToEvent(data.message.lottie_sticker, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.sticker",
		"m.mentions": {},
		body: "8",
		info: {
			mimetype: "image/png",
			w: 160,
			h: 160
		},
		url: "mxc://cadence.moe/ZtvvVbwMIdUZeovWVyGVFCeR"
	}])
})

test("message2event: skull webp attachment with content", async t => {
	const events = await messageToEvent(data.message.skull_webp_attachment_with_content, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "Image"
	}, {
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.image",
		body: "skull.webp",
		info: {
			w: 1200,
			h: 628,
			mimetype: "image/webp",
			size: 74290
		},
		external_url: "https://bridge.example.org/download/discordcdn/112760669178241024/1128084747910918195/skull.webp",
		filename: "skull.webp",
		url: "mxc://cadence.moe/sDxWmDErBhYBxtDcJQgBETes"
	}])
})

test("message2event: reply to skull webp attachment with content", async t => {
	const events = await messageToEvent(data.message.reply_to_skull_webp_attachment_with_content, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$oLyUTyZ_7e_SUzGNWZKz880ll9amLZvXGbArJCKai2Q"
			}
		},
		"m.mentions": {},
		msgtype: "m.text",
		body: "Reply"
	}, {
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.image",
		body: "RDT_20230704_0936184915846675925224905.jpg",
		info: {
			w: 2048,
			h: 1536,
			mimetype: "image/jpeg",
			size: 85906
		},
		external_url: "https://bridge.example.org/download/discordcdn/112760669178241024/1128084851023675515/RDT_20230704_0936184915846675925224905.jpg",
		filename: "RDT_20230704_0936184915846675925224905.jpg",
		url: "mxc://cadence.moe/WlAbFSiNRIHPDEwKdyPeGywa"
	}])
})

test("message2event: simple reply to matrix user", async t => {
	const events = await messageToEvent(data.message.simple_reply_to_matrix_user, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!kLRqKKUQXcibIMtOpl:cadence.moe", "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4", {
				type: "m.room.message",
				content: {
					msgtype: "m.text",
					body: "so can you reply to my webhook uwu"
				},
				sender: "@cadence:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4"
			}
		},
		"m.mentions": {
			user_ids: [
				"@cadence:cadence.moe"
			]
		},
		msgtype: "m.text",
		body: "Reply"
	}])
})

test("message2event: simple reply to matrix user, reply fallbacks disabled", async t => {
	const events = await messageToEvent(data.message.simple_reply_to_matrix_user, data.guild.general, {includeReplyFallback: false}, {
		api: {
			getEvent: mockGetEvent(t, "!kLRqKKUQXcibIMtOpl:cadence.moe", "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4", {
				type: "m.room.message",
				content: {
					msgtype: "m.text",
					body: "so can you reply to my webhook uwu"
				},
				sender: "@cadence:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4"
			}
		},
		"m.mentions": {
			user_ids: [
				"@cadence:cadence.moe"
			]
		},
		msgtype: "m.text",
		body: "Reply"
	}])
})

test("message2event: reply to matrix user with mention", async t => {
	const events = await messageToEvent(data.message.reply_to_matrix_user_mention, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!kLRqKKUQXcibIMtOpl:cadence.moe", "$7P2O_VTQNHvavX5zNJ35DV-dbJB1Ag80tGQP_JzGdhk", {
				type: "m.room.message",
				content: {
					msgtype: "m.text",
					body: "@_ooye_extremity:cadence.moe you owe me $30",
					format: "org.matrix.custom.html",
					formatted_body: "<a href=\"https://matrix.to/#/@_ooye_extremity:cadence.moe\">@_ooye_extremity:cadence.moe</a> you owe me $30"
				},
				sender: "@cadence:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$7P2O_VTQNHvavX5zNJ35DV-dbJB1Ag80tGQP_JzGdhk"
			}
		},
		"m.mentions": {
			user_ids: [
				"@cadence:cadence.moe"
			]
		},
		msgtype: "m.text",
		body: "kys"
	}])
})

test("message2event: reply with a video", async t => {
	const events = await messageToEvent(data.message.reply_with_video, data.guild.general, {
		api: {
			getEvent: mockGetEvent(t, "!kLRqKKUQXcibIMtOpl:cadence.moe", "$7tJoMw1h44n2gxgLUE1T_YinGrLbK0x-TDY1z6M7GBw", {
				type: "m.room.message",
				content: {
					msgtype: "m.text",
					body: 'deadpicord "extremity you woke up at 4 am"'
				},
				sender: "@_ooye_extremity:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.video",
		body: "Ins_1960637570.mp4",
		filename: "Ins_1960637570.mp4",
		url: "mxc://cadence.moe/kMqLycqMURhVpwleWkmASpnU",
		external_url: "https://bridge.example.org/download/discordcdn/112760669178241024/1197621094786531358/Ins_1960637570.mp4",
		info: {
			h: 854,
			mimetype: "video/mp4",
			size: 860559,
			w: 480,
		},
		"m.mentions": {},
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$7tJoMw1h44n2gxgLUE1T_YinGrLbK0x-TDY1z6M7GBw"
			}
		}
	}])
})

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://bridge.example.org/download/discordcdn/1099031887500034088/1112476845502365786/voice-message.ogg",
      filename: "voice-message.ogg",
      info: {
        duration: 3960,
        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://bridge.example.org/download/discordcdn/122155380120748034/1174514575220158545/the.yml",
      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 => {
	const events = await messageToEvent(data.message.simple_reply_to_reply_in_thread, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!FuDZhlOAtqswlyxzeR:cadence.moe", "$nUM-ABBF8KdnvrhXwLlYAE9dgDl_tskOvvcNIBrtsVo", {
				type: "m.room.message",
				sender: "@cadence:cadence.moe",
				content: {
					msgtype: "m.text",
					body: "> <@_ooye_cadence:cadence.moe> So what I'm wondering is about replies.\n\nWhat about them?",
					format: "org.matrix.custom.html",
					formatted_body: "<mx-reply><blockquote><a href=\"https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe/$fWQT8uOrzLzAXNVXz88VkGx7Oo724iS5uD8Qn5KUy9w?via=cadence.moe\">In reply to</a> <a href=\"https://matrix.to/#/@_ooye_cadence:cadence.moe\">@_ooye_cadence:cadence.moe</a><br>So what I&#39;m wondering is about replies.</blockquote></mx-reply>What about them?",
					"m.relates_to": {
						"m.in_reply_to": {
							event_id: "$fWQT8uOrzLzAXNVXz88VkGx7Oo724iS5uD8Qn5KUy9w"
						}
					}
				},
				event_id: "$nUM-ABBF8KdnvrhXwLlYAE9dgDl_tskOvvcNIBrtsVo",
				room_id: "!FuDZhlOAtqswlyxzeR:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$nUM-ABBF8KdnvrhXwLlYAE9dgDl_tskOvvcNIBrtsVo"
			}
		},
		"m.mentions": {
			user_ids: ["@cadence:cadence.moe"]
		},
		msgtype: "m.text",
      body: "Well, they don't seem to..."
	}])
})

test("message2event: infinidoge's reply to ami's matrix smalltext reply to infinidoge", async t => {
	const events = await messageToEvent(data.message.infinidoge_reply_to_ami_matrix_smalltext_reply_to_infinidoge, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!BnKuBPCvyfOkhcUjEu:cadence.moe", "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", {
				type: "m.room.message",
				sender: "@ami:the-apothecary.club",
				content: {
					msgtype: "m.text",
					body: `> <@_ooye_infinidoge:cadence.moe> Neat that they thought of that\n\nlet me guess they got a lot of bug reports like "empty chest with no loot?"`,
					format: "org.matrix.custom.html",
					formatted_body: `<mx-reply><blockquote><a href="https://matrix.to/#/!BnKuBPCvyfOkhcUjEu:cadence.moe/$baby?via=cadence.moe">In reply to</a> <a href="https://matrix.to/#/@_ooye_infinidoge:cadence.moe">@_ooye_infinidoge:cadence.moe</a><br>Neat that they thought of that</blockquote></mx-reply>let me guess they got a lot of bug reports like "empty chest with no loot?"`,
					"m.relates_to": {
						"m.in_reply_to": {
							event_id: "$baby"
						}
					}
				},
				event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4",
				room_id: "!BnKuBPCvyfOkhcUjEu:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4"
			}
		},
		"m.mentions": {
			user_ids: ["@ami:the-apothecary.club"]
		},
		msgtype: "m.text",
      body: `Most likely`
	}])
})

test("message2event: infinidoge's reply to ami's matrix smalltext singleline reply to infinidoge", async t => {
	const events = await messageToEvent(data.message.infinidoge_reply_to_ami_matrix_smalltext_singleline_reply_to_infinidoge, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!BnKuBPCvyfOkhcUjEu:cadence.moe", "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4", {
				type: "m.room.message",
				sender: "@ami:the-apothecary.club",
				content: {
					msgtype: "m.text",
					body: `> <@_ooye_infinidoge:cadence.moe> Neat that they thought of that\n\nlet me guess they got a lot of bug reports like "empty chest with no loot?"`,
					format: "org.matrix.custom.html",
					formatted_body: `<mx-reply><blockquote><a href="https://matrix.to/#/!BnKuBPCvyfOkhcUjEu:cadence.moe/$baby?via=cadence.moe">In reply to</a> <a href="https://matrix.to/#/@_ooye_infinidoge:cadence.moe">@_ooye_infinidoge:cadence.moe</a><br>Neat that they thought of that</blockquote></mx-reply>let me guess they got a lot of bug reports like "empty chest with no loot?"`,
					"m.relates_to": {
						"m.in_reply_to": {
							event_id: "$baby"
						}
					}
				},
				event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4",
				room_id: "!BnKuBPCvyfOkhcUjEu:cadence.moe"
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.relates_to": {
			"m.in_reply_to": {
				event_id: "$W1nsDhNIojWrcQOdnOD9RaEvrz2qyZErQoNhPRs1nK4"
			}
		},
		"m.mentions": {
			user_ids: ["@ami:the-apothecary.club"]
		},
		msgtype: "m.text",
      body: `Most likely`
	}])
})

test("message2event: reply to a Discord message that wasn't bridged", async t => {
	const events = await messageToEvent(data.message.reply_to_unknown_message, data.guild.general)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
      body: `> In reply to a 1-day-old unbridged message:`
			+ `\n> Occimyy: BILLY BOB THE GREAT`
			+ `\n\nenigmatic`,
      format: "org.matrix.custom.html",
      formatted_body: `<blockquote>In reply to a 1-day-old unbridged message from Occimyy:<br>BILLY BOB THE GREAT</blockquote>enigmatic`,
		"m.mentions": {}
	}])
})

test("message2event: simple written @mention for matrix user", async t => {
	const events = await messageToEvent(data.message.simple_written_at_mention_for_matrix, data.guild.general, {}, {
		api: {
			async getJoinedMembers(roomID) {
				t.equal(roomID, "!rEOspnYqdOalaIFniV:cadence.moe")
				return new Promise(resolve => {
					setTimeout(() => {
						resolve({
							joined: {
								"@she_who_brings_destruction:matrix.org": {
									avatar_url: "mxc://matrix.org/FKcfnfFZlEhspeMsERfYtCuO",
									display_name: "ash (Old)"
								},
								"@tomskeleton:cadence.moe": {
									avatar_url: "mxc://cadence.moe/OvYYicuOwfAACKaXKJCUPbVz",
									display_name: "tomskeleton"
								},
								"@she_who_brings_destruction:cadence.moe": {
									avatar_url: "mxc://cadence.moe/XDXLMbkieETPrjFupoeiwyyq",
									display_name: "ash"
								},
								"@_ooye_bot:cadence.moe": {
									avatar_url: "mxc://cadence.moe/jlrgFjYQHzfBvORedOmYqXVz",
									display_name: "Out Of Your Element"
								},
								"@cadence:cadence.moe": {
									avatar_url: "mxc://cadence.moe/GJDPWiryxIhyRBNJzRNYzAlh",
									display_name: "cadence [they]"
								},
								"@_ooye_tomskeleton:cadence.moe": {
									avatar_url: "mxc://cadence.moe/SdSrjjsrNVdyPTAKEGQUhKUK",
									display_name: "tomskeleton"
								},
								"@_ooye_queergasm:cadence.moe": {
									avatar_url: "mxc://cadence.moe/KqXYGbUqhPPJKifLmfpoLnmB",
									display_name: "queergasm"
								},
								"@_ooye_.subtext:cadence.moe": {
									avatar_url: "mxc://cadence.moe/heoCvaUmfCdpxdzaChwwkpEp",
									display_name: ".subtext"
								}
							}
						})
					})
				})
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {
			user_ids: [
				"@she_who_brings_destruction:cadence.moe"
			]
		},
		msgtype: "m.text",
		body: "@ash do you need anything from the store btw as I'm heading there after gym",
		format: "org.matrix.custom.html",
		formatted_body: `<a href="https://matrix.to/#/@she_who_brings_destruction:cadence.moe">@ash</a> do you need anything from the store btw as I'm heading there after gym`
	}])
})

test("message2event: many written @mentions for matrix users", async t => {
	let called = 0
	const events = await messageToEvent(data.message.advanced_written_at_mention_for_matrix, data.guild.general, {}, {
		api: {
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return new Promise(resolve => {
					setTimeout(() => {
						resolve({
							joined: {
								"@cadence:cadence.moe": {
									display_name: "cadence [they]",
									avatar_url: "whatever"
								},
								"@huckleton:cadence.moe": {
									display_name: "huck",
									avatar_url: "whatever"
								},
								"@_ooye_botrac4r:cadence.moe": {
									display_name: "botrac4r",
									avatar_url: "whatever"
								},
								"@_ooye_bot:cadence.moe": {
									display_name: "Out Of Your Element",
									avatar_url: "whatever"
								}
							}
						})
					})
				})
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {
			user_ids: [
				"@huckleton:cadence.moe",
				"@cadence:cadence.moe"
			]
		},
		msgtype: "m.text",
		body: "@Cadence, tell me about @Phil, the creator of the Chin Trick, who has become ever more powerful under the mentorship of @botrac4r and @huck",
		format: "org.matrix.custom.html",
		formatted_body: `<a href="https://matrix.to/#/@cadence:cadence.moe">@Cadence</a>, tell me about @Phil, the creator of the Chin Trick, who has become ever more powerful under the mentorship of @botrac4r and <a href="https://matrix.to/#/@huckleton:cadence.moe">@huck</a>`
	}])
	t.equal(called, 1, "should only look up the member list once")
})

test("message2event: written @mentions may match part of the name", async t => {
	let called = 0
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "I wonder if @cadence saw this?"
	}, data.guild.general, {}, {
		api: {
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return new Promise(resolve => {
					setTimeout(() => {
						resolve({
							joined: {
								"@secret:cadence.moe": {
									display_name: "cadence [they]",
									avatar_url: "whatever"
								},
								"@huckleton:cadence.moe": {
									display_name: "huck",
									avatar_url: "whatever"
								},
								"@_ooye_botrac4r:cadence.moe": {
									display_name: "botrac4r",
									avatar_url: "whatever"
								},
								"@_ooye_bot:cadence.moe": {
									display_name: "Out Of Your Element",
									avatar_url: "whatever"
								}
							}
						})
					})
				})
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {
			user_ids: [
				"@secret:cadence.moe",
			]
		},
		msgtype: "m.text",
		body: "I wonder if @cadence saw this?",
		format: "org.matrix.custom.html",
		formatted_body: `I wonder if <a href="https://matrix.to/#/@secret:cadence.moe">@cadence</a> saw this?`
	}])
})

test("message2event: written @mentions may match part of the mxid", async t => {
	let called = 0
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "I wonder if @huck saw this?"
	}, data.guild.general, {}, {
		api: {
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return new Promise(resolve => {
					setTimeout(() => {
						resolve({
							joined: {
								"@cadence:cadence.moe": {
									display_name: "cadence [they]",
									avatar_url: "whatever"
								},
								"@huckleton:cadence.moe": {
									display_name: "wa",
									avatar_url: "whatever"
								},
								"@_ooye_botrac4r:cadence.moe": {
									display_name: "botrac4r",
									avatar_url: "whatever"
								},
								"@_ooye_bot:cadence.moe": {
									display_name: "Out Of Your Element",
									avatar_url: "whatever"
								}
							}
						})
					})
				})
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {
			user_ids: [
				"@huckleton:cadence.moe",
			]
		},
		msgtype: "m.text",
		body: "I wonder if @huck saw this?",
		format: "org.matrix.custom.html",
		formatted_body: `I wonder if <a href="https://matrix.to/#/@huckleton:cadence.moe">@huck</a> saw this?`
	}])
})

test("message2event: written @mentions do not match in URLs", async t => {
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "the fucking around with pixel composer continues https://pub.mastodon.sleeping.town/@exa/116037641900024965"
	}, data.guild.general, {}, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "the fucking around with pixel composer continues https://pub.mastodon.sleeping.town/@exa/116037641900024965",
		format: "org.matrix.custom.html",
		formatted_body: `the fucking around with pixel composer continues <a href="https://pub.mastodon.sleeping.town/@exa/116037641900024965">https://pub.mastodon.sleeping.town/@exa/116037641900024965</a>`
	}])
})

test("message2event: written @mentions do not match in inline code", async t => {
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "`public @Nullable EntityType<?>`"
	}, data.guild.general, {}, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "`public @Nullable EntityType<?>`",
		format: "org.matrix.custom.html",
		formatted_body: `<code>public @Nullable EntityType&lt;?&gt;</code>`
	}])
})

test("message2event: written @mentions do not match in code block", async t => {
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "```java\npublic @Nullable EntityType<?>\n```"
	}, data.guild.general, {}, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "```java\npublic @Nullable EntityType<?>\n```",
		format: "org.matrix.custom.html",
		formatted_body: `<pre><code class="language-java">public @Nullable EntityType&lt;?&gt;</code></pre>`
	}])
})

test("message2event: entire message may match elaborate display name", async t => {
	let called = 0
	const events = await messageToEvent({
		...data.message.advanced_written_at_mention_for_matrix,
		content: "@Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆"
	}, data.guild.general, {}, {
		api: {
			async getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe")
				return new Promise(resolve => {
					setTimeout(() => {
						resolve({
							joined: {
								"@wa:cadence.moe": {
									display_name: "Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆",
									avatar_url: "whatever"
								},
								"@huckleton:cadence.moe": {
									display_name: "huck",
									avatar_url: "whatever"
								},
								"@_ooye_botrac4r:cadence.moe": {
									display_name: "botrac4r",
									avatar_url: "whatever"
								},
								"@_ooye_bot:cadence.moe": {
									display_name: "Out Of Your Element",
									avatar_url: "whatever"
								}
							}
						})
					})
				})
			}
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {
			user_ids: [
				"@wa:cadence.moe",
			]
		},
		msgtype: "m.text",
		body: "@Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆",
		format: "org.matrix.custom.html",
		formatted_body: `<a href="https://matrix.to/#/@wa:cadence.moe">@Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆</a>`
	}])
})

test("message2event: spoilers are removed from plaintext body", async t => {
	const events = await messageToEvent({
		content: "||**beatrice**||"
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "[spoiler]",
		format: "org.matrix.custom.html",
		formatted_body: `<span data-mx-spoiler=""><strong>beatrice</strong></span>`
	}])
})

test("message2event: very large attachment is linked instead of being uploaded", async t => {
	const events = await messageToEvent({
		content: "hey",
		attachments: [{
			filename: "hey.jpg",
			url: "https://cdn.discordapp.com/attachments/123/456/789.mega",
			content_type: "application/i-made-it-up",
			size: 100e6
		}]
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "hey\n📄 Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)",
		format: "org.matrix.custom.html",
		formatted_body: 'hey<br>📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)'
	}])
})

test("message2event: multiple attachments are combined into the same event where possible", async t => {
	const events = await messageToEvent({
		content: "hey",
		attachments: [{
			filename: "hey.jpg",
			url: "https://cdn.discordapp.com/attachments/123/456/789.mega",
			content_type: "application/i-made-it-up",
			size: 100e6
		}, {
			filename: "SPOILER_secret.jpg",
			url: "https://cdn.discordapp.com/attachments/123/456/SPOILER_secret.jpg",
			content_type: "image/jpeg",
			size: 38291
		}, {
			filename: "my enemies.txt",
			url: "https://cdn.discordapp.com/attachments/123/456/my_enemies.txt",
			content_type: "text/plain",
			size: 8911
		}, {
			filename: "hey.jpg",
			url: "https://cdn.discordapp.com/attachments/123/456/789.mega",
			content_type: "application/i-made-it-up",
			size: 100e6
		}]
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "hey"
			+ "\n📄 Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)"
			+ "\n📸 Uploaded SPOILER file: https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg (38 KB)"
			+ "\n📄 Uploaded file: https://bridge.example.org/download/discordcdn/123/456/789.mega (100 MB)",
		format: "org.matrix.custom.html",
		formatted_body: "hey"
			+ `<br>📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)`
			+ `<br><blockquote>📸 Uploaded SPOILER file: <a href="https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg">https://bridge.example.org/download/discordcdn/123/456/SPOILER_secret.jpg</a> (38 KB)</blockquote>`
			+ `📄 Uploaded file: <a href="https://bridge.example.org/download/discordcdn/123/456/789.mega">hey.jpg</a> (100 MB)`
	}, {
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.file",
		body: "my enemies.txt",
		filename: "my enemies.txt",
		external_url: "https://bridge.example.org/download/discordcdn/123/456/my_enemies.txt",
		url: "mxc://cadence.moe/y89EOTRp2lbeOkgdsEleGOge",
		info: {
			mimetype: "text/plain",
			size: 8911
		}
	}])
})

test("message2event: type 4 channel name change", async t => {
	const events = await messageToEvent(data.special_message.thread_name_change, data.guild.general)
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.emote",
		body: "changed the channel name to **worming**",
		format: "org.matrix.custom.html",
		formatted_body: "changed the channel name to <strong>worming</strong>"
	}])
})

test("message2event: type 12 channel follow add", async t => {
	const events = await messageToEvent(data.special_message.channel_follow_add, data.guild.general)
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.emote",
		body: "set this room to receive announcements from PluralKit #downtime",
		format: "org.matrix.custom.html",
		formatted_body: "set this room to receive announcements from <strong>PluralKit #downtime</strong>",
		"m.mentions": {}
	}])
})

test("message2event: thread start message reference", async t => {
	const events = await messageToEvent(data.special_message.thread_start_context, data.guild.general, {}, {
		api: {
			getEvent: mockGetEvent(t, "!BnKuBPCvyfOkhcUjEu:cadence.moe", "$FchUVylsOfmmbj-VwEs5Z9kY49_dt2zd0vWfylzy5Yo", {
				"type": "m.room.message",
				"sender": "@_ooye_kyuugryphon:cadence.moe",
				"content": {
					"m.mentions": {},
					"msgtype": "m.text",
					"body": "layer 4"
				}
			})
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		$sender: null,
		msgtype: "m.text",
		body: "layer 4",
		"m.mentions": {}
	}])
})

test("message2event: single large bridged emoji", async t => {
	const events = await messageToEvent(data.message.single_emoji, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: ":hippo:",
		format: "org.matrix.custom.html",
		formatted_body: '<img data-mx-emoticon height="32" src="mxc://cadence.moe/qWmbXeRspZRLPcjseyLmeyXC" title=":hippo:" alt=":hippo:">'
	}])
})

test("message2event: mid-message small bridged emoji", async t => {
	const events = await messageToEvent(data.message.surrounded_emoji, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "h is for :hippo:!",
		format: "org.matrix.custom.html",
		formatted_body: 'h is for <img data-mx-emoticon height="32" src="mxc://cadence.moe/qWmbXeRspZRLPcjseyLmeyXC" title=":hippo:" alt=":hippo:">!'
	}])
})

test("message2event: emoji that hasn't been registered yet", async t => {
	const events = await messageToEvent(data.message.not_been_registered_emoji, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: ":Yeah:",
		format: "org.matrix.custom.html",
		formatted_body: '<img data-mx-emoticon height="32" src="mxc://cadence.moe/pgdGTxAyEltccRgZKxdqzHHP" title=":Yeah:" alt=":Yeah:">'
	}])
})

test("message2event: emojihax", async t => {
	const events = await messageToEvent(data.message.emojihax, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "I only violate the don't modify our console part of terms of service :troll:",
		format: "org.matrix.custom.html",
		formatted_body: `I only violate the don't modify our console part of terms of service <img data-mx-emoticon height="32" src="mxc://cadence.moe/bvVJFgOIyNcAknKCbmaHDktG" title=":troll:" alt=":troll:">`
	}])
})

test("message2event: emoji triple long name", async t => {
	const events = await messageToEvent(data.message.emoji_triple_long_name, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: ":brillillillilliant_move::brillillillilliant_move::brillillillilliant_move:",
		format: "org.matrix.custom.html",
		formatted_body:
			  '<img data-mx-emoticon height="32" src="mxc://cadence.moe/scfRIDOGKWFDEBjVXocWYQHik" title=":brillillillilliant_move:" alt=":brillillillilliant_move:">'
			+ '<img data-mx-emoticon height="32" src="mxc://cadence.moe/scfRIDOGKWFDEBjVXocWYQHik" title=":brillillillilliant_move:" alt=":brillillillilliant_move:">'
			+ '<img data-mx-emoticon height="32" src="mxc://cadence.moe/scfRIDOGKWFDEBjVXocWYQHik" title=":brillillillilliant_move:" alt=":brillillillilliant_move:">'
	}])
})

test("message2event: crossposted announcements say where they are crossposted from", async t => {
	const events = await messageToEvent(data.special_message.crosspost_announcement, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "m.room.message",
		"m.mentions": {},
		msgtype: "m.text",
		body: "[🔀 Chewey Bot Official Server #announcements]\nAll text based commands are now inactive on Chewey Bot\nTo continue using commands you'll need to use them as slash commands",
		format: "org.matrix.custom.html",
		formatted_body: "🔀 <strong>Chewey Bot Official Server #announcements</strong><br>All text based commands are now inactive on Chewey Bot<br>To continue using commands you'll need to use them as slash commands"
	}])
})

test("message2event: @everyone", async t => {
	const events = await messageToEvent(data.message_mention_everyone.at_everyone)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "@room",
		"m.mentions": {
			room: true
		}
	}])
})

test("message2event: @here", async t => {
	const events = await messageToEvent(data.message_mention_everyone.at_here)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "@room",
		"m.mentions": {
			room: true
		}
	}])
})

test("message2event: @everyone without permission", async t => {
	const events = await messageToEvent(data.message_mention_everyone.at_everyone_without_permission)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "@everyone <-- this is testing that it DOESN'T mention. if this mentions everyone then my apologies.",
		format: "org.matrix.custom.html",
		formatted_body: "@everyone &lt;-- this is testing that it DOESN'T mention. if this mentions everyone then my apologies.",
		"m.mentions": {}
	}])
})

test("message2event: @here without permission", async t => {
	const events = await messageToEvent(data.message_mention_everyone.at_here_without_permission)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "@here <-- this is testing that it DOESN'T mention. if this mentions people then my apologies.",
		format: "org.matrix.custom.html",
		formatted_body: "@here &lt;-- this is testing that it DOESN'T mention. if this mentions people then my apologies.",
		"m.mentions": {}
	}])
})

test("message2event: @everyone within a link", async t => {
	const events = await messageToEvent(data.message_mention_everyone.at_everyone_within_link)
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "https://github.com/@everyone",
		format: "org.matrix.custom.html",
		formatted_body: `<a href="https://github.com/@everyone">https://github.com/@everyone</a>`,
		"m.mentions": {}
	}])
})

test("message2event: forwarded image", async t => {
	const events = await messageToEvent(data.message.forwarded_image)
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "[🔀 Forwarded message]",
			format: "org.matrix.custom.html",
			formatted_body: "🔀 <em>Forwarded message</em>",
			"m.mentions": {},
			msgtype: "m.notice",
		},
		{
			$type: "m.room.message",
			body: "100km.gif",
			external_url: "https://bridge.example.org/download/discordcdn/112760669178241024/1296237494987133070/100km.gif",
			filename: "100km.gif",
			info: {
				h: 300,
				mimetype: "image/gif",
				size: 2965649,
				w: 300,
			},
			"m.mentions": {},
			msgtype: "m.image",
			url: "mxc://cadence.moe/qDAotmebTfEIfsAIVCEZptLh",
		},
	])
})

test("message2event: constructed forwarded message", async t => {
	const events = await messageToEvent(data.message.constructed_forwarded_message, {}, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers() {
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "[🔀 Forwarded from #wonderland]"
				+ "\n» What's cooking, good looking? :hipposcope:",
			format: "org.matrix.custom.html",
			formatted_body: `🔀 <em>Forwarded from wonderland <a href="https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe/$tBIT8mO7XTTCgIINyiAIy6M2MSoPAdJenRl_RLyYuaE?via=cadence.moe&amp;via=matrix.org">[jump to event]</a></em>`
				+ `<br><blockquote>What's cooking, good looking? <img data-mx-emoticon height="32" src="mxc://cadence.moe/WbYqNlACRuicynBfdnPYtmvc" title=":hipposcope:" alt=":hipposcope:"></blockquote>`,
			"m.mentions": {},
			msgtype: "m.text",
		},
		{
			$type: "m.room.message",
			body: "100km.gif",
			external_url: "https://bridge.example.org/download/discordcdn/112760669178241024/1296237494987133070/100km.gif",
			filename: "100km.gif",
			info: {
				h: 300,
				mimetype: "image/gif",
				size: 2965649,
				w: 300,
			},
			"m.mentions": {},
			msgtype: "m.image",
			url: "mxc://cadence.moe/qDAotmebTfEIfsAIVCEZptLh",
		},
		{
			$type: "m.room.message",
			body: "» | ## This man"
				+ "\n» | "
				+ "\n» | ## This man is 100 km away from your house"
				+ "\n» | "
				+ "\n» | ### Distance away"
				+ "\n» | 99 km"
				+ "\n» | "
				+ "\n» | ### Distance away"
				+ "\n» | 98 km",
			format: "org.matrix.custom.html",
			formatted_body: "<blockquote><blockquote><p><strong>This man</strong></p><p><strong>This man is 100 km away from your house</strong></p><p><strong>Distance away</strong><br>99 km</p><p><strong>Distance away</strong><br>98 km</p></blockquote></blockquote>",
			"m.mentions": {},
			msgtype: "m.notice"
		}
	])
})

test("message2event: constructed forwarded text", async t => {
	const events = await messageToEvent(data.message.constructed_forwarded_text, {}, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			async getJoinedMembers() {
				return {
					joined: {
						"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
						"@user:matrix.org": {display_name: null, avatar_url: null}
					}
				}
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "[🔀 Forwarded from #amanda-spam]"
				+ "\n» What's cooking, good looking?",
			format: "org.matrix.custom.html",
			formatted_body: `🔀 <em>Forwarded from amanda-spam <a href="https://matrix.to/#/!CzvdIdUQXgUjDVKxeU:cadence.moe?via=cadence.moe&amp;via=matrix.org">[jump to room]</a></em>`
				+ `<br><blockquote>What's cooking, good looking?</blockquote>`,
			"m.mentions": {},
			msgtype: "m.text",
		},
		{
			$type: "m.room.message",
			body: "What's cooking everybody ‼️",
			"m.mentions": {},
			msgtype: "m.text",
		}
	])
})


test("message2event: don't scan forwarded messages for mentions", async t => {
	const events = await messageToEvent(data.message.forwarded_dont_scan_for_mentions, {}, {}, {})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "[🔀 Forwarded message]"
				+ "\n» If some folks have spare bandwidth then helping out ArchiveTeam with archiving soon to be deleted research and government data might be worthwhile https://social.luca.run/@luca/113950834185678114",
			format: "org.matrix.custom.html",
			formatted_body: `🔀 <em>Forwarded message</em>`
				+ `<br><blockquote>If some folks have spare bandwidth then helping out ArchiveTeam with archiving soon to be deleted research and government data might be worthwhile <a href="https://social.luca.run/@luca/113950834185678114">https://social.luca.run/@luca/113950834185678114</a></blockquote>`,
			"m.mentions": {},
			msgtype: "m.text"
		}
	])
})

test("message2event: invite no details embed if no event", async t => {
	const events = await messageToEvent({content: "https://discord.gg/placeholder?event=1381190945646710824"}, {}, {}, {
		snow: {
			invite: {
				getInvite: async () => ({...data.invite.irl, guild_scheduled_event: null})
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "https://discord.gg/placeholder?event=1381190945646710824",
			format: "org.matrix.custom.html",
			formatted_body: "<a href=\"https://discord.gg/placeholder?event=1381190945646710824\">https://discord.gg/placeholder?event=1381190945646710824</a>",
			"m.mentions": {},
			msgtype: "m.text",
		}
	])
})

test("message2event: irl invite event renders embed", async t => {
	const events = await messageToEvent({content: "https://discord.gg/placeholder?event=1381190945646710824"}, {}, {}, {
		snow: {
			invite: {
				getInvite: async () => data.invite.irl
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "https://discord.gg/placeholder?event=1381190945646710824",
			format: "org.matrix.custom.html",
			formatted_body: "<a href=\"https://discord.gg/placeholder?event=1381190945646710824\">https://discord.gg/placeholder?event=1381190945646710824</a>",
			"m.mentions": {},
			msgtype: "m.text",
		},
		{
			$type: "m.room.message",
			msgtype: "m.notice",
			body: `| Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT`
				+ `\n| ## forest exploration`
				+ `\n| `
				+ `\n| 📍 the dark forest`,
			format: "org.matrix.custom.html",
			formatted_body: `<blockquote><p>Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT</p>`
				+ `<strong>forest exploration</strong>`
				+ `<p>📍 the dark forest</p></blockquote>`,
			"m.mentions": {}
		}
	])
})

test("message2event: vc invite event renders embed", async t => {
	const events = await messageToEvent({content: "https://discord.gg/placeholder?event=1381174024801095751"}, {}, {}, {
		snow: {
			invite: {
				getInvite: async () => data.invite.vc
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "https://discord.gg/placeholder?event=1381174024801095751",
			format: "org.matrix.custom.html",
			formatted_body: "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>",
			"m.mentions": {},
			msgtype: "m.text",
		},
		{
			$type: "m.room.message",
			msgtype: "m.notice",
			body: `| Scheduled Event - 9 June at 3:00 pm NZT`
				+ `\n| ## Cooking (Netrunners)`
				+ `\n| Short circuited brain interfaces actually just means your brain is medium rare, yum.`
				+ `\n| `
				+ `\n| 🔊 Cooking`,
			format: "org.matrix.custom.html",
			formatted_body: `<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p>`
				+ `<strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.`
				+ `<p>🔊 Cooking</p></blockquote>`,
			"m.mentions": {}
		}
	])
})

test("message2event: vc invite event renders embed with room link", async t => {
	const events = await messageToEvent({content: "https://discord.gg/placeholder?event=1381174024801095751"}, {}, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			getJoinedMembers: async () => ({
				joined: {
					"@_ooye_bot:cadence.moe": {display_name: null, avatar_url: null},
				}
			})
		},
		snow: {
			invite: {
				getInvite: async () => data.invite.known_vc
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "https://discord.gg/placeholder?event=1381174024801095751",
			format: "org.matrix.custom.html",
			formatted_body: "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>",
			"m.mentions": {},
			msgtype: "m.text",
		},
		{
			$type: "m.room.message",
			msgtype: "m.notice",
			body: `| Scheduled Event - 9 June at 3:00 pm NZT`
				+ `\n| ## Cooking (Netrunners)`
				+ `\n| Short circuited brain interfaces actually just means your brain is medium rare, yum.`
				+ `\n| `
				+ `\n| 🔊 Hey. - https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe`,
			format: "org.matrix.custom.html",
			formatted_body: `<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p>`
				+ `<strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.`
				+ `<p>🔊 Hey. - <a href="https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe">Hey.</a></p></blockquote>`,
			"m.mentions": {}
		}
	])
})

test("message2event: expired/invalid invites are sent as-is", async t => {
	const events = await messageToEvent({content: "https://discord.gg/placeholder?event=1381190945646710824"}, {}, {}, {
		snow: {
			invite: {
				async getInvite() {
					throw new Error(`{"message": "Unknown Invite", "code": 10006}`)
				}
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "https://discord.gg/placeholder?event=1381190945646710824",
			format: "org.matrix.custom.html",
			formatted_body: "<a href=\"https://discord.gg/placeholder?event=1381190945646710824\">https://discord.gg/placeholder?event=1381190945646710824</a>",
			"m.mentions": {},
			msgtype: "m.text",
		}
	])
})

test("message2event: channel links are converted even inside lists (parser post-processer descends into list items)", async t => {
	let called = 0
	const events = await messageToEvent({
		content: "1. Don't be a dick"
		+ "\n2. Follow rule number 1"
		+ "\n3. Follow Discord TOS"
		+ "\n4. Do **not** post NSFW content, shock content, suggestive content"
		+ "\n5. Please keep <#176333891320283136> professional and helpful, no random off-topic joking"
		+ "\nThis list will probably change in the future"
	}, data.guild.general, {}, {
		api: {
			getEffectivePower: mockGetEffectivePower(),
			getJoinedMembers(roomID) {
				called++
				t.equal(roomID, "!qzDBLKlildpzrrOnFZ:cadence.moe")
				return {
					joined: {
						"@quadradical:federated.nexus": {
							membership: "join",
							display_name: "quadradical"
						}
					}
				}
			}
		}
	})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			body: "1. Don't be a dick"
			+ "\n2. Follow rule number 1"
			+ "\n3. Follow Discord TOS"
			+ "\n4. Do **not** post NSFW content, shock content, suggestive content"
			+ "\n5. Please keep #wonderland professional and helpful, no random off-topic joking"
			+ "\nThis list will probably change in the future",
			format: "org.matrix.custom.html",
			formatted_body: "<ol start=\"1\"><li>Don't be a dick</li><li>Follow rule number 1</li><li>Follow Discord TOS</li><li>Do <strong>not</strong> post NSFW content, shock content, suggestive content</li><li>Please keep <a href=\"https://matrix.to/#/!qzDBLKlildpzrrOnFZ:cadence.moe?via=cadence.moe&via=federated.nexus\">#wonderland</a> professional and helpful, no random off-topic joking</li></ol>This list will probably change in the future",
			"m.mentions": {},
			msgtype: "m.text"
		}
	])
	t.equal(called, 1)
})

test("message2event: emoji added special message", async t => {
	const events = await messageToEvent(data.special_message.emoji_added)
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			msgtype: "m.emote",
			body: "added a new emoji, :cx_marvelous: :cx_marvelous:",
			format: "org.matrix.custom.html",
			formatted_body: `added a new emoji, <img data-mx-emoticon height="32" src="mxc://cadence.moe/TPZdosVUjTIopsLijkygIbti" title=":cx_marvelous:" alt=":cx_marvelous:"> :cx_marvelous:`,
			"m.mentions": {}
		}
	])
})

test("message2event: cross-room reply", async t => {
	let called = 0
	const events = await messageToEvent({
		type: 19,
		message_reference: {
			channel_id: "1161864271370666075",
			guild_id: "1160893336324931584",
			message_id: "1458091145136443547"
		},
		referenced_message: {
			channel_id: "1161864271370666075",
			id: "1458091145136443547",
			content: "",
			attachments: [{
				filename: "image.png",
				id: "1456813607693193478",
				size: 104006,
				content_type: "image/png",
				url: "https://cdn.discordapp.com/attachments/1160893337029586956/1458790740338409605/image.png?ex=696194ff&is=6960437f&hm=923d0ef7d1b249470be49edbc37628cc4ff8a438f0ab12f54c045578135f7050"
			}],
			author: {
				username: "Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆"
			}
		},
		content: "cross-room reply"
	}, {}, {}, {api: {
		async getEvent(roomID, eventID) {
			called++
			t.equal(roomID, "!mHmhQQPwXNananaOLD:cadence.moe")
			t.equal(eventID, "$pgzCQjq_y5sy8RvWOUuoF3obNHjs8iNvt9c-odrOCPY")
			return {
				type: "m.room.message",
				sender: "@cadence:cadence.moe",
				content: {
					"body": "image.png",
					"info": {
						"h": 738,
						"mimetype": "image/png",
						"org.matrix.msc4230.is_animated": false,
						"size": 111189,
						"w": 772,
						"xyz.amorgan.blurhash": "L255Oa~qRPD$-pxuoJoLIUM{xuxu"
					},
					"m.mentions": {},
					"msgtype": "m.image",
					"url": "mxc://matrix.org/QbSujQjRLekzPknKlPsXbGDS"
				}
			}
		}
	}})
	t.deepEqual(events, [
		{
			$type: "m.room.message",
			msgtype: "m.text",
			body: "> Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆: [Media]\n\ncross-room reply",
			format: "org.matrix.custom.html",
			formatted_body: `<blockquote><a href="https://matrix.to/#/!mHmhQQPwXNananaOLD:cadence.moe/$pgzCQjq_y5sy8RvWOUuoF3obNHjs8iNvt9c-odrOCPY">In reply to</a> <a href="https://matrix.to/#/@cadence:cadence.moe">Cadence, Maid of Creation, Eye of Clarity, Empress of Hope ☆</a><br>[Media]</blockquote>cross-room reply`,
			"m.mentions": {
				user_ids: [
					"@cadence:cadence.moe"
				]
			}
		}
	])
})

test("message2event: forwarded message with unreferenced mention", async t => {
	const events = await messageToEvent({
		type: 0,
		content: "",
		attachments: [],
		embeds: [],
		timestamp: "2026-01-20T14:14:21.281Z",
		edited_timestamp: null,
		flags: 16384,
		components: [],
		id: "1463174818823405651",
		channel_id: "893634327722721290",
		author: {
			id: "100031256988766208",
			username: "leo60228",
			discriminator: "0",
			avatar: "8a164f29946f23eb4f45cde71a75e5a6",
			avatar_decoration_data: null,
			public_flags: 768,
			global_name: "leo vriska",
			primary_guild: null,
			collectibles: null,
			display_name_styles: null
		},
		bot: false,
		pinned: false,
		mentions: [],
		mention_roles: [],
		mention_everyone: false,
		tts: false,
		message_reference: {
			type: 1,
			channel_id: "937181373943382036",
			message_id: "1032034158261846038",
			guild_id: "936370934292549712"
		},
		message_snapshots: [
			{
				message: {
					type: 0,
					content: "<@77084495118868480>",
					attachments: [
						{
							id: "1463174815119704114",
							filename: "2022-10-18_16-49-46.mp4",
							size: 51238885,
							url: "https://cdn.discordapp.com/attachments/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4?ex=6970df3c&is=696f8dbc&hm=515d3cbcc8464bdada7f4c3d9ccc8174f671cb75391ce21a46a804fcb1e4befe&",
							proxy_url: "https://media.discordapp.net/attachments/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4?ex=6970df3c&is=696f8dbc&hm=515d3cbcc8464bdada7f4c3d9ccc8174f671cb75391ce21a46a804fcb1e4befe&",
							width: 1920,
							height: 1080,
							content_type: "video/mp4",
							content_scan_version: 3,
							spoiler: false
						}
					],
					embeds: [],
					timestamp: "2022-10-18T20:55:17.597Z",
					edited_timestamp: null,
					flags: 0,
					components: []
				}
			}
		]
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		body: "[🔀 Forwarded message]\n» @unknown-user:\n» 🎞️ Uploaded file: https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4 (51 MB)",
		format: "org.matrix.custom.html",
		formatted_body: "🔀 <em>Forwarded message</em><br><blockquote>@unknown-user:<br>🎞️ Uploaded file: <a href=\"https://bridge.example.org/download/discordcdn/893634327722721290/1463174815119704114/2022-10-18_16-49-46.mp4\">2022-10-18_16-49-46.mp4</a> (51 MB)</blockquote>",
		"m.mentions": {}
	}])
})

test("message2event: single-choice poll", async t => {
	const events = await messageToEvent(data.message.poll_single_choice, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "org.matrix.msc3381.poll.start",
		"org.matrix.msc3381.poll.start": {
			question: {
				"org.matrix.msc1767.text": "only one answer allowed!",
				body: "only one answer allowed!",
				msgtype: "m.text"
			},
			kind: "org.matrix.msc3381.poll.disclosed", // Discord always lets you see results, so keeping this consistent with that.
			max_selections: 1,
			answers: [{
					id: "1",
					"org.matrix.msc1767.text": "[\ud83d\udc4d] answer one"
				}, {
					id: "2",
					"org.matrix.msc1767.text": "[\ud83d\udc4e] answer two"
				}, {
					id: "3",
					"org.matrix.msc1767.text": "answer three"
				}]
		},
		"org.matrix.msc1767.text": "only one answer allowed!\n1. [\ud83d\udc4d] answer one\n2. [\ud83d\udc4e] answer two\n3. answer three"
	}])
})

test("message2event: multiple-choice poll", async t => {
	const events = await messageToEvent(data.message.poll_multiple_choice, data.guild.general, {})
	t.deepEqual(events, [{
		$type: "org.matrix.msc3381.poll.start",
		"org.matrix.msc3381.poll.start": {
			question: {
				"org.matrix.msc1767.text": "more than one answer allowed",
				body: "more than one answer allowed",
				msgtype: "m.text"
			},
			kind: "org.matrix.msc3381.poll.disclosed", // Discord always lets you see results, so keeping this consistent with that.
			max_selections: 3,
			answers: [{
					id: "1",
					"org.matrix.msc1767.text": "[😭] no"
				}, {
					id: "2",
					"org.matrix.msc1767.text": "oh no"
				}, {
					id: "3",
					"org.matrix.msc1767.text": "oh noooooo"
				}]
		},
		"org.matrix.msc1767.text": "more than one answer allowed\n1. [😭] no\n2. oh no\n3. oh noooooo"
	}])
})

test("message2event: smalltext from regular user", async t => {
	const events = await messageToEvent({
		content: "-# hmm",
		author: {
			bot: false
		}
	})
	t.deepEqual(events, [{
		$type: "m.room.message",
		msgtype: "m.text",
		"m.mentions": {},
		body: "...hmm"
	}])
})
