Session 54: Audit cleanup — name edges + polish (2255 tests)
P1 name edge cases (BOTH playerName.js copies, kept identical): - normalizeName strips hyphens (display+key): "Jung-hoo Lee" === "Jung Hoo Lee". - nameKey strips single-letter MIDDLE tokens: "Josh H Smith" === "Josh Smith" (keeps first+last; real middle names + collapsed initials untouched). - richie -> richard added to NICKNAMES. P2 polish: - Team Hub names normalized at the source (teamService.getTeamHub) so "J.C. Escarra" renders as "JC Escarra" like the dashboard. - snapshotService dedup keeps the highest-confidence GRADE but the richest DISPLAY (accented "José" over "Jose") so prop rows match the pitcher line. - correlationWarning names the game: "2 legs from the same game (NYY @ BOS)". Backend 2246 -> 2255 tests (+9), 194 suites. Web build clean (exit 0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// Session 54 — audit cleanup: name edge cases (hyphen, middle initial, richie)
|
||||
// + accent-keeping dedup + correlation copy.
|
||||
|
||||
const be = require('../../src/utils/playerName');
|
||||
const fe = require('../../web/src/lib/playerName');
|
||||
const parlay = require('../../src/services/parlayService');
|
||||
|
||||
describe('Phase 1 — name edge cases', () => {
|
||||
it('merges hyphenated vs spaced ("Jung-hoo Lee" === "Jung Hoo Lee")', () => {
|
||||
expect(be.nameKey('Jung-hoo Lee')).toBe(be.nameKey('Jung Hoo Lee'));
|
||||
});
|
||||
it('strips middle initials ("Josh H Smith" === "Josh Smith")', () => {
|
||||
expect(be.nameKey('Josh H Smith')).toBe(be.nameKey('Josh Smith'));
|
||||
});
|
||||
it('resolves richie ("Richie Palacios" === "Richard Palacios")', () => {
|
||||
expect(be.nameKey('Richie Palacios')).toBe(be.nameKey('Richard Palacios'));
|
||||
});
|
||||
it('frontend + backend copies agree on the new cases', () => {
|
||||
for (const n of ['Jung-hoo Lee', 'Jung Hoo Lee', 'Josh H Smith', 'Richie Palacios', 'José Soriano', 'JC Escarra']) {
|
||||
expect(fe.nameKey(n)).toBe(be.nameKey(n));
|
||||
expect(fe.normalizeName(n).display).toBe(be.normalizeName(n).display);
|
||||
}
|
||||
});
|
||||
|
||||
// Guard against over-merging distinct players.
|
||||
it('does not strip real middle names ("Juan Carlos Smith" kept)', () => {
|
||||
expect(be.nameKey('Juan Carlos Smith')).toBe('juan carlos smith');
|
||||
});
|
||||
it('keeps distinct players distinct', () => {
|
||||
expect(be.nameKey('Aaron Judge')).not.toBe(be.nameKey('Aaron Nola'));
|
||||
});
|
||||
it('display keeps accents ("José Soriano")', () => {
|
||||
expect(be.normalizeName('José Soriano').display).toBe('José Soriano');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Phase 2 — correlation copy includes the game id', () => {
|
||||
it('same-game (different teams) warning names the game', () => {
|
||||
const w = parlay.correlationWarning([
|
||||
{ player: 'A', team: 'NYY', game: 'NYY @ BOS' },
|
||||
{ player: 'B', team: 'BOS', game: 'NYY @ BOS' },
|
||||
]);
|
||||
expect(w).toBe('⚠ 2 legs from the same game (NYY @ BOS) — correlated');
|
||||
});
|
||||
});
|
||||
@@ -64,7 +64,7 @@ describe('correlationWarning', () => {
|
||||
});
|
||||
it('flags same-game legs on different teams', () => {
|
||||
expect(svc.correlationWarning([{ game: 'g', team: 'A', player: 'x' }, { game: 'g', team: 'B', player: 'y' }]))
|
||||
.toBe('⚠ 2 legs from the same game — correlated');
|
||||
.toBe('⚠ 2 legs from the same game (g) — correlated');
|
||||
});
|
||||
it('null when all legs are independent', () => {
|
||||
expect(svc.correlationWarning([{ game: 'g1', team: 'A', player: 'x' }, { game: 'g2', team: 'B', player: 'y' }])).toBeNull();
|
||||
|
||||
@@ -63,6 +63,17 @@ describe('getTeamHub (MLB, injected)', () => {
|
||||
expect(await svc.getTeamHub('mlb', 'ZZZ', { mlbAdapter, cacheGet: cache.cacheGet, cacheSet: cache.cacheSet })).toBeNull();
|
||||
});
|
||||
|
||||
it('normalizes roster player display names (no dots) — Session 54', async () => {
|
||||
const dotted = {
|
||||
...mlbAdapter,
|
||||
async getTeamRoster() { return [{ id: 99, name: 'J.C. Escarra', position: 'C' }]; },
|
||||
async getSeasonAverages() { return null; },
|
||||
};
|
||||
const cache = memCache({ 'grades:mlb': { grades: [] } });
|
||||
const hub = await svc.getTeamHub('mlb', 'NYY', { mlbAdapter: dotted, cacheGet: cache.cacheGet, cacheSet: cache.cacheSet });
|
||||
expect(hub.roster[0].player).toBe('JC Escarra');
|
||||
});
|
||||
|
||||
it('caches the assembled hub (writes teamhub:{sport}:{abbr})', async () => {
|
||||
const cache = memCache({ 'grades:mlb': gradesEnv });
|
||||
await svc.getTeamHub('mlb', 'NYY', { mlbAdapter, cacheGet: cache.cacheGet, cacheSet: cache.cacheSet });
|
||||
|
||||
Reference in New Issue
Block a user