diff --git a/src/web/pug/guild_not_linked.pug b/src/web/pug/guild_not_linked.pug
index 59de2fb..61c57e9 100644
--- a/src/web/pug/guild_not_linked.pug
+++ b/src/web/pug/guild_not_linked.pug
@@ -4,7 +4,7 @@ mixin space(space)
.s-user-card.flex__1
span.s-avatar.s-avatar__32.s-user-card--avatar
if space.avatar
- img.s-avatar--image(src=mUtils.getPublicUrlForMxc(space.avatar))
+ img.s-avatar--image(src=mUtils.getPublicUrlForMxc(space.avatar) alt="")
else
.s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= space.name[0]
.s-user-card--info.ai-start
diff --git a/src/web/pug/includes/template.pug b/src/web/pug/includes/template.pug
index d9f1c30..93aaefc 100644
--- a/src/web/pug/includes/template.pug
+++ b/src/web/pug/includes/template.pug
@@ -1,7 +1,7 @@
mixin guild(guild)
span.s-avatar.s-avatar__32.s-user-card--avatar
if guild.icon
- img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32`)
+ img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32` alt="")
else
.s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= guild.name[0]
.s-user-card--info.ai-start
@@ -82,10 +82,10 @@ html(lang="en")
+define-themed-button("matrix", "black")
body.themed.theme-system
header.s-topbar
- .s-topbar--skip-link(href="#content") Skip to main content
+ a.s-topbar--skip-link(href="#content") Skip to main content
.s-topbar--container.wmx9
a.s-topbar--logo(href=rel("/"))
- img.s-avatar.s-avatar__32(src=rel("/icon.png"))
+ img.s-avatar.s-avatar__32(src=rel("/icon.png") alt="")
nav.s-topbar--navigation
ul.s-topbar--content
li.ps-relative.g8
diff --git a/src/web/routes/guild.test.js b/src/web/routes/guild.test.js
index ea59173..bb77c12 100644
--- a/src/web/routes/guild.test.js
+++ b/src/web/routes/guild.test.js
@@ -89,7 +89,7 @@ test("web guild: unbridged self-service guild shows available spaces", async t =
})
t.has(html, `Data Horde`)
t.has(html, `
here is the space topic`)
- t.has(html, `
`)
+ t.has(html, `
`)
t.notMatch(html, /some room<\/strong>/)
t.notMatch(html, /somebody else's space<\/strong>/)
})
@@ -190,21 +190,66 @@ test("api invite: can invite with valid nonce", async t => {
api: {
async getStateEvent(roomID, type, key) {
called++
- return {membership: "leave"}
+ if (type === "m.room.member" && key === "@cadence:cadence.moe") {
+ return {membership: "leave"}
+ } else if (type === "m.room.power_levels" && key === "") {
+ return {}
+ } else {
+ t.fail(`unexpected getStateEvent call. roomID: ${roomID}, type: ${type}, key: ${key}`)
+ }
+ },
+ async getStateEventOuter(roomID, type, key) {
+ called++
+ return {
+ type: "m.room.create",
+ state_key: "",
+ sender: "@_ooye_bot:cadence.moe",
+ event_id: "$create",
+ origin_server_ts: 0,
+ room_id: roomID,
+ content: {
+ room_version: "11"
+ }
+ }
},
async inviteToRoom(roomID, mxidToInvite, mxid) {
+ called++
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe")
- called++
},
- async setUserPowerCascade(roomID, mxid, power) {
- t.equal(power, 50) // moderator
+ async *generateFullHierarchy(spaceID) {
called++
+ yield {
+ room_id: "!hierarchy",
+ children_state: [],
+ guest_can_join: false,
+ num_joined_members: 2,
+ }
+ },
+ async sendState(roomID, type, key, content) {
+ called++
+ t.ok(["!hierarchy", "!jjmvBegULiLucuWEHU:cadence.moe"].includes(roomID), `expected room ID to be in hierarchy, but was ${roomID}`)
+ t.equal(type, "m.room.power_levels")
+ t.equal(key, "")
+ t.deepEqual(content, {
+ users: {"@cadence:cadence.moe": 50}
+ })
+ return "$updated"
}
}
})
)
t.notOk(error)
- t.equal(called, 3)
+ /*
+ 1. get membership
+ 2. invite to room
+ set power:
+ 3. generate hierarchy
+ 4-5. calculate powers
+ 6. send state
+ 7-8. calculate powers
+ 9. send state
+ */
+ t.equal(called, 9) // get membership +
})
test("api invite: access denied when nonce has been used", async t => {
@@ -235,21 +280,56 @@ test("api invite: can invite to a moderated guild", async t => {
api: {
async getStateEvent(roomID, type, key) {
called++
- throw new MatrixServerError({errcode: "M_NOT_FOUND", error: "Event not found or something"})
+ if (type === "m.room.member" && key === "@cadence:cadence.moe") {
+ return {membership: "leave"}
+ } else if (type === "m.room.power_levels" && key === "") {
+ return {}
+ } else {
+ t.fail(`unexpected getStateEvent call. roomID: ${roomID}, type: ${type}, key: ${key}`)
+ }
+ },
+ async getStateEventOuter(roomID, type, key) {
+ called++
+ return {
+ type: "m.room.create",
+ state_key: "",
+ sender: "@_ooye_bot:cadence.moe",
+ event_id: "$create",
+ origin_server_ts: 0,
+ room_id: roomID,
+ content: {
+ room_version: "11"
+ }
+ }
},
async inviteToRoom(roomID, mxidToInvite, mxid) {
+ called++
t.equal(roomID, "!jjmvBegULiLucuWEHU:cadence.moe")
- called++
},
- async setUserPowerCascade(roomID, mxid, power) {
- t.equal(power, 100) // moderator
+ async *generateFullHierarchy(spaceID) {
called++
+ yield {
+ room_id: "!hierarchy",
+ children_state: [],
+ guest_can_join: false,
+ num_joined_members: 2,
+ }
+ },
+ async sendState(roomID, type, key, content) {
+ called++
+ t.ok(["!hierarchy", "!jjmvBegULiLucuWEHU:cadence.moe"].includes(roomID), `expected room ID to be in hierarchy, but was ${roomID}`)
+ t.equal(type, "m.room.power_levels")
+ t.equal(key, "")
+ t.deepEqual(content, {
+ users: {"@cadence:cadence.moe": 100}
+ })
+ return "$updated"
}
}
})
)
t.notOk(error)
- t.equal(called, 3)
+ t.equal(called, 9)
})
test("api invite: does not reinvite joined users", async t => {