Skip to content

Commit

Permalink
👻 Add unit tests and hook for useAssessmentStatus
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Bolton <[email protected]>
  • Loading branch information
ibolton336 committed Mar 11, 2024
1 parent 3e3d690 commit 3074620
Show file tree
Hide file tree
Showing 4 changed files with 438 additions and 84 deletions.
76 changes: 76 additions & 0 deletions client/src/app/hooks/useAssessmentStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// hooks/useAssessmentStatus.js
import { Assessment, Archetype, Application } from "@app/api/models";
import { useMemo } from "react";

export const useAssessmentStatus = (
assessments: Assessment[],
archetypes: Archetype[],
application: Application
) => {
return useMemo(() => {
const applicationAssessments = assessments?.filter(
(assessment: Assessment) => assessment.application?.id === application.id
);
const inheritedArchetypes = archetypes?.filter(
(archetype: Archetype) =>
archetype.applications?.map((app) => app.id).includes(application.id)
);

const assessmentsWithArchetypes = inheritedArchetypes.map(
(inheritedArchetype) => ({
inheritedArchetype,
assessments: assessments.filter(
(assessment) => assessment.archetype?.id === inheritedArchetype.id
),
})
);

const allArchetypesAssessed =
assessmentsWithArchetypes.length > 0 &&
assessmentsWithArchetypes.every(({ inheritedArchetype, assessments }) => {
const requiredAssessments = assessments.filter(
(assessment) => assessment.required
);
return (
inheritedArchetype.assessed &&
assessments.length > 0 &&
requiredAssessments.length > 0 &&
requiredAssessments.every(
(assessment) => assessment.status === "complete"
)
);
});

const assessmentsFromArchetypesCount = assessmentsWithArchetypes.filter(
({ assessments }) => assessments.some((assessment) => assessment.required)
).length;

const assessedArchetypesCount = assessmentsWithArchetypes.filter(
({ assessments, inheritedArchetype }) =>
assessments.some(
(assessment) =>
assessment.required &&
assessment.status === "complete" &&
inheritedArchetype.assessed
)
).length;

const hasApplicationAssessmentInProgress = applicationAssessments?.some(
(assessment: Assessment) =>
assessment.status === "started" ||
assessment.status === "empty" ||
assessment.status === "complete"
);
const isDirectlyAssessed =
(application.assessed && (application.assessments?.length ?? 0) > 0) ??
false;

return {
allArchetypesAssessed,
countOfFullyAssessedArchetypes: assessedArchetypesCount,
countOfArchetypesWithRequiredAssessments: assessmentsFromArchetypesCount,
hasApplicationAssessmentInProgress,
isApplicationDirectlyAssessed: isDirectlyAssessed,
};
}, [assessments, archetypes, application]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
import { Application, Archetype, Assessment } from "@app/api/models";
import { IconedStatus, IconedStatusPreset } from "@app/components/IconedStatus";
import { Spinner } from "@patternfly/react-core";
import { useAssessmentStatus } from "@app/hooks/useAssessmentStatus";
interface ApplicationAssessmentStatusProps {
application: Application;
assessments: Assessment[];
Expand All @@ -15,77 +16,11 @@ export const ApplicationAssessmentStatus: React.FC<
> = ({ application, assessments, archetypes, isLoading }) => {
const { t } = useTranslation();

const applicationAssessments = assessments?.filter(
(assessment: Assessment) => assessment.application?.id === application.id
const assessmentStatusInfo = useAssessmentStatus(
assessments,
archetypes,
application
);
const inheritedArchetypes = archetypes?.filter(
(archetype: Archetype) =>
archetype.applications?.map((app) => app.id).includes(application.id)
);
const assessmentStatusInfo = React.useMemo(() => {
const assessmentsWithArchetypes = inheritedArchetypes.map(
(inheritedArchetype) => ({
inheritedArchetype,
assessments: assessments.filter(
(assessment) => assessment.archetype?.id === inheritedArchetype.id
),
})
);

const someArchetypesAssessed = assessmentsWithArchetypes.some(
({ assessments }) => assessments.length > 0
);

const allArchetypesAssessed =
assessmentsWithArchetypes.length > 0 &&
assessmentsWithArchetypes.every(({ inheritedArchetype, assessments }) => {
const requiredAssessments = assessments.filter(
(assessment) => assessment.required
);
return (
inheritedArchetype.assessed &&
assessments.length > 0 &&
requiredAssessments.length > 0 &&
requiredAssessments.every(
(assessment) => assessment.status === "complete"
)
);
});

const hasInProgressOrNotStartedRequiredAssessments =
assessmentsWithArchetypes.some(({ assessments }) =>
assessments.some(
(assessment) =>
assessment.required &&
["empty", "started"].includes(assessment.status)
)
);

const assessedArchetypesWithARequiredAssessment =
assessmentsWithArchetypes.filter(({ assessments, inheritedArchetype }) =>
assessments.some(
(assessment) =>
assessment.required &&
assessment.status === "complete" &&
inheritedArchetype.assessed
)
);
const assessedArchetypeCount =
inheritedArchetypes?.filter(
(inheritedArchetype) =>
inheritedArchetype?.assessments?.length ??
(0 > 0 && inheritedArchetype.assessed)
).length || 0;

return {
assessmentsWithArchetypes,
someArchetypesAssessed,
allArchetypesAssessed,
hasInProgressOrNotStartedRequiredAssessments,
assessedArchetypesWithARequiredAssessment,
assessedArchetypeCount,
};
}, [inheritedArchetypes, assessments]);

if (isLoading) {
return <Spinner size="sm" />;
Expand All @@ -94,28 +29,23 @@ export const ApplicationAssessmentStatus: React.FC<
let statusPreset: IconedStatusPreset = "NotStarted"; // Default status
let tooltipCount: number = 0;

const isDirectlyAssessed =
application.assessed && (application.assessments?.length ?? 0) > 0;

const {
allArchetypesAssessed,
assessedArchetypesWithARequiredAssessment,
hasInProgressOrNotStartedRequiredAssessments,
countOfFullyAssessedArchetypes,
countOfArchetypesWithRequiredAssessments,
hasApplicationAssessmentInProgress,
isApplicationDirectlyAssessed,
} = assessmentStatusInfo;

if (isDirectlyAssessed) {
if (isApplicationDirectlyAssessed) {
statusPreset = "Completed";
} else if (allArchetypesAssessed) {
statusPreset = "InheritedAssessments";
tooltipCount = assessedArchetypesWithARequiredAssessment.length;
} else if (hasInProgressOrNotStartedRequiredAssessments) {
tooltipCount = countOfFullyAssessedArchetypes;
} else if (countOfArchetypesWithRequiredAssessments > 0) {
statusPreset = "InProgressInheritedAssessments";
tooltipCount = assessedArchetypesWithARequiredAssessment.length;
} else if (
applicationAssessments?.some(
(assessment) => assessment.status === "started"
)
) {
tooltipCount = countOfArchetypesWithRequiredAssessments;
} else if (hasApplicationAssessmentInProgress) {
statusPreset = "InProgress";
}
return <IconedStatus preset={statusPreset} tooltipCount={tooltipCount} />;
Expand Down
Loading

0 comments on commit 3074620

Please sign in to comment.