Fix empty TTR preview and retain singles with missing ratings
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 58s

This commit is contained in:
Torsten Schulz (local)
2026-10-28 10:40:27 +01:00
parent 9f349ed7b5
commit c473b64150
2 changed files with 128 additions and 26 deletions

View File

@@ -0,0 +1,86 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import vm from 'node:vm';
import { calculateTtrChange } from '../src/services/ttrCalculator.mjs';
const source = readFileSync(new URL('../src/components/MatchReportApiDialog.vue', import.meta.url), 'utf8');
const script = source.match(/<script>([\s\S]*?)<\/script>/)[1]
.replace(/^import .*;\n/gm, '')
.replace('export default', 'globalThis.component =');
const requests = [];
const context = vm.createContext({ console, calculateTtrChange, apiClient: {
async post(url, body) {
requests.push({ url, body });
return { data: { players: [] } };
},
} });
vm.runInContext(script, context);
const { methods, computed } = context.component;
function dialog() {
return Object.assign({}, methods, {
results: [
{ label: 'D1-D1', homeName: 'Anton Schottdorf / Anna Wolf', guestName: 'Yumin Kim / Timo Engler' },
{ label: '1. Einzel der Runde', homeName: 'Anton Schottdorf', guestName: 'Yumin Kim', completed: false },
],
ttrSnapshots: {},
ttrPlayers: [],
});
}
test('singles with a D in their title are retained while double formation labels are excluded', () => {
const report = dialog();
assert.equal(report.isTtrDouble(report.results[0]), true);
assert.equal(report.isTtrDouble(report.results[1]), false);
assert.equal(report.isTtrDouble({ label: 'DA2 – DB2' }), true);
assert.equal(report.isTtrDouble({ label: 'Doppel 1' }), true);
assert.equal(report.isTtrDouble({ label: '3. Runde', matchType: 'SINGLE' }), false);
});
test('missing TTR values retain the single and are not treated as zero', () => {
const report = dialog();
report.applyTtrPreviewPlayers([
{ side: 'home', name: 'Anton Schottdorf', ttr: 1300 },
{ side: 'guest', name: 'Yumin Kim', ttr: null },
]);
const rows = computed.ttrSingles.call(report);
assert.equal(rows.length, 1);
assert.equal(rows[0].homeTtr, 1300);
assert.equal(rows[0].guestTtr, null);
assert.equal(rows[0].preview, null);
assert.equal(computed.ttrUnavailablePlayers.call(report)[0], 'Yumin Kim');
});
test('available ratings produce the preview and a completed single uses the entered result', () => {
const report = dialog();
report.applyTtrPreviewPlayers([
{ side: 'home', name: 'Anton Schottdorf', ttr: 1300 },
{ side: 'guest', name: 'Yumin Kim', ttr: 1300 },
]);
assert.equal(computed.ttrSingles.call(report)[0].preview.homeWin.displayChange, 8);
report.results[1].completed = true;
report.getPlayerSetWins = (_match, side) => side === 'home' ? 3 : 0;
const row = computed.ttrSingles.call(report)[0];
assert.equal(row.actual.home.displayChange, 8);
assert.equal(row.actual.guest.displayChange, -8);
});
test('standalone test mode calls the API and keeps real pairings without inventing ratings', async () => {
const report = dialog();
Object.assign(report, {
standaloneTest: true,
canOpenTtrPreview: true,
meetingDetails: {},
meetingData: {},
$store: { getters: { currentClub: 1 } },
ttrLineupPlayers: () => [],
});
await report.loadTtrPreview();
assert.equal(requests.at(-1).url, '/matches/ttr-preview/standalone');
assert.equal(report.ttrError, '');
const rows = computed.ttrSingles.call(report);
assert.equal(rows.length, 1);
assert.equal(rows[0].homeTtr, null);
assert.equal(rows[0].preview, null);
});