Skip to content

Commit 5fa41a7

Browse files
committed
feat: add membership calcuation tests
1 parent 606076b commit 5fa41a7

File tree

4 files changed

+1745
-45
lines changed

4 files changed

+1745
-45
lines changed

apps/rpc/src/modules/user/membership-service.ts

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,34 @@ import { differenceInMonths, subYears } from "date-fns"
33
import invariant from "tiny-invariant"
44
import type { NTNUGroup } from "../feide/feide-groups-repository"
55
import { getLogger } from "@dotkomonline/logger"
6-
import { getCurrentUTC } from "@dotkomonline/utils"
7-
import type { TZDate } from "@date-fns/tz"
86

97
export interface MembershipService {
10-
findEstimatedStudyStart(
8+
/**
9+
* Find the approximate semester based on a student's courses against a hard-coded set of courses.
10+
*
11+
* NOTE: The value is 0-indexed.
12+
*
13+
* Master studies begin at semester 6.
14+
*
15+
* @see getCourseStart(semester) in types package
16+
* @see getStudyGrade(semester) in types package
17+
*
18+
* @example
19+
* findEstimatedSemester(...) -> 0 // 1st semester Bachelor (Autumn)
20+
* findEstimatedSemester(...) -> 1 // 2nd semester Bachelor (Spring)
21+
* findEstimatedSemester(...) -> 2 // 3rd semester Bachelor
22+
* findEstimatedSemester(...) -> 3 // 4th semester Bachelor
23+
* findEstimatedSemester(...) -> 4 // 5th semester Bachelor
24+
* findEstimatedSemester(...) -> 5 // 6th semester Bachelor
25+
* findEstimatedSemester(...) -> 6 // 1st semester Master (regardless of prior Bachelor length)
26+
* findEstimatedSemester(...) -> 7 // 2nd semester Master
27+
* findEstimatedSemester(...) -> 8 // 3rd semester Master
28+
* findEstimatedSemester(...) -> 9 // 4th semester Master
29+
*/
30+
findEstimatedSemester(
1131
study: "BACHELOR" | "MASTER",
12-
courses: NTNUGroup[]
13-
): { start: TZDate; semester: number; grade: number }
32+
courses: ReadonlyArray<NTNUGroup>
33+
): number
1434
}
1535

1636
const BACHELOR_STUDY_PLAN = [
@@ -44,19 +64,19 @@ const BACHELOR_STUDY_PLAN = [
4464

4565
const MASTER_STUDY_PLAN = [
4666
{
47-
semester: 0,
67+
semester: 6,
4868
courses: [],
4969
},
5070
{
51-
semester: 1,
71+
semester: 7,
5272
courses: [],
5373
},
5474
{
55-
semester: 2,
75+
semester: 8,
5676
courses: ["IT3915"],
5777
},
5878
{
59-
semester: 3,
79+
semester: 9,
6080
courses: ["IT3920"],
6181
},
6282
] as const
@@ -90,8 +110,7 @@ export function getMembershipService(): MembershipService {
90110
/**
91111
* Find the approximate semester based on a student's courses against a hard-coded set of courses.
92112
*/
93-
function findEstimatedSemester(courseSet: StudyPlanCourseSet, studentCourses: NTNUGroup[]): number {
94-
logger.info("Searching for applicable membership based on courses %o and study plan %o", studentCourses, courseSet)
113+
function estimateSemester(courseSet: StudyPlanCourseSet, studentCourses: ReadonlyArray<NTNUGroup>): number {
95114
let largestSemester = 0
96115
for (let i = 0; i < courseSet.length; i++) {
97116
const semester = courseSet[i]
@@ -176,33 +195,9 @@ export function getMembershipService(): MembershipService {
176195
}
177196

178197
return {
179-
findEstimatedStudyStart(study, courses) {
198+
findEstimatedSemester(study, courses) {
180199
const studyPlan = study === "MASTER" ? MASTER_STUDY_PLAN : BACHELOR_STUDY_PLAN
181-
const semester = findEstimatedSemester(studyPlan, courses)
182-
183-
// We use Math#round because it will give us the correct year delta:
184-
// Year 1 autumn (value 0) : round(0 / 2) = 0 (Start year = current year)
185-
// Year 1 spring (value 1): round(1 / 2) = 1 (Start year = current - 1, since spring is in the next calendar year)
186-
// Year 2 autumn (value 2) : round(2 / 2) = 1 (Start year = current - 1)
187-
// Year 2 spring (value 3): round(3 / 2) = 2 (Start year = current - 2)
188-
// ...
189-
const yearOffset = Math.round(semester / 2)
190-
const start = subYears(getAcademicStart(getCurrentUTC()), yearOffset)
191-
192-
// A school year consists of two semesters (Autumn and Spring). So this formula will give us the year:
193-
// Year 1 autumn (value 0): floor(0 / 2) + 1 = 1 (Year 1)
194-
// Year 1 spring (value 1): floor(1 / 2) + 1 = 1 (Year 1)
195-
// Year 2 autumn (value 2): floor(2 / 2) + 1 = 2 (Year 2)
196-
// Year 2 spring (value 3): floor(3 / 2) + 1 = 2 (Year 2)
197-
// Year 3 autumn (value 4): floor(4 / 2) + 1 = 3 (Year 3)
198-
// ...
199-
const grade = Math.floor(semester / 2) + 1
200-
201-
return {
202-
semester,
203-
start,
204-
grade,
205-
}
200+
return estimateSemester(studyPlan, courses)
206201
},
207202
}
208203
}

0 commit comments

Comments
 (0)