From 8da2a40248dfc4a425c12ca7a3e76c3be78c5758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20=C3=96hlerking?= <103562092+MarvinOehlerkingCap@users.noreply.github.com> Date: Fri, 3 Nov 2023 13:58:57 +0100 Subject: [PATCH] N21-1310 Refactor user login migration api spec (#4520) --- apps/server/src/modules/provisioning/index.ts | 2 +- .../modules/provisioning/strategy/index.ts | 2 +- .../provisioning/strategy/sanis/index.ts | 3 + .../api-test/user-login-migration.api.spec.ts | 234 ++++++++++++------ .../response/user-login-migration.response.ts | 4 + .../user-login-migration.controller.ts | 5 +- .../mapper/user-login-migration.mapper.ts | 3 +- .../src/shared/testing/factory/index.ts | 1 + .../shared/testing/user-role-permissions.ts | 1 + 9 files changed, 170 insertions(+), 85 deletions(-) create mode 100644 apps/server/src/modules/provisioning/strategy/sanis/index.ts diff --git a/apps/server/src/modules/provisioning/index.ts b/apps/server/src/modules/provisioning/index.ts index b9814818220..0e0bc64d04a 100644 --- a/apps/server/src/modules/provisioning/index.ts +++ b/apps/server/src/modules/provisioning/index.ts @@ -1,4 +1,4 @@ export * from './provisioning.module'; export * from './dto/provisioning.dto'; export * from './service/provisioning.service'; -export * from './strategy/index'; +export * from './strategy'; diff --git a/apps/server/src/modules/provisioning/strategy/index.ts b/apps/server/src/modules/provisioning/strategy/index.ts index 369357cc351..e0eeeae1776 100644 --- a/apps/server/src/modules/provisioning/strategy/index.ts +++ b/apps/server/src/modules/provisioning/strategy/index.ts @@ -2,4 +2,4 @@ export * from './base.strategy'; export * from './iserv/iserv.strategy'; export * from './oidc/oidc.strategy'; export * from './oidc-mock/oidc-mock.strategy'; -export * from './sanis/sanis.strategy'; +export * from './sanis'; diff --git a/apps/server/src/modules/provisioning/strategy/sanis/index.ts b/apps/server/src/modules/provisioning/strategy/sanis/index.ts new file mode 100644 index 00000000000..4f98cbd73e9 --- /dev/null +++ b/apps/server/src/modules/provisioning/strategy/sanis/index.ts @@ -0,0 +1,3 @@ +export * from './response'; +export * from './sanis.strategy'; +export * from './sanis-response.mapper'; diff --git a/apps/server/src/modules/user-login-migration/controller/api-test/user-login-migration.api.spec.ts b/apps/server/src/modules/user-login-migration/controller/api-test/user-login-migration.api.spec.ts index b2de2ac9fc0..154148c1fa0 100644 --- a/apps/server/src/modules/user-login-migration/controller/api-test/user-login-migration.api.spec.ts +++ b/apps/server/src/modules/user-login-migration/controller/api-test/user-login-migration.api.spec.ts @@ -1,12 +1,16 @@ import { Configuration } from '@hpi-schul-cloud/commons/lib'; import { EntityManager, ObjectId } from '@mikro-orm/mongodb'; +import { OauthTokenResponse } from '@modules/oauth/service/dto'; +import { SanisResponse, SanisRole } from '@modules/provisioning'; +import { ServerTestModule } from '@modules/server'; import { HttpStatus, INestApplication } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; -import { Permission, SchoolEntity, SystemEntity, User } from '@shared/domain'; +import { SchoolEntity, SystemEntity, User } from '@shared/domain'; import { UserLoginMigrationEntity } from '@shared/domain/entity/user-login-migration.entity'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { cleanupCollections, + JwtTestFactory, schoolFactory, systemFactory, TestApiClient, @@ -14,14 +18,11 @@ import { userFactory, userLoginMigrationFactory, } from '@shared/testing'; -import { JwtTestFactory } from '@shared/testing/factory/jwt.test.factory'; -import { OauthTokenResponse } from '@modules/oauth/service/dto'; -import { ServerTestModule } from '@modules/server'; +import { ErrorResponse } from '@src/core/error/dto'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { UUID } from 'bson'; import { Response } from 'supertest'; -import { SanisResponse, SanisRole } from '@modules/provisioning/strategy/sanis/response'; import { UserLoginMigrationResponse } from '../dto'; import { Oauth2MigrationParams } from '../dto/oauth2-migration.params'; @@ -37,6 +38,7 @@ jest.mock('jwks-rsa', () => () => { getSigningKeys: jest.fn(), }; }); + describe('UserLoginMigrationController (API)', () => { let app: INestApplication; let em: EntityManager; @@ -80,8 +82,8 @@ describe('UserLoginMigrationController (API)', () => { sourceSystem, startedAt: date, mandatorySince: date, - closedAt: undefined, - finishedAt: undefined, + closedAt: date, + finishedAt: date, }); const { teacherAccount, teacherUser } = UserAndAccountTestFactory.buildTeacher({ school }); @@ -107,6 +109,7 @@ describe('UserLoginMigrationController (API)', () => { expect(response.body).toEqual({ data: [ { + id: userLoginMigration.id, sourceSystemId: sourceSystem.id, targetSystemId: targetSystem.id, startedAt: userLoginMigration.startedAt.toISOString(), @@ -130,7 +133,7 @@ describe('UserLoginMigrationController (API)', () => { }); describe('[GET] /user-login-migrations/schools/:schoolId', () => { - describe('when a user login migration is found', () => { + describe('when a user login migration exists', () => { const setup = async () => { const date: Date = new Date(2023, 5, 4); const sourceSystem: SystemEntity = systemFactory.withLdapConfig().buildWithId({ alias: 'SourceSystem' }); @@ -147,9 +150,7 @@ describe('UserLoginMigrationController (API)', () => { closedAt: undefined, finishedAt: undefined, }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); @@ -171,6 +172,7 @@ describe('UserLoginMigrationController (API)', () => { expect(response.status).toEqual(HttpStatus.OK); expect(response.body).toEqual({ + id: userLoginMigration.id, sourceSystemId: sourceSystem.id, targetSystemId: targetSystem.id, startedAt: userLoginMigration.startedAt.toISOString(), @@ -181,12 +183,10 @@ describe('UserLoginMigrationController (API)', () => { }); }); - describe('when no user login migration is found', () => { + describe('when no user login migration exists', () => { const setup = async () => { const school: SchoolEntity = schoolFactory.buildWithId(); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([school, adminAccount, adminUser]); @@ -198,13 +198,26 @@ describe('UserLoginMigrationController (API)', () => { }; }; - it('should return the users migration', async () => { + it('should have the status "not found"', async () => { const { loggedInClient, school } = await setup(); const response: Response = await loggedInClient.get(`schools/${school.id}`); expect(response.status).toEqual(HttpStatus.NOT_FOUND); }); + + it('should return an error response', async () => { + const { loggedInClient, school } = await setup(); + + const response: Response = await loggedInClient.get(`schools/${school.id}`); + + expect(response.body).toEqual({ + message: 'Not Found', + type: 'NOT_FOUND', + code: 404, + title: 'Not Found', + }); + }); }); describe('when unauthorized', () => { @@ -217,7 +230,7 @@ describe('UserLoginMigrationController (API)', () => { }); describe('[POST] /start', () => { - describe('when current User start the migration successfully', () => { + describe('when current user start the migration successfully', () => { const setup = async () => { const sourceSystem: SystemEntity = systemFactory.withLdapConfig().buildWithId({ alias: 'SourceSystem' }); const targetSystem: SystemEntity = systemFactory.withOauthConfig().buildWithId({ alias: 'SANIS' }); @@ -226,9 +239,7 @@ describe('UserLoginMigrationController (API)', () => { officialSchoolNumber: '12345', }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser]); @@ -236,6 +247,8 @@ describe('UserLoginMigrationController (API)', () => { return { loggedInClient, + sourceSystem, + targetSystem, }; }; @@ -246,6 +259,28 @@ describe('UserLoginMigrationController (API)', () => { expect(response.status).toEqual(HttpStatus.CREATED); }); + + it('should return the user login migration', async () => { + const { loggedInClient, sourceSystem, targetSystem } = await setup(); + + const response: Response = await loggedInClient.post(`/start`); + + expect(response.body).toEqual({ + id: expect.any(String), + sourceSystemId: sourceSystem.id, + startedAt: expect.any(String), + targetSystemId: targetSystem.id, + }); + }); + + it('should should change the database correctly', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.post(`/start`); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + await em.findOneOrFail(UserLoginMigrationEntity, { id: response.body.id }); + }); }); describe('when current User start the migration and is not authorized', () => { @@ -296,9 +331,7 @@ describe('UserLoginMigrationController (API)', () => { mandatorySince: date, }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); @@ -339,9 +372,7 @@ describe('UserLoginMigrationController (API)', () => { finishedAt: date, }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); @@ -370,9 +401,7 @@ describe('UserLoginMigrationController (API)', () => { systems: [sourceSystem], }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser]); @@ -466,10 +495,10 @@ describe('UserLoginMigrationController (API)', () => { startedAt: new Date('2022-12-17T03:24:00'), }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin( - { school, externalId: 'externalUserId' }, - [Permission.USER_LOGIN_MIGRATION_ADMIN] - ); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ + school, + externalId: 'externalUserId', + }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -610,9 +639,7 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -642,16 +669,29 @@ describe('UserLoginMigrationController (API)', () => { expect(response.body).not.toHaveProperty('closedAt'); expect(response.body).not.toHaveProperty('finishedAt'); }); + + it('should should change the database correctly', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.put(`/restart`); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + const entity = await em.findOneOrFail(UserLoginMigrationEntity, { id: response.body.id }); + + expect(entity.startedAt).toBeDefined(); + expect(entity.closedAt).toBeUndefined(); + expect(entity.finishedAt).toBeUndefined(); + }); }); describe('when invalid User restart the migration', () => { const setup = async () => { - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin(); + const { teacherAccount, teacherUser } = UserAndAccountTestFactory.buildTeacher(); - await em.persistAndFlush([adminAccount, adminUser]); + await em.persistAndFlush([teacherAccount, teacherUser]); em.clear(); - const loggedInClient = await testApiClient.login(adminAccount); + const loggedInClient = await testApiClient.login(teacherAccount); return { loggedInClient, @@ -692,9 +732,7 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -734,9 +772,7 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -778,9 +814,7 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -801,6 +835,17 @@ describe('UserLoginMigrationController (API)', () => { const responseBody = response.body as UserLoginMigrationResponse; expect(responseBody.mandatorySince).toBeDefined(); }); + + it('should should change the database correctly', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.put('/mandatory', { mandatory: true }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + const entity = await em.findOneOrFail(UserLoginMigrationEntity, { id: response.body.id }); + + expect(entity.mandatorySince).toBeDefined(); + }); }); describe('when migration is set from mandatory to optional', () => { @@ -818,13 +863,10 @@ describe('UserLoginMigrationController (API)', () => { sourceSystem, startedAt: new Date(2023, 1, 4), mandatorySince: new Date(2023, 1, 4), - closedAt: new Date(2023, 1, 5), }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -845,6 +887,17 @@ describe('UserLoginMigrationController (API)', () => { const responseBody = response.body as UserLoginMigrationResponse; expect(responseBody.mandatorySince).toBeUndefined(); }); + + it('should should change the database correctly', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.put('/mandatory', { mandatory: false }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + const entity = await em.findOneOrFail(UserLoginMigrationEntity, { id: response.body.id }); + + expect(entity.mandatorySince).toBeUndefined(); + }); }); describe('when migration is not started', () => { @@ -856,9 +909,7 @@ describe('UserLoginMigrationController (API)', () => { officialSchoolNumber: '12345', }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser]); em.clear(); @@ -897,9 +948,7 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -947,12 +996,12 @@ describe('UserLoginMigrationController (API)', () => { }); school.userLoginMigration = userLoginMigration; - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, []); + const { teacherAccount, teacherUser } = UserAndAccountTestFactory.buildTeacher({ school }); - await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); + await em.persistAndFlush([sourceSystem, targetSystem, school, teacherAccount, teacherUser, userLoginMigration]); em.clear(); - const loggedInClient = await testApiClient.login(adminAccount); + const loggedInClient = await testApiClient.login(teacherAccount); return { loggedInClient, @@ -990,9 +1039,7 @@ describe('UserLoginMigrationController (API)', () => { lastLoginSystemChange: new Date(2023, 1, 5), }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([ sourceSystem, @@ -1018,7 +1065,7 @@ describe('UserLoginMigrationController (API)', () => { const response: Response = await loggedInClient.post('/close'); - expect(response.status).toEqual(HttpStatus.CREATED); + expect(response.status).toEqual(HttpStatus.OK); }); it('should return the closed user login migration', async () => { @@ -1027,6 +1074,7 @@ describe('UserLoginMigrationController (API)', () => { const response: Response = await loggedInClient.post('/close'); expect(response.body).toEqual({ + id: expect.any(String), targetSystemId: userLoginMigration.targetSystem.id, sourceSystemId: userLoginMigration.sourceSystem?.id, startedAt: userLoginMigration.startedAt.toISOString(), @@ -1034,6 +1082,18 @@ describe('UserLoginMigrationController (API)', () => { finishedAt: expect.any(String), }); }); + + it('should should change the database correctly', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.post('/close'); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + const entity = await em.findOneOrFail(UserLoginMigrationEntity, { id: response.body.id }); + + expect(entity.closedAt).toBeDefined(); + expect(entity.finishedAt).toBeDefined(); + }); }); describe('when migration is not started', () => { @@ -1045,9 +1105,7 @@ describe('UserLoginMigrationController (API)', () => { officialSchoolNumber: '12345', }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser]); em.clear(); @@ -1066,6 +1124,19 @@ describe('UserLoginMigrationController (API)', () => { expect(response.status).toEqual(HttpStatus.NOT_FOUND); }); + + it('should return an error response', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.post('/close'); + + expect(response.body).toEqual({ + message: 'Not Found', + type: 'USER_LOGIN_MIGRATION_NOT_FOUND', + code: 404, + title: 'User Login Migration Not Found', + }); + }); }); describe('when the migration is already closed', () => { @@ -1085,9 +1156,7 @@ describe('UserLoginMigrationController (API)', () => { closedAt: new Date(2023, 1, 5), }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -1100,12 +1169,21 @@ describe('UserLoginMigrationController (API)', () => { }; }; + it('should return status ok', async () => { + const { loggedInClient } = await setup(); + + const response: Response = await loggedInClient.post('/close'); + + expect(response.status).toEqual(HttpStatus.OK); + }); + it('should return the same user login migration', async () => { const { loggedInClient, userLoginMigration } = await setup(); const response: Response = await loggedInClient.post('/close'); expect(response.body).toEqual({ + id: userLoginMigration.id, targetSystemId: userLoginMigration.targetSystem.id, sourceSystemId: userLoginMigration.sourceSystem?.id, startedAt: userLoginMigration.startedAt.toISOString(), @@ -1132,9 +1210,7 @@ describe('UserLoginMigrationController (API)', () => { finishedAt: new Date(2023, 1, 6), }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); em.clear(); @@ -1181,12 +1257,12 @@ describe('UserLoginMigrationController (API)', () => { closedAt: new Date(2023, 1, 5), }); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, []); + const { teacherAccount, teacherUser } = UserAndAccountTestFactory.buildTeacher({ school }); - await em.persistAndFlush([sourceSystem, targetSystem, school, adminAccount, adminUser, userLoginMigration]); + await em.persistAndFlush([sourceSystem, targetSystem, school, teacherAccount, teacherUser, userLoginMigration]); em.clear(); - const loggedInClient = await testApiClient.login(adminAccount); + const loggedInClient = await testApiClient.login(teacherAccount); return { loggedInClient, @@ -1220,9 +1296,7 @@ describe('UserLoginMigrationController (API)', () => { const user: User = userFactory.buildWithId(); - const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }, [ - Permission.USER_LOGIN_MIGRATION_ADMIN, - ]); + const { adminAccount, adminUser } = UserAndAccountTestFactory.buildAdmin({ school }); await em.persistAndFlush([ sourceSystem, diff --git a/apps/server/src/modules/user-login-migration/controller/dto/response/user-login-migration.response.ts b/apps/server/src/modules/user-login-migration/controller/dto/response/user-login-migration.response.ts index 51c02793d09..efa9fd83720 100644 --- a/apps/server/src/modules/user-login-migration/controller/dto/response/user-login-migration.response.ts +++ b/apps/server/src/modules/user-login-migration/controller/dto/response/user-login-migration.response.ts @@ -1,6 +1,9 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class UserLoginMigrationResponse { + @ApiProperty() + id: string; + @ApiPropertyOptional({ description: 'Id of the system which is the origin of the migration', }) @@ -32,6 +35,7 @@ export class UserLoginMigrationResponse { finishedAt?: Date; constructor(props: UserLoginMigrationResponse) { + this.id = props.id; this.sourceSystemId = props.sourceSystemId; this.targetSystemId = props.targetSystemId; this.mandatorySince = props.mandatorySince; diff --git a/apps/server/src/modules/user-login-migration/controller/user-login-migration.controller.ts b/apps/server/src/modules/user-login-migration/controller/user-login-migration.controller.ts index 3e788a54725..fc1c9c9f9cf 100644 --- a/apps/server/src/modules/user-login-migration/controller/user-login-migration.controller.ts +++ b/apps/server/src/modules/user-login-migration/controller/user-login-migration.controller.ts @@ -1,4 +1,5 @@ -import { Body, Controller, Get, Param, Post, Put, Query } from '@nestjs/common'; +import { Authenticate, CurrentUser, ICurrentUser, JWT } from '@modules/authentication'; +import { Body, Controller, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { ApiForbiddenResponse, ApiInternalServerErrorResponse, @@ -11,7 +12,6 @@ import { ApiUnprocessableEntityResponse, } from '@nestjs/swagger'; import { Page, UserLoginMigrationDO } from '@shared/domain'; -import { Authenticate, CurrentUser, ICurrentUser, JWT } from '@modules/authentication'; import { SchoolNumberMissingLoggableException, UserLoginMigrationAlreadyClosedLoggableException, @@ -181,6 +181,7 @@ export class UserLoginMigrationController { } @Post('close') + @HttpCode(HttpStatus.OK) @ApiUnprocessableEntityResponse({ description: 'User login migration is already closed and cannot be modified. Restart is possible.', type: UserLoginMigrationAlreadyClosedLoggableException, diff --git a/apps/server/src/modules/user-login-migration/mapper/user-login-migration.mapper.ts b/apps/server/src/modules/user-login-migration/mapper/user-login-migration.mapper.ts index cf11c639133..272e2309392 100644 --- a/apps/server/src/modules/user-login-migration/mapper/user-login-migration.mapper.ts +++ b/apps/server/src/modules/user-login-migration/mapper/user-login-migration.mapper.ts @@ -1,6 +1,6 @@ import { UserLoginMigrationDO } from '@shared/domain'; import { UserLoginMigrationResponse, UserLoginMigrationSearchParams } from '../controller/dto'; -import { UserLoginMigrationQuery } from '../uc/dto/user-login-migration-query'; +import { UserLoginMigrationQuery } from '../uc'; export class UserLoginMigrationMapper { static mapSearchParamsToQuery(searchParams: UserLoginMigrationSearchParams): UserLoginMigrationQuery { @@ -12,6 +12,7 @@ export class UserLoginMigrationMapper { static mapUserLoginMigrationDoToResponse(domainObject: UserLoginMigrationDO): UserLoginMigrationResponse { const response: UserLoginMigrationResponse = new UserLoginMigrationResponse({ + id: domainObject.id as string, sourceSystemId: domainObject.sourceSystemId, targetSystemId: domainObject.targetSystemId, startedAt: domainObject.startedAt, diff --git a/apps/server/src/shared/testing/factory/index.ts b/apps/server/src/shared/testing/factory/index.ts index d981b4ca29c..7d5ec2ab753 100644 --- a/apps/server/src/shared/testing/factory/index.ts +++ b/apps/server/src/shared/testing/factory/index.ts @@ -36,3 +36,4 @@ export * from './user-login-migration.factory'; export * from './user.do.factory'; export * from './user.factory'; export * from './legacy-file-entity-mock.factory'; +export * from './jwt.test.factory'; diff --git a/apps/server/src/shared/testing/user-role-permissions.ts b/apps/server/src/shared/testing/user-role-permissions.ts index 6c38287a37e..a3c82aecc7c 100644 --- a/apps/server/src/shared/testing/user-role-permissions.ts +++ b/apps/server/src/shared/testing/user-role-permissions.ts @@ -140,4 +140,5 @@ export const adminPermissions = [ Permission.IMPORT_USER_VIEW, Permission.SCHOOL_TOOL_ADMIN, Permission.GROUP_FULL_ADMIN, + Permission.USER_LOGIN_MIGRATION_ADMIN, ] as Permission[];