Show non-eliminated loser's manager tag in Scored Matches notifications #136
2 changed files with 41 additions and 3 deletions
|
|
@ -1940,8 +1940,10 @@ export async function recalculateAffectedLeagues(
|
||||||
// in the World Cup) does not qualify on its own — their owner hasn't earned anything yet.
|
// in the World Cup) does not qualify on its own — their owner hasn't earned anything yet.
|
||||||
// When a match qualifies because the loser is owned, the winner's manager tag is still
|
// When a match qualifies because the loser is owned, the winner's manager tag is still
|
||||||
// shown for context (who beat them), but the winner is not Discord-pinged.
|
// shown for context (who beat them), but the winner is not Discord-pinged.
|
||||||
// Losers who advance to another match (loserAdvances=true, e.g. NBA 7v8 → PIR2) have
|
// Both managers' tags are always shown for context when their teams are drafted; the
|
||||||
// showLoser=false and are correctly suppressed.
|
// showLoser flag (isLoserNotifiable) only gates whether the loser is @-pinged — a loser
|
||||||
|
// who advanced rather than being eliminated (loserAdvances=true, e.g. NBA 7v8 → PIR2, or
|
||||||
|
// a World Cup semifinal loser) is named but not pinged.
|
||||||
let scoredMatches: ScoredMatch[] | undefined;
|
let scoredMatches: ScoredMatch[] | undefined;
|
||||||
if (allCompletedMatches.length > 0) {
|
if (allCompletedMatches.length > 0) {
|
||||||
const relevant = allCompletedMatches.filter(
|
const relevant = allCompletedMatches.filter(
|
||||||
|
|
@ -1974,7 +1976,12 @@ export async function recalculateAffectedLeagues(
|
||||||
winnerName: x.m.winnerName ?? "",
|
winnerName: x.m.winnerName ?? "",
|
||||||
loserName: x.m.loserName ?? "",
|
loserName: x.m.loserName ?? "",
|
||||||
winnerUsername: x.winnerOwnerId ? usernameByUserId.get(x.winnerOwnerId) : undefined,
|
winnerUsername: x.winnerOwnerId ? usernameByUserId.get(x.winnerOwnerId) : undefined,
|
||||||
loserUsername: x.showLoser && x.loserOwnerId ? usernameByUserId.get(x.loserOwnerId) : undefined,
|
// Show the loser's manager tag whenever their team is drafted, mirroring the
|
||||||
|
// winner above — even when the loser advances rather than being eliminated
|
||||||
|
// (World Cup semifinal → 3rd-place playoff, AFL Qualifying Final → Semi Final).
|
||||||
|
// The @-ping stays gated by showLoser (loserDiscordUserId below): a still-alive
|
||||||
|
// loser who neither scored nor was eliminated is named for context but not pinged.
|
||||||
|
loserUsername: x.loserOwnerId ? usernameByUserId.get(x.loserOwnerId) : undefined,
|
||||||
winnerDiscordUserId: x.winnerScoreChanged && x.winnerOwnerId ? discordIdByUserId.get(x.winnerOwnerId) : undefined,
|
winnerDiscordUserId: x.winnerScoreChanged && x.winnerOwnerId ? discordIdByUserId.get(x.winnerOwnerId) : undefined,
|
||||||
loserDiscordUserId: x.showLoser && x.loserOwnerId ? discordIdByUserId.get(x.loserOwnerId) : undefined,
|
loserDiscordUserId: x.showLoser && x.loserOwnerId ? discordIdByUserId.get(x.loserOwnerId) : undefined,
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,37 @@ describe("sendStandingsUpdateNotification", () => {
|
||||||
expect(desc).toContain("• **Sporting (christhrowsrocks)** def. Bodø/Glimt (apatel)");
|
expect(desc).toContain("• **Sporting (christhrowsrocks)** def. Bodø/Glimt (apatel)");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("names a non-eliminated loser for context without @-pinging them", async () => {
|
||||||
|
// Argentina beats England in the World Cup semifinal. Argentina scored, so it's
|
||||||
|
// pinged; England advances to the 3rd-place playoff (not eliminated, no points
|
||||||
|
// change), so its manager is shown by plain username but NOT @-pinged.
|
||||||
|
await sendStandingsUpdateNotification({
|
||||||
|
webhookUrl: WEBHOOK_URL,
|
||||||
|
seasonName: "Diablo League 2026",
|
||||||
|
standings: [{ teamId: "a", teamName: "Alpha", totalPoints: 160, rank: 7 }],
|
||||||
|
previousStandings: new Map([["a", 130]]),
|
||||||
|
scoredMatches: [
|
||||||
|
{
|
||||||
|
winnerName: "Argentina",
|
||||||
|
loserName: "England",
|
||||||
|
winnerUsername: "philosohraptors",
|
||||||
|
winnerDiscordUserId: "111",
|
||||||
|
loserUsername: "elementsoul",
|
||||||
|
// no loserDiscordUserId — still alive, no ping
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = getPayload();
|
||||||
|
const desc = payload.embeds[0].description as string;
|
||||||
|
// Winner scored → rendered as an @-mention; loser is named by plain username.
|
||||||
|
expect(desc).toContain("• **Argentina (<@111>)** def. England (elementsoul)");
|
||||||
|
// England's manager is named but not mentioned/pinged.
|
||||||
|
expect(desc).not.toContain("England (<@");
|
||||||
|
expect(payload.content ?? "").toContain("<@111>");
|
||||||
|
expect(payload.content ?? "").not.toContain("elementsoul");
|
||||||
|
});
|
||||||
|
|
||||||
it("shows winner's manager for context when the match fires due to an owned loser", async () => {
|
it("shows winner's manager for context when the match fires due to an owned loser", async () => {
|
||||||
// Brazil beats Japan (R32, non-scoring). Japan's manager is the reason for the
|
// Brazil beats Japan (R32, non-scoring). Japan's manager is the reason for the
|
||||||
// notification; Brazil's manager is shown for context even though they didn't score.
|
// notification; Brazil's manager is shown for context even though they didn't score.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue