Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions hasura/functions/leaderboard/get_leaderboard.sql
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ $$;
-- therefore take no window, season, match type or source - a player's FACEIT
-- rating is what it is whether or not they played here this week, and filtering
-- one by "last 7 days" would empty the board rather than narrow it.
--
-- They do take one filter the other categories get for free by construction:
-- the board is OUR players. Importing a demo mints a players row for everyone
-- in the match, so without this the board fills up with strangers who have
-- never signed in here - a rating we scraped in passing, attached to someone
-- who is not on the platform. Signed in at least once AND played a match here.
CREATE OR REPLACE FUNCTION public._leaderboard_external_rank(_rating TEXT)
RETURNS SETOF public.leaderboard_entries
LANGUAGE plpgsql STABLE
Expand All @@ -168,7 +174,17 @@ BEGIN
0,
p.custom_avatar_url
FROM public.players p
WHERE p.faceit_elo IS NOT NULL
WHERE p.last_sign_in_at IS NOT NULL
AND EXISTS (
SELECT 1
FROM public.match_lineup_players mlp
JOIN public.match_lineups ml ON ml.id = mlp.match_lineup_id
JOIN public.matches m ON m.id = ml.match_id
WHERE mlp.steam_id = p.steam_id
AND m.source = '5stack'
AND m.status = 'Finished'
)
AND p.faceit_elo IS NOT NULL
ORDER BY p.faceit_elo DESC, p.name ASC;
ELSE
RETURN QUERY
Expand All @@ -183,9 +199,19 @@ BEGIN
0,
p.custom_avatar_url
FROM public.players p
-- The demo importer writes 0 for a player who has not placed this
-- season; ranked as a number that sorts as the worst rating in the game.
WHERE NULLIF(p.premier_rank, 0) IS NOT NULL
WHERE p.last_sign_in_at IS NOT NULL
AND EXISTS (
SELECT 1
FROM public.match_lineup_players mlp
JOIN public.match_lineups ml ON ml.id = mlp.match_lineup_id
JOIN public.matches m ON m.id = ml.match_id
WHERE mlp.steam_id = p.steam_id
AND m.source = '5stack'
AND m.status = 'Finished'
)
-- The demo importer writes 0 for a player who has not placed this
-- season; ranked as a number that sorts as the worst rating in the game.
AND NULLIF(p.premier_rank, 0) IS NOT NULL
ORDER BY p.premier_rank DESC, p.name ASC;
END IF;
END;
Expand Down
69 changes: 68 additions & 1 deletion test/external-rank-leaderboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,63 @@ describe("external rank leaderboard (SQL-driven)", () => {
db = await bootMigratedDb("ExternalRankLeaderboardTest");
postgres = db.postgres;
fx = new Fixtures(postgres, 76561196200000000n);
await fx.region("TestExternalRank");
}, 600_000);

afterAll(async () => {
await db?.stop();
});

beforeEach(async () => {
await postgres.query("DELETE FROM matches");
await postgres.query("DELETE FROM match_options");
await postgres.query("DELETE FROM players");
});

// A rated player who also belongs here: signed in at least once and played a
// match on this platform. Anyone who has not is off the board entirely.
const withRanks = async (ranks: {
name?: string;
faceitElo?: number | null;
faceitLevel?: number | null;
premierRank?: number | null;
signedIn?: boolean;
playedHere?: boolean;
}) => {
const steamId = await fx.player(ranks.name);
await postgres.query(
`UPDATE players
SET faceit_elo = $2,
faceit_skill_level = $3,
premier_rank = $4
premier_rank = $4,
last_sign_in_at = CASE WHEN $5 THEN now() ELSE NULL END
WHERE steam_id = $1::bigint`,
[
steamId,
ranks.faceitElo ?? null,
ranks.faceitLevel ?? null,
ranks.premierRank ?? null,
ranks.signedIn ?? true,
],
);

if (ranks.playedHere ?? true) {
await playAMatch(steamId);
}

return steamId;
};

const playAMatch = async (steamId: string, status = "Finished") => {
const match = await fx.match({ regions: ["TestExternalRank"] });
await fx.lineupPlayer(match.lineup_1_id, steamId);
await postgres.query("UPDATE matches SET status = $2 WHERE id = $1", [
match.id,
status,
]);
return match;
};

type Entry = {
player_steam_id: string;
player_name: string;
Expand Down Expand Up @@ -135,6 +159,49 @@ describe("external rank leaderboard (SQL-driven)", () => {
});
});

describe("who belongs on an external board", () => {
it("leaves out a rated player who has never signed in", async () => {
// an imported demo can mint a player row for someone who has no account
// here; their FACEIT rating is not ours to put on a board
await withRanks({ faceitElo: 3000, signedIn: false });
await withRanks({ premierRank: 25000, signedIn: false });

expect(await board("faceit_elo")).toHaveLength(0);
expect(await board("premier_rank")).toHaveLength(0);
});

it("leaves out a rated player who has never played here", async () => {
await withRanks({ faceitElo: 3000, playedHere: false });
await withRanks({ premierRank: 25000, playedHere: false });

expect(await board("faceit_elo")).toHaveLength(0);
expect(await board("premier_rank")).toHaveLength(0);
});

it("counts a player who has signed in and played", async () => {
await withRanks({ faceitElo: 3000 });
await withRanks({ premierRank: 25000 });

expect(await board("faceit_elo")).toHaveLength(1);
expect(await board("premier_rank")).toHaveLength(1);
});

it("does not count a match that never finished", async () => {
const player = await withRanks({ faceitElo: 2000, playedHere: false });
await playAMatch(player, "Canceled");

expect(await board("faceit_elo")).toHaveLength(0);
});

it("counts a player once however many matches they have played", async () => {
const player = await withRanks({ faceitElo: 2000 });
await playAMatch(player);
await playAMatch(player);

expect(await board("faceit_elo")).toHaveLength(1);
});
});

it("gives a player their rank on an external board", async () => {
await withRanks({ faceitElo: 3000 });
const middle = await withRanks({ faceitElo: 2000 });
Expand Down
Loading