generator-jhipster 7.4.1 → 7.5.0

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.
Files changed (162) hide show
  1. package/generators/app/index.js +11 -1
  2. package/generators/cleanup.js +27 -171
  3. package/generators/client/files-angular.js +6 -1
  4. package/generators/client/files-vue.js +5 -1
  5. package/generators/client/index.js +2 -1
  6. package/generators/client/templates/angular/angular.json.ejs +5 -0
  7. package/generators/client/templates/angular/jest.conf.js.ejs +2 -0
  8. package/generators/client/templates/angular/package.json +24 -24
  9. package/generators/client/templates/angular/package.json.ejs +3 -1
  10. package/generators/client/templates/angular/src/main/webapp/app/account/activate/activate.component.ts.ejs +4 -4
  11. package/generators/client/templates/angular/src/main/webapp/app/account/password/password-strength-bar/password-strength-bar.component.ts.ejs +1 -1
  12. package/generators/client/templates/angular/src/main/webapp/app/account/password/password.component.ts.ejs +4 -4
  13. package/generators/client/templates/angular/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts.ejs +4 -4
  14. package/generators/client/templates/angular/src/main/webapp/app/account/register/register.component.spec.ts.ejs +10 -9
  15. package/generators/client/templates/angular/src/main/webapp/app/account/register/register.component.ts.ejs +1 -1
  16. package/generators/client/templates/angular/src/main/webapp/app/account/settings/settings.component.spec.ts.ejs +8 -6
  17. package/generators/client/templates/angular/src/main/webapp/app/admin/health/health.component.ts.ejs +4 -4
  18. package/generators/client/templates/angular/src/main/webapp/app/admin/user-management/list/user-management.component.spec.ts.ejs +4 -4
  19. package/generators/client/templates/angular/src/main/webapp/app/admin/user-management/list/user-management.component.ts.ejs +4 -4
  20. package/generators/client/templates/angular/src/main/webapp/app/admin/user-management/update/user-management-update.component.ts.ejs +8 -8
  21. package/generators/client/templates/angular/src/main/webapp/app/app-routing.module.ts.ejs +14 -3
  22. package/generators/client/templates/angular/src/main/webapp/app/app.module.ts.ejs +8 -29
  23. package/generators/client/templates/angular/src/main/webapp/app/config/datepicker-adapter.ts.ejs +1 -1
  24. package/generators/client/templates/angular/src/main/webapp/app/config/dayjs.ts.ejs +4 -4
  25. package/generators/client/templates/angular/src/main/webapp/app/core/auth/account.service.spec.ts.ejs +14 -9
  26. package/generators/client/templates/angular/src/main/webapp/app/core/tracker/tracker.service.ts.ejs +6 -6
  27. package/generators/client/templates/angular/src/main/webapp/app/core/util/parse-links.service.ts.ejs +1 -1
  28. package/generators/client/templates/angular/src/main/webapp/app/entities/entity-navbar-items.ts.ejs +29 -0
  29. package/generators/client/templates/angular/src/main/webapp/app/home/home.component.spec.ts.ejs +14 -4
  30. package/generators/client/templates/angular/src/main/webapp/app/layouts/main/main.component.ts.ejs +1 -1
  31. package/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.html.ejs +20 -0
  32. package/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.spec.ts.ejs +10 -4
  33. package/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.ts.ejs +41 -2
  34. package/generators/client/templates/angular/src/main/webapp/app/login/login.component.spec.ts.ejs +3 -2
  35. package/generators/client/templates/angular/src/main/webapp/app/login/login.component.ts.ejs +4 -4
  36. package/generators/client/templates/angular/src/main/webapp/app/shared/auth/has-any-authority.directive.spec.ts.ejs +4 -4
  37. package/generators/client/templates/angular/src/main/webapp/app/shared/date/duration.pipe.ts.ejs +1 -1
  38. package/generators/client/templates/angular/src/main/webapp/app/shared/date/format-medium-date.pipe.spec.ts.ejs +1 -1
  39. package/generators/client/templates/angular/src/main/webapp/app/shared/date/format-medium-date.pipe.ts.ejs +1 -1
  40. package/generators/client/templates/angular/src/main/webapp/app/shared/date/format-medium-datetime.pipe.spec.ts.ejs +1 -1
  41. package/generators/client/templates/angular/src/main/webapp/app/shared/date/format-medium-datetime.pipe.ts.ejs +1 -1
  42. package/generators/client/templates/angular/src/main/webapp/app/shared/language/translate.directive.ts.ejs +6 -6
  43. package/generators/client/templates/angular/src/main/webapp/app/shared/language/translation.module.ts.ejs +83 -0
  44. package/generators/client/templates/angular/src/main/webapp/declarations.d.ts.ejs +16 -2
  45. package/generators/client/templates/angular/tsconfig.json.ejs +2 -0
  46. package/generators/client/templates/angular/tsconfig.spec.json.ejs +0 -1
  47. package/generators/client/templates/angular/webpack/proxy.conf.js.ejs +0 -2
  48. package/generators/client/templates/angular/webpack/webpack.custom.js.ejs +0 -16
  49. package/generators/client/templates/angular/webpack/webpack.microfrontend.js.ejs +12 -5
  50. package/generators/client/templates/common/package.json +2 -2
  51. package/generators/client/templates/common/src/main/webapp/robots.txt.ejs +0 -1
  52. package/generators/client/templates/common/src/main/webapp/swagger-ui/index.html.ejs +86 -56
  53. package/generators/client/templates/react/package.json +27 -27
  54. package/generators/client/templates/react/package.json.ejs +2 -0
  55. package/generators/client/templates/react/src/main/webapp/app/config/axios-interceptor.spec.ts.ejs +3 -2
  56. package/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.scss.ejs +9 -0
  57. package/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs +1 -1
  58. package/generators/client/templates/react/src/main/webapp/app/shared/reducers/authentication.spec.ts.ejs +1 -1
  59. package/generators/client/templates/react/webpack/webpack.dev.js.ejs +0 -2
  60. package/generators/client/templates/vue/package.json +22 -22
  61. package/generators/client/templates/vue/package.json.ejs +3 -3
  62. package/generators/client/templates/vue/src/main/webapp/app/account/account.service.ts.ejs +19 -9
  63. package/generators/client/templates/vue/src/main/webapp/app/entities/entities.component.ts.ejs +6 -0
  64. package/generators/client/templates/vue/src/main/webapp/app/entities/user/{user.oauth2.service.ts.ejs → user.service.ts.ejs} +1 -1
  65. package/generators/client/templates/vue/src/main/webapp/app/main.ts.ejs +0 -8
  66. package/generators/client/templates/vue/src/test/javascript/spec/app/admin/user-management/user-management-edit.component.spec.ts.ejs +4 -4
  67. package/generators/client/templates/vue/src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts.ejs +2 -2
  68. package/generators/client/templates/vue/webpack/webpack.common.js.ejs +0 -2
  69. package/generators/common/templates/README.md.jhi.ejs +1 -3
  70. package/generators/common/templates/package.json +3 -3
  71. package/generators/cypress/templates/cypress.json.ejs +9 -2
  72. package/generators/cypress/templates/src/test/javascript/cypress/integration/account/login-page.spec.ts.ejs +3 -14
  73. package/generators/cypress/templates/src/test/javascript/cypress/integration/account/password-page.spec.ts.ejs +33 -39
  74. package/generators/cypress/templates/src/test/javascript/cypress/integration/account/register-page.spec.ts.ejs +52 -62
  75. package/generators/cypress/templates/src/test/javascript/cypress/integration/account/reset-password-page.spec.ts.ejs +2 -10
  76. package/generators/cypress/templates/src/test/javascript/cypress/integration/account/settings-page.spec.ts.ejs +25 -34
  77. package/generators/cypress/templates/src/test/javascript/cypress/integration/administration/administration.spec.ts.ejs +1 -22
  78. package/generators/cypress/templates/src/test/javascript/cypress/support/commands.ts.ejs +38 -6
  79. package/generators/cypress/templates/src/test/javascript/cypress/support/index.ts.ejs +1 -6
  80. package/generators/cypress/templates/src/test/javascript/cypress/support/navbar.ts.ejs +7 -7
  81. package/generators/cypress/templates/src/test/javascript/cypress/support/oauth2.ts.ejs +0 -9
  82. package/generators/docker-compose/templates/realm-config/jhipster-realm.json.ejs +1 -1
  83. package/generators/entity/index.js +45 -3
  84. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/delete/entity-management-delete-dialog.component.spec.ts.ejs +1 -1
  85. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/detail/entity-management-detail.component.html.ejs +1 -1
  86. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management.module.ts.ejs +1 -35
  87. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity.model.ts.ejs +1 -1
  88. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/entity-management.component.html.ejs +4 -4
  89. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/entity-management.component.spec.ts.ejs +8 -8
  90. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/entity-management.component.ts.ejs +1 -1
  91. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/infinite-scroll-template.ejs +8 -8
  92. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/no-pagination-template.ejs +8 -8
  93. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/list/pagination-template.ejs +8 -8
  94. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/route/entity-management-routing-resolve.service.spec.ts.ejs +15 -6
  95. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/service/entity.service.spec.ts.ejs +1 -1
  96. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/service/entity.service.ts.ejs +1 -1
  97. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/update/entity-management-update.component.spec.ts.ejs +12 -5
  98. package/generators/entity-client/templates/angular/src/main/webapp/app/entities/update/entity-management-update.component.ts.ejs +5 -5
  99. package/generators/entity-client/templates/angular/src/test/javascript/e2e/entities/entity.spec.ts.ejs +1 -1
  100. package/generators/entity-client/templates/common/src/test/javascript/cypress/integration/entity/entity.spec.ts.ejs +14 -37
  101. package/generators/entity-client/templates/react/src/main/webapp/app/entities/entity.reducer.ts.ejs +5 -4
  102. package/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity-update.component.ts.ejs +23 -19
  103. package/generators/entity-client/templates/vue/src/test/javascript/spec/app/entities/entity-update.component.spec.ts.ejs +4 -6
  104. package/generators/entity-server/files.js +10 -0
  105. package/generators/entity-server/templates/src/main/java/package/common/get_all_template.ejs +2 -2
  106. package/generators/entity-server/templates/src/main/java/package/common/search_template.ejs +1 -1
  107. package/generators/entity-server/templates/src/main/java/package/domain/Entity.java.jhi.ejs +5 -8
  108. package/generators/entity-server/templates/src/main/java/package/repository/search/EntitySearchRepository.java.ejs +18 -2
  109. package/generators/entity-server/templates/src/main/java/package/repository/search/SortToFieldSortBuilderConverter.java.ejs +24 -0
  110. package/generators/entity-server/templates/src/main/java/package/service/dto/EntityDTO.java.ejs +4 -6
  111. package/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs +2 -2
  112. package/generators/entity-server/templates/src/test/java/package/web/rest/EntityResourceIT.java.ejs +2 -2
  113. package/generators/generator-base-private.js +2 -1
  114. package/generators/generator-base.js +13 -3
  115. package/generators/generator-constants.js +7 -7
  116. package/generators/server/__snapshots__/generator.spec.mjs.snap +16 -15
  117. package/generators/server/cleanup.js +151 -0
  118. package/generators/server/files.js +16 -14
  119. package/generators/server/index.js +34 -23
  120. package/generators/server/templates/build.gradle.ejs +214 -188
  121. package/generators/server/templates/gradle.properties.ejs +8 -8
  122. package/generators/server/templates/npmw +7 -5
  123. package/generators/server/templates/npmw.cmd +12 -7
  124. package/generators/server/templates/pom.xml.ejs +419 -329
  125. package/generators/server/templates/src/main/docker/config/realm-config/jhipster-realm.json.ejs +2 -2
  126. package/generators/server/templates/src/main/java/package/config/LocaleConfiguration.java.ejs +3 -2
  127. package/generators/server/templates/src/main/java/package/config/OpenApiConfiguration.java.ejs +17 -54
  128. package/generators/server/templates/src/main/java/package/config/SecurityConfiguration.java.ejs +5 -5
  129. package/generators/server/templates/src/main/java/package/config/SecurityConfiguration_reactive.java.ejs +3 -5
  130. package/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs +0 -2
  131. package/generators/server/templates/src/main/java/package/config/neo4j/Neo4jMigrations.java.ejs +19 -9
  132. package/generators/server/templates/src/main/java/package/repository/AuthorityRepository.java.ejs +2 -2
  133. package/generators/server/templates/src/main/java/package/repository/UserRepository.java.ejs +0 -2
  134. package/generators/server/templates/src/main/java/package/security/jwt/TokenProvider.java.ejs +6 -4
  135. package/generators/server/templates/src/main/java/package/security/oauth2/CustomClaimConverter.java.ejs +2 -2
  136. package/generators/server/templates/src/main/java/package/service/UserService.java.ejs +3 -3
  137. package/generators/server/templates/src/main/java/package/service/dto/UserDTO.java.ejs +6 -6
  138. package/generators/server/templates/src/main/java/package/web/filter/ModifyServersOpenApiFilter.java.ejs +3 -2
  139. package/generators/server/templates/src/main/java/package/web/filter/SpaWebFilter.java.ejs +1 -1
  140. package/generators/server/templates/src/main/java/package/web/rest/PublicUserResource.java.ejs +2 -2
  141. package/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs +2 -2
  142. package/generators/server/templates/src/main/resources/config/application.yml.ejs +17 -3
  143. package/generators/server/templates/src/main/resources/logback-spring.xml.ejs +1 -2
  144. package/generators/server/templates/src/test/java/package/cucumber/CucumberIT.java.ejs +2 -6
  145. package/generators/server/templates/src/test/java/package/cucumber/CucumberTestContextConfiguration.java.ejs +2 -3
  146. package/generators/server/templates/src/test/java/package/cucumber/stepdefs/UserStepDefs.java.ejs +41 -6
  147. package/generators/server/templates/src/test/java/package/management/SecurityMetersServiceTests.java.ejs +7 -7
  148. package/generators/server/templates/src/test/java/package/security/jwt/TokenProviderSecurityMetersTests.java.ejs +10 -10
  149. package/generators/server/templates/src/test/java/package/security/oauth2/AuthorizationHeaderUtilTest.java.ejs +1 -1
  150. package/generators/server/templates/src/test/java/package/service/MailServiceIT.java.ejs +1 -1
  151. package/generators/server/templates/src/test/java/package/web/rest/AccountResourceIT.java.ejs +2 -3
  152. package/generators/server/templates/src/test/java/package/web/rest/ClientForwardControllerTest.java.ejs +9 -0
  153. package/generators/server/templates/src/test/resources/junit-platform.properties.ejs +2 -0
  154. package/generators/server/templates/src/test/resources/logback.xml.ejs +1 -1
  155. package/generators/server/templates/src/test/{features → resources/package/features}/gitkeep +0 -0
  156. package/generators/server/templates/src/test/{features → resources/package/features}/user/user.feature.ejs +0 -0
  157. package/generators/spring-controller/templates/src/test/java/package/web/rest/ResourceIT.java.ejs +1 -1
  158. package/package.json +9 -9
  159. package/utils/entity.js +1 -5
  160. package/generators/server/templates/src/main/java/package/config/apidocs/GatewaySwaggerResourcesProvider.java.ejs +0 -91
  161. package/generators/server/templates/src/test/java/package/config/apidocs/GatewaySwaggerResourcesProviderTest.java.ejs +0 -79
  162. package/generators/server/templates/src/test/resources/cucumber.properties.ejs +0 -1
@@ -26,16 +26,9 @@ import {
26
26
  } from '../../support/commands';
27
27
 
28
28
  describe('forgot your password', () => {
29
- const username = Cypress.env('E2E_USERNAME') ?? 'admin';
29
+ const username = Cypress.env('E2E_USERNAME') ?? 'user';
30
30
 
31
- before(() => {
32
- cy.window().then((win) => {
33
- win.sessionStorage.clear()
34
- });
35
- <%_ if (authenticationTypeSession) { _%>
36
- cy.clearCookie('SESSION');
37
- <%_ } _%>
38
- cy.clearCookies();
31
+ beforeEach(() => {
39
32
  cy.visit('');
40
33
  cy.clickOnLoginItem();
41
34
  cy.get(usernameLoginSelector).type(username);
@@ -57,7 +50,6 @@ describe('forgot your password', () => {
57
50
  cy.get(submitInitResetPasswordSelector).click({ force: true });
58
51
  <%_ } _%>
59
52
  cy.get(emailResetPasswordSelector).should('have.class', classValid);
60
- cy.get(emailResetPasswordSelector).clear();
61
53
  });
62
54
 
63
55
  it('should be able to init reset password', () => {
@@ -24,31 +24,31 @@ import {
24
24
  } from '../../support/commands';
25
25
 
26
26
  describe('/account/settings', () => {
27
- const username = Cypress.env('E2E_USERNAME') ?? 'admin';
28
- const password = Cypress.env('E2E_PASSWORD') ?? 'admin';
27
+ const adminUsername = Cypress.env('E2E_USERNAME') ?? 'admin';
28
+ const adminPassword = Cypress.env('E2E_PASSWORD') ?? 'admin';
29
+ const username = Cypress.env('E2E_USERNAME') ?? 'user';
30
+ const password = Cypress.env('E2E_PASSWORD') ?? 'user';
29
31
 
30
- before(() => {
31
- cy.window().then((win) => {
32
- win.sessionStorage.clear()
33
- });
34
- <%_ if (authenticationTypeSession) { _%>
35
- cy.clearCookie('SESSION');
36
- <%_ } _%>
37
- cy.clearCookies();
38
- cy.visit('');
39
- cy.login('user', 'user');
40
- cy.clickOnSettingsItem();
41
- })
32
+ beforeEach(() => {
33
+ cy.login(username, password);
34
+ cy.visit('/account/settings');
35
+ });
42
36
 
43
37
  beforeEach(() => {
44
38
  cy.intercept('POST', '/api/account').as('settingsSave');
45
39
  });
46
40
 
41
+ it('should be accessible through menu', () => {
42
+ cy.visit('');
43
+ cy.clickOnSettingsItem();
44
+ cy.url().should('match', /\/account\/settings$/);
45
+ });
46
+
47
47
  it("should be able to change 'user' firstname settings", () => {
48
48
  cy.get(firstNameSettingsSelector).clear().type('jhipster');
49
49
  // need to modify email because default email does not match regex in vue
50
50
  cy.get(emailSettingsSelector).clear().type('user@localhost.fr');
51
- cy.get(submitSettingsSelector).click({force: true});
51
+ cy.get(submitSettingsSelector).click();
52
52
  cy.wait('@settingsSave').then(({ response }) => expect(response.statusCode).to.equal(200));
53
53
  });
54
54
 
@@ -56,39 +56,30 @@ describe('/account/settings', () => {
56
56
  cy.get(lastNameSettingsSelector).clear().type('retspihj');
57
57
  // need to modify email because default email does not match regex in vue
58
58
  cy.get(emailSettingsSelector).clear().type('user@localhost.fr');
59
- cy.get(submitSettingsSelector).click({force: true});
59
+ cy.get(submitSettingsSelector).click();
60
60
  cy.wait('@settingsSave').then(({ response }) => expect(response.statusCode).to.equal(200));
61
61
  });
62
62
 
63
63
  it("should be able to change 'user' email settings", () => {
64
64
  cy.get(emailSettingsSelector).clear().type('user@localhost.fr');
65
- cy.get(submitSettingsSelector).click({force: true});
65
+ cy.get(submitSettingsSelector).click();
66
66
  cy.wait('@settingsSave').then(({ response }) => expect(response.statusCode).to.equal(200));
67
67
  });
68
68
 
69
69
  it("should not be able to change 'user' settings if email already exists", () => {
70
- // add an email for admin account
71
- cy.clickOnLogoutItem();
70
+ cy.login(adminUsername, adminPassword);
72
71
  cy.visit('');
73
- cy.login(username, password);
74
72
  cy.clickOnSettingsItem();
75
73
  cy.get(emailSettingsSelector).clear().type('admin@localhost.fr');
76
- cy.get(submitSettingsSelector).click({force: true});
77
- cy.clickOnLogoutItem();
74
+ cy.get(submitSettingsSelector).click();
78
75
 
79
- // try to reuse email used in admin account
80
- cy.window().then((win) => {
81
- win.sessionStorage.clear()
82
- });
76
+ cy.login(username, password);
83
77
  cy.visit('');
84
- cy.intercept('POST', '/api/account').as('settingsNotSave');
85
- cy.login('user', 'user');
86
78
  cy.clickOnSettingsItem();
79
+
80
+ cy.intercept('POST', '/api/account').as('settingsNotSave');
87
81
  cy.get(emailSettingsSelector).clear().type('admin@localhost.fr');
88
- cy.get(submitSettingsSelector).click({force: true});
89
- // Fix in future version of cypress
90
- // => https://glebbahmutov.com/blog/cypress-intercept-problems/#no-overwriting-interceptors
91
- // => https://github.com/cypress-io/cypress/issues/9302
92
- // cy.wait('@settingsNotSave').then(({ response }) => expect(response.statusCode).to.equal(400));
82
+ cy.get(submitSettingsSelector).click();
83
+ cy.wait('@settingsNotSave').then(({ response }) => expect(response.statusCode).to.equal(400));
93
84
  });
94
- })
85
+ });
@@ -34,31 +34,10 @@ describe('/admin', () => {
34
34
  const username = Cypress.env('E2E_USERNAME') ?? 'admin';
35
35
  const password = Cypress.env('E2E_PASSWORD') ?? 'admin';
36
36
 
37
- <%_ if (authenticationTypeOauth2) { _%>
38
37
  beforeEach(() => {
39
- cy.getOauth2Data();
40
- cy.get('@oauth2Data').then(oauth2Data => {
41
- cy.oauthLogin(oauth2Data, username, password);
42
- });
43
- });
44
-
45
- afterEach(() => {
46
- cy.oauthLogout();
47
- cy.clearCache();
48
- });
49
- <%_ } else { _%>
50
- before(() => {
51
- cy.window().then((win) => {
52
- win.sessionStorage.clear()
53
- });
54
- <%_ if (authenticationTypeSession) { _%>
55
- cy.clearCookie('SESSION');
56
- <%_ } _%>
57
- cy.clearCookies();
58
- cy.visit('');
59
38
  cy.login(username, password);
39
+ cy.visit('');
60
40
  });
61
- <%_ } _%>
62
41
 
63
42
  <%_ if (!skipUserManagement) { _%>
64
43
  describe('/user-management', () => {
@@ -122,6 +122,7 @@ Cypress.Commands.add('authenticatedRequest', (data: any) => {
122
122
  return cy.request({
123
123
  ...data,
124
124
  headers: {
125
+ ...data.headers,
125
126
  'X-XSRF-TOKEN': csrfCookie?.value,
126
127
  },
127
128
  });
@@ -129,15 +130,46 @@ Cypress.Commands.add('authenticatedRequest', (data: any) => {
129
130
  <%_ } _%>
130
131
  });
131
132
 
132
- <%_ if (!authenticationTypeOauth2) { _%>
133
133
  Cypress.Commands.add('login', (username: string, password: string) => {
134
- cy.clickOnLoginItem();
135
- cy.get(usernameLoginSelector).type(username);
136
- cy.get(passwordLoginSelector).type(password);
137
- cy.get(submitLoginSelector).click();
134
+ cy.session(
135
+ [username, password],
136
+ () => {
137
+ <%_ if (authenticationTypeOauth2) { _%>
138
+ cy.getOauth2Data();
139
+ cy.get('@oauth2Data').then(oauth2Data => {
140
+ cy.oauthLogin(oauth2Data, username, password);
141
+ });
142
+ <%_ } else { _%>
143
+ cy.request({
144
+ method: 'GET',
145
+ url: '/api/account',
146
+ failOnStatusCode: false,
147
+ });
148
+ cy.authenticatedRequest({
149
+ method: 'POST',
150
+ body: { username, password },
151
+ url: Cypress.env('authenticationUrl'),
152
+ <%_ if (authenticationTypeSession) { _%>
153
+ form: true,
154
+ <%_ } else { _%>
155
+ }).then(({ body: { id_token } }) => {
156
+ <%_ if (clientFrameworkVue) { _%>
157
+ sessionStorage.setItem(Cypress.env('jwtStorageName'), id_token);
158
+ <%_ } else { _%>
159
+ sessionStorage.setItem(Cypress.env('jwtStorageName'), JSON.stringify(id_token));
160
+ <%_ } _%>
161
+ <%_ } _%>
162
+ });
163
+ <%_ } _%>
164
+ },
165
+ {
166
+ validate() {
167
+ cy.authenticatedRequest({ url: '/api/account' }).its('status').should('eq', 200);
168
+ },
169
+ }
170
+ );
138
171
  });
139
172
 
140
- <%_ } _%>
141
173
  declare global {
142
174
  namespace Cypress {
143
175
  interface Chainable {
@@ -41,12 +41,7 @@ import './management';
41
41
  <%_ if (authenticationTypeOauth2) { _%>
42
42
  import './oauth2';
43
43
  <%_ } _%>
44
- <%_ if (authenticationTypeSession) { _%>
45
- Cypress.Cookies.defaults({
46
- preserve: ['XSRF-TOKEN','SESSION', 'JSESSIONID']
47
- })
48
- <%_ } _%>
49
- <%_ if (clientFrameworkReact || clientFrameworkVue) { _%>
44
+ <%_ if (clientFrameworkVue && communicationSpringWebsocket) { _%>
50
45
 
51
46
  // https://docs.cypress.io/api/events/catalog-of-events#Uncaught-Exceptions
52
47
  Cypress.on('uncaught:exception', (err, runnable) => {
@@ -32,31 +32,31 @@ import {
32
32
  } from './commands';
33
33
 
34
34
  Cypress.Commands.add('clickOnLoginItem', () => {
35
- return cy.get(navbarSelector).get(accountMenuSelector).click({force: true}).get(loginItemSelector).click({force: true});
35
+ return cy.get(navbarSelector).get(accountMenuSelector).click().get(loginItemSelector).click();
36
36
  });
37
37
 
38
38
  Cypress.Commands.add('clickOnLogoutItem', () => {
39
- return cy.get(navbarSelector).get(accountMenuSelector).click({force: true}).get(logoutItemSelector).click({force: true});
39
+ return cy.get(navbarSelector).get(accountMenuSelector).click().get(logoutItemSelector).click();
40
40
  });
41
41
 
42
42
  Cypress.Commands.add('clickOnRegisterItem', () => {
43
- return cy.get(navbarSelector).get(accountMenuSelector).click({force: true}).get(registerItemSelector).click({force: true});
43
+ return cy.get(navbarSelector).get(accountMenuSelector).click().get(registerItemSelector).click();
44
44
  });
45
45
 
46
46
  Cypress.Commands.add('clickOnSettingsItem', () => {
47
- return cy.get(navbarSelector).get(accountMenuSelector).click({force: true}).get(settingsItemSelector).click({force: true});
47
+ return cy.get(navbarSelector).get(accountMenuSelector).click().get(settingsItemSelector).click();
48
48
  });
49
49
 
50
50
  Cypress.Commands.add('clickOnPasswordItem', () => {
51
- return cy.get(navbarSelector).get(accountMenuSelector).click({force: true}).get(passwordItemSelector).click({force: true});
51
+ return cy.get(navbarSelector).get(accountMenuSelector).click().get(passwordItemSelector).click();
52
52
  });
53
53
 
54
54
  Cypress.Commands.add('clickOnAdminMenuItem', (item: string) => {
55
- return cy.get(navbarSelector).get(adminMenuSelector).click({force: true}).get(`.dropdown-item[href="/admin/${item}"]`).click({force: true});
55
+ return cy.get(navbarSelector).get(adminMenuSelector).click().get(`.dropdown-item[href="/admin/${item}"]`).click();
56
56
  });
57
57
 
58
58
  Cypress.Commands.add('clickOnEntityMenuItem', (entityName: string) => {
59
- return cy.get(navbarSelector).get(entityItemSelector).click({force: true}).get(`.dropdown-item[href="/${entityName}"]`).click({force: true});
59
+ return cy.get(navbarSelector).get(entityItemSelector).click().get(`.dropdown-item[href="/${entityName}"]`).click();
60
60
  });
61
61
 
62
62
  declare global {
@@ -155,14 +155,6 @@ Cypress.Commands.add('oauthLogout', () => {
155
155
  });
156
156
  });
157
157
 
158
- Cypress.Commands.add('clearCache', () => {
159
- cy.clearCookies();
160
- cy.clearLocalStorage();
161
- cy.window().then(win => {
162
- win.sessionStorage.clear();
163
- });
164
- });
165
-
166
158
  declare global {
167
159
  namespace Cypress {
168
160
  interface Chainable<Subject> {
@@ -172,7 +164,6 @@ declare global {
172
164
  auth0Login(oauth2Data: any, username: string, password: string): Cypress.Chainable;
173
165
  oktaLogin(oauth2Data: any, username: string, password: string): Cypress.Chainable;
174
166
  oauthLogout(): Cypress.Chainable;
175
- clearCache(): Cypress.Chainable;
176
167
  }
177
168
  }
178
169
  }
@@ -2492,7 +2492,7 @@
2492
2492
  "clientOfflineSessionIdleTimeout": "0",
2493
2493
  "cibaInterval": "5"
2494
2494
  },
2495
- "keycloakVersion": "15.0.2",
2495
+ "keycloakVersion": "16.1.0",
2496
2496
  "userManagedAccessAllowed": false,
2497
2497
  "clientProfiles": {
2498
2498
  "profiles": []
@@ -38,6 +38,8 @@ const { prepareFieldForTemplates, fieldIsEnum } = require('../../utils/field');
38
38
  const { prepareRelationshipForTemplates } = require('../../utils/relationship');
39
39
  const { stringify } = require('../../utils');
40
40
  const { GATEWAY, MICROSERVICE } = require('../../jdl/jhipster/application-types');
41
+ const { NO: CLIENT_FRAMEWORK_NO } = require('../../jdl/jhipster/client-framework-types');
42
+ const { NO: SEARCH_ENGINE_NO } = require('../../jdl/jhipster/search-engine-types');
41
43
  const { CASSANDRA, COUCHBASE, MONGODB, NEO4J, ORACLE, SQL } = require('../../jdl/jhipster/database-types');
42
44
  const {
43
45
  GENERATOR_ENTITIES,
@@ -234,7 +236,9 @@ class EntityGenerator extends BaseBlueprintGenerator {
234
236
 
235
237
  if (this.jhipsterConfig.applications && !this.entityConfig.skipClient) {
236
238
  const remoteConfig = this.jhipsterConfig.applications[this.entityConfig.microserviceName];
237
- if (remoteConfig.clientFramework === 'vue') {
239
+ if (remoteConfig && remoteConfig.clientFramework && remoteConfig.clientFramework !== CLIENT_FRAMEWORK_NO) {
240
+ // Gateway requires entities to discover a microfrontend.
241
+ // Microfrontends is generated at the microservice side, so skip it at gateway side.
238
242
  this.entityConfig.skipClient = true;
239
243
  }
240
244
  }
@@ -359,8 +363,34 @@ class EntityGenerator extends BaseBlueprintGenerator {
359
363
  throw new Error(validation);
360
364
  }
361
365
 
366
+ if (this.entityConfig.searchEngine === undefined) {
367
+ const backendOnlyMicroservice =
368
+ context.applicationType === MICROSERVICE && (!context.clientFramework || context.clientFramework === CLIENT_FRAMEWORK_NO);
369
+ if (backendOnlyMicroservice && context.searchEngine && context.searchEngine !== SEARCH_ENGINE_NO && !context.entityExisted) {
370
+ // Propagate searchEngine to the entity, it's opt-in and should be propagated to gateway
371
+ this.entityConfig.searchEngine = true;
372
+ }
373
+ } else if (
374
+ (!context.searchEngine || context.searchEngine === SEARCH_ENGINE_NO) &&
375
+ (context.applicationType !== GATEWAY || !this.entityConfig.microserviceName)
376
+ ) {
377
+ if (this.entityConfig.searchEngine === SEARCH_ENGINE_NO) {
378
+ // Convert to boolean.
379
+ this.entityConfig.searchEngine = false;
380
+ }
381
+ // If search engine is disabled at application, and unless it's a gateway publishing a microservice entity.
382
+ if (this.entityConfig.searchEngine) {
383
+ this.warning('Search engine disabled at application, cannot be enabled at entity, disabling');
384
+ this.entityConfig.searchEngine = false;
385
+ }
386
+ }
387
+
362
388
  this.entityConfig.name = this.entityConfig.name || context.name;
363
- if (![SQL, MONGODB, COUCHBASE, NEO4J].includes(context.databaseType)) {
389
+ // disable pagination if there is no database, unless it’s a microservice entity published by a gateway
390
+ if (
391
+ ![SQL, MONGODB, COUCHBASE, NEO4J].includes(context.databaseType) &&
392
+ (context.applicationType !== GATEWAY || !this.entityConfig.microserviceName)
393
+ ) {
364
394
  this.entityConfig.pagination = NO_PAGINATION;
365
395
  }
366
396
 
@@ -493,13 +523,25 @@ class EntityGenerator extends BaseBlueprintGenerator {
493
523
  _loading() {
494
524
  return {
495
525
  loadEntity() {
526
+ loadRequiredConfigIntoEntity(this.context, this.jhipsterConfig);
496
527
  // Update current context with config from file.
497
528
  Object.assign(this.context, this.entityStorage.getAll());
498
529
  this.loadDerivedAppConfig(this.context);
530
+
531
+ // Entity searchEngine support should opt-in instead of opt-out for gateway/microservice.
532
+ // The entity definition should take precedence so frontend and backend are in sync.
533
+ // Doesn't apply to microfrontends.
534
+ if (
535
+ this.entityConfig.searchEngine === undefined &&
536
+ !this.context.microfrontend &&
537
+ (this.context.applicationTypeMicroservice || (this.entityConfig.microserviceName && this.context.applicationTypeGateway))
538
+ ) {
539
+ this.info(`searchEngine is missing in .jhipster/${this.entityConfig.name}.json, should opt-in for gateway/microservice entities`);
540
+ this.context.searchEngine = false;
541
+ }
499
542
  this.loadDerivedClientConfig(this.context);
500
543
  this.loadDerivedServerConfig(this.context);
501
544
  this.loadDerivedPlatformConfig(this.context);
502
- loadRequiredConfigIntoEntity(this.context, this.jhipsterConfig);
503
545
  if (this.context.fields) {
504
546
  this.context.fields
505
547
  .filter(field => field.options)
@@ -56,7 +56,7 @@ describe('<%= entityAngularName %> Management Delete Component', () => {
56
56
  inject([],
57
57
  fakeAsync(() => {
58
58
  // GIVEN
59
- jest.spyOn(service, 'delete').mockReturnValue(of(new HttpResponse({})));
59
+ jest.spyOn(service, 'delete').mockReturnValue(of(new HttpResponse({ body: {} })));
60
60
 
61
61
  // WHEN
62
62
  comp.confirmDelete(<%- tsKeyId %>);
@@ -107,7 +107,7 @@ _%>
107
107
  <%_ if (!readOnly) { _%>
108
108
 
109
109
  <button type="button"
110
- [routerLink]="['/<%= entityUrl %>', <%= entityInstance %>.<%= primaryKey.name %>, 'edit']"
110
+ [routerLink]="['/<%= entityPage %>', <%= entityInstance %>.<%= primaryKey.name %>, 'edit']"
111
111
  class="btn btn-primary">
112
112
  <fa-icon icon="pencil-alt"></fa-icon>&nbsp;<span <%= jhiPrefix %>Translate="entity.action.edit">Edit</span>
113
113
  </button>
@@ -17,13 +17,6 @@
17
17
  limitations under the License.
18
18
  -%>
19
19
  import { NgModule } from '@angular/core';
20
- <%_ if (applicationTypeMicroservice && enableTranslation) { _%>
21
- import { HttpClient } from '@angular/common/http';
22
- import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
23
- import { TranslateHttpLoader } from '@ngx-translate/http-loader';
24
-
25
- import { ApplicationConfigService } from 'app/core/config/application-config.service';
26
- <%_ } _%>
27
20
  import { SharedModule } from 'app/shared/shared.module';
28
21
  import { <%= entityAngularName %>Component } from './list/<%= entityFileName %>.component';
29
22
  import { <%= entityAngularName %>DetailComponent } from './detail/<%= entityFileName %>-detail.component';
@@ -33,28 +26,10 @@ import { <%= entityAngularName %>DeleteDialogComponent } from './delete/<%= enti
33
26
  <%_ } _%>
34
27
  import { <%= entityAngularName %>RoutingModule } from './route/<%= entityFileName %>-routing.module';
35
28
 
36
- <%_ if (applicationTypeMicroservice && enableTranslation) { _%>
37
- function translatePartialLoader(http: HttpClient, applicationConfigService: ApplicationConfigService): TranslateLoader {
38
- const prefix = applicationConfigService.isMicrofrontend() ? 'i18n/' : applicationConfigService.getEndpointFor('i18n/', '<%= microserviceName %>');
39
- return new TranslateHttpLoader(http, prefix, `.json?_=${I18N_HASH}`);
40
- }
41
-
42
- <%_ } _%>
43
29
  @NgModule({
44
30
  imports: [
45
31
  SharedModule,
46
32
  <%= entityAngularName %>RoutingModule,
47
- <%_ if (applicationTypeMicroservice && enableTranslation) { _%>
48
- TranslateModule.forChild({
49
- loader: {
50
- provide: TranslateLoader,
51
- useFactory: (translatePartialLoader),
52
- deps: [HttpClient, ApplicationConfigService]
53
- },
54
- isolate: false,
55
- extend: true,
56
- }),
57
- <%_ } _%>
58
33
  ],
59
34
  declarations: [
60
35
  <%= entityAngularName %>Component,
@@ -70,13 +45,4 @@ function translatePartialLoader(http: HttpClient, applicationConfigService: Appl
70
45
  ]
71
46
  <%_ } _%>
72
47
  })
73
- export class <%= locals.microserviceName ? upperFirstCamelCase(locals.microserviceName) : '' %><%= entityAngularName %>Module {
74
- <%_ if (applicationTypeMicroservice && enableTranslation) { _%>
75
- constructor(private translateService: TranslateService, private translateLoader: TranslateLoader) {
76
- const currentLang = translateService.store.currentLang;
77
- this.translateLoader.getTranslation(currentLang).subscribe(translation => {
78
- this.translateService.setTranslation(currentLang, translation);
79
- });
80
- }
81
- <%_ } _%>
82
- }
48
+ export class <%= locals.microserviceName ? upperFirstCamelCase(locals.microserviceName) : '' %><%= entityAngularName %>Module {}
@@ -23,7 +23,7 @@ const defaultVariablesValues = generateEntityClientFieldDefaultValues(fields);
23
23
  const enumImports = generateEntityClientEnumImports(fields);
24
24
  %>
25
25
  <%_ if (fieldsContainInstant || fieldsContainZonedDateTime || fieldsContainLocalDate) { _%>
26
- import * as dayjs from 'dayjs';
26
+ import dayjs from 'dayjs/esm';
27
27
  <%_ } _%>
28
28
  <%_ typeImports.forEach((importedPath, importedType) => { _%>
29
29
  <%_ if (importedType !== `I${entityAngularName}`) { _%>
@@ -37,7 +37,7 @@ _%>
37
37
  </button>
38
38
  <%_ if (!readOnly) { _%>
39
39
 
40
- <button id="jh-create-entity" data-cy="entityCreateButton" class="btn btn-primary jh-create-entity create-<%= entityUrl %>" [routerLink]="['/<%= entityUrl %>/new']">
40
+ <button id="jh-create-entity" data-cy="entityCreateButton" class="btn btn-primary jh-create-entity create-<%= entityUrl %>" [routerLink]="['/<%= entityPage %>/new']">
41
41
  <fa-icon icon="plus"></fa-icon>
42
42
  <span <% if (searchEngine !== false) { %>class="hidden-sm-down" <% } %> <%= jhiPrefix %>Translate="<%= i18nKeyPrefix %>.home.createLabel">
43
43
  Create a new <%= entityClassHumanized %>
@@ -97,7 +97,7 @@ _%>
97
97
  <tbody<% if (paginationInfiniteScroll) { %> infinite-scroll (scrolled)="loadPage(page + 1)" [infiniteScrollDisabled]="page >= links['last']" [infiniteScrollDistance]="0"<% } %>>
98
98
  <tr *ngFor="let <%= entityInstance %> of <%= entityInstancePlural %>; trackBy: track<%= primaryKey.nameCapitalized %>" data-cy="entityTable">
99
99
  <%_
100
- const routerLink = ` [routerLink]="['/${ entityUrl }', ${entityInstance}.${primaryKey.name}, 'view']"`;
100
+ const routerLink = ` [routerLink]="['/${ entityPage }', ${entityInstance}.${primaryKey.name}, 'view']"`;
101
101
  for (field of fields.filter(field => !field.hidden)) {
102
102
  const fieldName = field.fieldName;
103
103
  const fieldType = field.fieldType;
@@ -163,7 +163,7 @@ _%>
163
163
  <td class="text-right">
164
164
  <div class="btn-group">
165
165
  <button type="submit"
166
- [routerLink]="['/<%= entityUrl %>', <%= entityInstance %>.<%= primaryKey.name %>, 'view']"
166
+ [routerLink]="['/<%= entityPage %>', <%= entityInstance %>.<%= primaryKey.name %>, 'view']"
167
167
  class="btn btn-info btn-sm"
168
168
  data-cy="entityDetailsButton">
169
169
  <fa-icon icon="eye"></fa-icon>
@@ -172,7 +172,7 @@ _%>
172
172
  <%_ if (!readOnly) { _%>
173
173
 
174
174
  <button type="submit"
175
- [routerLink]="['/<%= entityUrl %>', <%= entityInstance %>.<%= primaryKey.name %>, 'edit']"
175
+ [routerLink]="['/<%= entityPage %>', <%= entityInstance %>.<%= primaryKey.name %>, 'edit']"
176
176
  class="btn btn-primary btn-sm"
177
177
  data-cy="entityEditButton">
178
178
  <fa-icon icon="pencil-alt"></fa-icon>
@@ -21,17 +21,13 @@ const entityArrayOptionalChainSymbol = paginationInfiniteScroll ? '' : '?.';
21
21
  const order = paginationInfiniteScroll ? 'asc' : 'desc';
22
22
  const testEntityPrimaryKey = generateTestEntityPrimaryKey(primaryKey, 0);
23
23
  _%>
24
- <%_ if (paginationPagination || searchEngine) { _%>
25
- jest.mock('@angular/router');
26
- <%_ } _%>
27
24
 
28
25
  import { ComponentFixture, TestBed } from '@angular/core/testing';
29
26
  import { HttpHeaders, HttpResponse } from '@angular/common/http';
30
27
  import { HttpClientTestingModule } from '@angular/common/http/testing';
31
- <%_ if (paginationPagination) { _%>
32
- import { ActivatedRoute, Router } from '@angular/router';
33
- <%_ } else if (searchEngine) { _%>
28
+ <%_ if (paginationPagination || searchEngine) { _%>
34
29
  import { ActivatedRoute } from '@angular/router';
30
+ import { RouterTestingModule } from '@angular/router/testing';
35
31
  <%_ } _%>
36
32
  import { of } from 'rxjs';
37
33
 
@@ -46,11 +42,15 @@ describe('<%= entityAngularName %> Management Component', () => {
46
42
 
47
43
  beforeEach(() => {
48
44
  TestBed.configureTestingModule({
49
- imports: [HttpClientTestingModule],
45
+ imports: [
46
+ <%_ if (paginationPagination || searchEngine) { _%>
47
+ RouterTestingModule.withRoutes([{ path: '<%= entityPage %>', component: <%= entityAngularName %>Component }]),
48
+ <%_ } _%>
49
+ HttpClientTestingModule
50
+ ],
50
51
  declarations: [<%= entityAngularName %>Component],
51
52
  <%_ if (paginationPagination) { _%>
52
53
  providers: [
53
- Router,
54
54
  {
55
55
  provide: ActivatedRoute,
56
56
  useValue: {
@@ -132,7 +132,7 @@ _%>
132
132
  this.ngbPaginationPage = this.page;
133
133
  <%_ } _%>
134
134
  if (navigate) {
135
- this.router.navigate(['/<%= entityUrl %>'], {
135
+ this.router.navigate(['/<%= entityPage %>'], {
136
136
  queryParams: {
137
137
  page: this.page,
138
138
  size: this.itemsPerPage,
@@ -62,15 +62,15 @@
62
62
  page: this.page,
63
63
  size: this.itemsPerPage,
64
64
  sort: this.sort()
65
- }).subscribe(
66
- (res: HttpResponse<I<%= entityAngularName %>[]>) => {
65
+ }).subscribe({
66
+ next: (res: HttpResponse<I<%= entityAngularName %>[]>) => {
67
67
  this.isLoading = false;
68
68
  this.paginate<%= entityClassPlural %>(res.body, res.headers);
69
69
  },
70
- () => {
70
+ error: () => {
71
71
  this.isLoading = false;
72
72
  }
73
- );
73
+ });
74
74
  return;
75
75
  }
76
76
  <%_ } _%>
@@ -79,15 +79,15 @@
79
79
  page: this.page,
80
80
  size: this.itemsPerPage,
81
81
  sort: this.sort()
82
- }).subscribe(
83
- (res: HttpResponse<I<%= entityAngularName %>[]>) => {
82
+ }).subscribe({
83
+ next: (res: HttpResponse<I<%= entityAngularName %>[]>) => {
84
84
  this.isLoading = false;
85
85
  this.paginate<%= entityClassPlural %>(res.body, res.headers);
86
86
  },
87
- () => {
87
+ error: () => {
88
88
  this.isLoading = false;
89
89
  }
90
- );
90
+ });
91
91
  }
92
92
 
93
93
  reset(): void {
@@ -45,28 +45,28 @@
45
45
  if (this.currentSearch) {
46
46
  this.<%= entityInstance %>Service.search({
47
47
  query: this.currentSearch,
48
- }).subscribe(
49
- (res: HttpResponse<I<%= entityAngularName %>[]>) => {
48
+ }).subscribe({
49
+ next: (res: HttpResponse<I<%= entityAngularName %>[]>) => {
50
50
  this.isLoading = false;
51
51
  this.<%= entityInstancePlural %> = res.body ?? [];
52
52
  },
53
- () => {
53
+ error: () => {
54
54
  this.isLoading = false;
55
55
  }
56
- );
56
+ });
57
57
  return;
58
58
  }
59
59
  <%_ } _%>
60
60
 
61
- this.<%= entityInstance %>Service.query().subscribe(
62
- (res: HttpResponse<I<%= entityAngularName %>[]>) => {
61
+ this.<%= entityInstance %>Service.query().subscribe({
62
+ next: (res: HttpResponse<I<%= entityAngularName %>[]>) => {
63
63
  this.isLoading = false;
64
64
  this.<%= entityInstancePlural %> = res.body ?? [];
65
65
  },
66
- () => {
66
+ error: () => {
67
67
  this.isLoading = false;
68
68
  }
69
- );
69
+ });
70
70
  }
71
71
 
72
72
  <%_ if (searchEngine) { _%>