More code coverage
This commit is contained in:
@@ -58,7 +58,7 @@ async function addButton(roomID, eventID, key, mxid) {
|
||||
setInterval(() => {
|
||||
const now = Date.now()
|
||||
buttons = buttons.filter(b => now - b.created < 2*60*60*1000)
|
||||
}, 10*60*1000)
|
||||
}, 10*60*1000).unref()
|
||||
|
||||
/** @param {Ty.Event.Outer<Ty.Event.M_Reaction>} event */
|
||||
function onReactionAdd(event) {
|
||||
|
||||
+16
-14
@@ -4,12 +4,8 @@ const assert = require("assert/strict")
|
||||
const Ty = require("../types")
|
||||
const {Semaphore} = require("@chriscdn/promise-semaphore")
|
||||
const {tag} = require("@cloudrac3r/html-template-tag")
|
||||
const {discord, db, sync, as, select, from} = require("../passthrough")
|
||||
const {db, sync, select, from} = require("../passthrough")
|
||||
|
||||
/** @type {import("./api")}) */
|
||||
const api = sync.require("./api")
|
||||
/** @type {import("../d2m/actions/create-room")}) */
|
||||
const createRoom = sync.require("../d2m/actions/create-room")
|
||||
/** @type {import("./utils")}) */
|
||||
const utils = sync.require("./utils")
|
||||
|
||||
@@ -17,11 +13,12 @@ const roomUpgradeSema = new Semaphore()
|
||||
|
||||
/**
|
||||
* @param {Ty.Event.StateOuter<Ty.Event.M_Room_Tombstone>} event
|
||||
* @param {import("./api")} api
|
||||
*/
|
||||
async function onTombstone(event) {
|
||||
// Validate
|
||||
if (event.state_key !== "") return
|
||||
if (!event.content.replacement_room) return
|
||||
async function onTombstone(event, api) {
|
||||
// Preconditions (checked by event-dispatcher, enforced here)
|
||||
assert.equal(event.state_key, "")
|
||||
assert.ok(event.content.replacement_room)
|
||||
|
||||
// Set up
|
||||
const oldRoomID = event.room_id
|
||||
@@ -48,13 +45,21 @@ async function onTombstone(event) {
|
||||
|
||||
/**
|
||||
* @param {Ty.Event.StateOuter<Ty.Event.M_Room_Member>} event
|
||||
* @param {import("./api")} api
|
||||
* @param {import("../d2m/actions/create-room")} createRoom
|
||||
* @returns {Promise<boolean>} whether to cancel other membership actions
|
||||
*/
|
||||
async function onBotMembership(event) {
|
||||
async function onBotMembership(event, api, createRoom) {
|
||||
// Preconditions (checked by event-dispatcher, enforced here)
|
||||
assert.equal(event.type, "m.room.member")
|
||||
assert.equal(event.state_key, utils.bot)
|
||||
|
||||
// Check if an upgrade is pending for this room
|
||||
const newRoomID = event.room_id
|
||||
const oldRoomID = select("room_upgrade_pending", "old_room_id", {new_room_id: newRoomID}).pluck().get()
|
||||
if (!oldRoomID) return
|
||||
const channelRow = from("channel_room").join("guild_space", "guild_id").where({room_id: oldRoomID}).select("space_id", "guild_id", "channel_id").get()
|
||||
assert(channelRow) // this could only fail if the channel was unbridged or something between upgrade and joining
|
||||
|
||||
// Check if is join/invite
|
||||
if (event.content.membership !== "invite" && event.content.membership !== "join") return
|
||||
@@ -65,9 +70,6 @@ async function onBotMembership(event) {
|
||||
await api.joinRoom(newRoomID)
|
||||
}
|
||||
|
||||
const channelRow = from("channel_room").join("guild_space", "guild_id").where({room_id: oldRoomID}).select("space_id", "guild_id", "channel_id").get()
|
||||
assert(channelRow)
|
||||
|
||||
// Remove old room from space
|
||||
await api.sendState(channelRow.space_id, "m.space.child", oldRoomID, {})
|
||||
// await api.sendState(oldRoomID, "m.space.parent", spaceID, {}) // keep this - the room isn't advertised but should still be grouped if opened
|
||||
@@ -75,7 +77,7 @@ async function onBotMembership(event) {
|
||||
// Remove declaration that old room is bridged (if able)
|
||||
try {
|
||||
await api.sendState(oldRoomID, "uk.half-shot.bridge", `moe.cadence.ooye://discord/${channelRow.guild_id}/${channelRow.channel_id}`, {})
|
||||
} catch (e) {}
|
||||
} catch (e) { /* c8 ignore next */ }
|
||||
|
||||
// Update database
|
||||
db.transaction(() => {
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
const {test} = require("supertape")
|
||||
const {select} = require("../passthrough")
|
||||
const {onTombstone, onBotMembership} = require("./room-upgrade")
|
||||
|
||||
test("join upgraded room: only cares about upgrades in progress", async t => {
|
||||
let called = 0
|
||||
await onBotMembership({
|
||||
type: "m.room.member",
|
||||
state_key: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!JBxeGYnzQwLnaooOLD:cadence.moe",
|
||||
content: {
|
||||
membership: "invite"
|
||||
}
|
||||
}, {
|
||||
/* c8 ignore next 4 */
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
throw new Error("should not join this room")
|
||||
}
|
||||
})
|
||||
t.equal(called, 0)
|
||||
})
|
||||
|
||||
test("tombstone: only cares about bridged rooms", async t => {
|
||||
let called = 0
|
||||
await onTombstone({
|
||||
event_id: "$tombstone",
|
||||
type: "m.room.tombstone",
|
||||
state_key: "",
|
||||
sender: "@cadence:cadence.moe",
|
||||
origin_server_ts: 0,
|
||||
room_id: "!imaginary:cadence.moe",
|
||||
content: {
|
||||
body: "This room has been replaced",
|
||||
replacement_room: "!JBxeGYnzQwLnaooNEW:cadence.moe"
|
||||
}
|
||||
}, {
|
||||
/* c8 ignore next 4 */
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
throw new Error("should not join this room")
|
||||
}
|
||||
})
|
||||
t.equal(called, 0)
|
||||
})
|
||||
|
||||
test("tombstone: joins new room and stores upgrade in database", async t => {
|
||||
let called = 0
|
||||
await onTombstone({
|
||||
event_id: "$tombstone",
|
||||
type: "m.room.tombstone",
|
||||
state_key: "",
|
||||
sender: "@cadence:cadence.moe",
|
||||
origin_server_ts: 0,
|
||||
room_id: "!JBxeGYnzQwLnaooOLD:cadence.moe",
|
||||
content: {
|
||||
body: "This room has been replaced",
|
||||
replacement_room: "!JBxeGYnzQwLnaooNEW:cadence.moe"
|
||||
}
|
||||
}, {
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
t.equal(roomID, "!JBxeGYnzQwLnaooNEW:cadence.moe")
|
||||
return roomID
|
||||
}
|
||||
})
|
||||
t.equal(called, 1)
|
||||
t.ok(select("room_upgrade_pending", ["old_room_id", "new_room_id"], {new_room_id: "!JBxeGYnzQwLnaooNEW:cadence.moe", old_room_id: "!JBxeGYnzQwLnaooOLD:cadence.moe"}).get())
|
||||
})
|
||||
|
||||
test("tombstone: requests invite from upgrader if can't join room", async t => {
|
||||
let called = 0
|
||||
await onTombstone({
|
||||
event_id: "$tombstone",
|
||||
type: "m.room.tombstone",
|
||||
state_key: "",
|
||||
sender: "@cadence:cadence.moe",
|
||||
origin_server_ts: 0,
|
||||
room_id: "!JBxeGYnzQwLnaooOLD:cadence.moe",
|
||||
content: {
|
||||
body: "This room has been replaced",
|
||||
replacement_room: "!JBxeGYnzQwLnaooNEW:cadence.moe"
|
||||
}
|
||||
}, {
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
t.equal(roomID, "!JBxeGYnzQwLnaooNEW:cadence.moe")
|
||||
throw new Error("access denied or something")
|
||||
},
|
||||
async usePrivateChat(sender) {
|
||||
called++
|
||||
t.equal(sender, "@cadence:cadence.moe")
|
||||
return "!private"
|
||||
},
|
||||
async sendEvent(roomID, type, content) {
|
||||
called++
|
||||
t.equal(roomID, "!private")
|
||||
t.equal(type, "m.room.message")
|
||||
t.deepEqual(content, {
|
||||
msgtype: "m.text",
|
||||
body: "You upgraded the bridged room winners. To keep bridging, I need you to invite me to the new room: https://matrix.to/#/!JBxeGYnzQwLnaooNEW:cadence.moe",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: `You upgraded the bridged room <strong>winners</strong>. To keep bridging, I need you to invite me to the new room: <a href="https://matrix.to/#/!JBxeGYnzQwLnaooNEW:cadence.moe">https://matrix.to/#/!JBxeGYnzQwLnaooNEW:cadence.moe</a>`
|
||||
})
|
||||
}
|
||||
})
|
||||
t.equal(called, 3)
|
||||
})
|
||||
|
||||
test("join upgraded room: only cares about invites/joins", async t => {
|
||||
let called = 0
|
||||
await onBotMembership({
|
||||
type: "m.room.member",
|
||||
state_key: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!JBxeGYnzQwLnaooNEW:cadence.moe",
|
||||
content: {
|
||||
membership: "leave"
|
||||
}
|
||||
}, {
|
||||
/* c8 ignore next 4 */
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
throw new Error("should not join this room")
|
||||
}
|
||||
})
|
||||
t.equal(called, 0)
|
||||
})
|
||||
|
||||
test("join upgraded room: joins invited room, updates database", async t => {
|
||||
let called = 0
|
||||
await onBotMembership({
|
||||
type: "m.room.member",
|
||||
state_key: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!JBxeGYnzQwLnaooNEW:cadence.moe",
|
||||
content: {
|
||||
membership: "invite"
|
||||
}
|
||||
}, {
|
||||
async joinRoom(roomID) {
|
||||
called++
|
||||
t.equal(roomID, "!JBxeGYnzQwLnaooNEW:cadence.moe")
|
||||
return roomID
|
||||
},
|
||||
async sendState(roomID, type, key, content) {
|
||||
called++
|
||||
if (type === "m.space.child") {
|
||||
t.equal(roomID, "!CvQMeeqXIkgedUpkzv:cadence.moe") // space
|
||||
t.equal(key, "!JBxeGYnzQwLnaooOLD:cadence.moe")
|
||||
t.deepEqual(content, {})
|
||||
return "$child"
|
||||
} else if (type === "uk.half-shot.bridge") {
|
||||
t.equal(roomID, "!JBxeGYnzQwLnaooOLD:cadence.moe")
|
||||
t.equal(key, "moe.cadence.ooye://discord/1345641201902288987/598707048112193536")
|
||||
t.deepEqual(content, {})
|
||||
return "$bridge"
|
||||
}
|
||||
/* c8 ignore next */
|
||||
throw new Error(`unexpected sendState: ${roomID} - ${type}/${key}`)
|
||||
}
|
||||
}, {
|
||||
async syncRoom(channelID) {
|
||||
called++
|
||||
t.equal(channelID, "598707048112193536")
|
||||
}
|
||||
})
|
||||
t.equal(called, 4)
|
||||
t.equal(select("channel_room", "room_id", {channel_id: "598707048112193536"}).pluck().get(), "!JBxeGYnzQwLnaooNEW:cadence.moe")
|
||||
t.equal(select("historical_channel_room", "historical_room_index", {reference_channel_id: "598707048112193536"}).pluck().all().length, 2)
|
||||
})
|
||||
Reference in New Issue
Block a user