Skip to content

Commit

Permalink
Merge branch 'release-0101' into SPSH-1634
Browse files Browse the repository at this point in the history
  • Loading branch information
DPDS93CT committed Dec 16, 2024
2 parents d536d8a + 7c955d4 commit d0a7df0
Show file tree
Hide file tree
Showing 54 changed files with 1,642 additions and 388 deletions.
5 changes: 4 additions & 1 deletion src/console/console.module.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { Test, TestingModule } from '@nestjs/testing';
import { ConsoleModule } from './console.module.js';
import { DbConsole } from './db.console.js';
import { DbInitConsole } from './db-init.console.js';
import { LoggingTestModule } from '../../test/utils/index.js';
import { PersonModule } from '../modules/person/person.module.js';
import { KeycloakAdministrationModule } from '../modules/keycloak-administration/keycloak-administration.module.js';

describe('ConsoleModule', () => {
let module: TestingModule;

beforeAll(async () => {
module = await Test.createTestingModule({
imports: [ConsoleModule],
imports: [PersonModule, KeycloakAdministrationModule, ConsoleModule, LoggingTestModule],
}).compile();
});

Expand Down
2 changes: 0 additions & 2 deletions src/console/console.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { DbConsole } from './db.console.js';
import { DbInitConsole } from './db-init.console.js';
import { LoggerModule } from '../core/logging/logger.module.js';
import { KeycloakAdministrationModule } from '../modules/keycloak-administration/keycloak-administration.module.js';
import { UsernameGeneratorService } from '../modules/person/domain/username-generator.service.js';
import { KeycloakConfigModule } from '../modules/keycloak-administration/keycloak-config.module.js';
import { OrganisationModule } from '../modules/organisation/organisation.module.js';
import { RolleModule } from '../modules/rolle/rolle.module.js';
Expand Down Expand Up @@ -93,7 +92,6 @@ import { KeycloakConsoleModule } from './keycloak/keycloak-console.module.js';
DbInitMigrationConsole,
DbCreateMigrationConsole,
DbApplyMigrationConsole,
UsernameGeneratorService,
DbSeedDataGeneratorConsole,
],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { DBiamPersonenkontextService } from '../../modules/personenkontext/domai
import { DbSeedReferenceRepo } from './repo/db-seed-reference.repo.js';
import { PersonenKontextModule } from '../../modules/personenkontext/personenkontext.module.js';
import { LdapClient } from '../../core/ldap/domain/ldap-client.js';
import { OxUserBlacklistRepo } from '../../modules/person/persistence/ox-user-blacklist.repo.js';

describe('DbSeedConsoleMockedDbSeedRepo', () => {
let module: TestingModule;
Expand All @@ -50,6 +51,7 @@ describe('DbSeedConsoleMockedDbSeedRepo', () => {
providers: [
UsernameGeneratorService,
DBiamPersonenkontextRepo,
OxUserBlacklistRepo,
DbSeedConsole,
DbSeedService,
DBiamPersonenkontextService,
Expand Down
3 changes: 2 additions & 1 deletion src/console/dbseed/db-seed.console.integration-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { RolleModule } from '../../modules/rolle/rolle.module.js';
import { ServiceProviderModule } from '../../modules/service-provider/service-provider.module.js';
import { DbSeedModule } from './db-seed.module.js';
import { PersonenKontextModule } from '../../modules/personenkontext/personenkontext.module.js';
import { OxUserBlacklistRepo } from '../../modules/person/persistence/ox-user-blacklist.repo.js';

describe('DbSeedConsoleIntegration', () => {
let module: TestingModule;
Expand All @@ -41,7 +42,7 @@ describe('DbSeedConsoleIntegration', () => {
ServiceProviderModule,
PersonenKontextModule,
],
providers: [UsernameGeneratorService, DBiamPersonenkontextRepo],
providers: [UsernameGeneratorService, DBiamPersonenkontextRepo, OxUserBlacklistRepo],
})
.overrideModule(KeycloakConfigModule)
.useModule(KeycloakConfigTestModule.forRoot({ isKeycloakRequired: true }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { PersonModule } from '../../../modules/person/person.module.js';
import { DbSeedModule } from '../db-seed.module.js';
import { PersonenKontextModule } from '../../../modules/personenkontext/personenkontext.module.js';
import { VornameForPersonWithTrailingSpaceError } from '../../../modules/person/domain/vorname-with-trailing-space.error.js';
import { OxUserBlacklistRepo } from '../../../modules/person/persistence/ox-user-blacklist.repo.js';

describe('DbSeedServiceIntegration', () => {
let module: TestingModule;
Expand All @@ -42,7 +43,7 @@ describe('DbSeedServiceIntegration', () => {
LoggingTestModule,
PersonenKontextModule,
],
providers: [UsernameGeneratorService, DBiamPersonenkontextRepo],
providers: [UsernameGeneratorService, DBiamPersonenkontextRepo, OxUserBlacklistRepo],
})
.overrideModule(KeycloakConfigModule)
.useModule(KeycloakConfigTestModule.forRoot({ isKeycloakRequired: true }))
Expand Down
150 changes: 129 additions & 21 deletions src/core/ldap/domain/ldap-client.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { LdapEmailDomainError } from '../error/ldap-email-domain.error.js';
import { LdapEmailAddressError } from '../error/ldap-email-address.error.js';
import { LdapCreateLehrerError } from '../error/ldap-create-lehrer.error.js';
import { LdapModifyEmailError } from '../error/ldap-modify-email.error.js';
import { PersonRepository } from '../../../modules/person/persistence/person.repository.js';
import { LdapInstanceConfig } from '../ldap-instance-config.js';
import { LdapModifyUserPasswordError } from '../error/ldap-modify-user-password.error.js';

describe('LDAP Client Service', () => {
let app: INestApplication;
Expand All @@ -40,7 +40,6 @@ describe('LDAP Client Service', () => {
let loggerMock: DeepMocked<ClassLogger>;
let eventServiceMock: DeepMocked<EventService>;
let clientMock: DeepMocked<Client>;
let personRepoMock: DeepMocked<PersonRepository>;
let instanceConfig: LdapInstanceConfig;

let person: Person<true>;
Expand Down Expand Up @@ -69,8 +68,6 @@ describe('LDAP Client Service', () => {
.useValue(createMock<ClassLogger>())
.overrideProvider(EventService)
.useValue(createMock<EventService>())
.overrideProvider(PersonRepository)
.useValue(createMock<PersonRepository>())
.compile();

orm = module.get(MikroORM);
Expand All @@ -80,7 +77,6 @@ describe('LDAP Client Service', () => {
loggerMock = module.get(ClassLogger);
eventServiceMock = module.get(EventService);
clientMock = createMock<Client>();
personRepoMock = module.get(PersonRepository);
instanceConfig = module.get(LdapInstanceConfig);

person = Person.construct(
Expand Down Expand Up @@ -459,7 +455,6 @@ describe('LDAP Client Service', () => {
clientMock.del.mockResolvedValueOnce();
return clientMock;
});
personRepoMock.findById.mockResolvedValueOnce(person);

const result: Result<PersonID> = await ldapClientService.deleteLehrerByReferrer(person.referrer!);

Expand Down Expand Up @@ -613,13 +608,13 @@ describe('LDAP Client Service', () => {

describe('when bind returns error', () => {
it('should return falsy result', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockRejectedValueOnce(new Error());
return clientMock;
});
const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
faker.string.uuid(),
faker.internet.userName(),
fakeSchuleSHAddress,
);

Expand All @@ -629,9 +624,9 @@ describe('LDAP Client Service', () => {

describe('when person can not be found in DB', () => {
it('should return falsy result', async () => {
personRepoMock.findById.mockResolvedValueOnce(undefined);
const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
faker.string.uuid(),
faker.internet.userName(),
fakeSchuleSHAddress,
);

Expand All @@ -641,10 +636,9 @@ describe('LDAP Client Service', () => {

describe('when called with invalid emailDomain', () => {
it('should return LdapEmailDomainError', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
faker.string.uuid(),
faker.internet.userName(),
'[email protected]',
);

Expand All @@ -656,10 +650,9 @@ describe('LDAP Client Service', () => {

describe('when called with newEmailAddress that is not splittable', () => {
it('should return LdapEmailAddressError', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
faker.string.uuid(),
faker.internet.userName(),
'user-at-wrong-email-domain.de',
);

Expand All @@ -671,7 +664,6 @@ describe('LDAP Client Service', () => {

describe('when person cannot be found by personID', () => {
it('should return LdapSearchError', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
Expand All @@ -684,6 +676,7 @@ describe('LDAP Client Service', () => {

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
faker.string.uuid(),
faker.internet.userName(),
fakeSchuleSHAddress,
);

Expand All @@ -702,8 +695,6 @@ describe('LDAP Client Service', () => {
const currentEmailAddress: string = '[email protected]';

it('should set mailAlternativeAddress as current mailPrimaryAddress and throw LdapPersonEntryChangedEvent', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
Expand All @@ -723,6 +714,7 @@ describe('LDAP Client Service', () => {

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
fakePersonID,
faker.internet.userName(),
newEmailAddress,
);

Expand Down Expand Up @@ -750,8 +742,6 @@ describe('LDAP Client Service', () => {

describe('and already has a mailPrimaryAddress', () => {
it('should set mailAlternativeAddress as current mailPrimaryAddress and throw LdapPersonEntryChangedEvent', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
Expand All @@ -771,6 +761,7 @@ describe('LDAP Client Service', () => {

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
fakePersonID,
faker.internet.userName(),
newEmailAddress,
);

Expand Down Expand Up @@ -798,8 +789,6 @@ describe('LDAP Client Service', () => {

describe('and already has a mailPrimaryAddress', () => {
it('should set mailAlternativeAddress as current mailPrimaryAddress and throw LdapPersonEntryChangedEvent', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
Expand All @@ -819,6 +808,7 @@ describe('LDAP Client Service', () => {

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
fakePersonID,
faker.internet.userName(),
newEmailAddress,
);

Expand All @@ -839,8 +829,6 @@ describe('LDAP Client Service', () => {

describe('but does NOT have a mailPrimaryAddress', () => {
it('should set mailAlternativeAddress to same value as mailPrimaryAddress and throw LdapPersonEntryChangedEvent', async () => {
personRepoMock.findById.mockResolvedValueOnce(person);

ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
Expand All @@ -860,6 +848,7 @@ describe('LDAP Client Service', () => {

const result: Result<PersonID> = await ldapClientService.changeEmailAddressByPersonId(
fakePersonID,
faker.internet.userName(),
newEmailAddress,
);

Expand All @@ -878,4 +867,123 @@ describe('LDAP Client Service', () => {
});
});
});

describe('changeUserPasswordByPersonId', () => {
describe('when bind returns error', () => {
it('should return falsy result', async () => {
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockRejectedValueOnce(new Error());
return clientMock;
});
const result: Result<PersonID> = await ldapClientService.changeUserPasswordByPersonId(
faker.string.uuid(),
faker.internet.userName(),
);

expect(result.ok).toBeFalsy();
});
});

describe('when person cannot be found by personID', () => {
it('should return LdapSearchError', async () => {
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
createMock<SearchResult>({
searchEntries: [],
}),
);
return clientMock;
});

const result: Result<PersonID> = await ldapClientService.changeUserPasswordByPersonId(
faker.string.uuid(),
faker.internet.userName(),
);

expect(result.ok).toBeFalsy();
expect(result).toEqual({
ok: false,
error: new LdapSearchError(LdapEntityType.LEHRER),
});
});
});

describe('when person can be found but modification fails', () => {
const fakePersonID: string = faker.string.uuid();
const fakeDN: string = faker.string.alpha();

it('should NOT publish event and throw LdapPersonEntryChangedEvent', async () => {
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
createMock<SearchResult>({
searchEntries: [
createMock<Entry>({
dn: fakeDN,
}),
],
}),
);
clientMock.modify.mockRejectedValueOnce(new Error());

return clientMock;
});

const result: Result<PersonID> = await ldapClientService.changeUserPasswordByPersonId(
fakePersonID,
faker.internet.userName(),
);

if (result.ok) throw Error();
expect(result.error).toStrictEqual(new LdapModifyUserPasswordError());
expect(loggerMock.error).toHaveBeenLastCalledWith(
`LDAP: Modifying userPassword (UEM) FAILED, errMsg:{}`,
);
expect(eventServiceMock.publish).toHaveBeenCalledTimes(0);
});
});

describe('when person can be found and userPassword can be modified', () => {
let fakePersonID: string;
let fakeDN: string;

beforeEach(() => {
fakePersonID = faker.string.uuid();
fakeDN = faker.string.alpha();
});

describe('when', () => {
it('should publish event and return new (UEM) userPassword', async () => {
ldapClientMock.getClient.mockImplementation(() => {
clientMock.bind.mockResolvedValueOnce();
clientMock.search.mockResolvedValueOnce(
createMock<SearchResult>({
searchEntries: [
createMock<Entry>({
dn: fakeDN,
}),
],
}),
);
clientMock.modify.mockResolvedValueOnce(undefined);

return clientMock;
});

const result: Result<PersonID> = await ldapClientService.changeUserPasswordByPersonId(
fakePersonID,
faker.internet.userName(),
);

if (!result.ok) throw Error();
expect(result.value).toHaveLength(8);
expect(loggerMock.info).toHaveBeenLastCalledWith(
`LDAP: Successfully modified userPassword (UEM) for personId:${fakePersonID}`,
);
expect(eventServiceMock.publish).toHaveBeenCalledTimes(1);
});
});
});
});
});
Loading

0 comments on commit d0a7df0

Please sign in to comment.