@mshima/generator-jhipster-nodejs 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +204 -0
- package/README.md +243 -2
- package/build-info.json +3 -0
- package/cli/cli-customizations.cjs +9 -0
- package/cli/cli.cjs +40 -0
- package/cli/logo.js +31 -0
- package/cli/version.cjs +12 -0
- package/generators/ci-cd/USAGE +5 -0
- package/generators/ci-cd/command.js +5 -0
- package/generators/ci-cd/generator.js +158 -0
- package/generators/ci-cd/index.js +2 -0
- package/generators/ci-cd/templates/.gitlab-ci.yml.ejs +137 -0
- package/generators/ci-cd/templates/azure-pipelines.yml.ejs +68 -0
- package/generators/ci-cd/templates/circle.yml.ejs +59 -0
- package/generators/ci-cd/templates/docker-registry.yml.ejs +58 -0
- package/generators/ci-cd/templates/github-ci.yml.ejs +90 -0
- package/generators/ci-cd/templates/jenkins/Jenkinsfile.ejs +104 -0
- package/generators/ci-cd/templates/jenkins/idea.gdsl +90 -0
- package/generators/ci-cd/templates/jenkins/jenkins.yml.ejs +33 -0
- package/generators/ci-cd/templates/travis.yml.ejs +75 -0
- package/generators/client/command.js +5 -0
- package/generators/client/generator.js +21 -0
- package/generators/client/generators/bootstrap/command.js +5 -0
- package/generators/client/generators/bootstrap/generator.js +28 -0
- package/generators/client/generators/bootstrap/index.js +2 -0
- package/generators/client/index.js +2 -0
- package/generators/common/generators/bootstrap/command.js +5 -0
- package/generators/common/generators/bootstrap/generator.js +37 -0
- package/generators/common/generators/bootstrap/index.js +2 -0
- package/generators/docker/command.js +5 -0
- package/generators/docker/generator.js +16 -0
- package/generators/docker/generators/bootstrap/command.js +5 -0
- package/generators/docker/generators/bootstrap/generator.js +56 -0
- package/generators/docker/generators/bootstrap/index.js +2 -0
- package/generators/docker/index.js +2 -0
- package/generators/docker/templates/docker/app.yml.ejs +25 -0
- package/generators/generator-nodejs-constants.js +32 -0
- package/generators/languages/command.js +5 -0
- package/generators/languages/generator.js +22 -0
- package/generators/languages/index.js +2 -0
- package/generators/languages/templates/src/main/webapp/i18n/en/home.json +19 -0
- package/generators/languages/templates/src/main/webapp/i18n/es/home.json +19 -0
- package/generators/languages/templates/src/main/webapp/i18n/it/home.json +19 -0
- package/generators/node-server/command.js +96 -0
- package/generators/node-server/entity-files.js +41 -0
- package/generators/node-server/files.js +254 -0
- package/generators/node-server/generator.js +702 -0
- package/generators/node-server/generators/bootstrap/command.js +5 -0
- package/generators/node-server/generators/bootstrap/generator.js +83 -0
- package/generators/node-server/generators/bootstrap/index.js +2 -0
- package/generators/node-server/index.js +2 -0
- package/generators/node-server/resources/package.json +76 -0
- package/generators/node-server/support/api-fake-data.js +54 -0
- package/generators/node-server/support/columns.js +73 -0
- package/generators/node-server/support/database.js +24 -0
- package/generators/node-server/support/entity-authorities.js +32 -0
- package/generators/node-server/support/entity-paths.js +13 -0
- package/generators/node-server/support/enums.js +11 -0
- package/generators/node-server/support/index.js +9 -0
- package/generators/node-server/support/mail-templates.js +82 -0
- package/generators/node-server/support/migrations.js +197 -0
- package/generators/node-server/support/validators.js +25 -0
- package/generators/node-server/templates/.dockerignore.ejs +16 -0
- package/generators/node-server/templates/.gitignore.jhi.nodejs.ejs +24 -0
- package/generators/node-server/templates/Dockerfile.ejs +54 -0
- package/generators/node-server/templates/README.md.jhi.nodejs.ejs +220 -0
- package/generators/node-server/templates/package.json.ejs +84 -0
- package/generators/node-server/templates/server/README.md.ejs +269 -0
- package/generators/node-server/templates/server/e2e/_entityFileName_.database.e2e-spec.ts.ejs +192 -0
- package/generators/node-server/templates/server/e2e/_entityFileName_.e2e-spec.ts.ejs +402 -0
- package/generators/node-server/templates/server/e2e/account.e2e-spec.ts.ejs +349 -0
- package/generators/node-server/templates/server/e2e/app.e2e-spec.ts.ejs +188 -0
- package/generators/node-server/templates/server/e2e/authority.e2e-spec.ts.ejs +50 -0
- package/generators/node-server/templates/server/e2e/cors.e2e-spec.ts.ejs +110 -0
- package/generators/node-server/templates/server/e2e/management.e2e-spec.ts.ejs +180 -0
- package/generators/node-server/templates/server/e2e/oauth2-bearer.e2e-spec.ts.ejs +71 -0
- package/generators/node-server/templates/server/e2e/session.e2e-spec.ts.ejs +219 -0
- package/generators/node-server/templates/server/e2e/setup.test.js.ejs +1 -0
- package/generators/node-server/templates/server/e2e/user.e2e-spec.ts.ejs +318 -0
- package/generators/node-server/templates/server/env.ejs +1 -0
- package/generators/node-server/templates/server/eslint.config.mjs.ejs +48 -0
- package/generators/node-server/templates/server/nest-cli.json.ejs +11 -0
- package/generators/node-server/templates/server/ormconfig.ts.ejs +35 -0
- package/generators/node-server/templates/server/package.json.ejs +143 -0
- package/generators/node-server/templates/server/sonar-project.properties.ejs +10 -0
- package/generators/node-server/templates/server/src/app.config.spec.ts.ejs +13 -0
- package/generators/node-server/templates/server/src/app.config.ts.ejs +179 -0
- package/generators/node-server/templates/server/src/app.module.ts.ejs +80 -0
- package/generators/node-server/templates/server/src/application-config.ts.ejs +153 -0
- package/generators/node-server/templates/server/src/auth/account.controller.ts.ejs +183 -0
- package/generators/node-server/templates/server/src/auth/auth.module.ts.ejs +104 -0
- package/generators/node-server/templates/server/src/auth/auth.service.ts.ejs +294 -0
- package/generators/node-server/templates/server/src/auth/csrf.middleware.spec.ts.ejs +65 -0
- package/generators/node-server/templates/server/src/auth/csrf.middleware.ts.ejs +76 -0
- package/generators/node-server/templates/server/src/auth/decorators/auth-user.decorator.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/auth/decorators/roles.decorator.ts.ejs +4 -0
- package/generators/node-server/templates/server/src/auth/dto/key-and-password.dto.ts.ejs +17 -0
- package/generators/node-server/templates/server/src/auth/dto/password-change.dto.ts.ejs +17 -0
- package/generators/node-server/templates/server/src/auth/dto/user-login.dto.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/auth/guards/auth.guard.ts.ejs +50 -0
- package/generators/node-server/templates/server/src/auth/guards/oauth2-login.guard.ts.ejs +6 -0
- package/generators/node-server/templates/server/src/auth/guards/roles.guard.ts.ejs +25 -0
- package/generators/node-server/templates/server/src/auth/index.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/auth/jwt.config.spec.ts.ejs +22 -0
- package/generators/node-server/templates/server/src/auth/jwt.config.ts.ejs +29 -0
- package/generators/node-server/templates/server/src/auth/oauth2.authorities.spec.ts.ejs +24 -0
- package/generators/node-server/templates/server/src/auth/oauth2.authorities.ts.ejs +33 -0
- package/generators/node-server/templates/server/src/auth/oauth2.config.ts.ejs +51 -0
- package/generators/node-server/templates/server/src/auth/passport.jwt.strategy.ts.ejs +45 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2-bearer.strategy.ts.ejs +32 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.spec.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.ts.ejs +44 -0
- package/generators/node-server/templates/server/src/auth/password-util.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/auth/password.service.ts.ejs +34 -0
- package/generators/node-server/templates/server/src/auth/payload.interface.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/auth/role-type.ts.ejs +7 -0
- package/generators/node-server/templates/server/src/auth/session-user.middleware.ts.ejs +33 -0
- package/generators/node-server/templates/server/src/auth/session.entity.ts.ejs +36 -0
- package/generators/node-server/templates/server/src/auth/session.store.spec.ts.ejs +99 -0
- package/generators/node-server/templates/server/src/auth/session.store.ts.ejs +116 -0
- package/generators/node-server/templates/server/src/auth/user.jwt.controller.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/auth/user.oauth2.controller.ts.ejs +78 -0
- package/generators/node-server/templates/server/src/auth/user.session.controller.ts.ejs +103 -0
- package/generators/node-server/templates/server/src/common/common.module.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/common/database/base.entity.ts.ejs +13 -0
- package/generators/node-server/templates/server/src/common/database/column-transformers.spec.ts.ejs +46 -0
- package/generators/node-server/templates/server/src/common/database/column-transformers.ts.ejs +69 -0
- package/generators/node-server/templates/server/src/common/database/column-types.spec.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/common/database/column-types.ts.ejs +29 -0
- package/generators/node-server/templates/server/src/common/database/pagination.entity.spec.ts.ejs +66 -0
- package/generators/node-server/templates/server/src/common/database/pagination.entity.ts.ejs +108 -0
- package/generators/node-server/templates/server/src/common/dto/base.dto.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/common/errors/error-constants.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/common/errors/problem-details.filter.ts.ejs +63 -0
- package/generators/node-server/templates/server/src/common/errors/problem.exception.ts.ejs +92 -0
- package/generators/node-server/templates/server/src/common/field_validators.ejs +77 -0
- package/generators/node-server/templates/server/src/common/header-util.ts.ejs +105 -0
- package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.spec.ts.ejs +93 -0
- package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.ts.ejs +48 -0
- package/generators/node-server/templates/server/src/common/logging.spec.ts.ejs +83 -0
- package/generators/node-server/templates/server/src/common/logging.ts.ejs +129 -0
- package/generators/node-server/templates/server/src/common/metrics.spec.ts.ejs +43 -0
- package/generators/node-server/templates/server/src/common/metrics.ts.ejs +198 -0
- package/generators/node-server/templates/server/src/common/request.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/common/sortable-properties.ts.ejs +43 -0
- package/generators/node-server/templates/server/src/common/updatable-properties.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/config/application-dev.yml.ejs +118 -0
- package/generators/node-server/templates/server/src/config/application-prod.yml.ejs +97 -0
- package/generators/node-server/templates/server/src/config/application-secret-samples.yml.ejs +42 -0
- package/generators/node-server/templates/server/src/config/application-test.yml.ejs +68 -0
- package/generators/node-server/templates/server/src/config/application-tls-samples.yml.ejs +15 -0
- package/generators/node-server/templates/server/src/config/application-tls.yml.ejs +15 -0
- package/generators/node-server/templates/server/src/config/application.yml.ejs +149 -0
- package/generators/node-server/templates/server/src/config.spec.ts.ejs +81 -0
- package/generators/node-server/templates/server/src/config.ts.ejs +255 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.controller.ts.ejs +178 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.entity.ts.ejs +110 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.mapper.ts.ejs +37 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.module.ts.ejs +14 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.service.ts.ejs +123 -0
- package/generators/node-server/templates/server/src/entities/_entityFileName_/dto/_entityFileName_.dto.ts.ejs +99 -0
- package/generators/node-server/templates/server/src/mail/mail.module.ts.ejs +49 -0
- package/generators/node-server/templates/server/src/mail/mail.service.spec.ts.ejs +105 -0
- package/generators/node-server/templates/server/src/mail/mail.service.ts.ejs +120 -0
- package/generators/node-server/templates/server/src/main.ts.ejs +114 -0
- package/generators/node-server/templates/server/src/management/api-docs.controller.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/management/api-docs.service.ts.ejs +8 -0
- package/generators/node-server/templates/server/src/management/configuration.controller.ts.ejs +80 -0
- package/generators/node-server/templates/server/src/management/health.controller.spec.ts.ejs +79 -0
- package/generators/node-server/templates/server/src/management/health.controller.ts.ejs +87 -0
- package/generators/node-server/templates/server/src/management/health.module.ts.ejs +9 -0
- package/generators/node-server/templates/server/src/management/loggers.controller.ts.ejs +40 -0
- package/generators/node-server/templates/server/src/management/management.controller.spec.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/management/management.controller.ts.ejs +34 -0
- package/generators/node-server/templates/server/src/management/management.module.ts.ejs +21 -0
- package/generators/node-server/templates/server/src/management/metrics.controller.ts.ejs +85 -0
- package/generators/node-server/templates/server/src/migrations/1570200270081-CreateTables.ts.ejs +64 -0
- package/generators/node-server/templates/server/src/migrations/1570200270082-CreateSessions.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/migrations/1570200490072-SeedUsersRoles.ts.ejs +74 -0
- package/generators/node-server/templates/server/src/migrations/_entityConstraintsMigration_.ts.ejs +40 -0
- package/generators/node-server/templates/server/src/migrations/_entityMigration_.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/migrations/support/schema.ts.ejs +202 -0
- package/generators/node-server/templates/server/src/orm.config.ts.ejs +147 -0
- package/generators/node-server/templates/server/src/registry/consul.service.ts.ejs +70 -0
- package/generators/node-server/templates/server/src/registry/eureka.service.ts.ejs +129 -0
- package/generators/node-server/templates/server/src/swagger.ts.ejs +24 -0
- package/generators/node-server/templates/server/src/tls.ts.ejs +27 -0
- package/generators/node-server/templates/server/src/users/authority.controller.ts.ejs +85 -0
- package/generators/node-server/templates/server/src/users/authority.entity.ts.ejs +22 -0
- package/generators/node-server/templates/server/src/users/dto/authority.dto.ts.ejs +10 -0
- package/generators/node-server/templates/server/src/users/dto/user.dto.ts.ejs +116 -0
- package/generators/node-server/templates/server/src/users/public.user.controller.ts.ejs +51 -0
- package/generators/node-server/templates/server/src/users/user.controller.ts.ejs +191 -0
- package/generators/node-server/templates/server/src/users/user.entity.ts.ejs +63 -0
- package/generators/node-server/templates/server/src/users/user.mapper.ts.ejs +26 -0
- package/generators/node-server/templates/server/src/users/user.module.ts.ejs +19 -0
- package/generators/node-server/templates/server/src/users/user.service.ts.ejs +156 -0
- package/generators/node-server/templates/server/tsconfig.build.json.ejs +9 -0
- package/generators/node-server/templates/server/tsconfig.json.ejs +23 -0
- package/generators/node-server/templates/server/typeorm-migration.ts.ejs +18 -0
- package/generators/node-server/templates/server/vitest.config.e2e.ts.ejs +16 -0
- package/generators/node-server/templates/server/vitest.config.ts.ejs +16 -0
- package/generators/server/command.js +7 -0
- package/generators/server/generator.js +20 -0
- package/generators/server/generators/bootstrap/command.js +5 -0
- package/generators/server/generators/bootstrap/generator.js +15 -0
- package/generators/server/generators/bootstrap/index.js +2 -0
- package/generators/server/index.js +2 -0
- package/package.json +75 -4
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
<%_
|
|
2
|
+
// The fake data of this test, whatever the templates rendered before: the faker of the entity is seeded for it.
|
|
3
|
+
resetFakerSeed('nodejs-e2e-mock');
|
|
4
|
+
const numericId = primaryKey.tsType === 'number';
|
|
5
|
+
// The fake data of the fields, reproducible (the faker of the entity is seeded): distinct ids of the type of the primary
|
|
6
|
+
// key, as TypeScript literals, and a value for each field of the entity, as the API exchanges it.
|
|
7
|
+
const idField = primaryKey.fields[0];
|
|
8
|
+
const [entityId, unknownId, anotherId] = [idField.generateFakeData('ts'), idField.generateFakeData('ts'), idField.generateFakeData('ts')];
|
|
9
|
+
const fakeFields = fields
|
|
10
|
+
.filter(field => !field.id && !field.transient && !field.collection)
|
|
11
|
+
.map(field => [field.propertyName, field.nodejsApiFakeValue()])
|
|
12
|
+
.filter(([, value]) => value !== undefined && value !== null);
|
|
13
|
+
// An id the pipe of the path rejects: neither a number nor a UUID.
|
|
14
|
+
const invalidId = faker.lorem.word({ length: { min: 5, max: 10 } });
|
|
15
|
+
_%>
|
|
16
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
17
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
18
|
+
import request from 'supertest';
|
|
19
|
+
import { AppModule } from '../src/app.module.ts';
|
|
20
|
+
import { configureApp } from '../src/app.config.ts';
|
|
21
|
+
import { INestApplication } from '@nestjs/common';
|
|
22
|
+
import { AuthGuard } from '../src/auth/guards/auth.guard.ts';
|
|
23
|
+
import { RolesGuard } from '../src/auth/guards/roles.guard.ts';
|
|
24
|
+
import { <%= dtoClass %> } from '../src/entities/<%= entityFileName %>/dto/<%= entityFileName %>.dto.ts';
|
|
25
|
+
import { <%= entityClass %>Service } from '../src/entities/<%= entityFileName %>/<%= entityFileName %>.service.ts';
|
|
26
|
+
import { DataSource, EntityMetadata } from 'typeorm';
|
|
27
|
+
import { <%= entityClass %> } from '../src/entities/<%= entityFileName %>/<%= entityFileName %>.entity.ts';
|
|
28
|
+
|
|
29
|
+
// The alert headers the JHipster clients read, named after jhipster.clientApp.name.
|
|
30
|
+
const alertHeader = (headers: Record<string, unknown>, suffix: string): unknown => headers[`x-<%= frontendAppName.toLowerCase() %>${suffix}`];
|
|
31
|
+
|
|
32
|
+
describe('<%= entityClass %> Controller', () => {
|
|
33
|
+
let app: INestApplication;
|
|
34
|
+
|
|
35
|
+
const authGuardMock = { canActivate: (): any => true };
|
|
36
|
+
const rolesGuardMock = { canActivate: (): any => true };
|
|
37
|
+
const entityMock: any = {
|
|
38
|
+
id: <%- entityId %>,
|
|
39
|
+
<%_ for (const [propertyName, value] of fakeFields) { _%>
|
|
40
|
+
<%- propertyName %>: <%- JSON.stringify(value) %>,
|
|
41
|
+
<%_ } _%>
|
|
42
|
+
}
|
|
43
|
+
const unknownId = <%- unknownId %>;
|
|
44
|
+
const anotherId = <%- anotherId %>;
|
|
45
|
+
<%_
|
|
46
|
+
// The global ValidationPipe of configureApp validates the requests: a body with valid values of the validated fields.
|
|
47
|
+
resetFakerSeed('nodejs-e2e');
|
|
48
|
+
const validatedFields = fields.filter(field => !field.id && field.fieldValidate && field.fieldType !== 'byte[]');
|
|
49
|
+
const validValues = Object.fromEntries(
|
|
50
|
+
validatedFields
|
|
51
|
+
.map(field => [field.fieldName, field.nodejsApiFakeValue()])
|
|
52
|
+
.filter(([, value]) => value !== undefined && value !== null),
|
|
53
|
+
);
|
|
54
|
+
const requiredField = validatedFields.find(field => field.fieldValidationRequired);
|
|
55
|
+
const enumField = fields.find(field => !field.id && field.fieldIsEnum);
|
|
56
|
+
_%>
|
|
57
|
+
const validEntity: any = {
|
|
58
|
+
...entityMock,
|
|
59
|
+
<%_ for (const [fieldName, value] of Object.entries(validValues)) { _%>
|
|
60
|
+
<%= fieldName %>: <%- JSON.stringify(value) %>,
|
|
61
|
+
<%_ } _%>
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const serviceMock: { metadata?: EntityMetadata, [method: string]: unknown } = {
|
|
65
|
+
findById: (id: any): any => (id === entityMock.id ? { ...entityMock } : undefined),
|
|
66
|
+
findAndCount: (): any => [entityMock, 0],
|
|
67
|
+
save: (): any => entityMock,
|
|
68
|
+
update: (dto: any): any => dto,
|
|
69
|
+
deleteById: (): any => entityMock
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
beforeEach(async () => {
|
|
74
|
+
const moduleFixture: TestingModule = await Test.createTestingModule({
|
|
75
|
+
imports: [AppModule],
|
|
76
|
+
}).overrideGuard(AuthGuard)
|
|
77
|
+
.useValue(authGuardMock)
|
|
78
|
+
.overrideGuard(RolesGuard)
|
|
79
|
+
.useValue(rolesGuardMock)
|
|
80
|
+
.overrideProvider(<%= entityClass %>Service)
|
|
81
|
+
.useValue(serviceMock)
|
|
82
|
+
.compile();
|
|
83
|
+
// The sort is validated with the TypeORM metadata of the entity.
|
|
84
|
+
serviceMock.metadata = moduleFixture.get(DataSource).getMetadata(<%= entityClass %>);
|
|
85
|
+
|
|
86
|
+
app = moduleFixture.createNestApplication();
|
|
87
|
+
configureApp(app);
|
|
88
|
+
await app.init();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('/GET all <%= entityApiUrl %> ', async () => {
|
|
92
|
+
|
|
93
|
+
const getEntities: <%= dtoClass %>[] = (await request(app.getHttpServer())
|
|
94
|
+
.get('/api/<%= entityApiUrl %>')
|
|
95
|
+
.expect(200)).body;
|
|
96
|
+
|
|
97
|
+
expect(getEntities).toEqual(entityMock);
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
<%_
|
|
103
|
+
const sortField = fields.find(field => !field.id && !field.transient);
|
|
104
|
+
const sortRelationship = relationships.find(relationship => relationship.ownerSide && !relationship.collection);
|
|
105
|
+
_%>
|
|
106
|
+
|
|
107
|
+
it('/GET all <%= entityApiUrl %> sorted on a property of the entity', async () => {
|
|
108
|
+
await request(app.getHttpServer())
|
|
109
|
+
.get('/api/<%= entityApiUrl %>?sort=<%= sortField ? sortField.fieldName : primaryKey.name %>,desc')
|
|
110
|
+
.expect(200);
|
|
111
|
+
});
|
|
112
|
+
<%_ if (sortRelationship) { _%>
|
|
113
|
+
|
|
114
|
+
it('/GET all <%= entityApiUrl %> sorted on the id and the label of a relationship', async () => {
|
|
115
|
+
await request(app.getHttpServer())
|
|
116
|
+
.get('/api/<%= entityApiUrl %>?sort=<%= sortRelationship.propertyName %>.id,asc')
|
|
117
|
+
.expect(200);
|
|
118
|
+
await request(app.getHttpServer())
|
|
119
|
+
.get('/api/<%= entityApiUrl %>?sort=<%= sortRelationship.propertyName %>.<%= sortRelationship.otherEntityField %>,desc')
|
|
120
|
+
.expect(200);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('/GET all <%= entityApiUrl %> sorted on a deeper property of a relationship', async () => {
|
|
124
|
+
await request(app.getHttpServer())
|
|
125
|
+
.get('/api/<%= entityApiUrl %>?sort=<%= sortRelationship.propertyName %>.id.unknown,asc')
|
|
126
|
+
.expect(400);
|
|
127
|
+
});
|
|
128
|
+
<%_ } _%>
|
|
129
|
+
|
|
130
|
+
it('/GET all <%= entityApiUrl %> sorted on an unknown property', async () => {
|
|
131
|
+
const response = await request(app.getHttpServer())
|
|
132
|
+
.get('/api/<%= entityApiUrl %>?sort=unknownProperty,asc')
|
|
133
|
+
.expect(400);
|
|
134
|
+
|
|
135
|
+
expect(response.body.detail).toBe('Invalid sort property: unknownProperty');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
<%_ if (pagination === 'no') { _%>
|
|
139
|
+
it('/GET all <%= entityApiUrl %> without pagination, like JHipster Spring Boot', async () => {
|
|
140
|
+
const { findAndCount } = serviceMock;
|
|
141
|
+
const options: any[] = [];
|
|
142
|
+
(serviceMock as any).findAndCount = (findOptions: any): any => {
|
|
143
|
+
options.push(findOptions);
|
|
144
|
+
return [[entityMock], 45];
|
|
145
|
+
};
|
|
146
|
+
try {
|
|
147
|
+
const response = await request(app.getHttpServer())
|
|
148
|
+
.get('/api/<%= entityApiUrl %>')
|
|
149
|
+
.expect(200);
|
|
150
|
+
|
|
151
|
+
expect(options[0].take).toBeUndefined();
|
|
152
|
+
expect(response.headers['x-total-count']).toBeUndefined();
|
|
153
|
+
expect(response.headers.link).toBeUndefined();
|
|
154
|
+
} finally {
|
|
155
|
+
serviceMock.findAndCount = findAndCount;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
<%_ } else { _%>
|
|
160
|
+
it('/GET all <%= entityApiUrl %> with the links of the pages', async () => {
|
|
161
|
+
const { findAndCount } = serviceMock;
|
|
162
|
+
// 45 records, 3 pages of 20.
|
|
163
|
+
serviceMock.findAndCount = (): any => [[entityMock], 45];
|
|
164
|
+
try {
|
|
165
|
+
const response = await request(app.getHttpServer())
|
|
166
|
+
.get('/api/<%= entityApiUrl %>?page=1&size=20')
|
|
167
|
+
.expect(200);
|
|
168
|
+
|
|
169
|
+
expect(response.headers['x-total-count']).toBe('45');
|
|
170
|
+
expect(response.headers.link.split(',')).toEqual([
|
|
171
|
+
'</api/<%= entityApiUrl %>?page=2&size=20>; rel="next"',
|
|
172
|
+
'</api/<%= entityApiUrl %>?page=0&size=20>; rel="prev"',
|
|
173
|
+
'</api/<%= entityApiUrl %>?page=2&size=20>; rel="last"',
|
|
174
|
+
'</api/<%= entityApiUrl %>?page=0&size=20>; rel="first"',
|
|
175
|
+
]);
|
|
176
|
+
} finally {
|
|
177
|
+
serviceMock.findAndCount = findAndCount;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('/GET all <%= entityApiUrl %> without records links the first page as the last one', async () => {
|
|
182
|
+
const response = await request(app.getHttpServer())
|
|
183
|
+
.get('/api/<%= entityApiUrl %>')
|
|
184
|
+
.expect(200);
|
|
185
|
+
|
|
186
|
+
expect(response.headers.link).toContain('page=0&size=20>; rel="last"');
|
|
187
|
+
expect(response.headers.link).not.toContain('rel="next"');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
<%_ } _%>
|
|
191
|
+
it('/GET <%= entityApiUrl %> by id', async () => {
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
const getEntity: <%= dtoClass %> = (await request(app.getHttpServer())
|
|
195
|
+
.get(`/api/<%= entityApiUrl %>/${entityMock.id}`)
|
|
196
|
+
.expect(200)).body;
|
|
197
|
+
|
|
198
|
+
expect(getEntity).toEqual(entityMock);
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
it('/GET <%= entityApiUrl %> by an unknown id', async () => {
|
|
204
|
+
await request(app.getHttpServer())
|
|
205
|
+
.get(`/api/<%= entityApiUrl %>/${unknownId}`)
|
|
206
|
+
.expect(404);
|
|
207
|
+
});
|
|
208
|
+
<%_ if (numericId || primaryKey.typeUUID) { _%>
|
|
209
|
+
|
|
210
|
+
it('/GET <%= entityApiUrl %> by an invalid id', async () => {
|
|
211
|
+
await request(app.getHttpServer())
|
|
212
|
+
.get('/api/<%= entityApiUrl %>/<%= invalidId %>')
|
|
213
|
+
.expect(400);
|
|
214
|
+
});
|
|
215
|
+
<%_ } _%>
|
|
216
|
+
|
|
217
|
+
it('/POST create <%= entityApiUrl %>', async () => {
|
|
218
|
+
const { id: _id, ...newEntity } = validEntity;
|
|
219
|
+
const response = await request(app.getHttpServer())
|
|
220
|
+
.post('/api/<%= entityApiUrl %>')
|
|
221
|
+
.send(newEntity)
|
|
222
|
+
.expect(201);
|
|
223
|
+
|
|
224
|
+
expect(response.body).toEqual(entityMock);
|
|
225
|
+
expect(response.headers.location).toBe(`/api/<%= entityApiUrl %>/${entityMock.id}`);
|
|
226
|
+
expect(alertHeader(response.headers, '-alert')).toMatch(<%- enableTranslation ? `/^${frontendAppName}\\.${entityAlertName}\\.created$/` : `/^A new ${entityAlertName} is created with identifier /` %>);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('/POST create <%= entityApiUrl %> ignores the properties its DTO does not declare', async () => {
|
|
230
|
+
// Like JHipster Spring Boot, which ignores the unknown properties of a request: the service gets the declared ones.
|
|
231
|
+
const { id: _id, ...newEntity } = validEntity;
|
|
232
|
+
const save = vi.spyOn(serviceMock as any, 'save');
|
|
233
|
+
try {
|
|
234
|
+
await request(app.getHttpServer())
|
|
235
|
+
.post('/api/<%= entityApiUrl %>')
|
|
236
|
+
.send({ ...newEntity, unknownProperty: 'unknown' })
|
|
237
|
+
.expect(201);
|
|
238
|
+
|
|
239
|
+
const [dto] = save.mock.calls[0];
|
|
240
|
+
expect(dto).not.toHaveProperty('unknownProperty');
|
|
241
|
+
expect(Object.keys(dto as object)).toEqual(expect.arrayContaining(Object.keys(JSON.parse(JSON.stringify(newEntity)))));
|
|
242
|
+
} finally {
|
|
243
|
+
save.mockRestore();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('/POST create <%= entityApiUrl %> with an id', async () => {
|
|
248
|
+
const response = await request(app.getHttpServer())
|
|
249
|
+
.post('/api/<%= entityApiUrl %>')
|
|
250
|
+
.send(validEntity)
|
|
251
|
+
.expect(400);
|
|
252
|
+
|
|
253
|
+
expect(alertHeader(response.headers, '-error')).toBe('error.idexists');
|
|
254
|
+
expect(response.body).toMatchObject({ message: 'error.idexists', params: '<%= entityAlertName %>' });
|
|
255
|
+
expect(alertHeader(response.headers, '-params')).toBe('<%= entityAlertName %>');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
<%_ if (requiredField) { _%>
|
|
259
|
+
it('/POST create <%= entityApiUrl %> without <%= requiredField.fieldName %> is a validation error', async () => {
|
|
260
|
+
const { <%= requiredField.fieldName %>: _<%= requiredField.fieldName %>, ...invalidEntity } = validEntity;
|
|
261
|
+
|
|
262
|
+
const error = (await request(app.getHttpServer())
|
|
263
|
+
.post('/api/<%= entityApiUrl %>')
|
|
264
|
+
.send(invalidEntity)
|
|
265
|
+
.expect(400)).body;
|
|
266
|
+
|
|
267
|
+
expect(error).toMatchObject({
|
|
268
|
+
type: 'https://www.jhipster.tech/problem/constraint-violation',
|
|
269
|
+
message: 'error.validation',
|
|
270
|
+
fieldErrors: [{ objectName: '<%= entityInstance %>', field: '<%= requiredField.fieldName %>', message: expect.any(String) }],
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
<%_ } _%>
|
|
275
|
+
<%_ if (enumField) { _%>
|
|
276
|
+
it('/POST create <%= entityApiUrl %> with a <%= enumField.fieldName %> out of its enum is a validation error', async () => {
|
|
277
|
+
const error = (await request(app.getHttpServer())
|
|
278
|
+
.post('/api/<%= entityApiUrl %>')
|
|
279
|
+
.send({ ...validEntity, <%= enumField.fieldName %>: 'NOT_A_<%= enumField.fieldType.toUpperCase() %>' })
|
|
280
|
+
.expect(400)).body;
|
|
281
|
+
|
|
282
|
+
expect(error).toMatchObject({ message: 'error.validation', fieldErrors: [expect.objectContaining({ field: '<%= enumField.fieldName %>' })] });
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
<%_ } _%>
|
|
286
|
+
it('/PUT update <%= entityApiUrl %> from id', async () => {
|
|
287
|
+
const response = await request(app.getHttpServer())
|
|
288
|
+
.put(`/api/<%= entityApiUrl %>/${entityMock.id}`)
|
|
289
|
+
.send(validEntity)
|
|
290
|
+
.expect(200);
|
|
291
|
+
|
|
292
|
+
expect(response.body).toEqual(validEntity);
|
|
293
|
+
expect(alertHeader(response.headers, '-alert')).toMatch(<%- enableTranslation ? `/^${frontendAppName}\\.${entityAlertName}\\.updated$/` : `/^A ${entityAlertName} is updated with identifier /` %>);
|
|
294
|
+
expect(alertHeader(response.headers, '-params')).toBe(String(entityMock.id));
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
it('/PUT update <%= entityApiUrl %> from another id', async () => {
|
|
299
|
+
const response = await request(app.getHttpServer())
|
|
300
|
+
.put(`/api/<%= entityApiUrl %>/${anotherId}`)
|
|
301
|
+
.send(validEntity)
|
|
302
|
+
.expect(400);
|
|
303
|
+
|
|
304
|
+
expect(alertHeader(response.headers, '-error')).toBe('error.idinvalid');
|
|
305
|
+
expect(response.body).toMatchObject({ message: 'error.idinvalid', params: '<%= entityAlertName %>' });
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('/PUT update <%= entityApiUrl %> without id', async () => {
|
|
309
|
+
const response = await request(app.getHttpServer())
|
|
310
|
+
.put(`/api/<%= entityApiUrl %>/${entityMock.id}`)
|
|
311
|
+
.send({ ...validEntity, id: undefined })
|
|
312
|
+
.expect(400);
|
|
313
|
+
|
|
314
|
+
expect(alertHeader(response.headers, '-error')).toBe('error.idnull');
|
|
315
|
+
expect(response.body).toMatchObject({ message: 'error.idnull', params: '<%= entityAlertName %>' });
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('/PUT update an unknown <%= entityApiUrl %>', async () => {
|
|
319
|
+
const response = await request(app.getHttpServer())
|
|
320
|
+
.put(`/api/<%= entityApiUrl %>/${unknownId}`)
|
|
321
|
+
.send({ ...validEntity, id: unknownId })
|
|
322
|
+
.expect(400);
|
|
323
|
+
|
|
324
|
+
expect(alertHeader(response.headers, '-error')).toBe('error.idnotfound');
|
|
325
|
+
expect(response.body).toMatchObject({ message: 'error.idnotfound', params: '<%= entityAlertName %>' });
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('/DELETE <%= entityApiUrl %>', async () => {
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
const deletedEntity: <%= dtoClass %> = (await request(app.getHttpServer())
|
|
332
|
+
.delete(`/api/<%= entityApiUrl %>/${entityMock.id}`)
|
|
333
|
+
.expect(204)).body;
|
|
334
|
+
|
|
335
|
+
expect(deletedEntity).toEqual({});
|
|
336
|
+
}
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
afterEach(async () => {
|
|
340
|
+
await app?.close();
|
|
341
|
+
});
|
|
342
|
+
<%_ if (nodejsReadRoles) { _%>
|
|
343
|
+
|
|
344
|
+
describe('with the roles of <%= entityClass %>, like the @PreAuthorize of JHipster Spring Boot', () => {
|
|
345
|
+
let rolesApp: INestApplication;
|
|
346
|
+
|
|
347
|
+
/** The application with its RolesGuard, for a user of these roles. */
|
|
348
|
+
const appOfUser = async (authorities: string[]): Promise<INestApplication> => {
|
|
349
|
+
const moduleFixture: TestingModule = await Test.createTestingModule({
|
|
350
|
+
imports: [AppModule],
|
|
351
|
+
}).overrideGuard(AuthGuard)
|
|
352
|
+
.useValue({ canActivate: (context: any): boolean => {
|
|
353
|
+
context.switchToHttp().getRequest().user = { login: 'user', authorities };
|
|
354
|
+
return true;
|
|
355
|
+
} })
|
|
356
|
+
.overrideProvider(<%= entityClass %>Service)
|
|
357
|
+
.useValue(serviceMock)
|
|
358
|
+
.compile();
|
|
359
|
+
serviceMock.metadata = moduleFixture.get(DataSource).getMetadata(<%= entityClass %>);
|
|
360
|
+
const rolesNestApp = moduleFixture.createNestApplication();
|
|
361
|
+
configureApp(rolesNestApp);
|
|
362
|
+
await rolesNestApp.init();
|
|
363
|
+
return rolesNestApp;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
afterEach(async () => {
|
|
367
|
+
await rolesApp?.close();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('refuses a user without its roles with 403', async () => {
|
|
371
|
+
rolesApp = await appOfUser(['ROLE_OTHER']);
|
|
372
|
+
await request(rolesApp.getHttpServer()).get('/api/<%= entityApiUrl %>').expect(403);
|
|
373
|
+
await request(rolesApp.getHttpServer()).get(`/api/<%= entityApiUrl %>/${entityMock.id}`).expect(403);
|
|
374
|
+
<%_ if (nodejsWriteRoles) { _%>
|
|
375
|
+
const { id: _id, ...newEntity } = validEntity;
|
|
376
|
+
await request(rolesApp.getHttpServer()).post('/api/<%= entityApiUrl %>').send(newEntity).expect(403);
|
|
377
|
+
await request(rolesApp.getHttpServer()).delete(`/api/<%= entityApiUrl %>/${entityMock.id}`).expect(403);
|
|
378
|
+
<%_ } _%>
|
|
379
|
+
});
|
|
380
|
+
<%_ if (nodejsWriteRoles) { _%>
|
|
381
|
+
|
|
382
|
+
it('allows a user of its roles to read and to write', async () => {
|
|
383
|
+
rolesApp = await appOfUser([<%- nodejsWriteRoles %>]);
|
|
384
|
+
await request(rolesApp.getHttpServer()).get('/api/<%= entityApiUrl %>').expect(200);
|
|
385
|
+
const { id: _id, ...newEntity } = validEntity;
|
|
386
|
+
await request(rolesApp.getHttpServer()).post('/api/<%= entityApiUrl %>').send(newEntity).expect(201);
|
|
387
|
+
});
|
|
388
|
+
<%_ } _%>
|
|
389
|
+
<%_ if (nodejsReadOnlyRoles) { _%>
|
|
390
|
+
|
|
391
|
+
it('allows a user of its read roles to read only', async () => {
|
|
392
|
+
rolesApp = await appOfUser([<%- nodejsReadOnlyRoles %>]);
|
|
393
|
+
await request(rolesApp.getHttpServer()).get('/api/<%= entityApiUrl %>').expect(200);
|
|
394
|
+
<%_ if (nodejsWriteRoles) { _%>
|
|
395
|
+
const { id: _id, ...newEntity } = validEntity;
|
|
396
|
+
await request(rolesApp.getHttpServer()).post('/api/<%= entityApiUrl %>').send(newEntity).expect(403);
|
|
397
|
+
<%_ } _%>
|
|
398
|
+
});
|
|
399
|
+
<%_ } _%>
|
|
400
|
+
});
|
|
401
|
+
<%_ } _%>
|
|
402
|
+
});
|