Skip to content

Commit

Permalink
add UserManagement entity
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima committed Feb 2, 2024
1 parent 2f19de3 commit ce89b7e
Show file tree
Hide file tree
Showing 10 changed files with 936 additions and 117 deletions.
2 changes: 2 additions & 0 deletions generators/app/__snapshots__/generator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ exports[`generator - app with default config should match snapshot 1`] = `
"upperFirstCamelCaseBaseName": "Jhipster",
"useNpmWrapper": true,
"user": Any<Object>,
"userManagement": Any<Object>,
"webappEnumerationsDir": "src/main/webapp/app/entities/enumerations/",
"webappLoginRegExp": "^[a-zA-Z0-9!$&*+=?^_\`{|}~.-]+@[a-zA-Z0-9-]+(?:\\\\.[a-zA-Z0-9-]+)*$|^[_.@A-Za-z0-9-]+$",
"websocket": "no",
Expand Down Expand Up @@ -1324,6 +1325,7 @@ exports[`generator - app with gateway should match snapshot 1`] = `
"upperFirstCamelCaseBaseName": "Jhipster",
"useNpmWrapper": true,
"user": Any<Object>,
"userManagement": Any<Object>,
"webappEnumerationsDir": "src/main/webapp/app/entities/enumerations/",
"webappLoginRegExp": "^[a-zA-Z0-9!$&*+=?^_\`{|}~.-]+@[a-zA-Z0-9-]+(?:\\\\.[a-zA-Z0-9-]+)*$|^[_.@A-Za-z0-9-]+$",
"websocket": "no",
Expand Down
2 changes: 2 additions & 0 deletions generators/app/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe(`generator - ${generator}`, () => {
expect(runResult.generator.sharedData.getApplication()).toMatchSnapshot({
user: expect.any(Object),
authority: expect.any(Object),
userManagement: expect.any(Object),
jhipsterPackageJson: expect.any(Object),
});
});
Expand All @@ -75,6 +76,7 @@ describe(`generator - ${generator}`, () => {
expect(runResult.generator.sharedData.getApplication()).toMatchSnapshot({
user: expect.any(Object),
authority: expect.any(Object),
userManagement: expect.any(Object),
jhipsterPackageJson: expect.any(Object),
jwtSecretKey: expect.any(String),
});
Expand Down
100 changes: 54 additions & 46 deletions generators/base-application/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ describe(`generator - ${generator}`, () => {
const entitiesArg = {
...controlArg,
...applicationArg,
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
};

expect(initializing).toBeCalledWith(controlArg);
Expand All @@ -248,35 +248,39 @@ describe(`generator - ${generator}`, () => {
expect(configuringEachEntity).toHaveBeenNthCalledWith(2, { ...entityConfiguringArg, entityName: 'Two' });
expect(configuringEachEntity).toHaveBeenNthCalledWith(3, { ...entityConfiguringArg, entityName: 'Three' });

expect(preparingEachEntity).toBeCalledTimes(5);
expect(preparingEachEntity).toBeCalledTimes(6);
expect(preparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'UserManagement' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(6, { ...entityArg, entityName: 'Three' });

expect(preparingEachEntityField).toBeCalledTimes(9);
expect(preparingEachEntityField).toBeCalledTimes(29);
expect(preparingEachEntityField).toHaveBeenNthCalledWith(1, { ...fieldArg, description: 'User#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(2, { ...fieldArg, description: 'User#login' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(3, { ...fieldArg, description: 'User#firstName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(4, { ...fieldArg, description: 'User#lastName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(9, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(3);
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(1, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(5);
// Ommit UserManagement fields
expect(preparingEachEntityField).toHaveBeenNthCalledWith(25, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(26, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(27, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(28, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(29, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(4);
// Ommit UserManagement relationships
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(4, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(6);
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'UserManagement' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(6, { ...entityArg, entityName: 'Three' });

expect(defaultTask).toBeCalledWith(entitiesArg);
expect(writingEntities).toBeCalledWith(entitiesArg);
Expand Down Expand Up @@ -471,7 +475,7 @@ describe(`generator - ${generator}`, () => {

const entitiesArg = {
...applicationArg,
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
};

const writingEntitiesArg = {
Expand All @@ -495,35 +499,39 @@ describe(`generator - ${generator}`, () => {
expect(configuringEachEntity).toHaveBeenNthCalledWith(2, { ...entityConfiguringArg, entityName: 'Two' });
expect(configuringEachEntity).toHaveBeenNthCalledWith(3, { ...entityConfiguringArg, entityName: 'Three' });

expect(preparingEachEntity).toBeCalledTimes(5);
expect(preparingEachEntity).toBeCalledTimes(6);
expect(preparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'UserManagement' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(6, { ...entityArg, entityName: 'Three' });

expect(preparingEachEntityField).toBeCalledTimes(9);
expect(preparingEachEntityField).toBeCalledTimes(29);
expect(preparingEachEntityField).toHaveBeenNthCalledWith(1, { ...fieldArg, description: 'User#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(2, { ...fieldArg, description: 'User#login' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(3, { ...fieldArg, description: 'User#firstName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(4, { ...fieldArg, description: 'User#lastName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(9, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(3);
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(1, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(5);
// Ommit UserManagement fields
expect(preparingEachEntityField).toHaveBeenNthCalledWith(25, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(26, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(27, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(28, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(29, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(4);
// Ommit UserManagement relationships
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(4, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(6);
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'UserManagement' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(6, { ...entityArg, entityName: 'Three' });

expect(defaultTask).toBeCalledWith(entitiesArg);

Expand Down
16 changes: 9 additions & 7 deletions generators/base-application/support/prepare-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const BASE_TEMPLATE_DATA = {
entityAuthority: undefined,
entityReadAuthority: undefined,
adminEntity: undefined,
builtInUserManagement: undefined,

requiresPersistableImplementation: false,
updatableEntity: undefined,
Expand Down Expand Up @@ -209,8 +210,11 @@ export default function prepareEntity(entityWithConfig, generator, application)
});

mutateData(entityWithConfig, {
entityFileName: data =>
data.entityFileName ?? kebabCase(entityWithConfig.entityNameCapitalized + upperFirst(entityWithConfig.entityAngularJSSuffix)),
__override__: false,
entityFileName: data => kebabCase(data.entityNameCapitalized + upperFirst(data.entityAngularJSSuffix)),
entityAngularName: data => data.entityClass + upperFirstCamelCase(entityWithConfig.entityAngularJSSuffix),
entityAngularNamePlural: data => pluralize(data.entityAngularName),
entityApiUrl: data => data.entityNamePluralizedAndSpinalCased,
});
entityWithConfig.entityFolderName = entityWithConfig.clientRootFolder
? `${entityWithConfig.clientRootFolder}/${entityWithConfig.entityFileName}`
Expand All @@ -220,11 +224,8 @@ export default function prepareEntity(entityWithConfig, generator, application)
entityWithConfig.entityPluralFileName = entityWithConfig.entityNamePluralizedAndSpinalCased + entityWithConfig.entityAngularJSSuffix;
entityWithConfig.entityServiceFileName = entityWithConfig.entityFileName;

entityWithConfig.entityAngularName = entityWithConfig.entityClass + upperFirstCamelCase(entityWithConfig.entityAngularJSSuffix);
entityWithConfig.entityAngularNamePlural = pluralize(entityWithConfig.entityAngularName);
entityWithConfig.entityReactName = entityWithConfig.entityClass + upperFirstCamelCase(entityWithConfig.entityAngularJSSuffix);

entityWithConfig.entityApiUrl = entityWithConfig.entityNamePluralizedAndSpinalCased;
entityWithConfig.entityStateName = kebabCase(entityWithConfig.entityAngularName);
entityWithConfig.entityUrl = entityWithConfig.entityStateName;

Expand All @@ -248,9 +249,10 @@ export default function prepareEntity(entityWithConfig, generator, application)
const { microserviceName, entityFileName, microfrontend } = entityWithConfig;
entityWithConfig.entityApi = microserviceName ? `services/${microserviceName.toLowerCase()}/` : '';
entityWithConfig.entityPage =
microfrontend && microserviceName && entityWithConfig.applicationType === MICROSERVICE
entityWithConfig.entityPage ??
(microfrontend && microserviceName && entityWithConfig.applicationType === MICROSERVICE
? `${microserviceName.toLowerCase()}/${entityFileName}`
: `${entityFileName}`;
: `${entityFileName}`);

const hasBuiltInUserField = entityWithConfig.relationships.some(relationship => relationship.otherEntity.builtInUser);
entityWithConfig.saveUserSnapshot =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default function prepareRelationship(entityWithConfig, relationship, gene
});
} else if (
!ignoreMissingRequiredRelationship &&
!relationship.relationshipIgnoreBackReference &&
entityWithConfig.databaseType !== NEO4J &&
entityWithConfig.databaseType !== DATABASE_NO &&
(relationship.relationshipType === 'one-to-many' || relationship.ownerSide === false)
Expand Down
4 changes: 4 additions & 0 deletions generators/base-application/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ type ApplicationType = DeterministicOptionWithDerivedProperties<
type UserManagement =
| {
skipUserManagement: true;
generateUserManagement: false;
generateBuiltInUserEntity?: false;
generateBuiltInAuthorityEntity: false;
}
| {
skipUserManagement: false;
generateBuiltInUserEntity?: boolean;
generateUserManagement: true;
user: any;
userManagement: any;
generateBuiltInAuthorityEntity: boolean;
authority: any;
};
Expand All @@ -76,6 +79,7 @@ type Oauth2Application = {
generateBuiltInUserEntity?: boolean;
user: any;
generateBuiltInAuthorityEntity: false;
generateUserManagement: false;
};

type SessionApplication = UserManagement & {
Expand Down
17 changes: 14 additions & 3 deletions generators/base/support/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,22 @@ export const pickFields = (source: Record<string | number, any>, fields: (string
* { prop: ({ prop }) => prop + '-bar', prop2: 'won\'t override' },
* );
*/
export const mutateData = (context: Record<string | number, any>, ...mutations: Record<string | number, any>[]) => {
export const mutateData = (
context: Record<string | number, any>,
...mutations: Array<
Record<string | number, any> & {
/** Set to false if you don't want functions to override the value */
__override__?: boolean;
}
>
) => {
for (const mutation of mutations) {
for (const [key, value] of Object.entries(mutation)) {
const override = mutation.__override__;
for (const [key, value] of Object.entries(mutation).filter(([key]) => key !== '__override__')) {
if (typeof value === 'function') {
context[key] = value(context);
if (override !== false || context[key] === undefined) {
context[key] = value(context);
}
} else if (context[key] === undefined) {
context[key] = value;
}
Expand Down
20 changes: 19 additions & 1 deletion generators/bootstrap-application-base/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
prepareField as prepareFieldForTemplates,
prepareRelationship,
} from '../base-application/support/index.js';
import { createAuthorityEntity, createUserEntity } from './utils.js';
import { createAuthorityEntity, createUserEntity, createUserManagementEntity } from './utils.js';
import { JAVA_DOCKER_DIR } from '../generator-constants.js';
import { GENERATOR_BOOTSTRAP, GENERATOR_BOOTSTRAP_APPLICATION_BASE, GENERATOR_COMMON, GENERATOR_PROJECT_NAME } from '../generator-list.js';
import { packageJson } from '../../lib/index.js';
Expand Down Expand Up @@ -233,6 +233,24 @@ export default class BootstrapApplicationBase extends BaseApplicationGenerator {
application.user = user;
}
},
loadUserManagement({ application, entitiesToLoad }) {
if (application.generateBuiltInUserEntity && application.generateUserManagement) {
if (this.sharedData.hasEntity('UserManagement')) {
throw new Error("Fail to bootstrap 'User', already exists.");
}

const customUserManagement = entitiesToLoad.find(entityToLoad => entityToLoad.entityName === 'UserManagement');
const customUserManagementData: any = customUserManagement?.entityStorage.getAll() ?? {};

const userManagement = createUserManagementEntity.call(
this,
{ ...customUserManagementData, ...customUserManagementData.annotations },
application,
);
this.sharedData.setEntity('UserManagement', userManagement);
application.userManagement = userManagement;
}
},
loadAuthority({ application, entitiesToLoad }) {
if (application.generateBuiltInAuthorityEntity) {
const authority = 'Authority';
Expand Down
Loading

0 comments on commit ce89b7e

Please sign in to comment.