feat(guilds): a UO guild is a Team (Teams cutover 5/6) #16
@@ -42,13 +42,22 @@ async function levelFor(actor) {
|
|||||||
return visibility.viewerLevel({ user: { id: actor.userId, role: actor.role } })
|
return visibility.viewerLevel({ user: { id: actor.userId, role: actor.role } })
|
||||||
}
|
}
|
||||||
|
|
||||||
// The nudge §9 answer 5 asks for, and only when it is TRUE. An unlinked caller
|
// The nudge §9 answer 5 asks for, and only when it is TRUE.
|
||||||
// who was told nothing because the shard publishes nothing is not helped by
|
//
|
||||||
// being invited to link; the prompt appears when linking is what would actually
|
// **Linking reaches exactly two rungs and no further.** Signing in gets a caller
|
||||||
// change the answer.
|
// to `logged_in` and linking a game account to `player`; `staff` and `admin` are
|
||||||
|
// roles an operator grants and no amount of linking will earn. So a shard that
|
||||||
|
// gates guilds to staff refuses an unlinked caller WITHOUT the invitation —
|
||||||
|
// telling them to link would be telling them to do something that changes
|
||||||
|
// nothing, which is worse than saying no.
|
||||||
|
//
|
||||||
|
// The live walk found this: gated to `staff`, the refusal still read "this shard
|
||||||
|
// shows guild information to linked players".
|
||||||
|
const LINKING_REACHES = new Set(['logged_in', 'player'])
|
||||||
|
|
||||||
function linkPrompt(actor, audience) {
|
function linkPrompt(actor, audience) {
|
||||||
if (actor.isLinked) return null
|
if (actor.isLinked) return null
|
||||||
if (audience === 'anonymous') return null
|
if (!LINKING_REACHES.has(audience)) return null
|
||||||
return 'Link your account on the site to see more — this shard shows guild information to linked players.'
|
return 'Link your account on the site to see more — this shard shows guild information to linked players.'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +163,10 @@ async function handler({ options, actor }) {
|
|||||||
if (!wanted) {
|
if (!wanted) {
|
||||||
const top = [...rows].sort((a, b) => (b.members || 0) - (a.members || 0)).slice(0, LIST_LIMIT)
|
const top = [...rows].sort((a, b) => (b.members || 0) - (a.members || 0)).slice(0, LIST_LIMIT)
|
||||||
return {
|
return {
|
||||||
title: `Guilds on ${core.baseUrl.replace(/^https?:\/\//, '')}`,
|
// Not "Guilds on <host>": `ctx.site` carries a base URL and no brand name,
|
||||||
|
// so naming the deployment here can only mean printing its hostname into
|
||||||
|
// an embed title, which is noise on a shard's own Discord server.
|
||||||
|
title: 'Guilds on this shard',
|
||||||
fields: top.map((g) => ({
|
fields: top.map((g) => ({
|
||||||
name: g.abbr ? `${g.name} [${g.abbr}]` : g.name,
|
name: g.abbr ? `${g.name} [${g.abbr}]` : g.name,
|
||||||
value: `${g.members || 0} members · ${g.online || 0} online`,
|
value: `${g.members || 0} members · ${g.online || 0} online`,
|
||||||
|
|||||||
@@ -88,6 +88,14 @@ test('an unlinked caller is invited to link — but only when linking would chan
|
|||||||
stub({ audience: 'anonymous', level: 'anonymous' })
|
stub({ audience: 'anonymous', level: 'anonymous' })
|
||||||
const open = await command.handler({ options: {}, actor: anonymous })
|
const open = await command.handler({ options: {}, actor: anonymous })
|
||||||
assert.equal(open.notice, null)
|
assert.equal(open.notice, null)
|
||||||
|
|
||||||
|
// Gated to staff: linking reaches `player` and stops there, so the invitation
|
||||||
|
// would be an instruction to do something that changes nothing. Found on the
|
||||||
|
// live rig, where a staff-gated shard still offered it.
|
||||||
|
stub({ audience: 'staff', level: 'anonymous' })
|
||||||
|
const unreachable = await command.handler({ options: {}, actor: anonymous })
|
||||||
|
assert.match(unreachable.text, /not shown to your account/)
|
||||||
|
assert.equal(unreachable.notice, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('a stale board answers offline rather than reporting what it still holds', async () => {
|
test('a stale board answers offline rather than reporting what it still holds', async () => {
|
||||||
@@ -99,6 +107,7 @@ test('a stale board answers offline rather than reporting what it still holds',
|
|||||||
test('no argument lists the largest guilds', async () => {
|
test('no argument lists the largest guilds', async () => {
|
||||||
stub()
|
stub()
|
||||||
const res = await command.handler({ options: {}, actor: anonymous })
|
const res = await command.handler({ options: {}, actor: anonymous })
|
||||||
|
assert.equal(res.title, 'Guilds on this shard')
|
||||||
assert.equal(res.fields.length, 2)
|
assert.equal(res.fields.length, 2)
|
||||||
assert.match(res.fields[0].name, /Knights of the Codex/)
|
assert.match(res.fields[0].name, /Knights of the Codex/)
|
||||||
assert.match(res.fields[0].value, /12 members · 3 online/)
|
assert.match(res.fields[0].value, /12 members · 3 online/)
|
||||||
|
|||||||
Reference in New Issue
Block a user