mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
655 lines
15 KiB
TypeScript
655 lines
15 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
import { databaseTimestampNow } from "~/utils/dates";
|
|
import { dbInsertUsers, dbReset } from "~/utils/Test";
|
|
import * as ArtRepository from "../art/ArtRepository.server";
|
|
import * as CalendarRepository from "../calendar/CalendarRepository.server";
|
|
import * as TeamRepository from "../team/TeamRepository.server";
|
|
import * as TournamentOrganizationRepository from "../tournament-organization/TournamentOrganizationRepository.server";
|
|
import * as ImageRepository from "./ImageRepository.server";
|
|
|
|
let imageCounter = 0;
|
|
let teamCounter = 0;
|
|
let orgCounter = 0;
|
|
|
|
const createImage = async ({
|
|
submitterUserId,
|
|
validatedAt = null,
|
|
}: {
|
|
submitterUserId: number;
|
|
validatedAt?: number | null;
|
|
}) => {
|
|
imageCounter++;
|
|
const url = `image-${submitterUserId}-${imageCounter}.png`;
|
|
|
|
return ImageRepository.addNewImage({
|
|
submitterUserId,
|
|
url,
|
|
validatedAt,
|
|
type: "team-pfp",
|
|
});
|
|
};
|
|
|
|
const createTeam = async (ownerUserId: number) => {
|
|
teamCounter++;
|
|
const customUrl = `team-${teamCounter}`;
|
|
await TeamRepository.create({
|
|
name: `Team ${teamCounter}`,
|
|
customUrl,
|
|
ownerUserId,
|
|
isMainTeam: true,
|
|
});
|
|
const team = await TeamRepository.findByCustomUrl(customUrl);
|
|
if (!team) throw new Error("Team not found after creation");
|
|
return team;
|
|
};
|
|
|
|
const createOrganization = async (ownerId: number) => {
|
|
orgCounter++;
|
|
return TournamentOrganizationRepository.create({
|
|
name: `Org ${orgCounter}`,
|
|
ownerId,
|
|
});
|
|
};
|
|
|
|
const createCalendarEvent = async (authorId: number, avatarImgId?: number) => {
|
|
return CalendarRepository.create({
|
|
isFullTournament: false,
|
|
authorId,
|
|
badges: [],
|
|
bracketUrl: `https://example.com/bracket-${Date.now()}`,
|
|
description: null,
|
|
discordInviteCode: null,
|
|
name: `Event ${Date.now()}`,
|
|
organizationId: null,
|
|
startTimes: [databaseTimestampNow()],
|
|
tags: null,
|
|
mapPickingStyle: "AUTO_SZ",
|
|
bracketProgression: null,
|
|
deadlines: "DEFAULT",
|
|
rules: null,
|
|
avatarImgId,
|
|
});
|
|
};
|
|
|
|
describe("findById", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
await dbInsertUsers(3);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("finds image by id", async () => {
|
|
const img = await createImage({ submitterUserId: 1 });
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result?.tournamentId).toBeNull();
|
|
});
|
|
|
|
test("finds image with calendar event data", async () => {
|
|
const img = await createImage({ submitterUserId: 1 });
|
|
await createCalendarEvent(1, img.id);
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result?.tournamentId).toBeDefined();
|
|
});
|
|
|
|
test("returns undefined for non-existent image", async () => {
|
|
const result = await ImageRepository.findById(999);
|
|
|
|
expect(result).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("deleteImageById", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
await dbInsertUsers(2);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("deletes image by id", async () => {
|
|
const img = await createImage({ submitterUserId: 1 });
|
|
|
|
await ImageRepository.deleteImageById(img.id);
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
test("deletes associated art when deleting image", async () => {
|
|
imageCounter++;
|
|
const art = await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: Date.now(),
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const artsBefore = await ArtRepository.findArtsByUserId(1);
|
|
expect(artsBefore).toHaveLength(1);
|
|
expect(artsBefore[0].id).toBe(art.id);
|
|
|
|
const imgId = art.imgId;
|
|
|
|
await ImageRepository.deleteImageById(imgId);
|
|
|
|
const result = await ImageRepository.findById(imgId);
|
|
expect(result).toBeUndefined();
|
|
|
|
const artsAfter = await ArtRepository.findArtsByUserId(1);
|
|
expect(artsAfter).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe("countUnvalidatedArt", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
await dbInsertUsers(3);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("counts unvalidated art by author", async () => {
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const count = await ImageRepository.countUnvalidatedArt(1);
|
|
|
|
expect(count).toBe(2);
|
|
});
|
|
|
|
test("does not count validated art", async () => {
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: Date.now(),
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const count = await ImageRepository.countUnvalidatedArt(1);
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("returns 0 when author has no unvalidated art", async () => {
|
|
const count = await ImageRepository.countUnvalidatedArt(1);
|
|
|
|
expect(count).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("countAllUnvalidated", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
teamCounter = 0;
|
|
await dbInsertUsers(3);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("counts unvalidated images used in teams", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("counts unvalidated images used in art", async () => {
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("counts unvalidated images used in calendar events", async () => {
|
|
const img = await createImage({ submitterUserId: 1 });
|
|
await createCalendarEvent(1, img.id);
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("does not count validated images", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: Date.now(),
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(0);
|
|
});
|
|
|
|
test("counts multiple unvalidated images across different types", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 1,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(2);
|
|
});
|
|
|
|
test("returns 0 when no unvalidated images exist", async () => {
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
|
|
expect(count).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("countUnvalidatedBySubmitterUserId", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
teamCounter = 0;
|
|
await dbInsertUsers(3);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("counts unvalidated team images by submitter", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countUnvalidatedBySubmitterUserId(1);
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("does not count validated images", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: Date.now(),
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countUnvalidatedBySubmitterUserId(1);
|
|
|
|
expect(count).toBe(0);
|
|
});
|
|
|
|
test("does not count images from other submitters", async () => {
|
|
const team1 = await createTeam(1);
|
|
const team2 = await createTeam(2);
|
|
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team1-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team1.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 2,
|
|
url: `team2-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team2.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countUnvalidatedBySubmitterUserId(1);
|
|
|
|
expect(count).toBe(1);
|
|
});
|
|
|
|
test("returns 0 when user has no unvalidated team images", async () => {
|
|
const count = await ImageRepository.countUnvalidatedBySubmitterUserId(1);
|
|
|
|
expect(count).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("validateImage", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
await dbInsertUsers(2);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("marks image as validated", async () => {
|
|
const img = await createImage({ submitterUserId: 1 });
|
|
|
|
await ImageRepository.validateImage(img.id);
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
expect(result).toBeDefined();
|
|
});
|
|
|
|
test("validated image is not included in unvalidated count", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
const img = await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const countBefore = await ImageRepository.countAllUnvalidated();
|
|
expect(countBefore).toBe(1);
|
|
|
|
await ImageRepository.validateImage(img.id);
|
|
|
|
const countAfter = await ImageRepository.countAllUnvalidated();
|
|
expect(countAfter).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("unvalidatedImages", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
teamCounter = 0;
|
|
await dbInsertUsers(10);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("fetches unvalidated images with submitter info", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
const filename = `team-avatar-${imageCounter}.png`;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: filename,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const result = await ImageRepository.unvalidatedImages();
|
|
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0].submitterUserId).toBe(1);
|
|
expect(result[0].username).toBe("user1");
|
|
expect(result[0].url).toBe(`http://127.0.0.1:9000/sendou/${filename}`);
|
|
});
|
|
|
|
test("does not fetch validated images", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: Date.now(),
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const result = await ImageRepository.unvalidatedImages();
|
|
|
|
expect(result).toHaveLength(0);
|
|
});
|
|
|
|
test("fetches images from teams, art, and calendar events", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
imageCounter++;
|
|
await ArtRepository.insert({
|
|
authorId: 2,
|
|
url: `art-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
description: null,
|
|
linkedUsers: [],
|
|
tags: [],
|
|
});
|
|
|
|
const img2 = await createImage({ submitterUserId: 3 });
|
|
await createCalendarEvent(3, img2.id);
|
|
|
|
const result = await ImageRepository.unvalidatedImages();
|
|
|
|
expect(result).toHaveLength(3);
|
|
});
|
|
|
|
test("respects the max unvalidated images to show at once for approval limit constant", async () => {
|
|
for (let i = 0; i < 10; i++) {
|
|
const teamOwnerId = i + 1;
|
|
const team = await createTeam(teamOwnerId);
|
|
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: teamOwnerId,
|
|
url: `team-avatar-${i}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
}
|
|
|
|
const result = await ImageRepository.unvalidatedImages();
|
|
|
|
expect(result.length).toBe(5);
|
|
});
|
|
|
|
test("returns empty array when no unvalidated images exist", async () => {
|
|
const result = await ImageRepository.unvalidatedImages();
|
|
|
|
expect(result).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe("addNewImage", () => {
|
|
beforeEach(async () => {
|
|
imageCounter = 0;
|
|
teamCounter = 0;
|
|
orgCounter = 0;
|
|
await dbInsertUsers(3);
|
|
});
|
|
|
|
afterEach(() => {
|
|
dbReset();
|
|
});
|
|
|
|
test("creates image for team avatar", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
const filename = `team-avatar-${imageCounter}.png`;
|
|
|
|
const img = await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: filename,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
expect(img.url).toBe(filename);
|
|
expect(img.submitterUserId).toBe(1);
|
|
expect(img.validatedAt).toBeNull();
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
expect(result).toBeDefined();
|
|
});
|
|
|
|
test("creates image for team banner", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
const filename = `team-banner-${imageCounter}.png`;
|
|
|
|
const img = await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: filename,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-banner",
|
|
});
|
|
|
|
expect(img.url).toBe(filename);
|
|
expect(img.submitterUserId).toBe(1);
|
|
expect(img.validatedAt).toBeNull();
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
expect(result).toBeDefined();
|
|
});
|
|
|
|
test("creates image for organization avatar", async () => {
|
|
const org = await createOrganization(1);
|
|
imageCounter++;
|
|
const filename = `org-avatar-${imageCounter}.png`;
|
|
|
|
const img = await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: filename,
|
|
validatedAt: null,
|
|
organizationId: org.id,
|
|
type: "org-pfp",
|
|
});
|
|
|
|
expect(img.url).toBe(filename);
|
|
expect(img.submitterUserId).toBe(1);
|
|
expect(img.validatedAt).toBeNull();
|
|
|
|
const result = await ImageRepository.findById(img.id);
|
|
expect(result).toBeDefined();
|
|
});
|
|
|
|
test("creates validated image when validatedAt is provided", async () => {
|
|
const team = await createTeam(1);
|
|
const validatedAt = Date.now();
|
|
imageCounter++;
|
|
|
|
const img = await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
expect(img.validatedAt).toBe(validatedAt);
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
expect(count).toBe(0);
|
|
});
|
|
|
|
test("creates unvalidated image when validatedAt is null", async () => {
|
|
const team = await createTeam(1);
|
|
imageCounter++;
|
|
|
|
await ImageRepository.addNewImage({
|
|
submitterUserId: 1,
|
|
url: `team-avatar-${imageCounter}.png`,
|
|
validatedAt: null,
|
|
teamId: team.id,
|
|
type: "team-pfp",
|
|
});
|
|
|
|
const count = await ImageRepository.countAllUnvalidated();
|
|
expect(count).toBe(1);
|
|
});
|
|
});
|