Show instance and player counts on hosts
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
import { gameEvent } from '../helpers/telemetry.js';
|
||||
|
||||
let fixture: Fixture;
|
||||
beforeEach(async () => { vi.resetModules(); fixture = await newFixture([]); });
|
||||
@@ -33,12 +34,12 @@ describe('host detail instances', () => {
|
||||
|
||||
const { hostOverview } = await import('../../src/lib/server/hosts/overview.js');
|
||||
const overview = hostOverview();
|
||||
expect(overview.find(row => row.id === host.id)?.serverCount).toBe(2);
|
||||
expect(overview.find(row => row.id === other.id)?.serverCount).toBe(1);
|
||||
expect(overview.find(row => row.id === host.id)).toMatchObject({ serverCount: 2, playerCount: 2, unreportedInstances: 1 });
|
||||
expect(overview.find(row => row.id === other.id)).toMatchObject({ serverCount: 1, playerCount: 2, unreportedInstances: 0 });
|
||||
const { GET: list } = await import('../../src/routes/api/hosts/+server.js');
|
||||
const listed = await list({ request: new Request('https://ec.test/api/hosts') }).json();
|
||||
expect(listed.serverNow).toEqual(expect.any(Number));
|
||||
expect(listed.hosts.find((row: { id: string }) => row.id === host.id)).toMatchObject({ serverCount: 2 });
|
||||
expect(listed.hosts.find((row: { id: string }) => row.id === host.id)).toMatchObject({ serverCount: 2, playerCount: 2, unreportedInstances: 1 });
|
||||
const { GET } = await import('../../src/routes/api/hosts/[id]/+server.js');
|
||||
const read = async (id: string) => (await GET({ request: new Request(`https://ec.test/api/hosts/${id}`), params: { id } }).json());
|
||||
const body = await read(host.id);
|
||||
@@ -52,6 +53,13 @@ describe('host detail instances', () => {
|
||||
expect((await read(other.id)).instances.map((instance: { name: string }) => instance.name)).toEqual(['other-host']);
|
||||
const empty = createHost({ name: 'Empty host' });
|
||||
expect((await read(empty.id)).instances).toEqual([]);
|
||||
expect(hostOverview().find(row => row.id === empty.id)?.serverCount).toBe(0);
|
||||
expect(hostOverview().find(row => row.id === empty.id)).toMatchObject({ serverCount: 0, playerCount: 0, unreportedInstances: 0 });
|
||||
const report = { ...gameEvent('heartbeat', 15, 4, 'running'), receivedAt: now };
|
||||
db().prepare('INSERT INTO server_telemetry (server, round, players, received_at, payload) VALUES (?, ?, ?, ?, ?)')
|
||||
.run('running', 15, 4, now, JSON.stringify(report));
|
||||
expect(hostOverview().find(row => row.id === host.id)).toMatchObject({ playerCount: 4, unreportedInstances: 1 });
|
||||
db().prepare("DELETE FROM server_telemetry WHERE server='running'").run();
|
||||
db().prepare("UPDATE servers SET last_seen_at='2000-01-01T00:00:00Z',last_players=99 WHERE name='running'").run();
|
||||
expect(hostOverview().find(row => row.id === host.id)).toMatchObject({ playerCount: 0, unreportedInstances: 2 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,8 +56,11 @@ it('distinguishes real zero usage from missing or invalid metrics', () => {
|
||||
});
|
||||
|
||||
it('renders compact host links and workload without duplicate identity, setup metadata or deletion actions', () => {
|
||||
const body = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3 }], now } }).body;
|
||||
expect(body).toContain('3 assigned servers on ec-1');
|
||||
const body = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3, playerCount: 12, unreportedInstances: 0 }], now } }).body;
|
||||
expect(body).toContain('3 assigned instances on ec-1');
|
||||
expect(body).toContain('>Instances</th>');
|
||||
expect(body).toContain('>Players</th>');
|
||||
expect(body).toContain('>12</td>');
|
||||
expect(body).toContain('0.0%');
|
||||
expect(body).toContain('512.0 MiB / 1.0 GiB');
|
||||
expect(body.match(/>ec-1</g)).toHaveLength(1);
|
||||
@@ -65,7 +68,17 @@ it('renders compact host links and workload without duplicate identity, setup me
|
||||
expect(body).not.toContain('Game ports');
|
||||
expect(body).not.toContain('Automatic setup');
|
||||
expect(body).not.toContain('Resource readings stale');
|
||||
const stale = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3 }], now: now + 90_001 } }).body;
|
||||
const stale = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3, playerCount: 12, unreportedInstances: 0 }], now: now + 90_001 } }).body;
|
||||
expect(stale).toContain('Resource readings stale');
|
||||
expect(stale).toContain('Offline');
|
||||
});
|
||||
|
||||
it('marks partial player totals and distinguishes unavailable counts from empty hosts', () => {
|
||||
const partial = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3, playerCount: 4, unreportedInstances: 1 }], now } }).body;
|
||||
expect(partial).toContain('>4+</td>');
|
||||
expect(partial).toContain('Player counts unavailable for 1 of 3 instances');
|
||||
const unknown = render(HostList, { props: { hosts: [{ ...host(), serverCount: 3, playerCount: 0, unreportedInstances: 3 }], now } }).body;
|
||||
expect(unknown).toContain('>—</td>');
|
||||
const empty = render(HostList, { props: { hosts: [{ ...host(), serverCount: 0, playerCount: 0, unreportedInstances: 0 }], now } }).body;
|
||||
expect(empty).toContain('>0</td>');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user