diff --git a/apps/server/src/shared/repo/mongo.patterns.ts b/apps/server/src/shared/repo/mongo.patterns.ts index 572fc9819bc..0cee8dbcf3b 100644 --- a/apps/server/src/shared/repo/mongo.patterns.ts +++ b/apps/server/src/shared/repo/mongo.patterns.ts @@ -4,5 +4,5 @@ export class MongoPatterns { * Used to remove all non-language characters except numbers, whitespace or minus. */ static REGEX_MONGO_LANGUAGE_PATTERN_WHITELIST = - /[^\-_\w\d áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ]/gi; + /[^\-_\w\d áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒß]/gi; } diff --git a/apps/server/src/shared/repo/user/user.repo.integration.spec.ts b/apps/server/src/shared/repo/user/user.repo.integration.spec.ts index d499efc45e8..4dba77016ac 100644 --- a/apps/server/src/shared/repo/user/user.repo.integration.spec.ts +++ b/apps/server/src/shared/repo/user/user.repo.integration.spec.ts @@ -371,6 +371,31 @@ describe('user repo', () => { // id do not exist await expect(repo.findForImportUser(school)).rejects.toThrowError(); }); + + describe('when the first or lastname of the user contains "ß"', () => { + describe('when the name filter query is exactly the first or lastname of the user', () => { + const setup = async () => { + const school = schoolEntityFactory.build(); + const user = userFactory.build({ school, firstName: 'Martin', lastName: 'Beißner' }); + await em.persistAndFlush([user]); + em.clear(); + + return { + school, + user, + }; + }; + + it('should return the searched user', async () => { + const { school, user } = await setup(); + + const [result, count] = await repo.findForImportUser(school, { name: user.lastName }); + + expect(count).toEqual(1); + expect(result.map((u) => u.id)).toContain(user.id); + }); + }); + }); }); describe('findByEmail', () => { diff --git a/apps/server/src/shared/repo/user/user.scope.spec.ts b/apps/server/src/shared/repo/user/user.scope.spec.ts index 484c5958d6d..6957c9acb5c 100644 --- a/apps/server/src/shared/repo/user/user.scope.spec.ts +++ b/apps/server/src/shared/repo/user/user.scope.spec.ts @@ -158,6 +158,26 @@ describe('UserScope', () => { expect(scope.query).toEqual({}); }); }); + + describe('when a name contains "ß"', () => { + const setup = () => { + const name = 'Beißner'; + + return { + name, + }; + }; + + it('should return scope with added query where first or lastname is given without removing the "ß"', () => { + const { name } = setup(); + + scope.byName(name); + + expect(scope.query).toEqual({ + $or: [{ firstName: new RegExp(name, 'i') }, { lastName: new RegExp(name, 'i') }], + }); + }); + }); }); describe('withDeleted', () => { @@ -173,7 +193,7 @@ describe('UserScope', () => { it('should add a query that removes deleted users', () => { scope.withDeleted(false); - expect(scope.query).toEqual({ deletedAt: { $exists: false } }); + expect(scope.query).toEqual({ $or: [{ deletedAt: { $exists: false } }, { deletedAt: null }] }); }); }); }); diff --git a/apps/server/src/shared/repo/user/user.scope.ts b/apps/server/src/shared/repo/user/user.scope.ts index 47efd5afe71..884fe970a90 100644 --- a/apps/server/src/shared/repo/user/user.scope.ts +++ b/apps/server/src/shared/repo/user/user.scope.ts @@ -51,7 +51,7 @@ export class UserScope extends Scope { withDeleted(deleted?: boolean): UserScope { if (!deleted) { - this.addQuery({ deletedAt: { $exists: false } }); + this.addQuery({ $or: [{ deletedAt: { $exists: false } }, { deletedAt: null }] }); } return this; }