All files / server/src/features/assignment/utils removeOverlapLotterySignups.ts

84.61% Statements 33/39
80% Branches 16/20
100% Functions 7/7
84.61% Lines 33/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                              47x         60x 60x   60x 60x     60x 294x   8560x     294x                 294x 4836x   294x                   294x       261x 261x   1884x   94612x   1884x 3x   1881x       1881x         261x 96x     280x             294x       32x   32x             32x 1x               60x 12x 12x         60x    
import dayjs from "dayjs";
import { config } from "shared/config";
import { RemoveLotterySignupsStrategy } from "shared/config/eventConfigTypes";
import { MongoDbError } from "shared/types/api/errors";
import { ProgramItem } from "shared/types/models/programItem";
import { UserAssignmentResult } from "shared/types/models/result";
import { Result, makeSuccessResult } from "shared/utils/result";
import { getUpcomingLotterySignupProgramItemIds } from "server/features/assignment/utils/getUpcomingLotterySignups";
import {
  DeleteLotterySignupsParams,
  delLotterySignups,
} from "server/features/user/lottery-signup/lotterySignupRepository";
import { findUsers } from "server/features/user/userRepository";
import { logger } from "server/utils/logger";
 
export const removeOverlapLotterySignups = async (
  results: readonly UserAssignmentResult[],
  programItems: readonly ProgramItem[],
  assignmentTime: string,
): Promise<Result<void, MongoDbError>> => {
  logger.debug("Find overlapping lottery signups");
  const usersToUpdate: DeleteLotterySignupsParams[] = [];
 
  const usersResult = await findUsers();
  Iif (!usersResult.ok) {
    return usersResult;
  }
  results.flatMap((result) => {
    const assignmentSignupProgramItem = programItems.find(
      (programItem) =>
        programItem.programItemId === result.assignmentSignup.programItemId,
    );
 
    Iif (!assignmentSignupProgramItem) {
      logger.error(
        new Error(
          `removeOverlapLotterySignups: Error finding assignment signup: ${result.assignmentSignup.programItemId}`,
        ),
      );
      return [];
    }
 
    const signedUser = usersResult.value.find(
      (user) => user.username === result.username,
    );
    Iif (!signedUser) {
      logger.error(
        new Error(
          `removeOverlapLotterySignups: Error finding signed user: ${result.username}`,
        ),
      );
      return [];
    }
 
    // Cancel all lottery sign-ups that start during the lottery direct sign-up
    if (
      config.event().removeLotterySignupsStrategy ===
      RemoveLotterySignupsStrategy.OVERLAP
    ) {
      logger.info("Remove overlapping signups");
      const overlappingLotterySignups = signedUser.lotterySignups.filter(
        (lotterySignup) => {
          const foundProgramItem = programItems.find(
            (programItem) =>
              programItem.programItemId === lotterySignup.programItemId,
          );
          if (!foundProgramItem) {
            return false;
          }
          const startsDuring = dayjs(foundProgramItem.startTime).isBetween(
            dayjs(assignmentSignupProgramItem.startTime).add(1, "minutes"),
            dayjs(assignmentSignupProgramItem.endTime),
          );
          return startsDuring;
        },
      );
 
      // Only update users with overlapping lottery sign-ups
      if (overlappingLotterySignups.length > 0) {
        usersToUpdate.push({
          username: signedUser.username,
          lotterySignupProgramItemIds: overlappingLotterySignups.map(
            (signup) => signup.programItemId,
          ),
        });
      }
    }
 
    // Cancel all upcoming lottery sign-ups
    if (
      config.event().removeLotterySignupsStrategy ===
      RemoveLotterySignupsStrategy.ALL_UPCOMING
    ) {
      logger.info("Remove upcoming signups");
      const upcomingLotterySignupProgramItemIds =
        getUpcomingLotterySignupProgramItemIds(
          signedUser.lotterySignups,
          programItems,
          dayjs(assignmentTime),
        );
 
      // Only update users with upcoming lottery sign-ups
      if (upcomingLotterySignupProgramItemIds.length > 0) {
        usersToUpdate.push({
          username: signedUser.username,
          lotterySignupProgramItemIds: upcomingLotterySignupProgramItemIds,
        });
      }
    }
  });
 
  if (usersToUpdate.length > 0) {
    const delLotterySignupsResult = await delLotterySignups(usersToUpdate);
    Iif (!delLotterySignupsResult.ok) {
      return delLotterySignupsResult;
    }
  }
 
  return makeSuccessResult();
};