All files / server/src/features/program-item-popularity getPopularity.ts

100% Statements 19/19
100% Branches 10/10
100% Functions 4/4
100% Lines 16/16

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      45x 45x                 45x             8x 1x   7x       4x       15x 15x 15x   3x       3x 1x     2x 1x     1x    
import { Popularity } from "shared/types/models/programItem";
import { LotterySignup } from "shared/types/models/user";
 
const VERY_HIGH_MODIFIER_LIMIT = 3;
const EXTEME_MODIFIER_LIMIT = 5;
 
interface GetPopularityParams {
  minAttendance: number;
  maxAttendance: number;
  assignmentSignupCount: number;
  lotterySignups: LotterySignup[];
}
 
export const getPopularity = ({
  minAttendance,
  maxAttendance,
  assignmentSignupCount,
  lotterySignups,
}: GetPopularityParams): Popularity => {
  // Use assignment result when popularity is not maximum
  if (assignmentSignupCount < minAttendance) {
    return Popularity.LOW;
  }
  if (
    assignmentSignupCount >= minAttendance &&
    assignmentSignupCount < maxAttendance
  ) {
    return Popularity.MEDIUM;
  }
 
  // When assignment popularity is maximum, we need to use additional modifier to determine HIGH, VERY_HIGH and EXTREME
  const priority1 = lotterySignups.filter((signup) => signup.priority === 1);
  const priority2 = lotterySignups.filter((signup) => signup.priority === 2);
  const priority3 = lotterySignups.filter((signup) => signup.priority === 3);
 
  const modifier =
    (priority1.length + priority2.length / 2 + priority3.length / 3) /
    maxAttendance;
 
  if (modifier >= EXTEME_MODIFIER_LIMIT) {
    return Popularity.EXTREME;
  }
 
  if (modifier >= VERY_HIGH_MODIFIER_LIMIT) {
    return Popularity.VERY_HIGH;
  }
 
  return Popularity.HIGH;
};