Admin → Teams told an operator that an unsynced projection "is not a confirmed empty shard". Teams is a core primitive and core's word for the host is the game server; "shard" is Ultima Online's. The detail now reads "What is shown below does not confirm that the game server has no Teams." The matching test, and the four comments that said "shard" about the same state, follow it. Found while making runicgateway.com's core docs game-neutral (runicgateway.com#34), which had to paraphrase this line rather than quote it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
79 lines
3.4 KiB
JavaScript
79 lines
3.4 KiB
JavaScript
// What core's Team activity feed says (client/src/lib/teamActivity.js).
|
|
//
|
|
// The test that earns this file: a projection nobody can tell is stale, and a
|
|
// feed nobody can tell is filtered, both look like complete information. Every
|
|
// case below is about saying which one the reader is looking at.
|
|
//
|
|
// Note the wording assertions avoid core's own noun. The feed renders inside a
|
|
// page a MODULE titled — Guilds today, Clans next — so "this Team" would be
|
|
// core's vocabulary leaking onto a surface that deliberately does not use it.
|
|
import { test } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
|
|
import { activityScopeNote, freshnessNote, groupByDay, relativeTime } from '../src/lib/teamActivity.js'
|
|
|
|
const NOW = new Date('2026-08-17T12:00:00Z').getTime()
|
|
const ago = (ms) => new Date(NOW - ms).toISOString()
|
|
|
|
test('a deployment with no provider is not stale, it is uninvolved', () => {
|
|
assert.equal(freshnessNote({ configured: false }, NOW), null)
|
|
})
|
|
|
|
test('never synced is a warning, and never reads as a confirmed empty roster', () => {
|
|
const note = freshnessNote({ configured: true, lastSyncAt: null }, NOW)
|
|
assert.equal(note.tone, 'warn')
|
|
assert.match(note.text, /Not yet confirmed/)
|
|
})
|
|
|
|
test('a stale projection says how old it is and that the game may have moved on', () => {
|
|
const note = freshnessNote({ configured: true, lastSyncAt: ago(14 * 60_000), stale: true }, NOW)
|
|
assert.equal(note.tone, 'warn')
|
|
assert.equal(note.text, 'Last confirmed 14 minutes ago — the game may have moved on.')
|
|
})
|
|
|
|
test('a current projection is stated quietly', () => {
|
|
const note = freshnessNote({ configured: true, lastSyncAt: ago(90_000), stale: false }, NOW)
|
|
assert.equal(note.tone, 'idle')
|
|
assert.equal(note.text, 'Last confirmed 1 minute ago.')
|
|
})
|
|
|
|
test('relative time singularises and steps through the units', () => {
|
|
assert.equal(relativeTime(ago(5_000), NOW), 'just now')
|
|
assert.equal(relativeTime(ago(60_000), NOW), '1 minute ago')
|
|
assert.equal(relativeTime(ago(3 * 3_600_000), NOW), '3 hours ago')
|
|
assert.equal(relativeTime(ago(2 * 86_400_000), NOW), '2 days ago')
|
|
assert.equal(relativeTime(null, NOW), null)
|
|
assert.equal(relativeTime('not a date', NOW), null)
|
|
})
|
|
|
|
test('items group into days, newest day first, order kept within a day', () => {
|
|
const days = groupByDay([
|
|
{ id: 3, occurredAt: '2026-08-17T09:00:00' },
|
|
{ id: 2, occurredAt: '2026-08-17T08:00:00' },
|
|
{ id: 1, occurredAt: '2026-08-16T22:00:00' },
|
|
], 'en-US')
|
|
assert.equal(days.length, 2)
|
|
assert.deepEqual(days[0].items.map((i) => i.id), [3, 2])
|
|
assert.deepEqual(days[1].items.map((i) => i.id), [1])
|
|
})
|
|
|
|
test('an unparseable timestamp is skipped rather than making a day called Invalid Date', () => {
|
|
assert.deepEqual(groupByDay([{ id: 1, occurredAt: 'nonsense' }], 'en-US'), [])
|
|
})
|
|
|
|
test('a caller who saw everything is told nothing', () => {
|
|
assert.equal(activityScopeNote({ scope: 'members' }, true), null)
|
|
})
|
|
|
|
test('a filtered feed says so, and invites an anonymous caller to sign in', () => {
|
|
assert.match(activityScopeNote({ scope: 'public' }, false), /Sign in/)
|
|
assert.match(activityScopeNote({ scope: 'public' }, true), /members only/)
|
|
})
|
|
|
|
test('the wording never says "Team" — that is core\'s noun, not the page\'s', () => {
|
|
for (const signedIn of [true, false]) {
|
|
assert.doesNotMatch(activityScopeNote({ scope: 'public' }, signedIn), /Team/)
|
|
}
|
|
assert.doesNotMatch(freshnessNote({ configured: true, lastSyncAt: null }, NOW).text, /Team/)
|
|
})
|