Room version 12 and room upgrades

This commit is contained in:
Cadence Ember
2026-01-07 02:43:20 +13:00
parent 092a4cf7b0
commit 55e0e5dfa1
27 changed files with 666 additions and 483 deletions
+12 -10
View File
@@ -9,13 +9,15 @@ const {InteractionMethods} = require("snowtransfer")
/** @type {import("../../matrix/api")} */
const api = sync.require("../../matrix/api")
/** @type {import("../../m2d/converters/utils")} */
const utils = sync.require("../../m2d/converters/utils")
/**
* @param {DiscordTypes.APIContextMenuGuildInteraction} interaction
* @param {{api: typeof api}} di
* @param {{api: typeof api, utils: typeof utils}} di
* @returns {AsyncGenerator<{[k in keyof InteractionMethods]?: Parameters<InteractionMethods[k]>[2]}>}
*/
async function* _interact({data, guild_id}, {api}) {
async function* _interact({data, guild_id}, {api, utils}) {
// Get message info
const row = from("event_message")
.join("message_room", "message_id").join("historical_channel_room", "historical_room_index")
@@ -45,12 +47,10 @@ async function* _interact({data, guild_id}, {api}) {
assert(spaceID)
// Get the power level
/** @type {Ty.Event.M_Power_Levels} */
const powerLevelsContent = await api.getStateEvent(spaceID, "m.room.power_levels", "")
const userPower = powerLevelsContent.users?.[event.sender] || 0
const {powers: {[event.sender]: userPower, [utils.bot]: botPower}} = await utils.getEffectivePower(spaceID, [event.sender, utils.bot], api)
// Administrators equal to the bot cannot be demoted
if (userPower >= 100) {
// Administrators/founders equal to the bot cannot be demoted
if (userPower >= botPower) {
return yield {createInteractionResponse: {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: {
@@ -60,6 +60,8 @@ async function* _interact({data, guild_id}, {api}) {
}}
}
const adminLabel = botPower === 100 ? "Admin (you cannot undo this!)" : "Admin"
yield {createInteractionResponse: {
type: DiscordTypes.InteractionResponseType.ChannelMessageWithSource,
data: {
@@ -82,9 +84,9 @@ async function* _interact({data, guild_id}, {api}) {
value: "moderator",
default: userPower >= 50 && userPower < 100
}, {
label: "Admin (you cannot undo this!)",
label: adminLabel,
value: "admin",
default: userPower === 100
default: userPower >= 100
}
]
}
@@ -138,7 +140,7 @@ async function* _interactEdit({data, guild_id, message}, {api}) {
/** @param {DiscordTypes.APIContextMenuGuildInteraction} interaction */
async function interact(interaction) {
for await (const response of _interact(interaction, {api})) {
for await (const response of _interact(interaction, {api, utils})) {
if (response.createInteractionResponse) {
// TODO: Test if it is reasonable to remove `await` from these calls. Or zip these calls with the next interaction iteration and use Promise.all.
await discord.snow.interaction.createInteractionResponse(interaction.id, interaction.token, response.createInteractionResponse)
+43 -32
View File
@@ -2,6 +2,7 @@ const {test} = require("supertape")
const DiscordTypes = require("discord-api-types/v10")
const {select, db} = require("../../passthrough")
const {_interact, _interactEdit} = require("./permissions")
const {mockGetEffectivePower} = require("../../m2d/converters/utils.test")
/**
* @template T
@@ -46,6 +47,10 @@ test("permissions: reports permissions of selected matrix user (implicit default
},
guild_id: "112760669178241024"
}, {
utils: {
bot: "@_ooye_bot:cadence.moe",
getEffectivePower: mockGetEffectivePower()
},
api: {
async getEvent(roomID, eventID) {
called++
@@ -54,22 +59,13 @@ test("permissions: reports permissions of selected matrix user (implicit default
return {
sender: "@cadence:cadence.moe"
}
},
async getStateEvent(roomID, type, key) {
called++
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe") // space ID
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {
users: {}
}
}
}
}))
t.equal(msgs.length, 1)
t.equal(msgs[0].createInteractionResponse.data.content, "Showing permissions for `@cadence:cadence.moe`. Click to edit.")
t.deepEqual(msgs[0].createInteractionResponse.data.components[0].components[0].options[0], {label: "Default", value: "default", default: true})
t.equal(called, 2)
t.equal(called, 1)
})
test("permissions: reports permissions of selected matrix user (moderator)", async t => {
@@ -80,6 +76,10 @@ test("permissions: reports permissions of selected matrix user (moderator)", asy
},
guild_id: "112760669178241024"
}, {
utils: {
bot: "@_ooye_bot:cadence.moe",
getEffectivePower: mockGetEffectivePower(["@_ooye_bot:cadence.moe"], {"@cadence:cadence.moe": 50})
},
api: {
async getEvent(roomID, eventID) {
called++
@@ -88,27 +88,16 @@ test("permissions: reports permissions of selected matrix user (moderator)", asy
return {
sender: "@cadence:cadence.moe"
}
},
async getStateEvent(roomID, type, key) {
called++
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe") // space ID
t.equal(type, "m.room.power_levels")
t.equal(key, "")
return {
users: {
"@cadence:cadence.moe": 50
}
}
}
}
}))
t.equal(msgs.length, 1)
t.equal(msgs[0].createInteractionResponse.data.content, "Showing permissions for `@cadence:cadence.moe`. Click to edit.")
t.deepEqual(msgs[0].createInteractionResponse.data.components[0].components[0].options[1], {label: "Moderator", value: "moderator", default: true})
t.equal(called, 2)
t.equal(called, 1)
})
test("permissions: reports permissions of selected matrix user (admin)", async t => {
test("permissions: reports permissions of selected matrix user (admin v12 can be demoted)", async t => {
let called = 0
const msgs = await fromAsync(_interact({
data: {
@@ -116,6 +105,10 @@ test("permissions: reports permissions of selected matrix user (admin)", async t
},
guild_id: "112760669178241024"
}, {
utils: {
bot: "@_ooye_bot:cadence.moe",
getEffectivePower: mockGetEffectivePower(["@_ooye_bot:cadence.moe"], {"@cadence:cadence.moe": 100})
},
api: {
async getEvent(roomID, eventID) {
called++
@@ -124,16 +117,34 @@ test("permissions: reports permissions of selected matrix user (admin)", async t
return {
sender: "@cadence:cadence.moe"
}
},
async getStateEvent(roomID, type, key) {
}
}
}))
t.equal(msgs.length, 1)
t.equal(msgs[0].createInteractionResponse.data.content, "Showing permissions for `@cadence:cadence.moe`. Click to edit.")
t.deepEqual(msgs[0].createInteractionResponse.data.components[0].components[0].options[2], {label: "Admin", value: "admin", default: true})
t.equal(called, 1)
})
test("permissions: reports permissions of selected matrix user (admin v11 cannot be demoted)", async t => {
let called = 0
const msgs = await fromAsync(_interact({
data: {
target_id: "1128118177155526666"
},
guild_id: "112760669178241024"
}, {
utils: {
bot: "@_ooye_bot:cadence.moe",
getEffectivePower: mockGetEffectivePower(["@_ooye_bot:cadence.moe"], {"@cadence:cadence.moe": 100, "@_ooye_bot:cadence.moe": 100}, "11")
},
api: {
async getEvent(roomID, eventID) {
called++
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe") // space ID
t.equal(type, "m.room.power_levels")
t.equal(key, "")
t.equal(roomID, "!kLRqKKUQXcibIMtOpl:cadence.moe") // room ID
t.equal(eventID, "$Ij3qo7NxMA4VPexlAiIx2CB9JbsiGhJeyt-2OvkAUe4")
return {
users: {
"@cadence:cadence.moe": 100
}
sender: "@cadence:cadence.moe"
}
}
}
@@ -141,7 +152,7 @@ test("permissions: reports permissions of selected matrix user (admin)", async t
t.equal(msgs.length, 1)
t.equal(msgs[0].createInteractionResponse.data.content, "`@cadence:cadence.moe` has administrator permissions. This cannot be edited.")
t.notOk(msgs[0].createInteractionResponse.data.components)
t.equal(called, 2)
t.equal(called, 1)
})
test("permissions: can update user to moderator", async t => {