General code coverage
This commit is contained in:
@@ -18,21 +18,6 @@ class MatrixServerError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Response} res
|
||||
* @param {object} opts
|
||||
*/
|
||||
async function makeMatrixServerError(res, opts = {}) {
|
||||
delete opts.headers?.["Authorization"]
|
||||
if (res.headers.get("content-type") === "application/json") {
|
||||
return new MatrixServerError(await res.json(), opts)
|
||||
} else if (res.headers.get("content-type")?.startsWith("text/")) {
|
||||
return new MatrixServerError({errcode: "CX_SERVER_ERROR", error: `Server returned HTTP status ${res.status}`, message: await res.text()}, opts)
|
||||
} else {
|
||||
return new MatrixServerError({errcode: "CX_SERVER_ERROR", error: `Server returned HTTP status ${res.status}`, content_type: res.headers.get("content-type")}, opts)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {undefined | string | object | streamWeb.ReadableStream | stream.Readable} body
|
||||
* @returns {Promise<string | streamWeb.ReadableStream | stream.Readable | Buffer>}
|
||||
@@ -52,6 +37,21 @@ async function _convertBody(body) {
|
||||
|
||||
/* c8 ignore start */
|
||||
|
||||
/**
|
||||
* @param {Response} res
|
||||
* @param {object} opts
|
||||
*/
|
||||
async function makeMatrixServerError(res, opts = {}) {
|
||||
delete opts.headers?.["Authorization"]
|
||||
if (res.headers.get("content-type") === "application/json") {
|
||||
return new MatrixServerError(await res.json(), opts)
|
||||
} else if (res.headers.get("content-type")?.startsWith("text/")) {
|
||||
return new MatrixServerError({errcode: "CX_SERVER_ERROR", error: `Server returned HTTP status ${res.status}`, message: await res.text()}, opts)
|
||||
} else {
|
||||
return new MatrixServerError({errcode: "CX_SERVER_ERROR", error: `Server returned HTTP status ${res.status}`, content_type: res.headers.get("content-type")}, opts)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} method
|
||||
* @param {string} url
|
||||
|
||||
@@ -138,14 +138,17 @@ async function getViaServers(roomID, api) {
|
||||
candidates.push(reg.ooye.server_name)
|
||||
// Candidate 1: Highest joined non-sim non-bot power level user in the room
|
||||
// https://github.com/matrix-org/matrix-react-sdk/blob/552c65db98b59406fb49562e537a2721c8505517/src/utils/permalinks/Permalinks.ts#L172
|
||||
/* c8 ignore next */
|
||||
const call = "getEffectivePower" in api ? api.getEffectivePower(roomID, [bot], api) : getEffectivePower(roomID, [bot], api)
|
||||
const {allCreators, powerLevels} = await call
|
||||
const sorted = allCreators.concat(Object.entries(powerLevels.users ?? {}).sort((a, b) => b[1] - a[1]).map(([mxid]) => mxid)) // Highest...
|
||||
powerLevels.users ??= {}
|
||||
const sorted = allCreators.concat(Object.entries(powerLevels.users).sort((a, b) => b[1] - a[1]).map(([mxid]) => mxid)) // Highest...
|
||||
for (const mxid of sorted) {
|
||||
if (!(mxid in joined)) continue // joined...
|
||||
if (userRegex.some(r => mxid.match(r))) continue // non-sim non-bot...
|
||||
const match = mxid.match(/:(.*)/)
|
||||
assert(match)
|
||||
/* c8 ignore next - should be already covered by the userRegex test, but let's be explicit */
|
||||
if (candidates.includes(match[1])) continue // from a different server
|
||||
candidates.push(match[1])
|
||||
break
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// @ts-check
|
||||
|
||||
const {select} = require("../passthrough")
|
||||
const {test} = require("supertape")
|
||||
const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion} = require("./utils")
|
||||
const {eventSenderIsFromDiscord, getEventIDHash, MatrixStringBuilder, getViaServers, roomHasAtLeastVersion, removeCreatorsFromPowerLevels, setUserPower} = require("./utils")
|
||||
const util = require("util")
|
||||
|
||||
/** @param {string[]} mxids */
|
||||
@@ -201,4 +202,219 @@ test("getViaServers: only considers power levels of currently joined members", a
|
||||
t.deepEqual(result, ["cadence.moe", "tractor.invalid", "thecollective.invalid", "selfhosted.invalid"])
|
||||
})
|
||||
|
||||
test("roomHasAtLeastVersion: v9 < v11", t => {
|
||||
t.equal(roomHasAtLeastVersion("9", 11), false)
|
||||
})
|
||||
|
||||
test("roomHasAtLeastVersion: v12 >= v11", t => {
|
||||
t.equal(roomHasAtLeastVersion("12", 11), true)
|
||||
})
|
||||
|
||||
test("roomHasAtLeastVersion: v12 >= v12", t => {
|
||||
t.equal(roomHasAtLeastVersion("12", 12), true)
|
||||
})
|
||||
|
||||
test("roomHasAtLeastVersion: custom versions never match", t => {
|
||||
t.equal(roomHasAtLeastVersion("moe.cadence.silly", 11), false)
|
||||
})
|
||||
|
||||
test("removeCreatorsFromPowerLevels: removes the creator from a v12 room", t => {
|
||||
t.deepEqual(removeCreatorsFromPowerLevels({
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!example",
|
||||
event_id: "$create",
|
||||
origin_server_ts: 0,
|
||||
content: {
|
||||
room_version: "12"
|
||||
}
|
||||
}, {
|
||||
users: {
|
||||
"@_ooye_bot:cadence.moe": 100
|
||||
}
|
||||
}), {
|
||||
users: {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test("removeCreatorsFromPowerLevels: removes all creators from a v12 room", t => {
|
||||
t.deepEqual(removeCreatorsFromPowerLevels({
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!example",
|
||||
event_id: "$create",
|
||||
origin_server_ts: 0,
|
||||
content: {
|
||||
additional_creators: ["@cadence:cadence.moe"],
|
||||
room_version: "12"
|
||||
}
|
||||
}, {
|
||||
users: {
|
||||
"@_ooye_bot:cadence.moe": 100,
|
||||
"@cadence:cadence.moe": 100
|
||||
}
|
||||
}), {
|
||||
users: {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test("removeCreatorsFromPowerLevels: doesn't touch a v11 room", t => {
|
||||
t.deepEqual(removeCreatorsFromPowerLevels({
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!example",
|
||||
event_id: "$create",
|
||||
origin_server_ts: 0,
|
||||
content: {
|
||||
additional_creators: ["@cadence:cadence.moe"],
|
||||
room_version: "11"
|
||||
}
|
||||
}, {
|
||||
users: {
|
||||
"@_ooye_bot:cadence.moe": 100,
|
||||
"@cadence:cadence.moe": 100
|
||||
}
|
||||
}), {
|
||||
users: {
|
||||
"@_ooye_bot:cadence.moe": 100,
|
||||
"@cadence:cadence.moe": 100
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test("set user power: no-op", async t => {
|
||||
let called = 0
|
||||
await setUserPower("!room", "@cadence:cadence.moe", 0, {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
return {}
|
||||
},
|
||||
async getStateEventOuter(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.create")
|
||||
t.equal(key, "")
|
||||
return {
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!room",
|
||||
origin_server_ts: 0,
|
||||
event_id: "$create",
|
||||
content: {
|
||||
room_version: "11"
|
||||
}
|
||||
}
|
||||
},
|
||||
/* c8 ignore next 4 */
|
||||
async sendState() {
|
||||
called++
|
||||
throw new Error("should not try to send state")
|
||||
}
|
||||
})
|
||||
t.equal(called, 2)
|
||||
})
|
||||
|
||||
test("set user power: bridge bot must promote unprivileged users", async t => {
|
||||
let called = 0
|
||||
await setUserPower("!room", "@cadence:cadence.moe", 100, {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
return {
|
||||
users: {"@_ooye_bot:cadence.moe": 100}
|
||||
}
|
||||
},
|
||||
async getStateEventOuter(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.create")
|
||||
t.equal(key, "")
|
||||
return {
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!room",
|
||||
origin_server_ts: 0,
|
||||
event_id: "$create",
|
||||
content: {
|
||||
room_version: "11"
|
||||
}
|
||||
}
|
||||
},
|
||||
async sendState(roomID, type, key, content, mxid) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
t.deepEqual(content, {
|
||||
users: {
|
||||
"@_ooye_bot:cadence.moe": 100,
|
||||
"@cadence:cadence.moe": 100
|
||||
}
|
||||
})
|
||||
t.equal(mxid, undefined)
|
||||
return "$sent"
|
||||
}
|
||||
})
|
||||
t.equal(called, 3)
|
||||
})
|
||||
|
||||
test("set user power: privileged users must demote themselves", async t => {
|
||||
let called = 0
|
||||
await setUserPower("!room", "@cadence:cadence.moe", 0, {
|
||||
async getStateEvent(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
return {
|
||||
users: {
|
||||
"@cadence:cadence.moe": 100,
|
||||
"@_ooye_bot:cadence.moe": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
async getStateEventOuter(roomID, type, key) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.create")
|
||||
t.equal(key, "")
|
||||
return {
|
||||
type: "m.room.create",
|
||||
state_key: "",
|
||||
sender: "@_ooye_bot:cadence.moe",
|
||||
room_id: "!room",
|
||||
origin_server_ts: 0,
|
||||
event_id: "$create",
|
||||
content: {
|
||||
room_version: "11"
|
||||
}
|
||||
}
|
||||
},
|
||||
async sendState(roomID, type, key, content, mxid) {
|
||||
called++
|
||||
t.equal(roomID, "!room")
|
||||
t.equal(type, "m.room.power_levels")
|
||||
t.equal(key, "")
|
||||
t.deepEqual(content, {
|
||||
users: {"@_ooye_bot:cadence.moe": 100}
|
||||
})
|
||||
t.equal(mxid, "@cadence:cadence.moe")
|
||||
return "$sent"
|
||||
}
|
||||
})
|
||||
t.equal(called, 3)
|
||||
})
|
||||
|
||||
module.exports.mockGetEffectivePower = mockGetEffectivePower
|
||||
|
||||
Reference in New Issue
Block a user