Skip to content

Commit

Permalink
add location to school name
Browse files Browse the repository at this point in the history
  • Loading branch information
MarvinOehlerkingCap committed Nov 8, 2023
1 parent f38c0be commit 7d52916
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ export class ExternalSchoolDto {

officialSchoolNumber?: string;

location?: string;

constructor(props: ExternalSchoolDto) {
this.externalId = props.externalId;
this.name = props.name;
this.officialSchoolNumber = props.officialSchoolNumber;
this.location = props.location;
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { AccountService } from '@modules/account/services/account.service';
import { AccountSaveDto } from '@modules/account/services/dto';
import { Group, GroupService } from '@modules/group';
import { FederalStateService, LegacySchoolService, SchoolYearService } from '@modules/legacy-school';
import { RoleService } from '@modules/role';
import { RoleDto } from '@modules/role/service/dto/role.dto';
import { UserService } from '@modules/user';
import { UnprocessableEntityException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { NotFoundLoggableException } from '@shared/common/loggable-exception';
import { ExternalSource, LegacySchoolDo, RoleName, RoleReference, SchoolFeatures } from '@shared/domain';
import { UserDO } from '@shared/domain/domainobject/user.do';
import {
externalGroupDtoFactory,
federalStateFactory,
groupFactory,
roleDtoFactory,
legacySchoolDoFactory,
roleDtoFactory,
roleFactory,
schoolYearFactory,
userDoFactory,
roleFactory,
} from '@shared/testing';
import { Logger } from '@src/core/logger';
import { AccountService } from '@modules/account/services/account.service';
import { AccountSaveDto } from '@modules/account/services/dto';
import { Group, GroupService } from '@modules/group';
import { RoleService } from '@modules/role';
import { RoleDto } from '@modules/role/service/dto/role.dto';
import { FederalStateService, LegacySchoolService, SchoolYearService } from '@modules/legacy-school';
import { UserService } from '@modules/user';
import CryptoJS from 'crypto-js';
import { NotFoundLoggableException } from '@shared/common/loggable-exception';
import { ExternalGroupDto, ExternalSchoolDto, ExternalUserDto } from '../../../dto';
import { SchoolForGroupNotFoundLoggable, UserForGroupNotFoundLoggable } from '../../../loggable';
import { OidcProvisioningService } from './oidc-provisioning.service';
Expand Down Expand Up @@ -101,102 +101,193 @@ describe('OidcProvisioningService', () => {
});

describe('provisionExternalSchool', () => {
const setup = () => {
const systemId = 'systemId';
const externalSchoolDto: ExternalSchoolDto = new ExternalSchoolDto({
externalId: 'externalId',
name: 'name',
officialSchoolNumber: 'officialSchoolNumber',
});
const savedSchoolDO = legacySchoolDoFactory.build({
id: 'schoolId',
externalId: 'externalId',
name: 'name',
officialSchoolNumber: 'officialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
});
const existingSchoolDO = legacySchoolDoFactory.build({
id: 'schoolId',
externalId: 'externalId',
name: 'existingName',
officialSchoolNumber: 'existingOfficialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
});

schoolService.save.mockResolvedValue(savedSchoolDO);
schoolService.getSchoolByExternalId.mockResolvedValue(null);
schoolYearService.getCurrentSchoolYear.mockResolvedValue(schoolYearFactory.build());
federalStateService.findFederalStateByName.mockResolvedValue(federalStateFactory.build());
describe('when systemId is given and external school does not exist', () => {
const setup = () => {
const systemId = 'systemId';
const externalSchoolDto: ExternalSchoolDto = new ExternalSchoolDto({
externalId: 'externalId',
name: 'name',
officialSchoolNumber: 'officialSchoolNumber',
location: 'Hannover',
});

return {
systemId,
externalSchoolDto,
savedSchoolDO,
existingSchoolDO,
const schoolYear = schoolYearFactory.build();
const federalState = federalStateFactory.build();
const savedSchoolDO = new LegacySchoolDo({
id: 'schoolId',
externalId: 'externalId',
name: 'name (Hannover)',
officialSchoolNumber: 'officialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
schoolYear,
federalState,
});
const existingSchoolDO = legacySchoolDoFactory.build({
id: 'schoolId',
externalId: 'externalId',
name: 'existingName',
officialSchoolNumber: 'existingOfficialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
});

schoolService.save.mockResolvedValue(savedSchoolDO);
schoolService.getSchoolByExternalId.mockResolvedValue(null);
schoolYearService.getCurrentSchoolYear.mockResolvedValue(schoolYear);
federalStateService.findFederalStateByName.mockResolvedValue(federalState);

return {
systemId,
externalSchoolDto,
savedSchoolDO,
existingSchoolDO,
};
};
};

describe('when systemId is given and external school does not exist', () => {
it('should save the correct data', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();

await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith({ ...savedSchoolDO, id: undefined }, true);
});

it('should save the new school', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();

const result: LegacySchoolDo = await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(result).toEqual(savedSchoolDO);
});

describe('when the external system provides a location for the school', () => {
it('should append it to the school name', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();
externalSchoolDto.location = 'Hannover';
savedSchoolDO.name = 'name (Hannover)';

await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith({ ...savedSchoolDO, id: undefined }, true);
});
});

describe('when the external system does not provide a location for the school', () => {
it('should only use the school name', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();
externalSchoolDto.location = undefined;
savedSchoolDO.name = 'name';

await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith({ ...savedSchoolDO, id: undefined }, true);
});
});
});

describe('when external school already exist', () => {
it('should update the existing school', async () => {
const { systemId, externalSchoolDto, existingSchoolDO, savedSchoolDO } = setup();
const setup = () => {
const systemId = 'systemId';
const externalSchoolDto: ExternalSchoolDto = new ExternalSchoolDto({
externalId: 'externalId',
name: 'name',
officialSchoolNumber: 'officialSchoolNumber',
});

const schoolYear = schoolYearFactory.build();
const federalState = federalStateFactory.build();
const savedSchoolDO = legacySchoolDoFactory.build({
id: 'schoolId',
externalId: 'externalId',
name: 'name',
officialSchoolNumber: 'officialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
schoolYear,
federalState,
});
const existingSchoolDO = legacySchoolDoFactory.build({
id: 'schoolId',
externalId: 'externalId',
name: 'existingName',
officialSchoolNumber: 'existingOfficialSchoolNumber',
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
});

schoolService.save.mockResolvedValue(savedSchoolDO);
schoolService.getSchoolByExternalId.mockResolvedValue(existingSchoolDO);
schoolYearService.getCurrentSchoolYear.mockResolvedValue(schoolYear);
federalStateService.findFederalStateByName.mockResolvedValue(federalState);

return {
systemId,
externalSchoolDto,
savedSchoolDO,
existingSchoolDO,
};
};

it('should update the existing school', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();

const result: LegacySchoolDo = await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(result).toEqual(savedSchoolDO);
});

it('should append the new system', async () => {
const { systemId, externalSchoolDto, existingSchoolDO, savedSchoolDO } = setup();
const otherSystemId = 'otherSystemId';
existingSchoolDO.systems = [otherSystemId];

schoolService.getSchoolByExternalId.mockResolvedValue(existingSchoolDO);
describe('when the external system provides a location for the school', () => {
it('should append it to the school name', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();
externalSchoolDto.location = 'Hannover';
savedSchoolDO.name = 'name (Hannover)';

await service.provisionExternalSchool(externalSchoolDto, systemId);
await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith(
{
...savedSchoolDO,
systems: [otherSystemId, systemId],
},
true
);
expect(schoolService.save).toHaveBeenCalledWith(savedSchoolDO, true);
});
});

it('should create a new system list', async () => {
const { systemId, externalSchoolDto, existingSchoolDO, savedSchoolDO } = setup();
existingSchoolDO.systems = undefined;
describe('when the external system does not provide a location for the school', () => {
it('should only use the school name', async () => {
const { systemId, externalSchoolDto, savedSchoolDO } = setup();
externalSchoolDto.location = undefined;
savedSchoolDO.name = 'name';

schoolService.getSchoolByExternalId.mockResolvedValue(existingSchoolDO);
await service.provisionExternalSchool(externalSchoolDto, systemId);

await service.provisionExternalSchool(externalSchoolDto, systemId);
expect(schoolService.save).toHaveBeenCalledWith(savedSchoolDO, true);
});
});

expect(schoolService.save).toHaveBeenCalledWith(
{
...savedSchoolDO,
federalState: {
...savedSchoolDO.federalState,
createdAt: expect.any(Date),
updatedAt: expect.any(Date),
describe('when there is a system at the school', () => {
it('should append the new system', async () => {
const { systemId, externalSchoolDto, existingSchoolDO, savedSchoolDO } = setup();
const otherSystemId = 'otherSystemId';
existingSchoolDO.systems = [otherSystemId];

await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith(
{
...savedSchoolDO,
systems: [otherSystemId, systemId],
},
inMaintenanceSince: expect.any(Date),
},
true
);
true
);
});
});

describe('when there is no system at the school yet', () => {
it('should create a new system list', async () => {
const { systemId, externalSchoolDto, existingSchoolDO, savedSchoolDO } = setup();
existingSchoolDO.systems = undefined;

await service.provisionExternalSchool(externalSchoolDto, systemId);

expect(schoolService.save).toHaveBeenCalledWith(savedSchoolDO, true);
});
});
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { EntityId, ExternalSource, FederalStateEntity, SchoolFeatures, SchoolYearEntity } from '@shared/domain';
import { LegacySchoolDo, RoleReference, UserDO } from '@shared/domain/domainobject';
import { Logger } from '@src/core/logger';
import { AccountService } from '@modules/account/services/account.service';
import { AccountSaveDto } from '@modules/account/services/dto';
import { Group, GroupService, GroupUser } from '@modules/group';
Expand All @@ -10,9 +6,13 @@ import { FederalStateNames } from '@modules/legacy-school/types';
import { RoleService } from '@modules/role';
import { RoleDto } from '@modules/role/service/dto/role.dto';
import { UserService } from '@modules/user';
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { NotFoundLoggableException } from '@shared/common/loggable-exception';
import { EntityId, ExternalSource, FederalStateEntity, SchoolFeatures, SchoolYearEntity } from '@shared/domain';
import { LegacySchoolDo, RoleReference, UserDO } from '@shared/domain/domainobject';
import { Logger } from '@src/core/logger';
import { ObjectId } from 'bson';
import CryptoJS from 'crypto-js';
import { NotFoundLoggableException } from '@shared/common/loggable-exception';
import { ExternalGroupDto, ExternalGroupUserDto, ExternalSchoolDto, ExternalUserDto } from '../../../dto';
import { SchoolForGroupNotFoundLoggable, UserForGroupNotFoundLoggable } from '../../../loggable';

Expand All @@ -37,7 +37,7 @@ export class OidcProvisioningService {
let school: LegacySchoolDo;
if (existingSchool) {
school = existingSchool;
school.name = externalSchool.name;
school.name = this.getSchoolName(externalSchool);
school.officialSchoolNumber = externalSchool.officialSchoolNumber ?? existingSchool.officialSchoolNumber;
if (!school.systems) {
school.systems = [systemId];
Expand All @@ -52,7 +52,7 @@ export class OidcProvisioningService {

school = new LegacySchoolDo({
externalId: externalSchool.externalId,
name: externalSchool.name,
name: this.getSchoolName(externalSchool),
officialSchoolNumber: externalSchool.officialSchoolNumber,
systems: [systemId],
features: [SchoolFeatures.OAUTH_PROVISIONING_ENABLED],
Expand All @@ -63,9 +63,18 @@ export class OidcProvisioningService {
}

const savedSchool: LegacySchoolDo = await this.schoolService.save(school, true);

return savedSchool;
}

getSchoolName(externalSchool: ExternalSchoolDto): string {
const schoolName: string = externalSchool.location
? `${externalSchool.name} (${externalSchool.location})`
: externalSchool.name;

return schoolName;
}

async provisionExternalUser(externalUser: ExternalUserDto, systemId: EntityId, schoolId?: string): Promise<UserDO> {
let roleRefs: RoleReference[] | undefined;
if (externalUser.roles) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export * from './sanis-personenkontext-response';
export * from './sanis-gruppenzugehoerigkeit-response';
export * from './sanis-person-response';
export * from './sanis-sonstige-gruppenzugehoerige-response';
export * from './sanis-anschrift-response';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface SanisAnschriftResponse {
adresszeile?: string;

postleitzahl?: string;

ort?: string;

ortsteil?: string;
}
Loading

0 comments on commit 7d52916

Please sign in to comment.