136 lines
5.0 KiB
TypeScript
136 lines
5.0 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
parseServerName,
|
|
selectedZombieMap,
|
|
t5ZombieMapBySlug,
|
|
zombieMapBySlug,
|
|
T5_ZOMBIE_MAPS,
|
|
T6_ZOMBIE_MAPS
|
|
} from '../../src/lib/server/fleet/map-aliases.js';
|
|
import { serverTitle } from '../../src/lib/ui/server-labels.js';
|
|
|
|
describe('T6 map identity', () => {
|
|
it.each([
|
|
['towngrief', 'zm_transit'], ['farmgrief', 'zm_transit'], ['busdepotgrief', 'zm_transit'],
|
|
['cellblock', 'zm_prison'], ['buriedgrief', 'zm_buried'], ['diner', 'zm_transit_dr'], ['buriedturned', 'zm_buried']
|
|
])('excludes %s without falling back to a supported variant of the same engine map', (slug, canonical) => {
|
|
expect(zombieMapBySlug('t6', slug)).toBeUndefined();
|
|
expect(selectedZombieMap('t6', canonical, slug)).toBeUndefined();
|
|
expect(parseServerName(`t6_zombie_${slug}_1`)?.mapCanonical).toBeNull();
|
|
});
|
|
|
|
it.each(T6_ZOMBIE_MAPS)('parses and labels $friendly without losing its variant', (map) => {
|
|
const name = `t6_zombie_${map.slug}_2`;
|
|
expect(parseServerName(name)).toMatchObject({ game: 't6', gameMode: 'zombie', mapCanonical: map.canonical, mapSlug: map.slug, lobby: 2 });
|
|
expect(serverTitle(name)).toBe(`${map.friendly} · Lobby 2`);
|
|
});
|
|
|
|
it('does not interpret another game or mode through the T5 catalog', () => {
|
|
for (const name of ['t6_zombie_theater_1', 't5_zombie_tomb_1', 't5_mp_theater_1', 'iw5_theater_1']) {
|
|
expect(parseServerName(name)?.mapCanonical).toBeNull();
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('parseServerName (new naming: t5_<mode>_<slug>_<n>)', () => {
|
|
it('extracts game, mode, slug, canonical, and lobby from a T5 zombie name', () => {
|
|
expect(parseServerName('t5_zombie_cosmodrome_1')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'cosmodrome',
|
|
mapCanonical: 'zombie_cosmodrome',
|
|
lobby: 1
|
|
});
|
|
expect(parseServerName('t5_zombie_theater_2')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'theater',
|
|
mapCanonical: 'zombie_theater',
|
|
lobby: 2
|
|
});
|
|
expect(parseServerName('t5_zombie_coast_1')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'coast',
|
|
mapCanonical: 'zombie_coast',
|
|
lobby: 1
|
|
});
|
|
});
|
|
|
|
it('joins multi-segment slugs and matches the catalog', () => {
|
|
// 'shinonuma' is written in-catalog as one word, so a name with
|
|
// separators still resolves via join-without-separators lookup.
|
|
expect(parseServerName('t5_zombie_shi_no_numa_1')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'shinonuma',
|
|
mapCanonical: 'zombie_cod5_sumpf',
|
|
lobby: 1
|
|
});
|
|
});
|
|
|
|
it('treats an absent lobby number as null', () => {
|
|
expect(parseServerName('t5_zombie_moon')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'moon',
|
|
mapCanonical: 'zombie_moon',
|
|
lobby: null
|
|
});
|
|
});
|
|
|
|
it('returns mapCanonical=null for unknown slugs so operators can spot the gap', () => {
|
|
expect(parseServerName('t5_zombie_newmap_1')).toEqual({
|
|
game: 't5',
|
|
gameMode: 'zombie',
|
|
mapSlug: 'newmap',
|
|
mapCanonical: null,
|
|
lobby: 1
|
|
});
|
|
});
|
|
|
|
it('parses legacy names without a mode segment (mode=null)', () => {
|
|
// Not the new format, but a name like 't5_theater_1' still returns
|
|
// meaningful info so the seeder can surface it during migration.
|
|
const parsed = parseServerName('t5_theater_1');
|
|
expect(parsed).toEqual({
|
|
game: 't5',
|
|
gameMode: null,
|
|
mapSlug: 'theater',
|
|
mapCanonical: 'zombie_theater',
|
|
lobby: 1
|
|
});
|
|
});
|
|
|
|
it('rejects names with fewer than two segments', () => {
|
|
expect(parseServerName('t5')).toBeNull();
|
|
expect(parseServerName('')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('t5ZombieMapBySlug', () => {
|
|
it('excludes Dead Ops Arcade from supported map selection', () => {
|
|
expect(t5ZombieMapBySlug('zombietron')).toBeUndefined();
|
|
expect(selectedZombieMap('t5', 'zombietron')).toBeUndefined();
|
|
expect(parseServerName('t5_zombie_zombietron_1')?.mapCanonical).toBeNull();
|
|
});
|
|
|
|
it('resolves each catalog slug to its canonical + friendly', () => {
|
|
for (const entry of T5_ZOMBIE_MAPS) {
|
|
const found = t5ZombieMapBySlug(entry.slug);
|
|
expect(found?.canonical).toBe(entry.canonical);
|
|
expect(found?.friendly).toBe(entry.friendly);
|
|
}
|
|
});
|
|
|
|
it('is case-insensitive', () => {
|
|
expect(t5ZombieMapBySlug('COSMODROME')?.canonical).toBe('zombie_cosmodrome');
|
|
});
|
|
|
|
it('every catalog entry canonical starts with zombie', () => {
|
|
for (const entry of T5_ZOMBIE_MAPS) {
|
|
expect(entry.canonical.startsWith('zombie')).toBe(true);
|
|
}
|
|
});
|
|
});
|