Files
sendou.ink/app/features/user-activity/core/UserActivity.server.test.ts

129 lines
3.9 KiB
TypeScript

import { subHours } from "date-fns";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { backdate } from "~/db/seed/core/backdate";
import * as SQGroupFactory from "~/db/seed/factories/SQGroupFactory";
import * as UserFactory from "~/db/seed/factories/UserFactory";
import { refreshSendouQInstance } from "~/features/sendouq/core/SendouQ.server";
import { RunningTournaments } from "~/features/tournament-bracket/core/RunningTournaments.server";
import { runningTournamentWithMatch } from "~/features/tournament-bracket/core/tests/test-utils";
import * as UserActivity from "./UserActivity.server";
const { mockSeasonCurrentOrPrevious } = vi.hoisted(() => ({
mockSeasonCurrentOrPrevious: vi.fn(() => ({
nth: 1,
starts: new Date("2023-01-01"),
ends: new Date("2030-12-31"),
})),
}));
vi.mock("~/features/mmr/core/Seasons", () => ({
currentOrPrevious: mockSeasonCurrentOrPrevious,
}));
/** Users are interchangeable here, so tests name them by 1-based position. */
const users = UserFactory.pool();
describe("UserActivity.resolve", () => {
beforeEach(async () => {
await users.create(8);
RunningTournaments.clear();
await refreshSendouQInstance();
});
test("returns empty activity for a user doing nothing", () => {
const activity = UserActivity.resolve(users.id(1));
expect(activity.sendouq).toBeNull();
expect(activity.tournaments).toEqual([]);
});
test("resolves the user's SendouQ group with its received like count", async () => {
const likerGroup = await SQGroupFactory.create({
memberUserIds: [users.id(5)],
});
const group = await SQGroupFactory.create(
{ memberUserIds: [users.id(1), users.id(2)] },
{ likedByGroupIds: [likerGroup.id] },
);
await refreshSendouQInstance();
const activity = UserActivity.resolve(users.id(1));
expect(activity.sendouq?.group.id).toBe(group.id);
expect(activity.sendouq?.likesReceivedCount).toBe(1);
expect(activity.sendouq?.expired).toBe(false);
});
test("a given like does not count as received", async () => {
const likerGroup = await SQGroupFactory.create({
memberUserIds: [users.id(5)],
});
await SQGroupFactory.create(
{ memberUserIds: [users.id(1)] },
{ likedByGroupIds: [likerGroup.id] },
);
await refreshSendouQInstance();
expect(UserActivity.resolve(users.id(5)).sendouq?.likesReceivedCount).toBe(
0,
);
});
test("marks a group inactive for too long as expired", async () => {
const group = await SQGroupFactory.create({
memberUserIds: [users.id(1)],
});
await backdate("Group", group.id, {
latestActionAt: subHours(new Date(), 2),
});
await refreshSendouQInstance();
expect(UserActivity.resolve(users.id(1)).sendouq?.expired).toBe(true);
});
test("resolves running tournament statuses", () => {
RunningTournaments.add(
runningTournamentWithMatch({
tournamentId: 1,
teamOneUserIds: [users.id(1)],
teamTwoUserIds: [users.id(2)],
}),
);
const activity = UserActivity.resolve(users.id(1));
expect(activity.tournaments).toHaveLength(1);
expect(activity.tournaments[0].status.type).toBe("MATCH");
});
test("omits leagues, whose matches are not something the user is doing right now", () => {
RunningTournaments.add(
runningTournamentWithMatch({
tournamentId: 1,
teamOneUserIds: [users.id(1)],
teamTwoUserIds: [users.id(2)],
isLeague: true,
}),
);
expect(UserActivity.resolve(users.id(1)).tournaments).toEqual([]);
});
test("resolves SendouQ and tournament activity at the same time", async () => {
await SQGroupFactory.create({ memberUserIds: [users.id(1)] });
await refreshSendouQInstance();
RunningTournaments.add(
runningTournamentWithMatch({
tournamentId: 1,
teamOneUserIds: [users.id(1)],
teamTwoUserIds: [users.id(2)],
}),
);
const activity = UserActivity.resolve(users.id(1));
expect(activity.sendouq).not.toBeNull();
expect(activity.tournaments).toHaveLength(1);
});
});