diff --git a/apps/server/src/infra/sync/tsp/tsp-oauth-data.mapper.spec.ts b/apps/server/src/infra/sync/tsp/tsp-oauth-data.mapper.spec.ts index fda468415cb..4b7dd9d571d 100644 --- a/apps/server/src/infra/sync/tsp/tsp-oauth-data.mapper.spec.ts +++ b/apps/server/src/infra/sync/tsp/tsp-oauth-data.mapper.spec.ts @@ -1,17 +1,22 @@ import { faker } from '@faker-js/faker'; import { createMock, DeepMocked } from '@golevelup/ts-jest'; +import { ProvisioningSystemDto } from '@modules/provisioning'; import { - ExternalClassDto, - ExternalSchoolDto, - ExternalUserDto, - OauthDataDto, - ProvisioningSystemDto, -} from '@modules/provisioning'; + externalUserDtoFactory, + oauthDataDtoFactory, + externalClassDtoFactory, + provisioningSystemDtoFactory, + externalSchoolDtoFactory, +} from '@modules/provisioning/testing'; import { Test, TestingModule } from '@nestjs/testing'; import { RoleName } from '@shared/domain/interface'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; +import { + robjExportSchuelerFactory, + robjExportLehrerFactory, + robjExportKlasseFactory, +} from '@src/infra/tsp-client/testing'; import { Logger } from '@src/core/logger'; -import { RobjExportKlasse, RobjExportLehrer, RobjExportSchueler } from '@src/infra/tsp-client'; import { BadDataLoggableException } from '@src/modules/provisioning/loggable'; import { schoolFactory } from '@src/modules/school/testing'; import { systemFactory } from '@src/modules/system/testing'; @@ -64,71 +69,76 @@ describe(TspOauthDataMapper.name, () => { const lehrerUid = faker.string.alpha(); - const tspTeachers: RobjExportLehrer[] = [ - { - lehrerUid, - lehrerNachname: faker.string.alpha(), - lehrerVorname: faker.string.alpha(), - schuleNummer: school.externalId, - }, - ]; + const tspTeacher = robjExportLehrerFactory.build({ + lehrerUid, + schuleNummer: school.externalId, + }); + const tspTeachers = [tspTeacher]; const klasseId = faker.string.alpha(); - const tspClasses: RobjExportKlasse[] = [ - { - klasseId, - klasseName: faker.string.alpha(), - lehrerUid, - }, - ]; - - const tspStudents: RobjExportSchueler[] = [ - { - schuelerUid: faker.string.alpha(), - schuelerNachname: faker.string.alpha(), - schuelerVorname: faker.string.alpha(), - schuleNummer: school.externalId, - klasseId, - }, - ]; + const tspClass = robjExportKlasseFactory.build({ + klasseId, + lehrerUid, + }); + const tspClasses = [tspClass]; + + const tspStudent = robjExportSchuelerFactory.build({ + schuelerUid: faker.string.alpha(), + schuelerNachname: faker.string.alpha(), + schuelerVorname: faker.string.alpha(), + schuleNummer: school.externalId, + klasseId, + }); + const tspStudents = [tspStudent]; - const provisioningSystemDto = new ProvisioningSystemDto({ + const provisioningSystemDto: ProvisioningSystemDto = provisioningSystemDtoFactory.build({ systemId: system.id, provisioningStrategy: SystemProvisioningStrategy.TSP, }); - const externalSchool = new ExternalSchoolDto({ - externalId: school.externalId ?? '', + const externalClassDto = externalClassDtoFactory.build({ + externalId: tspClasses[0].klasseId ?? '', + name: tspClasses[0].klasseName, }); - const externalClass = new ExternalClassDto({ - externalId: klasseId, - name: tspClasses[0].klasseName, + const externalTeacherUserDto = externalUserDtoFactory.build({ + externalId: tspTeachers[0].lehrerUid ?? '', + firstName: tspTeachers[0].lehrerVorname, + lastName: tspTeachers[0].lehrerNachname, + roles: [RoleName.TEACHER], + email: undefined, + birthday: undefined, + }); + + const externalStudentUserDto = externalUserDtoFactory.build({ + externalId: tspStudents[0].schuelerUid ?? '', + firstName: tspStudents[0].schuelerVorname, + lastName: tspStudents[0].schuelerNachname, + roles: [RoleName.STUDENT], + email: undefined, + birthday: undefined, + }); + + const externalSchoolDto = externalSchoolDtoFactory.build({ + externalId: school.externalId, + name: school.name, + officialSchoolNumber: undefined, + location: undefined, }); - const expected: OauthDataDto[] = [ - new OauthDataDto({ + const expected = [ + oauthDataDtoFactory.build({ system: provisioningSystemDto, - externalUser: new ExternalUserDto({ - externalId: tspTeachers[0].lehrerUid ?? '', - firstName: tspTeachers[0].lehrerVorname, - lastName: tspTeachers[0].lehrerNachname, - roles: [RoleName.TEACHER], - }), - externalSchool, - externalClasses: [externalClass], + externalUser: externalTeacherUserDto, + externalClasses: [externalClassDto], + externalSchool: externalSchoolDto, }), - new OauthDataDto({ + oauthDataDtoFactory.build({ system: provisioningSystemDto, - externalUser: new ExternalUserDto({ - externalId: tspStudents[0].schuelerUid ?? '', - firstName: tspStudents[0].schuelerVorname, - lastName: tspStudents[0].schuelerNachname, - roles: [RoleName.STUDENT], - }), - externalSchool, - externalClasses: [externalClass], + externalUser: externalStudentUserDto, + externalClasses: [externalClassDto], + externalSchool: externalSchoolDto, }), ]; @@ -165,9 +175,9 @@ describe(TspOauthDataMapper.name, () => { const setup = () => { const system = systemFactory.build(); - const tspClass: RobjExportKlasse = { + const tspClass = robjExportKlasseFactory.build({ klasseId: undefined, - }; + }); return { system, tspClass }; }; @@ -185,9 +195,9 @@ describe(TspOauthDataMapper.name, () => { const setup = () => { const system = systemFactory.build(); - const tspTeacher: RobjExportLehrer = { + const tspTeacher = robjExportLehrerFactory.build({ lehrerUid: undefined, - }; + }); return { system, tspTeacher }; }; @@ -205,9 +215,9 @@ describe(TspOauthDataMapper.name, () => { const setup = () => { const system = systemFactory.build(); - const tspStudent: RobjExportSchueler = { + const tspStudent = robjExportSchuelerFactory.build({ schuelerUid: undefined, - }; + }); return { system, tspStudent }; }; diff --git a/apps/server/src/infra/sync/tsp/tsp-sync.strategy.spec.ts b/apps/server/src/infra/sync/tsp/tsp-sync.strategy.spec.ts index b4303779eef..38f97f56db9 100644 --- a/apps/server/src/infra/sync/tsp/tsp-sync.strategy.spec.ts +++ b/apps/server/src/infra/sync/tsp/tsp-sync.strategy.spec.ts @@ -13,10 +13,21 @@ import { Test, TestingModule } from '@nestjs/testing'; import { UserDO } from '@shared/domain/domainobject'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { userDoFactory } from '@shared/testing'; + +import { + externalUserDtoFactory, + oauthDataDtoFactory, + provisioningSystemDtoFactory, +} from '@src/modules/provisioning/testing'; +import { + robjExportSchuleFactory, + robjExportLehrerMigrationFactory, + robjExportSchuelerMigrationFactory, +} from '@src/infra/tsp-client/testing'; import { Logger } from '@src/core/logger'; import { Account } from '@src/modules/account'; import { accountDoFactory } from '@src/modules/account/testing'; -import { ExternalUserDto, OauthDataDto, ProvisioningService, ProvisioningSystemDto } from '@src/modules/provisioning'; +import { OauthDataDto, ProvisioningService } from '@src/modules/provisioning'; import { School } from '@src/modules/school'; import { schoolFactory } from '@src/modules/school/testing'; import { System } from '@src/modules/system'; @@ -164,12 +175,12 @@ describe(TspSyncStrategy.name, () => { describe('sync', () => { describe('when sync is called', () => { const setup = () => { - const oauthDataDto = new OauthDataDto({ - system: new ProvisioningSystemDto({ + const oauthDataDto = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build({ systemId: faker.string.alpha(), provisioningStrategy: SystemProvisioningStrategy.TSP, }), - externalUser: new ExternalUserDto({ + externalUser: externalUserDtoFactory.build({ externalId: faker.string.alpha(), roles: [], }), @@ -302,10 +313,7 @@ describe(TspSyncStrategy.name, () => { describe('when school does not exist', () => { const setup = () => { - const tspSchool: RobjExportSchule = { - schuleNummer: faker.string.alpha(), - schuleName: faker.string.alpha(), - }; + const tspSchool = robjExportSchuleFactory.build(); const tspSchools = [tspSchool]; setupMockServices({ @@ -324,10 +332,7 @@ describe(TspSyncStrategy.name, () => { describe('when school does exist', () => { const setup = () => { - const tspSchool: RobjExportSchule = { - schuleNummer: faker.string.alpha(), - schuleName: faker.string.alpha(), - }; + const tspSchool = robjExportSchuleFactory.build(); const tspSchools = [tspSchool]; const school = schoolFactory.build(); @@ -348,10 +353,8 @@ describe(TspSyncStrategy.name, () => { describe('when tsp school does not have a schulnummer', () => { const setup = () => { - const tspSchool: RobjExportSchule = { - schuleNummer: undefined, - schuleName: faker.string.alpha(), - }; + const tspSchool = robjExportSchuleFactory.build(); + tspSchool.schuleNummer = undefined; const tspSchools = [tspSchool]; setupMockServices({ @@ -372,14 +375,14 @@ describe(TspSyncStrategy.name, () => { describe('when UidAlt or UidNeu is missing during migration', () => { const setup = () => { - const tspTeacher: RobjExportLehrerMigration = { + const tspTeacher = robjExportLehrerMigrationFactory.build({ lehrerUidAlt: undefined, lehrerUidNeu: faker.string.alpha(), - }; - const tspStudent: RobjExportSchuelerMigration = { + }); + const tspStudent = robjExportSchuelerMigrationFactory.build({ schuelerUidAlt: faker.string.alpha(), schuelerUidNeu: undefined, - }; + }); setupMockServices({ fetchedStudentMigrations: [tspStudent], @@ -398,10 +401,10 @@ describe(TspSyncStrategy.name, () => { describe('when no user is found during migration', () => { const setup = () => { - const tspTeacher: RobjExportLehrerMigration = { + const tspTeacher = robjExportLehrerMigrationFactory.build({ lehrerUidAlt: faker.string.alpha(), lehrerUidNeu: faker.string.alpha(), - }; + }); setupMockServices({ fetchedTeacherMigrations: [tspTeacher], @@ -422,10 +425,10 @@ describe(TspSyncStrategy.name, () => { describe('when no account is found during migration', () => { const setup = () => { - const tspTeacher: RobjExportLehrerMigration = { + const tspTeacher = robjExportLehrerMigrationFactory.build({ lehrerUidAlt: faker.string.alpha(), lehrerUidNeu: faker.string.alpha(), - }; + }); setupMockServices({ fetchedTeacherMigrations: [tspTeacher], diff --git a/apps/server/src/infra/tsp-client/testing/index.ts b/apps/server/src/infra/tsp-client/testing/index.ts new file mode 100644 index 00000000000..84d95f3ceaa --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/index.ts @@ -0,0 +1,6 @@ +export { robjExportSchuleFactory } from './robj-export-schule.factory'; +export { robjExportKlasseFactory } from './robj-export-klasse.factory'; +export { robjExportLehrerFactory } from './robj-export-lehrer.factory'; +export { robjExportSchuelerFactory } from './robj-export-schueler.factory'; +export { robjExportLehrerMigrationFactory } from './robj-export-lehrer-migration.factory'; +export { robjExportSchuelerMigrationFactory } from './robj-export-schueler-migration.factory'; diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-klasse.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-klasse.factory.ts new file mode 100644 index 00000000000..cbdff111a16 --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-klasse.factory.ts @@ -0,0 +1,14 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { RobjExportKlasse } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportKlasseFactory = Factory.define(({ sequence }) => { + return { + id: new ObjectId().toHexString(), + version: `version ${sequence}`, + klasseName: `klasseName ${sequence}`, + schuleNummer: `schuleNummer ${sequence}`, + klasseId: `klasseId ${sequence}`, + lehrerUid: `lehrerUid ${sequence}`, + }; +}); diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-lehrer-migration.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-lehrer-migration.factory.ts new file mode 100644 index 00000000000..60c92b94d50 --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-lehrer-migration.factory.ts @@ -0,0 +1,12 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { RobjExportLehrerMigration } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportLehrerMigrationFactory = Factory.define( + () => { + return { + lehrerUidAlt: new ObjectId().toHexString(), + lehrerUidNeu: new ObjectId().toHexString(), + }; + } +); diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-lehrer.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-lehrer.factory.ts new file mode 100644 index 00000000000..4dffa58a85c --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-lehrer.factory.ts @@ -0,0 +1,13 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { RobjExportLehrer } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportLehrerFactory = Factory.define(({ sequence }) => { + return { + lehrerUid: new ObjectId().toHexString(), + lehrerTitel: `lehrerTitel ${sequence}`, + lehrerVorname: `lehrerVorname ${sequence}`, + lehrerNachname: `lehrerNachname ${sequence}`, + schuleNummer: `schuleNummer ${sequence}`, + }; +}); diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-schueler-migration.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-schueler-migration.factory.ts new file mode 100644 index 00000000000..52c509f40df --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-schueler-migration.factory.ts @@ -0,0 +1,13 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { RobjExportSchuelerMigration } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportSchuelerMigrationFactory = Factory.define< + RobjExportSchuelerMigration, + RobjExportSchuelerMigration +>(() => { + return { + schuelerUidAlt: new ObjectId().toHexString(), + schuelerUidNeu: new ObjectId().toHexString(), + }; +}); diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-schueler.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-schueler.factory.ts new file mode 100644 index 00000000000..4dd5a4e7ac6 --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-schueler.factory.ts @@ -0,0 +1,13 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { RobjExportSchueler } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportSchuelerFactory = Factory.define(({ sequence }) => { + return { + schuelerUid: new ObjectId().toHexString(), + schuelerVorname: `schuelerVorname ${sequence}`, + schuelerNachname: `schuelerNachname ${sequence}`, + schuleNummer: `schuleNummer ${sequence}`, + klasseId: `klasseId ${sequence}`, + }; +}); diff --git a/apps/server/src/infra/tsp-client/testing/robj-export-schule.factory.ts b/apps/server/src/infra/tsp-client/testing/robj-export-schule.factory.ts new file mode 100644 index 00000000000..460fdf6ea5e --- /dev/null +++ b/apps/server/src/infra/tsp-client/testing/robj-export-schule.factory.ts @@ -0,0 +1,9 @@ +import { RobjExportSchule } from '@src/infra/tsp-client'; +import { Factory } from 'fishery'; + +export const robjExportSchuleFactory = Factory.define(({ sequence }) => { + return { + schuleName: `schuleName ${sequence}`, + schuleNummer: `schuleNummer ${sequence}`, + }; +}); diff --git a/apps/server/src/modules/provisioning/dto/provisioning.dto.ts b/apps/server/src/modules/provisioning/dto/provisioning.dto.ts index 0c9bf53867b..f35fbc311d4 100644 --- a/apps/server/src/modules/provisioning/dto/provisioning.dto.ts +++ b/apps/server/src/modules/provisioning/dto/provisioning.dto.ts @@ -1,7 +1,7 @@ -export class ProvisioningDto { - externalUserId: string; - - constructor(provisioningDto: ProvisioningDto) { - this.externalUserId = provisioningDto.externalUserId; - } -} +export class ProvisioningDto { + externalUserId: string; + + constructor(provisioningDto: ProvisioningDto) { + this.externalUserId = provisioningDto.externalUserId; + } +} diff --git a/apps/server/src/modules/provisioning/loggable/school-for-group-not-found.loggable.spec.ts b/apps/server/src/modules/provisioning/loggable/school-for-group-not-found.loggable.spec.ts index 888a6a58514..1526b21dfba 100644 --- a/apps/server/src/modules/provisioning/loggable/school-for-group-not-found.loggable.spec.ts +++ b/apps/server/src/modules/provisioning/loggable/school-for-group-not-found.loggable.spec.ts @@ -1,5 +1,4 @@ -import { externalSchoolDtoFactory } from '@shared/testing'; -import { externalGroupDtoFactory } from '@shared/testing/factory/external-group-dto.factory'; +import { externalGroupDtoFactory, externalSchoolDtoFactory } from '@modules/provisioning/testing'; import { ExternalGroupDto, ExternalSchoolDto } from '../dto'; import { SchoolForGroupNotFoundLoggable } from './school-for-group-not-found.loggable'; diff --git a/apps/server/src/modules/provisioning/service/provisioning.service.spec.ts b/apps/server/src/modules/provisioning/service/provisioning.service.spec.ts index eae04147cd7..3a62d5cea50 100644 --- a/apps/server/src/modules/provisioning/service/provisioning.service.spec.ts +++ b/apps/server/src/modules/provisioning/service/provisioning.service.spec.ts @@ -1,13 +1,14 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { System, SystemService } from '@modules/system'; -import { systemFactory } from '@modules/system/testing'; import { InternalServerErrorException } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; +import { provisioningDtoFactory, oauthDataDtoFactory } from '@modules/provisioning/testing'; +import { provisioningSystemDtoFactory } from '@src/modules/provisioning/testing/provisioning-system-dto.factory'; +import { systemFactory } from '@src/modules/system/testing'; import { OauthDataDto, OauthDataStrategyInputDto, ProvisioningDto, ProvisioningSystemDto } from '../dto'; import { IservProvisioningStrategy, OidcMockProvisioningStrategy, SanisProvisioningStrategy } from '../strategy'; import { TspProvisioningStrategy } from '../strategy/tsp/tsp.strategy'; -import { externalUserDtoFactory } from '../testing'; import { ProvisioningService } from './provisioning.service'; describe('ProvisioningService', () => { @@ -78,18 +79,16 @@ describe('ProvisioningService', () => { provisioningUrl: 'https://api.moin.schule/', provisioningStrategy: SystemProvisioningStrategy.SANIS, }); - const provisioningSystemDto: ProvisioningSystemDto = new ProvisioningSystemDto({ + const provisioningSystemDto: ProvisioningSystemDto = provisioningSystemDtoFactory.build({ systemId: system.id, provisioningUrl: 'https://api.moin.schule/', provisioningStrategy: SystemProvisioningStrategy.SANIS, }); - const externalUser = externalUserDtoFactory.build(); - const oauthDataDto: OauthDataDto = new OauthDataDto({ + const oauthDataDto: OauthDataDto = oauthDataDtoFactory.build({ system: provisioningSystemDto, - externalUser, }); - const provisioningDto: ProvisioningDto = new ProvisioningDto({ - externalUserId: externalUser.externalId, + const provisioningDto: ProvisioningDto = provisioningDtoFactory.build({ + externalUserId: 'externalUserId', }); return { diff --git a/apps/server/src/modules/provisioning/service/tsp-provisioning.service.spec.ts b/apps/server/src/modules/provisioning/service/tsp-provisioning.service.spec.ts index b42ff993b92..d8e9963db7d 100644 --- a/apps/server/src/modules/provisioning/service/tsp-provisioning.service.spec.ts +++ b/apps/server/src/modules/provisioning/service/tsp-provisioning.service.spec.ts @@ -3,7 +3,6 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Test, TestingModule } from '@nestjs/testing'; import { NotFoundLoggableException } from '@shared/common/loggable-exception'; import { RoleName } from '@shared/domain/interface'; -import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { roleDtoFactory, roleFactory, userDoFactory } from '@shared/testing'; import { AccountService } from '@src/modules/account'; import { ClassService } from '@src/modules/class'; @@ -12,9 +11,15 @@ import { RoleService } from '@src/modules/role'; import { SchoolService } from '@src/modules/school'; import { schoolFactory } from '@src/modules/school/testing'; import { UserService } from '@src/modules/user'; -import { ExternalClassDto, ExternalSchoolDto, ExternalUserDto, OauthDataDto, ProvisioningSystemDto } from '../dto'; import { BadDataLoggableException } from '../loggable'; import { TspProvisioningService } from './tsp-provisioning.service'; +import { + provisioningSystemDtoFactory, + externalClassDtoFactory, + oauthDataDtoFactory, + externalUserDtoFactory, + externalSchoolDtoFactory, +} from '../testing'; describe('TspProvisioningService', () => { let module: TestingModule; @@ -25,27 +30,6 @@ describe('TspProvisioningService', () => { let userServiceMock: DeepMocked; let accountServiceMock: DeepMocked; - const setupExternalSystem = (props?: Partial) => { - const baseProps = { systemId: faker.string.uuid(), provisioningStrategy: SystemProvisioningStrategy.TSP }; - - return new ProvisioningSystemDto({ ...baseProps, ...props }); - }; - const setupExternalSchool = (props?: Partial) => { - const baseProps = { externalId: faker.string.uuid(), name: faker.string.sample() }; - - return new ExternalSchoolDto({ ...baseProps, ...props }); - }; - const setupExternalClass = (props?: Partial) => { - const baseProps = { externalId: faker.string.uuid(), name: faker.string.sample() }; - - return new ExternalClassDto({ ...baseProps, ...props }); - }; - const setupExternalUser = (props?: Partial) => { - const baseProps = { externalId: faker.string.uuid(), username: faker.internet.userName(), roles: [] }; - - return new ExternalUserDto({ ...baseProps, ...props }); - }; - beforeAll(async () => { module = await Test.createTestingModule({ providers: [ @@ -96,8 +80,8 @@ describe('TspProvisioningService', () => { describe('findSchoolOrFail', () => { describe('when school is found', () => { const setup = () => { - const system = setupExternalSystem(); - const externalSchool = setupExternalSchool(); + const system = provisioningSystemDtoFactory.build(); + const externalSchool = externalSchoolDtoFactory.build(); const school = schoolFactory.build(); schoolServiceMock.getSchools.mockResolvedValueOnce([school]); @@ -116,8 +100,8 @@ describe('TspProvisioningService', () => { describe('when school is not found', () => { const setup = () => { - const system = setupExternalSystem(); - const externalSchool = setupExternalSchool(); + const system = provisioningSystemDtoFactory.build(); + const externalSchool = externalSchoolDtoFactory.build(); schoolServiceMock.getSchools.mockResolvedValueOnce([]); @@ -136,7 +120,7 @@ describe('TspProvisioningService', () => { describe('when user ID is missing', () => { const setup = () => { const school = schoolFactory.build(); - const classes = [setupExternalClass()]; + const classes = [externalClassDtoFactory.build()]; const user = userDoFactory.build(); return { school, classes, user }; @@ -152,7 +136,7 @@ describe('TspProvisioningService', () => { describe('when class exists', () => { const setup = () => { const school = schoolFactory.build(); - const classes = [setupExternalClass()]; + const classes = [externalClassDtoFactory.build()]; const clazz = classFactory.build(); const user = userDoFactory.buildWithId({ roles: [roleFactory.build({ name: RoleName.TEACHER }), roleFactory.build({ name: RoleName.STUDENT })], @@ -175,7 +159,7 @@ describe('TspProvisioningService', () => { describe('when class does not exist', () => { const setup = () => { const school = schoolFactory.build(); - const classes = [setupExternalClass()]; + const classes = [externalClassDtoFactory.build()]; const user = userDoFactory.buildWithId({ roles: [roleFactory.build({ name: RoleName.TEACHER }), roleFactory.build({ name: RoleName.STUDENT })], }); @@ -198,9 +182,9 @@ describe('TspProvisioningService', () => { describe('provisionUser', () => { describe('when external school is missing', () => { const setup = () => { - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser(), + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalSchool: undefined, }); const school = schoolFactory.build(); @@ -217,10 +201,10 @@ describe('TspProvisioningService', () => { describe('when user exists and school is the same', () => { const setup = () => { const school = schoolFactory.build(); - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser(), - externalSchool: setupExternalSchool({ + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalUser: externalUserDtoFactory.build(), + externalSchool: externalSchoolDtoFactory.build({ externalId: school.externalId, }), }); @@ -246,10 +230,10 @@ describe('TspProvisioningService', () => { describe('when user exists and school is different', () => { const setup = () => { const school = schoolFactory.build(); - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser(), - externalSchool: setupExternalSchool(), + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalUser: externalUserDtoFactory.build(), + externalSchool: externalSchoolDtoFactory.build(), }); const user = userDoFactory.build({ id: faker.string.uuid() }); const roles = [ @@ -278,14 +262,14 @@ describe('TspProvisioningService', () => { describe('when user does not exist and has no firstname, lastname and email', () => { const setup = (withFirstname: boolean, withLastname: boolean, withEmail: boolean) => { const school = schoolFactory.build(); - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser({ + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalUser: externalUserDtoFactory.build({ firstName: withFirstname ? faker.person.firstName() : undefined, lastName: withLastname ? faker.person.lastName() : undefined, email: withEmail ? faker.internet.email() : undefined, }), - externalSchool: setupExternalSchool(), + externalSchool: externalSchoolDtoFactory.build(), }); userServiceMock.findByExternalId.mockResolvedValue(null); @@ -311,14 +295,14 @@ describe('TspProvisioningService', () => { describe('when user does not exist', () => { const setup = () => { const school = schoolFactory.build(); - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser({ + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalUser: externalUserDtoFactory.build({ firstName: faker.person.firstName(), lastName: faker.person.lastName(), email: faker.internet.email(), }), - externalSchool: setupExternalSchool(), + externalSchool: externalSchoolDtoFactory.build(), }); const user = userDoFactory.build({ id: faker.string.uuid(), roles: [] }); @@ -343,14 +327,14 @@ describe('TspProvisioningService', () => { describe('when user id is not set after create', () => { const setup = () => { const school = schoolFactory.build(); - const data = new OauthDataDto({ - system: setupExternalSystem(), - externalUser: setupExternalUser({ + const data = oauthDataDtoFactory.build({ + system: provisioningSystemDtoFactory.build(), + externalUser: externalUserDtoFactory.build({ firstName: faker.person.firstName(), lastName: faker.person.lastName(), email: faker.internet.email(), }), - externalSchool: setupExternalSchool(), + externalSchool: externalSchoolDtoFactory.build(), }); const user = userDoFactory.build({ id: undefined, roles: [] }); diff --git a/apps/server/src/modules/provisioning/strategy/schulconnex/schulconnex.strategy.spec.ts b/apps/server/src/modules/provisioning/strategy/schulconnex/schulconnex.strategy.spec.ts index f86346d37eb..8bbde69d3fe 100644 --- a/apps/server/src/modules/provisioning/strategy/schulconnex/schulconnex.strategy.spec.ts +++ b/apps/server/src/modules/provisioning/strategy/schulconnex/schulconnex.strategy.spec.ts @@ -7,13 +7,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { LegacySchoolDo, UserDO } from '@shared/domain/domainobject'; import { RoleName } from '@shared/domain/interface'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; -import { - externalGroupDtoFactory, - externalSchoolDtoFactory, - groupFactory, - legacySchoolDoFactory, - userDoFactory, -} from '@shared/testing'; +import { groupFactory, legacySchoolDoFactory, userDoFactory } from '@shared/testing'; import { Logger } from '@src/core/logger'; import { ExternalGroupDto, @@ -24,7 +18,7 @@ import { ProvisioningSystemDto, } from '../../dto'; import { ProvisioningConfig } from '../../provisioning.config'; -import { externalUserDtoFactory } from '../../testing'; +import { externalGroupDtoFactory, externalSchoolDtoFactory, externalUserDtoFactory } from '../../testing'; import { SchulconnexProvisioningStrategy } from './schulconnex.strategy'; import { SchulconnexCourseSyncService, diff --git a/apps/server/src/modules/provisioning/strategy/schulconnex/service/schulconnex-group-provisioning.service.spec.ts b/apps/server/src/modules/provisioning/strategy/schulconnex/service/schulconnex-group-provisioning.service.spec.ts index f5d48e48d4f..e005b01873b 100644 --- a/apps/server/src/modules/provisioning/strategy/schulconnex/service/schulconnex-group-provisioning.service.spec.ts +++ b/apps/server/src/modules/provisioning/strategy/schulconnex/service/schulconnex-group-provisioning.service.spec.ts @@ -16,16 +16,9 @@ import { NotFoundLoggableException } from '@shared/common/loggable-exception'; import { ExternalSource, LegacySchoolDo, Page, RoleReference, UserDO } from '@shared/domain/domainobject'; import { RoleName } from '@shared/domain/interface'; import { EntityId } from '@shared/domain/types'; -import { - externalGroupDtoFactory, - externalSchoolDtoFactory, - groupFactory, - legacySchoolDoFactory, - roleDtoFactory, - roleFactory, - userDoFactory, -} from '@shared/testing'; +import { groupFactory, legacySchoolDoFactory, roleDtoFactory, roleFactory, userDoFactory } from '@shared/testing'; import { Logger } from '@src/core/logger'; +import { externalGroupDtoFactory, externalSchoolDtoFactory } from '@modules/provisioning/testing'; import { ExternalGroupDto, ExternalSchoolDto } from '../../../dto'; import { SchoolForGroupNotFoundLoggable, UserForGroupNotFoundLoggable } from '../../../loggable'; import { SchulconnexGroupProvisioningService } from './schulconnex-group-provisioning.service'; diff --git a/apps/server/src/modules/provisioning/testing/external-class-dto.factory.ts b/apps/server/src/modules/provisioning/testing/external-class-dto.factory.ts new file mode 100644 index 00000000000..7bc8d9f3f55 --- /dev/null +++ b/apps/server/src/modules/provisioning/testing/external-class-dto.factory.ts @@ -0,0 +1,11 @@ +import { ExternalClassDto } from '@modules/provisioning'; +import { ObjectId } from '@mikro-orm/mongodb'; +import { Factory } from 'fishery'; + +export const externalClassDtoFactory = Factory.define( + ({ sequence }) => + new ExternalClassDto({ + externalId: new ObjectId().toHexString(), + name: `external Class ${sequence}`, + }) +); diff --git a/apps/server/src/modules/provisioning/testing/external-school-dto.factory.ts b/apps/server/src/modules/provisioning/testing/external-school-dto.factory.ts new file mode 100644 index 00000000000..31d93c4924e --- /dev/null +++ b/apps/server/src/modules/provisioning/testing/external-school-dto.factory.ts @@ -0,0 +1,12 @@ +import { ObjectId } from '@mikro-orm/mongodb'; +import { ExternalSchoolDto } from '@modules/provisioning/dto'; +import { BaseFactory } from '../../../shared/testing/factory/base.factory'; + +class ExternalSchoolDtoFactory extends BaseFactory> {} + +export const externalSchoolDtoFactory = ExternalSchoolDtoFactory.define(ExternalSchoolDto, ({ sequence }) => { + return { + externalId: new ObjectId().toHexString(), + name: `External School ${sequence}`, + }; +}); diff --git a/apps/server/src/modules/provisioning/testing/index.ts b/apps/server/src/modules/provisioning/testing/index.ts index 32854894142..4d180c58f64 100644 --- a/apps/server/src/modules/provisioning/testing/index.ts +++ b/apps/server/src/modules/provisioning/testing/index.ts @@ -1,3 +1,8 @@ export { externalUserDtoFactory } from './external-user-dto.factory'; export { externalGroupDtoFactory } from './external-group-dto.factory'; export { externalGroupUserDtoFactory } from './external-group-user-dto.factory'; +export { oauthDataDtoFactory } from './oauth-data-dto.factory'; +export { externalClassDtoFactory } from './external-class-dto.factory'; +export { externalSchoolDtoFactory } from './external-school-dto.factory'; +export { provisioningSystemDtoFactory } from './provisioning-system-dto.factory'; +export { provisioningDtoFactory } from './provisioning-dto.factory'; diff --git a/apps/server/src/modules/provisioning/testing/oauth-data-dto.factory.ts b/apps/server/src/modules/provisioning/testing/oauth-data-dto.factory.ts new file mode 100644 index 00000000000..b8a11d639f7 --- /dev/null +++ b/apps/server/src/modules/provisioning/testing/oauth-data-dto.factory.ts @@ -0,0 +1,15 @@ +import { OauthDataDto } from '@modules/provisioning'; +import { Factory } from 'fishery'; +import { externalUserDtoFactory } from './external-user-dto.factory'; +import { provisioningSystemDtoFactory } from './provisioning-system-dto.factory'; + +export const oauthDataDtoFactory = Factory.define(() => { + const system = provisioningSystemDtoFactory.build(); + const externalUser = externalUserDtoFactory.build(); + const oauthDataDto = new OauthDataDto({ + system, + externalUser, + }); + + return oauthDataDto; +}); diff --git a/apps/server/src/modules/provisioning/testing/provisioning-dto.factory.ts b/apps/server/src/modules/provisioning/testing/provisioning-dto.factory.ts new file mode 100644 index 00000000000..5262232bfa9 --- /dev/null +++ b/apps/server/src/modules/provisioning/testing/provisioning-dto.factory.ts @@ -0,0 +1,10 @@ +import { ProvisioningDto } from '@modules/provisioning'; +import { ObjectId } from '@mikro-orm/mongodb'; +import { Factory } from 'fishery'; + +export const provisioningDtoFactory = Factory.define( + () => + new ProvisioningDto({ + externalUserId: new ObjectId().toHexString(), + }) +); diff --git a/apps/server/src/modules/provisioning/testing/provisioning-system-dto.factory.ts b/apps/server/src/modules/provisioning/testing/provisioning-system-dto.factory.ts new file mode 100644 index 00000000000..131c5c72364 --- /dev/null +++ b/apps/server/src/modules/provisioning/testing/provisioning-system-dto.factory.ts @@ -0,0 +1,12 @@ +import { ProvisioningSystemDto } from '@modules/provisioning'; +import { ObjectId } from '@mikro-orm/mongodb'; +import { Factory } from 'fishery'; +import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; + +export const provisioningSystemDtoFactory = Factory.define( + () => + new ProvisioningSystemDto({ + systemId: new ObjectId().toHexString(), + provisioningStrategy: SystemProvisioningStrategy.TSP, + }) +); diff --git a/apps/server/src/shared/testing/factory/external-group-dto.factory.ts b/apps/server/src/shared/testing/factory/external-group-dto.factory.ts deleted file mode 100644 index a6172ff6acf..00000000000 --- a/apps/server/src/shared/testing/factory/external-group-dto.factory.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { GroupTypes } from '@modules/group'; -import { ExternalGroupDto } from '@modules/provisioning/dto'; -import { RoleName } from '@shared/domain/interface'; -import { ObjectId } from '@mikro-orm/mongodb'; -import { Factory } from 'fishery'; - -export const externalGroupDtoFactory = Factory.define(({ sequence }) => { - return { - externalId: new ObjectId().toHexString(), - name: `Group ${sequence}`, - type: GroupTypes.CLASS, - user: { - externalUserId: new ObjectId().toHexString(), - roleName: RoleName.TEACHER, - }, - otherUsers: [ - { - externalUserId: new ObjectId().toHexString(), - roleName: RoleName.STUDENT, - }, - ], - from: new Date(2023, 1), - until: new Date(2023, 6), - }; -}); diff --git a/apps/server/src/shared/testing/factory/external-school-dto.factory.ts b/apps/server/src/shared/testing/factory/external-school-dto.factory.ts deleted file mode 100644 index e56e64d9243..00000000000 --- a/apps/server/src/shared/testing/factory/external-school-dto.factory.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ExternalSchoolDto } from '@modules/provisioning/dto'; -import { ObjectId } from '@mikro-orm/mongodb'; -import { Factory } from 'fishery'; - -export const externalSchoolDtoFactory = Factory.define(({ sequence }) => { - return { - externalId: new ObjectId().toHexString(), - name: `External School ${sequence}`, - }; -}); diff --git a/apps/server/src/shared/testing/factory/index.ts b/apps/server/src/shared/testing/factory/index.ts index d0d2e9568d9..9a6500b12c5 100644 --- a/apps/server/src/shared/testing/factory/index.ts +++ b/apps/server/src/shared/testing/factory/index.ts @@ -10,8 +10,6 @@ export * from './coursegroup.factory'; export * from './currentuser.factory'; export * from './domainobject'; export * from './entity.factory'; -export * from './external-group-dto.factory'; -export { externalSchoolDtoFactory } from './external-school-dto.factory'; export * from './external-tool-pseudonym.factory'; export * from './federal-state.factory'; export * from './filerecord.factory';