Skip to content

Commit

Permalink
fix(server): Fix bug when matching double elim playoff matches 2-13 (#72
Browse files Browse the repository at this point in the history
)

Co-authored-by: Evan Strat <[email protected]>
  • Loading branch information
evan10s and evan10s authored Nov 1, 2023
1 parent 335609f commit 99aeacb
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 21 deletions.
15 changes: 1 addition & 14 deletions server/spec/tests/repos/JsonStorageRepo.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
/* globals describe expect expectAsync it */
import mockFs from "mock-fs";
import { type ISettings } from "@src/models/Settings";
import { readSettingsJson } from "@src/repos/JsonStorageRepo";

const sampleSettings: ISettings = {
eventName: "Example Event",
eventTbaCode: "2023gacmp",
videoSearchDirectory: "./videos",
googleAuthStatus: "",
googleClientId: "",
playoffsType: "Double elimination playoff",
sandboxModeEnabled: false,
youTubeVideoPrivacy: "private",
linkVideosOnTheBlueAlliance: false,
};
import { sampleSettings } from "../util";

describe("readSettingsJson", () => {
it("should throw if settings file doesn't exist", async () => {
Expand Down
51 changes: 51 additions & 0 deletions server/spec/tests/repos/MatchKey.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { CompLevel } from "@src/models/CompLevel";
import MatchKey from "@src/models/MatchKey";
import { PlayoffsType } from "@src/models/PlayoffsType";

describe("MatchKey", () => {
it("should parse a valid qualification match key", () => {
const matchkey = MatchKey.fromString("2023gadal_qm16", PlayoffsType.DoubleElimination);
expect(matchkey.compLevel).toEqual(CompLevel.Qualification);
expect(matchkey.eventCode).toEqual("gadal");
expect(matchkey.matchNumber).toEqual(16);
expect(matchkey.setNumber).toBeNull();
expect(matchkey.year).toEqual(2023);
});

it("should parse valid double elimination playoff match keys", () => {
const sf1m1 = MatchKey.fromString("2023gadal_sf1m1", PlayoffsType.DoubleElimination);
expect(sf1m1.compLevel).toEqual(CompLevel.Semifinal);
expect(sf1m1.eventCode).toEqual("gadal");
expect(sf1m1.matchNumber).toEqual(1);
expect(sf1m1.setNumber).toEqual(1);
expect(sf1m1.year).toEqual(2023);

const sf2m1 = MatchKey.fromString("2023gadal_sf2m1", PlayoffsType.DoubleElimination);
expect(sf2m1.compLevel).toEqual(CompLevel.Semifinal);
expect(sf2m1.eventCode).toEqual("gadal");
expect(sf2m1.matchNumber).toEqual(1);
expect(sf2m1.setNumber).toEqual(2);
expect(sf2m1.year).toEqual(2023);

const f1m1 = MatchKey.fromString("2023gadal_f1m1", PlayoffsType.DoubleElimination);
expect(f1m1.compLevel).toEqual(CompLevel.Final);
expect(f1m1.eventCode).toEqual("gadal");
expect(f1m1.matchNumber).toEqual(1);
expect(f1m1.setNumber).toEqual(1);
expect(f1m1.year).toEqual(2023);

const f1m2 = MatchKey.fromString("2023gadal_f1m2", PlayoffsType.DoubleElimination);
expect(f1m2.compLevel).toEqual(CompLevel.Final);
expect(f1m2.eventCode).toEqual("gadal");
expect(f1m2.matchNumber).toEqual(2);
expect(f1m2.setNumber).toEqual(1);
expect(f1m2.year).toEqual(2023);

const f1m3 = MatchKey.fromString("2023gadal_f1m3", PlayoffsType.DoubleElimination);
expect(f1m3.compLevel).toEqual(CompLevel.Final);
expect(f1m3.eventCode).toEqual("gadal");
expect(f1m3.matchNumber).toEqual(3);
expect(f1m3.setNumber).toEqual(1);
expect(f1m3.year).toEqual(2023);
});
});
30 changes: 30 additions & 0 deletions server/spec/tests/repos/MatchesServices.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Test getLocalVideoFilesForMatch function, using mockFs
import { getLocalVideoFilesForMatch } from "@src/services/MatchesService";
import MatchKey from "@src/models/MatchKey";
import { PlayoffsType } from "@src/models/PlayoffsType";
import mockFs from "mock-fs";
import { sampleSettings } from "../util";

const sampleVideos = {
"Qualification 1.mp4": "",
"Qualification 2.mp4": "",
"Qualification 10.mp4": "",
"Playoff 1.mp4": "",
"Playoff 2.mp4": "",
"Playoff 10.mp4": "",
};

describe("MatchesService", () => {
it("should return an empty array if no files are found", async () => {
mockFs({
videos: sampleVideos,
"settings/settings.example.json": JSON.stringify(sampleSettings),
});

const files = await getLocalVideoFilesForMatch(
MatchKey.fromString("2023gadal_qm16", PlayoffsType.DoubleElimination),
);
expect(files).toEqual([]);
mockFs.restore();
});
});
14 changes: 14 additions & 0 deletions server/spec/tests/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type ISettings } from "@src/models/Settings";

export const sampleSettings: ISettings = {
eventName: "Example Event",
eventTbaCode: "2023gacmp",
videoSearchDirectory: "./videos",
googleAuthStatus: "",
googleClientId: "",
playoffsType: "Double elimination playoff",
sandboxModeEnabled: false,
youTubeVideoPrivacy: "private",
linkVideosOnTheBlueAlliance: false,
useFrcEventsApi: false,
};
20 changes: 13 additions & 7 deletions server/src/services/MatchesService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ import { type TbaFrcTeam } from "@src/models/theBlueAlliance/tbaFrcTeam";
import { FrcEventsRepo } from "@src/repos/FrcEventsRepo";
import { PlayoffsType } from "@src/models/PlayoffsType";
import { getFrcApiMatchNumber } from "@src/models/frcEvents/frcScoredMatch";
import { toFrcEventsUrlTournamentLevel } from "@src/models/CompLevel";
import { CompLevel, toFrcEventsUrlTournamentLevel } from "@src/models/CompLevel";

export async function getLocalVideoFilesForMatch(matchKey: MatchKey): Promise<MatchVideoInfo[]> {
const settings = await getSettings();
const { eventName, videoSearchDirectory } = await getSettings();
const match = new Match(matchKey);
const videoFileMatchingName = capitalizeFirstLetter(match.videoFileMatchingName);
const matchTitleName = capitalizeFirstLetter(match.verboseMatchName);
const eventName = settings.eventName;

const files = await getFilesMatchingPattern(settings.videoSearchDirectory, `${videoFileMatchingName}*`);
const files = await getFilesMatchingPattern(videoSearchDirectory, `${videoFileMatchingName}*`);
const parseVideoLabelsRegex = /^[A-Za-z]+ (\d{1,3})\s?([A-Za-z\s]*)\..*$/;

return files.filter(file => {
Expand All @@ -34,12 +33,19 @@ export async function getLocalVideoFilesForMatch(matchKey: MatchKey): Promise<Ma
// Pulls the actual match number out of the file name using the 2nd capture group in parseVideoLabelsRegex
const fileMatchNumber = proposedVideoLabel[1];

// Filter out this file if the match number in the file name doesn't match the match we want to get videos for
if (!fileMatchNumber || Number.parseInt(fileMatchNumber, 10) !== match.key.matchNumber) {
if (!fileMatchNumber) {
return false;
}

return true;
// In double eliminations, playoff matches (before finals) have their sequence number in the set number, not
// the match number
if (match.key.playoffsType === PlayoffsType.DoubleElimination && match.key.compLevel === CompLevel.Semifinal) {
return Number.parseInt(fileMatchNumber, 10) === match.key.setNumber;
}

// Otherwise, check that when parsed as a number, the match number in the file name matches the match for which
// we are finding videos
return Number.parseInt(fileMatchNumber, 10) === match.key.matchNumber;
}).map((file) => {
const proposedVideoLabel = parseVideoLabelsRegex.exec(file);
let videoLabel: string | null = null;
Expand Down

0 comments on commit 99aeacb

Please sign in to comment.