"Diese SteamID ist bereits einem Spieler zugeordnet" liess offen, welchem - und damit blieb nur, den Bestand von Hand durchzusuchen. Die Meldung nennt jetzt den Namen und sagt auch, ob die Kennung dort die aktuelle ist oder als frueheres Konto haengt. Dabei fiel auf, dass die Pruefung nur die Hauptangaben ansah. Eine Kennung, die bei jemandem als frueheres Konto eingetragen war, liess sich bei einem anderen als aktuelle vergeben - und danach wuesste weder der Abgleich noch der Import, wem ein Kauf gehoert. Beides wird jetzt geprueft, in beide Richtungen: beim Anlegen und Bearbeiten eines Spielers ebenso wie beim Nachtragen eines frueheren Kontos.
195 lines
6.7 KiB
TypeScript
195 lines
6.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { after, before, describe, it } from 'node:test';
|
|
import { startTestDatabase, type TestDatabase } from './harness.js';
|
|
|
|
type Players = typeof import('../src/services/players.js');
|
|
type Scraper = typeof import('../src/services/scraper.js');
|
|
type Db = typeof import('../src/db.js');
|
|
|
|
let database: TestDatabase;
|
|
let players: Players;
|
|
let scraper: Scraper;
|
|
let db: Db;
|
|
let ctx: { actorId: number; actorName: string };
|
|
|
|
before(async () => {
|
|
database = await startTestDatabase(54335);
|
|
process.env.DATABASE_URL = database.url;
|
|
process.env.SESSION_SECRET = 'test-secret-that-is-long-enough-000000';
|
|
process.env.NODE_ENV = 'test';
|
|
|
|
db = await import('../src/db.js');
|
|
players = await import('../src/services/players.js');
|
|
scraper = await import('../src/services/scraper.js');
|
|
|
|
const user = await db.prisma.user.create({
|
|
data: { username: 'pfleger', passwordHash: 'x', role: 'ADMIN' },
|
|
});
|
|
ctx = { actorId: user.id, actorName: user.username };
|
|
});
|
|
|
|
after(async () => {
|
|
await db.prisma.$disconnect();
|
|
await database.stop();
|
|
});
|
|
|
|
describe('Frühere Konten', () => {
|
|
it('bringt eine nachgetragene SteamID auf dieselbe Form wie die Hauptangabe', async () => {
|
|
const player = await db.prisma.player.create({
|
|
data: { displayName: 'Umzügler', steamId: '76561198000001111' },
|
|
});
|
|
|
|
// In der Legacy-Schreibweise eingegeben, gespeichert wird die 64-Bit-Form.
|
|
await players.addAlias(player.id, 'STEAM_ID', 'STEAM_0:1:19867635', 'Alter Account', ctx);
|
|
|
|
const alias = await db.prisma.playerAlias.findFirstOrThrow({ where: { playerId: player.id } });
|
|
assert.equal(alias.value, '76561198000000999');
|
|
});
|
|
|
|
it('klappert beim Abgleich auch die früheren Konten ab', async () => {
|
|
const ids = await scraper.knownSteamIds();
|
|
const fuerUmzuegler = ids.filter((e) => e.steamId.startsWith('765611980000'));
|
|
|
|
assert.ok(
|
|
fuerUmzuegler.some((e) => e.steamId === '76561198000001111'),
|
|
'die aktuelle Kennung',
|
|
);
|
|
assert.ok(
|
|
fuerUmzuegler.some((e) => e.steamId === '76561198000000999'),
|
|
'und die frühere',
|
|
);
|
|
});
|
|
|
|
it('nimmt dieselbe Kennung nicht zweimal in den Lauf', async () => {
|
|
const ids = await scraper.knownSteamIds();
|
|
const eindeutig = new Set(ids.map((e) => e.steamId));
|
|
assert.equal(ids.length, eindeutig.size);
|
|
});
|
|
|
|
it('lässt ein Konto nicht zwei Spielern gehören', async () => {
|
|
const anderer = await db.prisma.player.create({ data: { displayName: 'Fremder' } });
|
|
|
|
await assert.rejects(
|
|
() => players.addAlias(anderer.id, 'STEAM_ID', '76561198000000999', undefined, ctx),
|
|
(error: Error & { code?: string }) => error.code === 'ALIAS_TAKEN',
|
|
);
|
|
});
|
|
|
|
it('weist die eigene Hauptangabe als Alias ab', async () => {
|
|
const player = await db.prisma.player.findFirstOrThrow({ where: { displayName: 'Umzügler' } });
|
|
|
|
await assert.rejects(
|
|
() => players.addAlias(player.id, 'STEAM_ID', '76561198000001111', undefined, ctx),
|
|
(error: Error & { code?: string }) => error.code === 'IS_PRIMARY',
|
|
);
|
|
});
|
|
|
|
it('weist Unsinn als SteamID ab', async () => {
|
|
const player = await db.prisma.player.findFirstOrThrow({ where: { displayName: 'Umzügler' } });
|
|
|
|
await assert.rejects(
|
|
() => players.addAlias(player.id, 'STEAM_ID', 'kein-account', undefined, ctx),
|
|
(error: Error & { code?: string }) => error.code === 'INVALID_STEAMID',
|
|
);
|
|
});
|
|
|
|
it('nimmt Forum-Namen ohne Umrechnung', async () => {
|
|
const player = await db.prisma.player.findFirstOrThrow({ where: { displayName: 'Umzügler' } });
|
|
const alias = await players.addAlias(player.id, 'FORUM_NAME', 'AlterName2019', undefined, ctx);
|
|
|
|
assert.equal(alias.value, 'AlterName2019');
|
|
});
|
|
});
|
|
|
|
describe('Eine SteamID gehört genau einem Spieler', () => {
|
|
it('nennt den Spieler, bei dem sie schon liegt', async () => {
|
|
await players.createPlayer(
|
|
{ displayName: 'Hat sie schon', steamId: '76561198000060001' },
|
|
ctx,
|
|
);
|
|
|
|
await assert.rejects(
|
|
() => players.createPlayer({ displayName: 'Will sie auch', steamId: '76561198000060001' }, ctx),
|
|
(error: Error & { code?: string }) => {
|
|
assert.equal(error.code, 'STEAMID_TAKEN');
|
|
assert.match(
|
|
error.message,
|
|
/Hat sie schon/,
|
|
'ohne den Namen sucht man von Hand durch den ganzen Bestand',
|
|
);
|
|
return true;
|
|
},
|
|
);
|
|
});
|
|
|
|
it('findet sie auch, wenn sie als früheres Konto hängt', async () => {
|
|
const umzuegler = await players.createPlayer(
|
|
{ displayName: 'Umgezogen', steamId: '76561198000060002' },
|
|
ctx,
|
|
);
|
|
await players.addAlias(umzuegler.id, 'STEAM_ID', '76561198000060003', 'Altes Konto', ctx);
|
|
|
|
await assert.rejects(
|
|
() => players.createPlayer({ displayName: 'Neuling', steamId: '76561198000060003' }, ctx),
|
|
(error: Error & { code?: string }) => {
|
|
assert.equal(error.code, 'STEAMID_TAKEN');
|
|
assert.match(error.message, /Umgezogen/);
|
|
assert.match(error.message, /früheres Konto/);
|
|
return true;
|
|
},
|
|
);
|
|
});
|
|
|
|
it('erkennt sie auch in einer anderen Schreibweise', async () => {
|
|
// STEAM_0:0:19897141 und 76561198000060010 sind dieselbe Kennung.
|
|
await players.createPlayer(
|
|
{ displayName: 'Legacy-Schreiber', steamId: '76561198000060010' },
|
|
ctx,
|
|
);
|
|
|
|
await assert.rejects(
|
|
() => players.createPlayer({ displayName: 'Doppelt', steamId: 'STEAM_0:0:19897141' }, ctx),
|
|
(error: Error & { code?: string }) => {
|
|
assert.equal(error.code, 'STEAMID_TAKEN');
|
|
assert.match(error.message, /Legacy-Schreiber/);
|
|
return true;
|
|
},
|
|
);
|
|
});
|
|
|
|
it('lässt die aktuelle Kennung eines anderen nicht als früheres Konto eintragen', async () => {
|
|
const einer = await players.createPlayer(
|
|
{ displayName: 'Aktueller Inhaber', steamId: '76561198000060004' },
|
|
ctx,
|
|
);
|
|
const anderer = await players.createPlayer(
|
|
{ displayName: 'Möchtegern', steamId: '76561198000060005' },
|
|
ctx,
|
|
);
|
|
|
|
await assert.rejects(
|
|
() => players.addAlias(anderer.id, 'STEAM_ID', '76561198000060004', undefined, ctx),
|
|
(error: Error & { code?: string }) => {
|
|
assert.equal(error.code, 'ALIAS_TAKEN');
|
|
assert.match(error.message, /Aktueller Inhaber/);
|
|
return true;
|
|
},
|
|
);
|
|
assert.ok(einer.id);
|
|
});
|
|
|
|
it('stört sich nicht an der eigenen Kennung beim Bearbeiten', async () => {
|
|
const spieler = await players.createPlayer(
|
|
{ displayName: 'Bleibt sich treu', steamId: '76561198000060006' },
|
|
ctx,
|
|
);
|
|
|
|
const geaendert = await players.updatePlayer(
|
|
spieler.id,
|
|
{ displayName: 'Neuer Name', steamId: '76561198000060006' },
|
|
ctx,
|
|
);
|
|
assert.equal(geaendert.displayName, 'Neuer Name');
|
|
});
|
|
});
|