Bei einer belegten SteamID sagen, wem sie gehoert
"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.
This commit is contained in:
@@ -192,11 +192,49 @@ function canonicalSteamId(input: string | null | undefined): string | null {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
async function assertSteamIdFree(steamId: string, exceptId?: number): Promise<void> {
|
||||
const existing = await prisma.player.findUnique({ where: { steamId }, select: { id: true } });
|
||||
if (existing && existing.id !== exceptId) {
|
||||
throw conflict('STEAMID_TAKEN', 'Diese SteamID ist bereits einem Spieler zugeordnet');
|
||||
/**
|
||||
* Wer diese SteamID schon führt - als Hauptangabe oder als früheres Konto.
|
||||
*
|
||||
* Beides muss geprüft werden: Eine Kennung, die bei einem Spieler als
|
||||
* früheres Konto hängt, gehört ihm genauso. Stünde sie daneben bei einem
|
||||
* anderen als Hauptangabe, wüsste weder der Abgleich noch der Import, wem
|
||||
* ein Kauf gehört.
|
||||
*/
|
||||
async function findeSteamIdInhaber(
|
||||
steamId: string,
|
||||
exceptId?: number,
|
||||
): Promise<{ id: number; displayName: string; alsAlias: boolean } | null> {
|
||||
const haupt = await prisma.player.findUnique({
|
||||
where: { steamId },
|
||||
select: { id: true, displayName: true },
|
||||
});
|
||||
if (haupt && haupt.id !== exceptId) return { ...haupt, alsAlias: false };
|
||||
|
||||
const alias = await prisma.playerAlias.findUnique({
|
||||
where: { type_value: { type: AliasType.STEAM_ID, value: steamId } },
|
||||
select: { playerId: true, player: { select: { displayName: true } } },
|
||||
});
|
||||
if (alias && alias.playerId !== exceptId) {
|
||||
return { id: alias.playerId, displayName: alias.player.displayName, alsAlias: true };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stellt sicher, dass die Kennung frei ist - und sagt sonst, bei wem sie
|
||||
* liegt. Ohne den Namen sucht man von Hand durch den ganzen Bestand.
|
||||
*/
|
||||
async function assertSteamIdFree(steamId: string, exceptId?: number): Promise<void> {
|
||||
const inhaber = await findeSteamIdInhaber(steamId, exceptId);
|
||||
if (!inhaber) return;
|
||||
|
||||
throw conflict(
|
||||
'STEAMID_TAKEN',
|
||||
inhaber.alsAlias
|
||||
? `Diese SteamID ist bei "${inhaber.displayName}" als früheres Konto eingetragen`
|
||||
: `Diese SteamID gehört bereits zu "${inhaber.displayName}"`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function createPlayer(input: PlayerInput, ctx: ActionContext) {
|
||||
@@ -419,6 +457,21 @@ export async function addAlias(
|
||||
);
|
||||
}
|
||||
|
||||
// Auch die Hauptangaben der anderen: dieselbe Kennung kann nicht bei einem
|
||||
// als früheres Konto und beim nächsten als aktuelles stehen.
|
||||
if (type === AliasType.STEAM_ID) {
|
||||
const fremd = await prisma.player.findUnique({
|
||||
where: { steamId: value },
|
||||
select: { id: true, displayName: true },
|
||||
});
|
||||
if (fremd && fremd.id !== playerId) {
|
||||
throw conflict(
|
||||
'ALIAS_TAKEN',
|
||||
`Diese SteamID ist die aktuelle Kennung von "${fremd.displayName}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const created = await prisma.playerAlias.create({
|
||||
data: { playerId, type, value, note: note?.trim() || null },
|
||||
});
|
||||
|
||||
@@ -100,3 +100,95 @@ describe('Frühere Konten', () => {
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user