Adjust Discord publication and lobby capacity defaults
CI / checks (push) Failing after 7m21s

This commit is contained in:
2026-10-18 17:23:50 -04:00
parent fd00ef5357
commit d715173719
15 changed files with 304 additions and 89 deletions
+64 -13
View File
@@ -122,7 +122,7 @@ beforeEach(() => {
enabled: true,
guildId,
channels: { t5: '444444444444444444', t6: '' },
publishedServers: [name]
excludedServers: []
};
vi.mocked(getDiscordSettings).mockImplementation(() => settings);
vi.mocked(fleetSnapshot).mockReturnValue({ servers: [server()] } as ReturnType<
@@ -137,7 +137,22 @@ afterEach(() => {
});
describe('Discord publication boundary', () => {
it('projects only opted-in servers and explicitly approved fields', () => {
it('publishes current and newly added servers by default while respecting exclusions', () => {
const original = server();
const added = server({ name: 't5_zombie_theater_2' });
expect(projectFleet([original], settings, now).map((item) => item.name)).toEqual([name]);
expect(projectFleet([original, added], settings, now).map((item) => item.name)).toEqual([
name,
added.name
]);
expect(
projectFleet([original, added], { ...settings, excludedServers: [name] }, now).map(
(item) => item.name
)
).toEqual([added.name]);
});
it('excludes unpublished servers and projects only explicitly approved fields', () => {
const raw = {
...server(),
host: { id: 'internal-host' },
@@ -147,7 +162,7 @@ describe('Discord publication boundary', () => {
};
const projected = projectFleet(
[raw as unknown as FleetServer, server({ name: 'unpublished' })],
settings,
{ ...settings, excludedServers: ['unpublished'] },
now
);
expect(projected).toHaveLength(1);
@@ -195,17 +210,54 @@ describe('Discord publication boundary', () => {
const projected = projectFleet([server(change)], settings, now)[0];
expect(projected).toMatchObject({ state, players });
if (players === null)
expect(projected).toMatchObject({ capacity: null, round: null, playerNames: [] });
expect(projected).toMatchObject({ capacity: 4, round: null, playerNames: [] });
});
it('never treats stale or previous-process capacity as an available space', () => {
it('uses the four-player lobby limit when current capacity is unavailable', () => {
for (const change of [
{ capacity_observed_at: new Date(now - 100000).toISOString() },
{ telemetry_after: new Date(now - 5000).toISOString() }
{ capacity: null, capacity_observed_at: null },
{ capacity: 0 },
{ capacity: 8, capacity_observed_at: new Date(now - 100000).toISOString() },
{
capacity: 8,
capacity_observed_at: new Date(now - 20000).toISOString(),
telemetry_after: new Date(now - 15000).toISOString()
}
]) {
const projected = projectFleet([server(change)], settings, now);
expect(projected[0].capacity).toBeNull();
expect(projected[0].capacity).toBe(4);
expect(filterServers(projected, { status: 'space' })).toEqual(projected);
for (const message of [
...renderBoard('t5', projected),
renderBrowser(projected),
renderServer(projected[0])
]) {
expect(messageText(message)).toContain('2/4 players');
expect(messageText(message)).not.toContain('2/?');
}
}
const full = projectFleet([server({ last_players: 4, capacity: null })], settings, now);
expect(full[0]).toMatchObject({ capacity: 4, state: 'full' });
expect(filterServers(full, { status: 'space' })).toEqual([]);
});
it('uses a current measured capacity when available', () => {
const projected = projectFleet([server({ capacity: 8, last_players: 4 })], settings, now);
expect(projected[0]).toMatchObject({ capacity: 8, state: 'in-progress' });
expect(messageText(renderServer(projected[0]))).toContain('4/8 players');
expect(filterServers(projected, { status: 'space' })).toEqual(projected);
});
it('never treats stale or previous-process occupancy as an available space', () => {
for (const change of [
{ last_seen_at: new Date(now - 100000).toISOString() },
{ health: 'stale' as const },
{ telemetry_after: new Date(now - 5000).toISOString() }
]) {
const projected = projectFleet([server({ ...change, capacity: null })], settings, now);
expect(projected[0]).toMatchObject({ capacity: 4, players: null });
expect(filterServers(projected, { status: 'space' })).toEqual([]);
expect(messageText(renderServer(projected[0]))).toContain('Players unknown');
}
});
@@ -218,12 +270,11 @@ describe('Discord publication boundary', () => {
map_slug: 'town',
telemetry: undefined
});
const setup = { ...settings, publishedServers: [town.name] };
expect(projectFleet([town], setup, now)[0]).toMatchObject({
expect(projectFleet([town], settings, now)[0]).toMatchObject({
map: 'Town Survival',
mapKey: 't6:zm_transit:town'
});
expect(projectFleet([{ ...town, last_map: 'zm_tomb' }], setup, now)[0]).toMatchObject({
expect(projectFleet([{ ...town, last_map: 'zm_tomb' }], settings, now)[0]).toMatchObject({
map: 'Origins',
mapKey: 't6:zm_tomb:tomb'
});
@@ -355,7 +406,7 @@ describe('Discord interaction isolation', () => {
expect(result.type).toBe(4);
expect(result.data.flags).toBe(32832);
expect(messageText(result.data)).toContain('Round 28');
settings.publishedServers = [];
settings.excludedServers = [name];
expect(
messageText(
(
@@ -400,7 +451,7 @@ describe('Discord interaction isolation', () => {
});
expect(messageText(result.data)).toContain('one DM');
vi.mocked(subscribeToMap).mockClear();
settings.publishedServers = [];
settings.excludedServers = [name];
await handleDiscordInteraction(
interaction({ custom_id: `ec:w:space:${discordServerKey('t5:zombie_theater')}` }, 3)
);