Fix MLB division leaders showing under wildcard #84
2 changed files with 33 additions and 0 deletions
|
|
@ -232,6 +232,23 @@ describe("MlbStandingsAdapter", () => {
|
||||||
expect(ori?.externalTeamId).toBe("2");
|
expect(ori?.externalTeamId).toBe("2");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("assigns divisionRank 1 to the division leader and 2 to the next", async () => {
|
||||||
|
vi.mocked(fetch).mockResolvedValueOnce({
|
||||||
|
ok: true,
|
||||||
|
json: async () => SAMPLE_ESPN_RESPONSE,
|
||||||
|
} as Response);
|
||||||
|
|
||||||
|
const adapter = new MlbStandingsAdapter();
|
||||||
|
const records = await adapter.fetchStandings();
|
||||||
|
|
||||||
|
const ori = records.find((r) => r.teamName === "Baltimore Orioles");
|
||||||
|
const bos = records.find((r) => r.teamName === "Boston Red Sox");
|
||||||
|
const mets = records.find((r) => r.teamName === "New York Mets");
|
||||||
|
expect(ori?.divisionRank).toBe(1);
|
||||||
|
expect(bos?.divisionRank).toBe(2);
|
||||||
|
expect(mets?.divisionRank).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
it("never sets otLosses (MLB has no OT losses)", async () => {
|
it("never sets otLosses (MLB has no OT losses)", async () => {
|
||||||
vi.mocked(fetch).mockResolvedValueOnce({
|
vi.mocked(fetch).mockResolvedValueOnce({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,21 @@ export class MlbStandingsAdapter implements StandingsSyncAdapter {
|
||||||
sm: statsMap(entry.stats),
|
sm: statsMap(entry.stats),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Compute divisionRank: rank each team within its own division by win/loss.
|
||||||
|
const divisionRankMap = new Map<string, number>();
|
||||||
|
const divisionGroups = new Map<string, typeof withSm>();
|
||||||
|
for (const item of withSm) {
|
||||||
|
const key = item.division;
|
||||||
|
if (!divisionGroups.has(key)) divisionGroups.set(key, []);
|
||||||
|
divisionGroups.get(key)?.push(item);
|
||||||
|
}
|
||||||
|
for (const divEntries of divisionGroups.values()) {
|
||||||
|
// Use the ESPN entry order within each division — ESPN already applies correct tiebreakers.
|
||||||
|
divEntries.forEach((e, i) => {
|
||||||
|
divisionRankMap.set(e.entry.team.id, i + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const sorted = [...withSm].toSorted(sortByWinLoss);
|
const sorted = [...withSm].toSorted(sortByWinLoss);
|
||||||
|
|
||||||
return sorted.map(({ entry, conference, division, sm }, leagueIdx): FetchedStandingsRecord => {
|
return sorted.map(({ entry, conference, division, sm }, leagueIdx): FetchedStandingsRecord => {
|
||||||
|
|
@ -76,6 +91,7 @@ export class MlbStandingsAdapter implements StandingsSyncAdapter {
|
||||||
conference: abbreviateLeague(conference),
|
conference: abbreviateLeague(conference),
|
||||||
division: abbreviatedDiv || undefined,
|
division: abbreviatedDiv || undefined,
|
||||||
conferenceRank: parseConferenceRank(sm),
|
conferenceRank: parseConferenceRank(sm),
|
||||||
|
divisionRank: divisionRankMap.get(entry.team.id),
|
||||||
leagueRank: leagueIdx + 1,
|
leagueRank: leagueIdx + 1,
|
||||||
streak,
|
streak,
|
||||||
lastTen,
|
lastTen,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue