All files / server/src/features/assignment/random/utils runRandomAssignment.ts

79.16% Statements 19/24
50% Branches 1/2
100% Functions 3/3
82.6% Lines 19/23

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                                                  44x   44x           31x         31x       31x             31x 31x                 31x 31x 31x 31x                     31x                     31x 31x 31x 31x   31x     44x       31x    
import { eventAssignment } from "eventassigner-random";
import { AssignmentElement } from "eventassigner-random/lib/typings/assignment";
import { CheckResult } from "eventassigner-random/lib/typings/checkResult";
import { config } from "shared/config";
import { getGroups } from "server/features/assignment/utils/getGroups";
import { getList } from "server/features/assignment/utils/getList";
import { formatResults } from "server/features/assignment/utils/formatResults";
import { ProgramItem } from "shared/types/models/programItem";
import { AssignmentAlgorithmResult } from "server/types/resultTypes";
import {
  ListItem,
  RandomAssignUpdateLInput,
} from "server/types/assignmentTypes";
import { User } from "shared/types/models/user";
import { DirectSignupsForProgramItem } from "server/features/direct-signup/directSignupTypes";
import {
  Result,
  makeErrorResult,
  makeSuccessResult,
} from "shared/utils/result";
import { AssignmentError } from "shared/types/api/errors";
import { logger } from "server/utils/logger";
import { calculateHappiness } from "server/features/assignment/padg/utils/calculateHappiness";
import { getEvents } from "server/features/assignment/utils/getEvents";
 
const updateL = (input: RandomAssignUpdateLInput): ListItem[] => input.L;
 
export const runRandomAssignment = (
  lotterySignupProgramItems: readonly ProgramItem[],
  attendeeGroups: readonly User[][],
  assignmentTime: string,
  lotteryParticipantDirectSignups: readonly DirectSignupsForProgramItem[],
): Result<AssignmentAlgorithmResult, AssignmentError> => {
  const groups = getGroups(
    attendeeGroups,
    assignmentTime,
    lotterySignupProgramItems,
  );
  const events = getEvents(
    lotterySignupProgramItems,
    lotteryParticipantDirectSignups,
  );
  const list = getList({
    attendeeGroups,
    assignmentTime,
    lotteryParticipantDirectSignups,
    lotterySignupProgramItems,
  });
 
  const { randomAssignmentRounds } = config.server();
  const input = {
    groups,
    events,
    L: list,
    updateL,
    assignmentRounds: randomAssignmentRounds,
  };
 
  let assignResults: AssignmentElement[] | CheckResult | undefined;
  try {
    logger.debug("Run random algorithm: start");
    assignResults = eventAssignment(input);
    logger.debug("Run random algorithm: finished");
  } catch (error) {
    logger.error(
      new Error(
        `Random assignment failed: ${String(error)}. Assignment time: ${assignmentTime}, Input: ${JSON.stringify(input)}`,
      ),
    );
    return makeErrorResult(AssignmentError.UNKNOWN_ERROR);
  }
 
  // CheckResult = invalid result
  Iif (isCheckResult(assignResults)) {
    logger.error(
      new Error(
        `Random assignment failed: ${
          assignResults.msg
        }. Input: ${JSON.stringify(input)}`,
      ),
    );
    return makeErrorResult(AssignmentError.UNKNOWN_ERROR);
  }
 
  const results = formatResults(assignResults, attendeeGroups);
  const happiness = calculateHappiness(assignResults, groups);
  const message = `Random assignment completed with happiness ${happiness}%`;
  logger.debug(message);
 
  return makeSuccessResult({ results, message });
};
 
const isCheckResult = (
  assignResults: AssignmentElement[] | CheckResult,
): assignResults is CheckResult => {
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  return (assignResults as CheckResult).value !== undefined;
};