diff --git a/i18n/en.pot b/i18n/en.pot
index 42705daf..eef4b4f9 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -5,8 +5,56 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"POT-Creation-Date: 2024-07-04T13:31:07.802Z\n"
-"PO-Revision-Date: 2024-07-04T13:31:07.802Z\n"
+"POT-Creation-Date: 2024-07-01T02:04:44.570Z\n"
+"PO-Revision-Date: 2024-07-01T02:04:44.570Z\n"
+
+msgid "Low"
+msgstr ""
+
+msgid "Medium"
+msgstr ""
+
+msgid "High"
+msgstr ""
+
+msgid "Less than 0.1%"
+msgstr ""
+
+msgid "Between 0.1% to 0.25%"
+msgstr ""
+
+msgid "Above 0.25%"
+msgstr ""
+
+msgid "Within a district"
+msgstr ""
+
+msgid "Within a province with more than one district affected"
+msgstr ""
+
+msgid "More than one province affected with high threat of spread locally and internationally"
+msgstr ""
+
+msgid "Available within the district with support from provincial and national level"
+msgstr ""
+
+msgid "Available within the province with minimal support from national level"
+msgstr ""
+
+msgid "Available at national with support required from international"
+msgstr ""
+
+msgid "Grade 1"
+msgstr ""
+
+msgid "Grade 2"
+msgstr ""
+
+msgid "Grade 3"
+msgstr ""
+
+msgid "Invalid grade"
+msgstr ""
msgid "Add new option"
msgstr ""
diff --git a/i18n/es.po b/i18n/es.po
index 4e848d1c..2dc83d3b 100644
--- a/i18n/es.po
+++ b/i18n/es.po
@@ -1,13 +1,64 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
-"POT-Creation-Date: 2024-07-04T13:31:07.802Z\n"
+"POT-Creation-Date: 2024-07-01T02:04:44.570Z\n"
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+msgid "Low"
+msgstr ""
+
+msgid "Medium"
+msgstr ""
+
+msgid "High"
+msgstr ""
+
+msgid "Less than 0.1%"
+msgstr ""
+
+msgid "Between 0.1% to 0.25%"
+msgstr ""
+
+msgid "Above 0.25%"
+msgstr ""
+
+msgid "Within a district"
+msgstr ""
+
+msgid "Within a province with more than one district affected"
+msgstr ""
+
+msgid ""
+"More than one province affected with high threat of spread locally and "
+"internationally"
+msgstr ""
+
+msgid ""
+"Available within the district with support from provincial and national level"
+msgstr ""
+
+msgid "Available within the province with minimal support from national level"
+msgstr ""
+
+msgid "Available at national with support required from international"
+msgstr ""
+
+msgid "Grade 1"
+msgstr ""
+
+msgid "Grade 2"
+msgstr ""
+
+msgid "Grade 3"
+msgstr ""
+
+msgid "Invalid grade"
+msgstr ""
+
msgid "Add new option"
msgstr ""
@@ -52,3 +103,18 @@ msgstr ""
msgid "Resources"
msgstr ""
+
+#~ msgid "Add"
+#~ msgstr "AƱadir"
+
+#~ msgid "List"
+#~ msgstr "Listar"
+
+#~ msgid "Back"
+#~ msgstr "Volver"
+
+#~ msgid "Help"
+#~ msgstr "Ayuda"
+
+#~ msgid "Hello {{name}}"
+#~ msgstr "Hola {{name}}"
diff --git a/index.html b/index.html
index 492d83db..1e5a8d80 100644
--- a/index.html
+++ b/index.html
@@ -4,15 +4,22 @@
-
+
-
+
-
Vite + React + TS
+ Zebra
diff --git a/package.json b/package.json
index a649d7aa..f3c68aa8 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,13 @@
{
- "name": "dhis2-app-skeleton",
- "description": "DHIS2 Skeleton App",
+ "name": "zebra",
+ "description": "Zambia Emergency Bridge for Response Application",
"version": "0.0.1",
"license": "GPL-3.0",
"author": "EyeSeeTea team",
"homepage": ".",
"repository": {
"type": "git",
- "url": "git+https://github.com/eyeseetea/dhis2-app-skeleton.git"
+ "url": "git+https://github.com/eyeseetea/zebra-dev.git"
},
"dependencies": {
"@dhis2/app-runtime": "2.8.0",
@@ -112,8 +112,8 @@
"script-example": "npx ts-node src/scripts/example.ts"
},
"manifest.webapp": {
- "name": "DHIS2 Skeleton App",
- "description": "DHIS2 Skeleton App",
+ "name": "zebra",
+ "description": "Zambia Emergency Bridge for Response Application",
"icons": {
"48": "icon.png"
},
diff --git a/src/domain/entities/DiseaseOutbreakEvent.ts b/src/domain/entities/DiseaseOutbreakEvent.ts
new file mode 100644
index 00000000..ad19ab9f
--- /dev/null
+++ b/src/domain/entities/DiseaseOutbreakEvent.ts
@@ -0,0 +1,60 @@
+import { Struct } from "./generic/Struct";
+import { IncidentActionPlan } from "./incident-action-plan/IncidentActionPlan";
+import { IncidentManagementTeam } from "./incident-management-team/IncidentManagementTeam";
+import { TeamMember } from "./incident-management-team/TeamMember";
+import { OrgUnit } from "./OrgUnit";
+import { CodedNamedRef, NamedRef } from "./Ref";
+import { RiskAssessment } from "./risk-assessment/RiskAssessment";
+import { Maybe } from "../../utils/ts-utils";
+
+type HazardType =
+ | "Biological:Human"
+ | "Biological:Animal"
+ | "Chemical"
+ | "Environmental"
+ | "Unknown";
+
+type IncidentStatusType = "Watch" | "Alert" | "Respond" | "Closed" | "Discarded";
+
+type DateWithNarrative = {
+ date: Date;
+ narrative: string;
+};
+
+type Syndrome = CodedNamedRef;
+type Disease = CodedNamedRef;
+type NotificationSource = CodedNamedRef;
+
+type DiseaseOutbreakEventAttrs = NamedRef & {
+ created: Date;
+ lastUpdated: Date;
+ createdBy: TeamMember;
+ hazardType: HazardType;
+ mainSyndrome: Syndrome;
+ suspectedDisease: Disease;
+ notificationSource: NotificationSource;
+ areasAffected: {
+ provinces: OrgUnit[];
+ districts: OrgUnit[];
+ };
+ incidentStatus: IncidentStatusType;
+ emerged: DateWithNarrative;
+ detected: DateWithNarrative;
+ notified: DateWithNarrative;
+ responseNarrative: string;
+ incidentManager: TeamMember;
+ notes: Maybe;
+ riskAssessments: RiskAssessment[];
+ IncidentActionPlan: IncidentActionPlan;
+ IncidentManagementTeam: IncidentManagementTeam;
+};
+/**
+ * Note: DiseaseOutbreakEvent represents Event in the Figma.
+ * Not using event as it is a keyword and can also be confused with dhis event
+ **/
+
+export class DiseaseOutbreakEvent extends Struct() {
+ static validateEventName() {
+ //TO DO : Ensure event name is unique on event creation.
+ }
+}
diff --git a/src/domain/entities/OrgUnit.ts b/src/domain/entities/OrgUnit.ts
new file mode 100644
index 00000000..554c0721
--- /dev/null
+++ b/src/domain/entities/OrgUnit.ts
@@ -0,0 +1,7 @@
+import { CodedNamedRef } from "./Ref";
+
+type OrgUnitLevelType = "Province" | "District";
+
+export type OrgUnit = CodedNamedRef & {
+ level: OrgUnitLevelType;
+};
diff --git a/src/domain/entities/Properties.ts b/src/domain/entities/Properties.ts
new file mode 100644
index 00000000..4fe8844a
--- /dev/null
+++ b/src/domain/entities/Properties.ts
@@ -0,0 +1,29 @@
+import { CodedNamedRef } from "./Ref";
+
+type PropertTypes = "string" | "date" | "number" | "boolean";
+
+type BaseProperty = CodedNamedRef & {
+ type: PropertTypes;
+};
+
+type StringProperty = BaseProperty & {
+ type: "string";
+ value: string;
+};
+
+type DateProperty = BaseProperty & {
+ type: "date";
+ value: Date;
+};
+
+type NumberProperty = BaseProperty & {
+ type: "number";
+ value: number;
+};
+
+type BooleanProperty = BaseProperty & {
+ type: "boolean";
+ value: boolean;
+};
+
+export type Property = StringProperty | DateProperty | NumberProperty | BooleanProperty;
diff --git a/src/domain/entities/Ref.ts b/src/domain/entities/Ref.ts
index 8b95ca2f..922a5d18 100644
--- a/src/domain/entities/Ref.ts
+++ b/src/domain/entities/Ref.ts
@@ -7,3 +7,7 @@ export interface Ref {
export interface NamedRef extends Ref {
name: string;
}
+
+export interface CodedNamedRef extends NamedRef {
+ code: string;
+}
diff --git a/src/domain/entities/generic/Either.ts b/src/domain/entities/generic/Either.ts
index 33234090..adff2c62 100644
--- a/src/domain/entities/generic/Either.ts
+++ b/src/domain/entities/generic/Either.ts
@@ -17,6 +17,11 @@
export class Either {
constructor(public value: EitherValue) {}
+ getOrThrow(): Data {
+ if (this.value.data) return this.value.data;
+ else throw this.value.error;
+ }
+
match(matchObj: MatchObject): Res {
switch (this.value.type) {
case "success":
diff --git a/src/domain/entities/generic/Struct.ts b/src/domain/entities/generic/Struct.ts
index cf4d9816..5a01041e 100644
--- a/src/domain/entities/generic/Struct.ts
+++ b/src/domain/entities/generic/Struct.ts
@@ -15,7 +15,7 @@
export function Struct() {
abstract class Base {
- constructor(_attributes: Attrs) {
+ protected constructor(_attributes: Attrs) {
Object.assign(this, _attributes);
}
@@ -28,15 +28,10 @@ export function Struct() {
const ParentClass = this.constructor as new (values: Attrs) => typeof this;
return new ParentClass({ ...this._getAttributes(), ...partialAttrs });
}
-
- static create(this: new (attrs: Attrs) => U, attrs: Attrs): U {
- return new this(attrs);
- }
}
return Base as {
new (values: Attrs): Attrs & Base;
- create: (typeof Base)["create"];
};
}
diff --git a/src/domain/entities/incident-action-plan/ActionPlan.ts b/src/domain/entities/incident-action-plan/ActionPlan.ts
new file mode 100644
index 00000000..09336e77
--- /dev/null
+++ b/src/domain/entities/incident-action-plan/ActionPlan.ts
@@ -0,0 +1,8 @@
+import { Property } from "../Properties";
+import { Struct } from "../generic/Struct";
+
+interface ActionPlanAttrs {
+ properties: Property[];
+}
+
+export class ActionPlan extends Struct() {}
diff --git a/src/domain/entities/incident-action-plan/IncidentActionPlan.ts b/src/domain/entities/incident-action-plan/IncidentActionPlan.ts
new file mode 100644
index 00000000..222a8df2
--- /dev/null
+++ b/src/domain/entities/incident-action-plan/IncidentActionPlan.ts
@@ -0,0 +1,12 @@
+import { ActionPlan } from "./ActionPlan";
+import { Ref } from "../Ref";
+import { Struct } from "../generic/Struct";
+import { ResponseAction } from "./ResponseAction";
+
+interface IncidentActionPlanAttrs extends Ref {
+ lastUpdated: Date;
+ actionPlan: ActionPlan;
+ responseActions: ResponseAction[];
+}
+
+export class IncidentActionPlan extends Struct() {}
diff --git a/src/domain/entities/incident-action-plan/ResponseAction.ts b/src/domain/entities/incident-action-plan/ResponseAction.ts
new file mode 100644
index 00000000..1d2c268c
--- /dev/null
+++ b/src/domain/entities/incident-action-plan/ResponseAction.ts
@@ -0,0 +1,22 @@
+import { CodedNamedRef } from "../Ref";
+import { Struct } from "../generic/Struct";
+import { TeamMember } from "../incident-management-team/TeamMember";
+
+type ResponseActionStatusType = "NotDone" | "Pending" | "InProgress" | "Complete";
+type ResponseActionVerificationType = "Verified" | "Unverified";
+type MainTask = CodedNamedRef;
+type SubPillar = CodedNamedRef;
+type TimeLine = CodedNamedRef;
+
+interface ResponseActionAttrs {
+ mainTask: MainTask;
+ subActivities: string;
+ subPillar: SubPillar;
+ responsibleOfficer: TeamMember;
+ dueDate: Date;
+ timeLine: TimeLine;
+ status: ResponseActionStatusType;
+ verification: ResponseActionVerificationType;
+}
+
+export class ResponseAction extends Struct() {}
diff --git a/src/domain/entities/incident-management-team/IncidentManagementTeam.ts b/src/domain/entities/incident-management-team/IncidentManagementTeam.ts
new file mode 100644
index 00000000..cb9298bf
--- /dev/null
+++ b/src/domain/entities/incident-management-team/IncidentManagementTeam.ts
@@ -0,0 +1,8 @@
+import { Struct } from "../generic/Struct";
+import { TeamMember } from "./TeamMember";
+
+interface IncidentManagementTeamAttrs {
+ teamHierarchy: TeamMember[];
+}
+
+export class IncidentManagementTeam extends Struct() {}
diff --git a/src/domain/entities/incident-management-team/TeamMember.ts b/src/domain/entities/incident-management-team/TeamMember.ts
new file mode 100644
index 00000000..4e77678e
--- /dev/null
+++ b/src/domain/entities/incident-management-team/TeamMember.ts
@@ -0,0 +1,25 @@
+import { NamedRef } from "../Ref";
+import { Struct } from "../generic/Struct";
+
+type PhoneNumber = string;
+type Email = string;
+type IncidentManagerStatus = "Available" | "Unavailable";
+
+export type TeamRole = NamedRef & {
+ level: number;
+};
+
+interface TeamMemberAttrs extends NamedRef {
+ phone: PhoneNumber;
+ email: Email;
+ status: IncidentManagerStatus;
+ photo: URL;
+ role: TeamRole;
+}
+
+export class TeamMember extends Struct() {
+ static validatePhAndEmail() {
+ //TO DO : any validations for phone number?
+ //TO DO : any validations for email?
+ }
+}
diff --git a/src/domain/entities/risk-assessment/RiskAssessment.ts b/src/domain/entities/risk-assessment/RiskAssessment.ts
new file mode 100644
index 00000000..1a3fd827
--- /dev/null
+++ b/src/domain/entities/risk-assessment/RiskAssessment.ts
@@ -0,0 +1,12 @@
+import { Struct } from "../generic/Struct";
+import { RiskAssessmentGrading } from "./RiskAssessmentGrading";
+import { RiskAssessmentQuestionnaire } from "./RiskAssessmentQuestionnaire";
+import { RiskAssessmentSummary } from "./RiskAssessmentSummary";
+
+interface RiskAssessmentAttrs {
+ grading: RiskAssessmentGrading[];
+ summary: RiskAssessmentSummary;
+ questionnaire: RiskAssessmentQuestionnaire[];
+}
+
+export class RiskAssessment extends Struct() {}
diff --git a/src/domain/entities/risk-assessment/RiskAssessmentGrading.ts b/src/domain/entities/risk-assessment/RiskAssessmentGrading.ts
new file mode 100644
index 00000000..3b053d60
--- /dev/null
+++ b/src/domain/entities/risk-assessment/RiskAssessmentGrading.ts
@@ -0,0 +1,153 @@
+import i18n from "@eyeseetea/feedback-component/locales";
+import { Ref } from "../Ref";
+import { Struct } from "../generic/Struct";
+import { Either } from "../generic/Either";
+
+type WeightedOptionTypes = "Low" | "Medium" | "High";
+type PopulationWeightOptionsTypes = "LessPercentage" | "MediumPercentage" | "HighPercentage";
+type GeographicalSpreadOptionsTypes =
+ | "WithinDistrict"
+ | "MoretThanOneDistrict"
+ | "MoreThanOneProvince";
+type CapacityOptionsTypes =
+ | "ProvincialNationalLevel"
+ | "ProvincialLevel"
+ | "NationalInternationalLevel";
+
+export type LowWeightedOption = {
+ type: "Low";
+ weight: 1;
+};
+export type MediumWeightedOption = {
+ type: "Medium";
+ weight: 2;
+};
+export type HighWeightedOption = {
+ type: "High";
+ weight: 3;
+};
+
+export type LowPopulationAtRisk = {
+ type: "LessPercentage";
+ weight: 1;
+};
+export type MediumPopulationAtRisk = {
+ type: "MediumPercentage";
+ weight: 2;
+};
+export type HighPopulationAtRisk = {
+ type: "HighPercentage";
+ weight: 3;
+};
+
+export type LowGeographicalSpread = {
+ type: "WithinDistrict";
+ weight: 1;
+};
+export type MediumGeographicalSpread = {
+ type: "MoretThanOneDistrict";
+ weight: 2;
+};
+export type HighGeographicalSpread = {
+ type: "MoreThanOneProvince";
+ weight: 3;
+};
+
+export type LowCapacity = {
+ type: "ProvincialNationalLevel";
+ weight: 1;
+};
+export type MediumCapacity = {
+ type: "ProvincialLevel";
+ weight: 2;
+};
+export type HighCapacity = {
+ type: "NationalInternationalLevel";
+ weight: 3;
+};
+
+export type Grade = "Grade1" | "Grade2" | "Grade3";
+
+type AllOptionTypes =
+ | WeightedOptionTypes
+ | PopulationWeightOptionsTypes
+ | GeographicalSpreadOptionsTypes
+ | CapacityOptionsTypes
+ | Grade;
+
+const translations: Record = {
+ Low: i18n.t("Low"),
+ Medium: i18n.t("Medium"),
+ High: i18n.t("High"),
+ LessPercentage: i18n.t("Less than 0.1%"),
+ MediumPercentage: i18n.t("Between 0.1% to 0.25%"),
+ HighPercentage: i18n.t("Above 0.25%"),
+ WithinDistrict: i18n.t("Within a district"),
+ MoretThanOneDistrict: i18n.t("Within a province with more than one district affected"),
+ MoreThanOneProvince: i18n.t(
+ "More than one province affected with high threat of spread locally and internationally"
+ ),
+ ProvincialNationalLevel: i18n.t(
+ "Available within the district with support from provincial and national level"
+ ),
+ ProvincialLevel: i18n.t(
+ "Available within the province with minimal support from national level"
+ ),
+ NationalInternationalLevel: i18n.t(
+ "Available at national with support required from international"
+ ),
+ Grade1: i18n.t("Grade 1"),
+ Grade2: i18n.t("Grade 2"),
+ Grade3: i18n.t("Grade 3"),
+};
+
+interface RiskAssessmentGradingAttrs extends Ref {
+ lastUpdated: Date;
+ populationAtRisk: LowPopulationAtRisk | MediumPopulationAtRisk | HighPopulationAtRisk;
+ attackRate: LowWeightedOption | MediumWeightedOption | HighWeightedOption;
+ geographicalSpread: LowGeographicalSpread | MediumGeographicalSpread | HighGeographicalSpread;
+ complexity: LowWeightedOption | MediumWeightedOption | HighWeightedOption;
+ capacity: LowCapacity | MediumCapacity | HighCapacity;
+ reputationalRisk: LowWeightedOption | MediumWeightedOption | HighWeightedOption;
+ severity: LowWeightedOption | MediumWeightedOption | HighWeightedOption;
+}
+
+export class RiskAssessmentGrading extends Struct() {
+ private constructor(attrs: RiskAssessmentGradingAttrs) {
+ super(attrs);
+ }
+
+ public static create(attrs: RiskAssessmentGradingAttrs): RiskAssessmentGrading {
+ return new RiskAssessmentGrading(attrs);
+ }
+
+ public static getTranslatedLabel(key: AllOptionTypes): string {
+ return translations[key];
+ }
+
+ getGrade(): Either {
+ return this.calculateGrade();
+ }
+
+ calculateGrade(): Either {
+ const totalWeight =
+ this.populationAtRisk.weight +
+ this.attackRate.weight +
+ this.geographicalSpread.weight +
+ this.complexity.weight +
+ this.capacity.weight +
+ this.reputationalRisk.weight +
+ this.severity.weight;
+
+ if (totalWeight > 21) return Either.error(new Error(i18n.t("Invalid grade")));
+
+ const grade: Grade =
+ totalWeight <= 7
+ ? "Grade1"
+ : totalWeight > 7 && totalWeight <= 14
+ ? "Grade2"
+ : "Grade3";
+
+ return Either.success(grade);
+ }
+}
diff --git a/src/domain/entities/risk-assessment/RiskAssessmentQuestionnaire.ts b/src/domain/entities/risk-assessment/RiskAssessmentQuestionnaire.ts
new file mode 100644
index 00000000..4a77cab4
--- /dev/null
+++ b/src/domain/entities/risk-assessment/RiskAssessmentQuestionnaire.ts
@@ -0,0 +1,8 @@
+import { Property } from "../Properties";
+import { Struct } from "../generic/Struct";
+
+interface RiskAssessmentQuestionnaireAttrs {
+ questions: Property[];
+}
+
+export class RiskAssessmentQuestionnaire extends Struct() {}
diff --git a/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts b/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts
new file mode 100644
index 00000000..21b26ce2
--- /dev/null
+++ b/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts
@@ -0,0 +1,8 @@
+import { Property } from "../Properties";
+import { Struct } from "../generic/Struct";
+
+interface RiskAssessmentSummaryAttrs {
+ properties: Property[];
+}
+
+export class RiskAssessmentSummary extends Struct() {}
diff --git a/src/domain/entities/risk-assessment/__tests__/RiskAssessmentGrading.spec.ts b/src/domain/entities/risk-assessment/__tests__/RiskAssessmentGrading.spec.ts
new file mode 100644
index 00000000..1f1b9e3c
--- /dev/null
+++ b/src/domain/entities/risk-assessment/__tests__/RiskAssessmentGrading.spec.ts
@@ -0,0 +1,66 @@
+import { describe, expect, it } from "vitest";
+import { RiskAssessmentGrading } from "../RiskAssessmentGrading";
+
+const lowPopulationAtRisk = { type: "LessPercentage" as const, weight: 1 as const };
+const mediumPopulationAtRisk = { type: "MediumPercentage" as const, weight: 2 as const };
+const highPopulationAtRisk = { type: "HighPercentage" as const, weight: 3 as const };
+const lowWeightedOption = { type: "Low" as const, weight: 1 as const };
+const mediumWeightedOption = { type: "Medium" as const, weight: 2 as const };
+const highWeightedOption = { type: "High" as const, weight: 3 as const };
+const lowGeographicalSpread = { type: "WithinDistrict" as const, weight: 1 as const };
+const mediumGeographicalSpread = { type: "MoretThanOneDistrict" as const, weight: 2 as const };
+const highGeographicalSpread = { type: "MoreThanOneProvince" as const, weight: 3 as const };
+const lowCapacity = { type: "ProvincialNationalLevel" as const, weight: 1 as const };
+const mediumCapacity = { type: "ProvincialLevel" as const, weight: 2 as const };
+const highCapacity = { type: "NationalInternationalLevel" as const, weight: 3 as const };
+
+describe("RiskAssessmentGrading", () => {
+ it("should be Grade1 if total weight is less than or equal to 7", () => {
+ const riskAssessmentGrading = RiskAssessmentGrading.create({
+ id: "1",
+ lastUpdated: new Date(),
+ populationAtRisk: lowPopulationAtRisk,
+ attackRate: lowWeightedOption,
+ geographicalSpread: lowGeographicalSpread,
+ complexity: lowWeightedOption,
+ capacity: lowCapacity,
+ reputationalRisk: lowWeightedOption,
+ severity: lowWeightedOption,
+ });
+ const grade = riskAssessmentGrading.getGrade().getOrThrow();
+ if (grade) expect(RiskAssessmentGrading.getTranslatedLabel(grade)).toBe("Grade 1");
+ });
+
+ it("should be Grade2 if total weight is greater than 7 and less than equal to 14", () => {
+ const riskAssessmentGrading = RiskAssessmentGrading.create({
+ id: "2",
+ lastUpdated: new Date(),
+ populationAtRisk: mediumPopulationAtRisk,
+ attackRate: mediumWeightedOption,
+ geographicalSpread: mediumGeographicalSpread,
+ complexity: mediumWeightedOption,
+ capacity: mediumCapacity,
+ reputationalRisk: mediumWeightedOption,
+ severity: mediumWeightedOption,
+ });
+ const grade = riskAssessmentGrading.getGrade().getOrThrow();
+ if (grade) expect(RiskAssessmentGrading.getTranslatedLabel(grade)).toBe("Grade 2");
+ });
+
+ it("should be Grade3 if score is greater than 14", () => {
+ const riskAssessmentGrading = RiskAssessmentGrading.create({
+ id: "3",
+ lastUpdated: new Date(),
+ populationAtRisk: highPopulationAtRisk,
+ attackRate: highWeightedOption,
+ geographicalSpread: highGeographicalSpread,
+ complexity: highWeightedOption,
+ capacity: highCapacity,
+ reputationalRisk: highWeightedOption,
+ severity: highWeightedOption,
+ });
+
+ const grade = riskAssessmentGrading.getGrade().getOrThrow();
+ if (grade) expect(RiskAssessmentGrading.getTranslatedLabel(grade)).toBe("Grade 3");
+ });
+});