Skip to content

Commit

Permalink
Merge branch 'main' into tech-debt-legacy-tags
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 authored Apr 1, 2024
2 parents 4e27ffb + 3bcce7a commit 0bb9ef2
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 103 deletions.
12 changes: 10 additions & 2 deletions client/src/app/hooks/useAssessmentStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,22 @@ export const useAssessmentStatus = (application: Application) => {
(assessment: Assessment) =>
assessment.status === "started" ||
assessment.status === "empty" ||
assessment.status === "complete"
(assessment.status === "complete" &&
application.assessments?.length !== 0)
);

return {
allArchetypesAssessed,
countOfFullyAssessedArchetypes: assessedArchetypesCount,
countOfArchetypesWithRequiredAssessments: assessmentsFromArchetypesCount,
hasApplicationAssessmentInProgress,
isApplicationDirectlyAssessed: isDirectlyAssessed,
};
}, [assessments, archetypes, application.id, isDirectlyAssessed]);
}, [
assessments,
archetypes,
application.id,
application.assessments,
isDirectlyAssessed,
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import {
// Queries
import { Application, Assessment, Ref, Task } from "@app/api/models";
import {
ApplicationsQueryKey,
useBulkDeleteApplicationMutation,
useFetchApplications,
} from "@app/queries/applications";
Expand Down Expand Up @@ -243,64 +242,54 @@ export const ApplicationsTable: React.FC = () => {
onDeleteApplicationError
);

const onDeleteReviewSuccess = (name: string) => {
pushNotification({
title: t("toastr.success.reviewDiscarded", {
application: name,
}),
variant: "success",
});
queryClient.invalidateQueries([ApplicationsQueryKey]);
};

const { mutate: deleteReview } = useDeleteReviewMutation(
onDeleteReviewSuccess
(name) => {
pushNotification({
title: t("toastr.success.reviewDiscarded", { application: name }),
variant: "success",
});
},
(error) => {
console.error("Error while deleting review:", error);
pushNotification({
title: getAxiosErrorMessage(error),
variant: "danger",
});
}
);

const { mutate: deleteAssessment } = useDeleteAssessmentMutation();

const discardAssessment = async (application: Application) => {
try {
if (application.assessments) {
await Promise.all(
application.assessments.map(async (assessment) => {
await deleteAssessment({
assessmentId: assessment.id,
applicationName: application.name,
});
})
).then(() => {
pushNotification({
title: t("toastr.success.assessmentDiscarded", {
application: application.name,
}),
variant: "success",
});
queryClient.invalidateQueries([ApplicationsQueryKey]);
});
}
} catch (error) {
const { mutate: deleteAssessment } = useDeleteAssessmentMutation(
(name) => {
pushNotification({
title: t("toastr.success.assessmentDiscarded", { application: name }),
variant: "success",
});
},
(error) => {
console.error("Error while deleting assessments:", error);
pushNotification({
title: getAxiosErrorMessage(error as AxiosError),
title: getAxiosErrorMessage(error),
variant: "danger",
});
}
);

const discardAssessment = async (application: Application) => {
if (application.assessments) {
application.assessments.forEach((assessment) => {
deleteAssessment({
assessmentId: assessment.id,
applicationName: application.name,
});
});
}
};

const discardReview = async (application: Application) => {
try {
if (application.review?.id) {
await deleteReview({
id: application.review.id,
name: application.name,
});
}
} catch (error) {
console.error("Error while deleting review:", error);
pushNotification({
title: getAxiosErrorMessage(error as AxiosError),
variant: "danger",
if (application.review) {
deleteReview({
id: application.review.id,
name: application.name,
});
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
} from "@app/test-config/test-utils";
import { rest } from "msw";
import { server } from "@mocks/server";
import { assessmentsQueryKey } from "@app/queries/assessments";
import { QueryClient } from "@tanstack/react-query";

describe("useAssessmentStatus", () => {
beforeEach(() => {
Expand All @@ -18,6 +20,73 @@ describe("useAssessmentStatus", () => {
server.resetHandlers();
});

it("Updates hasApplicationAssessmentInProgress to false once associated assessments are deleted", async () => {
server.use(
rest.get("/hub/assessments", (req, res, ctx) => {
return res(
ctx.json([
createMockAssessment({
id: 1,
application: { id: 1, name: "app1" },
questionnaire: { id: 1, name: "questionnaire1" },
status: "started",
sections: [],
}),
createMockAssessment({
id: 2,
application: { id: 1, name: "app1" },
questionnaire: { id: 2, name: "questionnaire2" },
status: "complete",
sections: [],
}),
])
);
}),
rest.get("/hub/archetypes", (req, res, ctx) => {
return res(
ctx.json([
createMockArchetype({
id: 1,
name: "archetype1",
applications: [],
assessed: false,
assessments: [],
}),
])
);
})
);
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
cacheTime: 1000,
},
},
});
const { result, rerender } = renderHook(
() => useAssessmentStatus(createMockApplication({ id: 1, name: "app1" })),
{ queryClient }
);

await waitFor(() => {
expect(result.current.hasApplicationAssessmentInProgress).toBe(true);
});

server.use(
rest.get("/hub/assessments", (req, res, ctx) => {
return res(ctx.json([]));
})
);
queryClient.invalidateQueries([assessmentsQueryKey]);

rerender(createMockApplication({ id: 1, name: "app1" }));

await waitFor(() => {
expect(result.current.hasApplicationAssessmentInProgress).toBe(false);
});
});

it("Correctly calculates status given one started assessment and one complete assessment for an application", async () => {
server.use(
rest.get("/hub/assessments", (req, res, ctx) => {
Expand Down Expand Up @@ -55,10 +124,10 @@ describe("useAssessmentStatus", () => {
);
})
);
const { result, waitForNextUpdate } = renderHook(() =>

const { result } = renderHook(() =>
useAssessmentStatus(createMockApplication({ id: 1, name: "app1" }))
);
await waitForNextUpdate();
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: false,
Expand Down Expand Up @@ -105,11 +174,8 @@ describe("useAssessmentStatus", () => {
assessments: mockAssessments,
});

const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
const { result } = renderHook(() => useAssessmentStatus(mockApplication));

await waitForNextUpdate();
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: false,
Expand Down Expand Up @@ -175,10 +241,7 @@ describe("useAssessmentStatus", () => {
],
assessed: false,
});
const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
await waitForNextUpdate();
const { result } = renderHook(() => useAssessmentStatus(mockApplication));
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: false,
Expand Down Expand Up @@ -228,10 +291,7 @@ describe("useAssessmentStatus", () => {
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
await waitForNextUpdate();
const { result } = renderHook(() => useAssessmentStatus(mockApplication));
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: true,
Expand Down Expand Up @@ -279,10 +339,7 @@ describe("useAssessmentStatus", () => {
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
await waitForNextUpdate();
const { result } = renderHook(() => useAssessmentStatus(mockApplication));
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: false,
Expand Down Expand Up @@ -331,10 +388,7 @@ describe("useAssessmentStatus", () => {
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
await waitForNextUpdate();
const { result } = renderHook(() => useAssessmentStatus(mockApplication));
await waitFor(() => {
expect(result.current).toEqual({
allArchetypesAssessed: true,
Expand Down Expand Up @@ -398,10 +452,7 @@ describe("useAssessmentStatus", () => {
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useAssessmentStatus(mockApplication)
);
await waitForNextUpdate();
const { result } = renderHook(() => useAssessmentStatus(mockApplication));

await waitFor(() => {
expect(result.current).toEqual({
Expand Down
15 changes: 3 additions & 12 deletions client/src/app/queries/assessments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from "@app/api/models";
import { QuestionnairesQueryKey } from "./questionnaires";
import { ARCHETYPE_QUERY_KEY } from "./archetypes";
import { ApplicationsQueryKey } from "./applications";

export const assessmentsQueryKey = "assessments";
export const assessmentQueryKey = "assessment";
Expand Down Expand Up @@ -120,20 +121,10 @@ export const useDeleteAssessmentMutation = (
archetypeId?: number;
}) => {
const deletedAssessment = deleteAssessment(args.assessmentId);
const isArchetype = !!args.archetypeId;

queryClient.invalidateQueries([assessmentQueryKey, args?.assessmentId]);
queryClient.invalidateQueries([ApplicationsQueryKey]);
queryClient.invalidateQueries([assessmentsQueryKey]);
queryClient.invalidateQueries([ARCHETYPE_QUERY_KEY, args?.archetypeId]);
queryClient.invalidateQueries([
assessmentsByItemIdQueryKey,
args?.archetypeId,
isArchetype,
]);
queryClient.invalidateQueries([
assessmentsByItemIdQueryKey,
args?.applicationId,
isArchetype,
]);

return deletedAssessment;
},
Expand Down
4 changes: 3 additions & 1 deletion client/src/app/queries/reviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from "@app/api/rest";
import { New, Review } from "@app/api/models";
import { AxiosError } from "axios";
import { ApplicationsQueryKey } from "./applications";

export const reviewQueryKey = "review";
export const reviewsByItemIdQueryKey = "reviewsByItemId";
Expand Down Expand Up @@ -85,13 +86,14 @@ export const useDeleteReviewMutation = (
onSuccess: (_, args) => {
onSuccess && onSuccess(args.name);
queryClient.invalidateQueries([reviewsQueryKey]);
queryClient.invalidateQueries([ApplicationsQueryKey]);
},
onError: onError && onError,
});
};

export const useFetchReviewById = (id?: number | string) => {
const { data, isLoading, error, isFetching } = useQuery({
const { data, error, isFetching } = useQuery({
queryKey: [reviewQueryKey, id],
queryFn: () =>
id === undefined ? Promise.resolve(null) : getReviewById(id),
Expand Down
Loading

0 comments on commit 0bb9ef2

Please sign in to comment.