Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
feat(match-meeting-info): assign time slots to stand matches (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianAndersen authored Jun 14, 2024
1 parent dcea886 commit b27878e
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
shuffler,
} from "./match-testing-utils";
import assignMeetingInfoToMatches from "./match-meeting-info";
import { MatchableUser, MatchWithMeetingInfo } from "./match-types";
import {
CandidateMatchVariant,
MatchableUser,
MatchWithMeetingInfo,
} from "./match-types";
import otto_treider_test_users_year_0 from "./test-data/test_users_year_0.json";
import otto_treider_test_users_year_1 from "./test-data/test_users_year_1.json";

Expand Down Expand Up @@ -77,6 +81,59 @@ describe("Simple Matches", () => {
);
});

it("should assign users to a stand match time slot right after their final match", () => {
const matchFinder = new MatchFinder([audun, kristine], [siri]);
const matches = matchFinder.generateMatches();
const standLocation = "Resepsjonen";
const meetingDuration = 900000; // 15 minutes
const matchesWithMeetingInfo = assignMeetingInfoToMatches(
matches,
standLocation,
[{ name: "Sal 1" }, { name: "Sal 2" }],
new Date("2024-06-12T12:00:00+0100"),
meetingDuration,
);
for (const matchWithMeetingInfo of matchesWithMeetingInfo) {
if (matchWithMeetingInfo.variant === CandidateMatchVariant.UserMatch)
continue;
const latestUserMatchForStandMatchCustomer = matchesWithMeetingInfo
.filter(
(match) =>
match.variant === CandidateMatchVariant.UserMatch &&
(match.senderId === matchWithMeetingInfo.userId ||
match.receiverId === matchWithMeetingInfo.userId),
)
.reduce((latest, next) =>
next.meetingInfo.date.getTime() > latest.meetingInfo.date.getTime()
? next
: latest,
);
const latestUserMatchTime =
latestUserMatchForStandMatchCustomer.meetingInfo.date.getTime();
expect(matchWithMeetingInfo.meetingInfo.date.getTime()).to.eq(
latestUserMatchTime + meetingDuration,
);
}
});

it("should assign the StandMatch date to startTime if the user only has Stand Matches", () => {
const matchFinder = new MatchFinder([audun], [elRi]);
const matches = matchFinder.generateMatches();
const startTime = new Date("2024-06-12T12:00:00+0100");
const matchesWithMeetingInfo = assignMeetingInfoToMatches(
matches,
"Resepsjonen",
[{ name: "Sal 1" }, { name: "Sal 2" }],
startTime,
900000,
);
for (const matchWithMeetingInfo of matchesWithMeetingInfo) {
expect(matchWithMeetingInfo.meetingInfo.date.getTime()).to.eq(
startTime.getTime(),
);
}
});

it("should not be able to be more matches than the location limit at a given time", () => {
const senders = createUserGroup("sender", 10, "A", "B", "C");
const receivers = createUserGroup("receiver", 10, "A", "B", "C");
Expand Down
52 changes: 29 additions & 23 deletions src/collections/match/helpers/match-finder-2/match-meeting-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,9 @@ function verifyStandMatches(
standLocation: string,
) {
if (
standMatches.some(
(match) =>
match.meetingInfo.date !== null ||
match.meetingInfo.location !== standLocation,
)
standMatches.some((match) => match.meetingInfo.location !== standLocation)
) {
throw new Error(
"All stand matches must have correct location and no assigned time slot",
);
throw new Error("All stand matches must have correct location");
}
}

Expand Down Expand Up @@ -213,19 +207,6 @@ function assignMeetingInfoToMatches(
startTime: Date,
meetingDurationInMS: number,
): MatchWithMeetingInfo[] {
const standMatches: CandidateStandMatch[] = matches
.filter((match) => match.variant === CandidateMatchVariant.StandMatch)
.map((match) => match as CandidateStandMatch);

const standMatchesWithMeetingInfo: StandMatchWithMeetingInfo[] =
standMatches.map((match) => ({
...match,
meetingInfo: {
location: standLocation,
date: null,
},
}));

const userMatches: CandidateUserMatch[] = matches
.filter((match) => match.variant === CandidateMatchVariant.UserMatch)
.map((match) => match as CandidateUserMatch);
Expand Down Expand Up @@ -300,15 +281,40 @@ function assignMeetingInfoToMatches(
});
}
}

verifyStandMatches(standMatchesWithMeetingInfo, standLocation);
verifyUserMatches(
userMatches,
userMatchesWithMeetingInfo,
startTime,
userMatchLocations,
);

const standMatches: CandidateStandMatch[] = matches
.filter((match) => match.variant === CandidateMatchVariant.StandMatch)
.map((match) => match as CandidateStandMatch);

const standMatchesWithMeetingInfo: StandMatchWithMeetingInfo[] =
standMatches.map((match) => ({
...match,
meetingInfo: {
location: standLocation,
date: new Date(
userMatchesWithMeetingInfo
.filter(
(matchWithMeetingInfo) =>
matchWithMeetingInfo.senderId === match.userId ||
matchWithMeetingInfo.receiverId === match.userId,
)
.reduce((latestTime, next) => {
const potentialTime =
next.meetingInfo.date.getTime() + meetingDurationInMS;
return potentialTime > latestTime ? potentialTime : latestTime;
}, startTime.getTime()),
),
},
}));

verifyStandMatches(standMatchesWithMeetingInfo, standLocation);

return [...userMatchesWithMeetingInfo, ...standMatchesWithMeetingInfo];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type CandidateMatch = CandidateStandMatch | CandidateUserMatch;
interface MatchMeetingInfo {
meetingInfo: {
location: string;
date: Date | null;
date: Date;
};
}

Expand Down
3 changes: 1 addition & 2 deletions src/collections/match/match.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ const matchBaseSchema = {
},
meetingInfo: {
location: { type: String, required: true },
// Can be null in case of a StandMatch
date: Date,
date: { type: Date, required: true },
},
};

Expand Down

0 comments on commit b27878e

Please sign in to comment.