From 0e16ea98280b258e7fea2bc68e07d96c0dbb158c Mon Sep 17 00:00:00 2001 From: mrikallab <93978883+mrikallab@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:13:24 +0200 Subject: [PATCH] N21-1324-migration-page-buttons-fix (#2834) --- .../AdminMigrationSection.unit.ts | 4 +- .../administration/AdminMigrationSection.vue | 2 +- src/store/user-login-migrations.ts | 44 ++++- src/store/user-login-migrations.unit.ts | 164 +++++++++++++++++- 4 files changed, 208 insertions(+), 6 deletions(-) diff --git a/src/components/administration/AdminMigrationSection.unit.ts b/src/components/administration/AdminMigrationSection.unit.ts index be068c5113..74fbdfc46a 100644 --- a/src/components/administration/AdminMigrationSection.unit.ts +++ b/src/components/administration/AdminMigrationSection.unit.ts @@ -567,7 +567,7 @@ describe("AdminMigrationSection", () => { userLoginMigrationModule.startUserLoginMigration ).toHaveBeenCalled(); expect( - userLoginMigrationModule.fetchLatestUserLoginMigrationForCurrentUser + userLoginMigrationModule.fetchLatestUserLoginMigrationForSchool ).toHaveBeenCalled(); }); }); @@ -676,7 +676,7 @@ describe("AdminMigrationSection", () => { userLoginMigrationModule.closeUserLoginMigration ).toHaveBeenCalled(); expect( - userLoginMigrationModule.fetchLatestUserLoginMigrationForCurrentUser + userLoginMigrationModule.fetchLatestUserLoginMigrationForSchool ).toHaveBeenCalled(); }); }); diff --git a/src/components/administration/AdminMigrationSection.vue b/src/components/administration/AdminMigrationSection.vue index a4b86781ac..737c31f348 100644 --- a/src/components/administration/AdminMigrationSection.vue +++ b/src/components/administration/AdminMigrationSection.vue @@ -201,7 +201,7 @@ export default defineComponent({ onMounted(async () => { // TODO remove in https://ticketsystem.dbildungscloud.de/browse/N21-820 await schoolsModule.fetchSchoolOAuthMigration(); - await userLoginMigrationModule.fetchLatestUserLoginMigrationForCurrentUser(); + await userLoginMigrationModule.fetchLatestUserLoginMigrationForSchool(); }); const userLoginMigration: ComputedRef = diff --git a/src/store/user-login-migrations.ts b/src/store/user-login-migrations.ts index 3efe717ee0..7f2454550f 100644 --- a/src/store/user-login-migrations.ts +++ b/src/store/user-login-migrations.ts @@ -1,5 +1,5 @@ import { $axios, mapAxiosErrorToResponseError } from "@/utils/api"; -import { AxiosError, AxiosResponse } from "axios"; +import { AxiosResponse, HttpStatusCode } from "axios"; import { Action, Module, Mutation, VuexModule } from "vuex-module-decorators"; import { PageContentResponse, @@ -173,6 +173,48 @@ export default class UserLoginMigrationModule extends VuexModule { this.setLoading(false); } + @Action + async fetchLatestUserLoginMigrationForSchool(): Promise { + this.setLoading(true); + + this.resetBusinessError(); + + if (authModule.getUser?.schoolId) { + try { + const response: AxiosResponse = + await this.userLoginMigrationApi.userLoginMigrationControllerFindUserLoginMigrationBySchool( + authModule.getUser?.schoolId + ); + + if (response.data.startedAt) { + const userLoginMigration: UserLoginMigration = + UserLoginMigrationMapper.mapToUserLoginMigration(response.data); + + this.setUserLoginMigration(userLoginMigration); + } + } catch (error: unknown) { + const apiError = mapAxiosErrorToResponseError(error); + + if (apiError.code === HttpStatusCode.NotFound) { + this.setUserLoginMigration(undefined); + return; + } + + console.log(apiError); + + this.setBusinessError({ + error: apiError, + statusCode: apiError.code, + message: apiError.message, + }); + + throw createApplicationError(apiError.code); + } + } + + this.setLoading(false); + } + @Action async startUserLoginMigration(): Promise { this.setLoading(true); diff --git a/src/store/user-login-migrations.unit.ts b/src/store/user-login-migrations.unit.ts index ad7daf18bf..abb0b952a7 100644 --- a/src/store/user-login-migrations.unit.ts +++ b/src/store/user-login-migrations.unit.ts @@ -13,6 +13,7 @@ import { } from "./user-login-migration"; import UserLoginMigrationModule from "./user-login-migrations"; import { + apiResponseErrorFactory, axiosErrorFactory, businessErrorFactory, mockApiResponse, @@ -248,7 +249,7 @@ describe("UserLoginMigrationModule", () => { authModule.setUser({ ...mockUser, id: "" }); }; - it("should not call the userMigrationApi.userMigrationControllerGetLatestUserLoginMigrationForCurrentUser", async () => { + it("should not get latest user login migration ", async () => { setup(); await module.fetchLatestUserLoginMigrationForCurrentUser(); @@ -370,7 +371,7 @@ describe("UserLoginMigrationModule", () => { }; }; - it("should call the userMigrationApi.userMigrationControllerGetLatestUserLoginMigrationForCurrentUser", async () => { + it("should get latest user login migrations", async () => { setup(); await module.fetchLatestUserLoginMigrationForCurrentUser(); @@ -454,6 +455,165 @@ describe("UserLoginMigrationModule", () => { }); }); + describe("getLatestUserLoginMigrationForSchool", () => { + describe("when school id is not available", () => { + const setup = () => { + authModule.setUser({ ...mockUser, schoolId: "" }); + }; + + it("should not get latest user login migrations", async () => { + setup(); + + await module.fetchLatestUserLoginMigrationForSchool(); + + expect( + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool + ).not.toHaveBeenCalled(); + }); + }); + + describe("when school is available", () => { + describe("when there is no migration for a school", () => { + const setup = () => { + authModule.setUser({ ...mockUser, schoolId: "schoolId" }); + + const error = axiosErrorFactory.build({ + response: { + data: apiResponseErrorFactory.build({ + code: HttpStatusCode.NotFound, + }), + }, + }); + + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool.mockRejectedValue( + error + ); + }; + + it("should set the user login migration to undefined", async () => { + setup(); + + await module.fetchLatestUserLoginMigrationForSchool(); + + expect(module.getUserLoginMigration).toBeUndefined(); + }); + }); + + describe("when there is a migration for the school", () => { + const setup = () => { + authModule.setUser({ ...mockUser, schoolId: "schoolId" }); + + const userLoginMigrationResponse: UserLoginMigrationResponse = + userLoginMigrationResponseFactory.build({ + sourceSystemId: "sourceSystemId", + targetSystemId: "targetSystemId", + startedAt: new Date(2000, 1, 1, 0, 0).toString(), + closedAt: new Date(2000, 1, 1, 0, 0).toString(), + finishedAt: new Date(2000, 1, 14, 0, 0).toString(), + mandatorySince: new Date(2000, 1, 1, 0, 0).toString(), + }); + + const userLoginMigration: UserLoginMigration = { + sourceSystemId: "sourceSystemId", + targetSystemId: "targetSystemId", + startedAt: new Date(2000, 1, 1, 0, 0), + closedAt: new Date(2000, 1, 1, 0, 0), + finishedAt: new Date(2000, 1, 14, 0, 0), + mandatorySince: new Date(2000, 1, 1, 0, 0), + }; + + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool.mockResolvedValue( + mockApiResponse({ data: userLoginMigrationResponse }) + ); + + return { + userLoginMigration, + userLoginMigrationResponse, + }; + }; + + it("should get latest user login migrations", async () => { + setup(); + + await module.fetchLatestUserLoginMigrationForSchool(); + + expect( + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool + ).toHaveBeenCalled(); + }); + + it("should set the UserLoginMigration", async () => { + const { userLoginMigration } = setup(); + + await module.fetchLatestUserLoginMigrationForSchool(); + + expect(module.getUserLoginMigration).toEqual(userLoginMigration); + }); + }); + }); + + describe("when the api throws an error", () => { + const setup = () => { + authModule.setUser({ ...mockUser, schoolId: "schoolId" }); + + const error = axiosErrorFactory.build(); + const apiError = mapAxiosErrorToResponseError(error); + + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool.mockRejectedValue( + error + ); + + return { + apiError, + }; + }; + + it("should set the businessError", async () => { + const { apiError } = setup(); + + await expect( + module.fetchLatestUserLoginMigrationForSchool() + ).rejects.toThrow(); + + expect(module.getBusinessError).toEqual({ + error: apiError, + statusCode: apiError.code, + message: apiError.message, + }); + }); + + it("should throw application error", async () => { + setup(); + + const func = () => module.fetchLatestUserLoginMigrationForSchool(); + + await expect(func()).rejects.toEqual( + createApplicationError(HttpStatusCode.BadRequest) + ); + }); + }); + + describe("when the api returns a bad request", () => { + const setup = () => { + authModule.setUser({ ...mockUser, schoolId: "schoolId" }); + + apiMock.userLoginMigrationControllerFindUserLoginMigrationBySchool.mockRejectedValue( + createApplicationError(HttpStatusCode.BadRequest) + ); + }; + + it("should throw an error with status code BadRequest when an ApplicationError is thrown", async () => { + setup(); + + const func = () => module.fetchLatestUserLoginMigrationForSchool(); + + await expect(func()).rejects.toEqual( + createApplicationError(HttpStatusCode.BadRequest) + ); + }); + }); + }); + describe("startUserLoginMigration", () => { describe("when it successfully calls the api", () => { const setup = () => {