Repository: jhipster/jhipster-lite
Pull request #11010 (2024-09-29 00:36:00)

rework react core like vue core
In order to rework react i18n module, it would be nice to rework the react core module like @DamnClin did for vue core module
Because translation typescript files will be shared between react and vue

=> home context with the component into the primary infrastructure

Obviously impacting react-i18n and react-jwt module

Prerequisites to #11002

murdos: Looks fine.
@pascalgrimaud : do you have any objections? This is somehow a breaking change, but I think it's a good idea to harmonise our clients.

Patch:
diff --git a/src/main/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactory.java
index e86dc7c9c..af68e0c43 100644
--- a/src/main/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactory.java
@@ -36,13 +36,15 @@ public class ReactCoreModulesFactory {
   private static final JHipsterSource APP_SOURCE = WEBAPP_SOURCE.append("app");
   private static final JHipsterDestination APP_DESTINATION = WEBAPP_DESTINATION.append("app");
 
-  private static final String PRIMARY_APP = "common/primary/app";
+  private static final JHipsterSource PIQURE_SOURCE = from("client/common/piqure");
+
+  private static final String PRIMARY_APP = "home/infrastructure/primary";
   private static final String ASSETS = "assets";
 
   private static final JHipsterSource PRIMARY_APP_SOURCE = APP_SOURCE.append(PRIMARY_APP);
   private static final JHipsterDestination PRIMARY_APP_DESTINATION = APP_DESTINATION.append(PRIMARY_APP);
 
-  private static final String TEST_PRIMARY = "src/test/webapp/unit/common/primary/app";
+  private static final String TEST_PRIMARY = "src/test/webapp/unit/home/infrastructure/primary";
   private static final String DEFAULT_TSCONFIG_PATH = "\"@/*\": [\"src/main/webapp/app/*\"]";
 
   public JHipsterModule buildModule(JHipsterModuleProperties properties) {
@@ -64,6 +66,7 @@ public class ReactCoreModulesFactory {
         .addDevDependency(packageName("vite"), COMMON)
         .addDependency(packageName("react"), REACT)
         .addDependency(packageName("react-dom"), REACT)
+        .addDependency(packageName("piqure"), COMMON)
         .addScript(scriptKey("dev"), scriptCommand("npm-run-all --parallel dev:*"))
         .addScript(scriptKey("dev:vite"), scriptCommand("vite"))
         .addScript(scriptKey("build"), scriptCommand("npm-run-all build:*"))
@@ -81,10 +84,13 @@ public class ReactCoreModulesFactory {
           .addTemplate("index.tsx")
           .addTemplate("vite-env.d.ts")
           .and()
+        .batch(PIQURE_SOURCE, APP_DESTINATION)
+          .addTemplate("injections.ts")
+        .and()
         .add(WEBAPP_SOURCE.template("index.html"), WEBAPP_DESTINATION.append("index.html"))
-        .add(SOURCE.append(TEST_PRIMARY).template("App.spec.tsx"), to(TEST_PRIMARY).append("App.spec.tsx"))
-        .add(PRIMARY_APP_SOURCE.template("App.tsx"), PRIMARY_APP_DESTINATION.append("App.tsx"))
-        .add(PRIMARY_APP_SOURCE.template("App.css"), PRIMARY_APP_DESTINATION.append("App.css"))
+        .add(SOURCE.append(TEST_PRIMARY).template("HomePage.spec.tsx"), to(TEST_PRIMARY).append("HomePage.spec.tsx"))
+        .add(PRIMARY_APP_SOURCE.template("HomePage.tsx"), PRIMARY_APP_DESTINATION.append("HomePage.tsx"))
+        .add(PRIMARY_APP_SOURCE.template("HomePage.css"), PRIMARY_APP_DESTINATION.append("HomePage.css"))
         .batch(WEBAPP_SOURCE.append(ASSETS), WEBAPP_DESTINATION.append(ASSETS))
           .addFile("JHipster-Lite-neon-blue.png")
           .addFile("ReactLogo.png")
@@ -171,6 +177,7 @@ public class ReactCoreModulesFactory {
           .add(text("plugins: ["), "plugins: [react(), ")
           .add(text("environment: 'node',"), "environment: 'jsdom',")
           .add(vitestCoverageExclusion(properties,"src/main/webapp/app/index.tsx"))
+          .add(vitestCoverageExclusion(properties,"src/main/webapp/app/injections.ts"))
           .and();
     //@formatter:on
   }
diff --git a/src/main/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactory.java
index 5ef997cf4..5a43f31d1 100644
--- a/src/main/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactory.java
@@ -24,7 +24,7 @@ public class ReactI18nModuleFactory {
   private static final JHipsterSource ASSETS_EN_SOURCE = from("client/react/i18n/src/main/webapp/assets/locales/en");
 
   private static final String INDEX = "src/main/webapp/";
-  private static final String INDEX_TEST = "src/test/webapp/unit/common/primary/app/";
+  private static final String INDEX_TEST = "src/test/webapp/unit/home/infrastructure/primary/";
 
   public JHipsterModule buildModule(JHipsterModuleProperties properties) {
     Assert.notNull("properties", properties);
@@ -49,7 +49,7 @@ public class ReactI18nModuleFactory {
         .and()
       .and()
       .mandatoryReplacements()
-        .in(path(INDEX + "app/common/primary/app/App.tsx"))
+        .in(path(INDEX + "app/home/infrastructure/primary/HomePage.tsx"))
           .add(lineAfterText("import ReactLogo from '@assets/ReactLogo.png';"), "import { useTranslation } from 'react-i18next';")
           .add(lineBeforeText("return ("), properties.indentation().times(1) + "const { t } = useTranslation();" + LINE_BREAK)
           .add(lineAfterText("</h1>"), LINE_BREAK +
@@ -58,9 +58,9 @@ public class ReactI18nModuleFactory {
         .in(path(INDEX + "app/index.tsx"))
           .add(lineAfterText("import './index.css';"), "import './i18n';" + LINE_BREAK)
           .and()
-        .in(path(INDEX_TEST + "App.spec.tsx"))
+        .in(path(INDEX_TEST + "HomePage.spec.tsx"))
           .add(append(), LINE_BREAK + """
-            describe('App I18next', () => {
+            describe('Home I18next', () => {
              it('renders with translation', () => {
                vi.mock('react-i18next', () => ({
                  useTranslation: () => {
@@ -72,8 +72,7 @@ public class ReactI18nModuleFactory {
                    };
                  },
                }));
-               render(<App />);
-               const { getAllByText } = render(<App />);
+               const { getAllByText } = render(<HomePage />);
                const title = getAllByText('Internationalization enabled');
                expect(title).toBeTruthy();
              });
diff --git a/src/main/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactory.java
index 016e2f6b4..2cbc372e5 100644
--- a/src/main/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactory.java
@@ -35,7 +35,7 @@ public class ReactJwtModuleFactory {
   private static final JHipsterDestination TEST_DESTINATION = to("src/test/webapp/unit/");
 
   private static final RegexNeedleBeforeReplacer LOGIN_FORM_MATCHER = lineBeforeRegex(
-    "[  ]{0,10}[<\\/div>]{0,1}\n{0,5}[  ]{0,10}<\\/div>\n{0,5}[  ]{0,10}[);]{0,2}\n{0,5}\\}\n{0,5}[  ]{0,10}export default App;"
+    "[  ]{0,10}[<\\/div>]{0,1}\n{0,5}[  ]{0,10}<\\/div>\n{0,5}[  ]{0,10}[);]{0,2}\n{0,5}\\}\n{0,5}[  ]{0,10}export default HomePage;"
   );
   private static final String AUTHENTICATION_STYLE =
     """
@@ -87,17 +87,17 @@ public class ReactJwtModuleFactory {
         .add(TEST_JAVASCRIPT_SOURCE.template("common/services/storage.test.ts"), TEST_DESTINATION.append("common/services/storage.test.ts"))
         .and()
       .mandatoryReplacements()
-        .in(path("src/main/webapp/app/common/primary/app/App.tsx"))
-          .add(lineBeforeText("function App() {"), "import LoginForm from '@/login/primary/loginForm';" + LINE_BREAK)
+        .in(path("src/main/webapp/app/home/infrastructure/primary/HomePage.tsx"))
+          .add(lineBeforeText("function HomePage() {"), "import LoginForm from '@/login/primary/loginForm';" + LINE_BREAK)
           .add(LOGIN_FORM_MATCHER, properties.indentation().times(4) + "<LoginForm />")
           .and()
         .in(path("src/main/webapp/app/index.tsx"))
           .add(lineBeforeText("import React from 'react';"), "import { NextUIProvider } from '@nextui-org/react';")
-          .add(regex("\\s+<App />"),
+          .add(regex("\\s+<HomePage />"),
                 """
 
               \t\t<NextUIProvider>
-              \t\t\t<App />
+              \t\t\t<HomePage />
               \t\t</NextUIProvider>\
               """.replace("\t", properties.indentation().spaces())
           )
@@ -107,7 +107,7 @@ public class ReactJwtModuleFactory {
         .and()
       .and()
       .optionalReplacements()
-        .in(path("src/main/webapp/app/common/primary/app/App.css"))
+        .in(path("src/main/webapp/app/home/infrastructure/primary/HomePage.css"))
           .add(text("  -moz-osx-font-smoothing: grayscale;"), AUTHENTICATION_STYLE)
           .and()
         .and()
diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
index 8b90f3a62..4e4e03664 100644
--- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java
@@ -30,6 +30,7 @@ public class VueModulesFactory {
 
   private static final JHipsterSource SOURCE = from("client/vue");
   private static final JHipsterSource APP_SOURCE = from("client/vue/webapp/app");
+  private static final JHipsterSource PIQURE_SOURCE = from("client/common/piqure");
   private static final JHipsterSource DOCUMENTATION_SOURCE = SOURCE.append("documentation");
   private static final JHipsterSource IMAGE_SOURCE = SOURCE.append("webapp/content/images");
 
@@ -60,7 +61,7 @@ public class VueModulesFactory {
         .addDependency(packageName("vue"), VUE)
         .addDependency(packageName("axios"), VUE)
         .addDependency(packageName("vue-router"), VUE)
-        .addDependency(packageName("piqure"), VUE)
+        .addDependency(packageName("piqure"), COMMON)
         .addDevDependency(packageName("@vitejs/plugin-vue"), VUE)
         .addDevDependency(packageName("@vue/test-utils"), VUE)
         .addDevDependency(packageName("@vue/tsconfig"), VUE)
@@ -89,9 +90,11 @@ public class VueModulesFactory {
           .addTemplate("env.d.ts")
           .addTemplate("main.ts")
           .addTemplate("AppVue.vue")
-          .addTemplate("injections.ts")
           .addTemplate("router.ts")
           .and()
+        .batch(PIQURE_SOURCE, MAIN_DESTINATION)
+          .addTemplate("injections.ts")
+        .and()
         .batch(APP_SOURCE.append("home"), MAIN_DESTINATION.append("home"))
           .addTemplate("application/HomeRouter.ts")
           .addTemplate("infrastructure/primary/HomepageVue.vue")
diff --git a/src/main/resources/generator/client/vue/webapp/app/injections.ts.mustache b/src/main/resources/generator/client/common/piqure/injections.ts.mustache
similarity index 100%
rename from src/main/resources/generator/client/vue/webapp/app/injections.ts.mustache
rename to src/main/resources/generator/client/common/piqure/injections.ts.mustache
diff --git a/src/main/resources/generator/client/react/core/src/main/webapp/app/common/primary/app/App.css.mustache b/src/main/resources/generator/client/react/core/src/main/webapp/app/home/infrastructure/primary/HomePage.css.mustache
similarity index 100%
rename from src/main/resources/generator/client/react/core/src/main/webapp/app/common/primary/app/App.css.mustache
rename to src/main/resources/generator/client/react/core/src/main/webapp/app/home/infrastructure/primary/HomePage.css.mustache
diff --git a/src/main/resources/generator/client/react/core/src/main/webapp/app/common/primary/app/App.tsx.mustache b/src/main/resources/generator/client/react/core/src/main/webapp/app/home/infrastructure/primary/HomePage.tsx.mustache
similarity index 93%
rename from src/main/resources/generator/client/react/core/src/main/webapp/app/common/primary/app/App.tsx.mustache
rename to src/main/resources/generator/client/react/core/src/main/webapp/app/home/infrastructure/primary/HomePage.tsx.mustache
index 7427295ad..48d7c713d 100644
--- a/src/main/resources/generator/client/react/core/src/main/webapp/app/common/primary/app/App.tsx.mustache
+++ b/src/main/resources/generator/client/react/core/src/main/webapp/app/home/infrastructure/primary/HomePage.tsx.mustache
@@ -1,9 +1,9 @@
-import './App.css';
+import './HomePage.css';
 
 import JHipsterLiteNeonBlue from '@assets/JHipster-Lite-neon-blue.png';
 import ReactLogo from '@assets/ReactLogo.png';
 
-function App() {
+function HomePage() {
   return (
     <div>
       <div id="app">
@@ -33,4 +33,4 @@ function App() {
   );
 }
 
-export default App;
+export default HomePage;
diff --git a/src/main/resources/generator/client/react/core/src/main/webapp/app/index.tsx.mustache b/src/main/resources/generator/client/react/core/src/main/webapp/app/index.tsx.mustache
index 0c99f1a20..8ba5e4e92 100644
--- a/src/main/resources/generator/client/react/core/src/main/webapp/app/index.tsx.mustache
+++ b/src/main/resources/generator/client/react/core/src/main/webapp/app/index.tsx.mustache
@@ -1,4 +1,4 @@
-import App from '@/common/primary/app/App';
+import HomePage from '@/home/infrastructure/primary/HomePage';
 import React from 'react';
 import { createRoot } from 'react-dom/client';
 import './index.css';
@@ -7,6 +7,6 @@ const container = document.getElementById('root');
 const root = createRoot(container!);
 root.render(
   <React.StrictMode>
-    <App />
+    <HomePage />
   </React.StrictMode>,
 );
diff --git a/src/main/resources/generator/client/react/security/jwt/src/main/webapp/app/common/primary/app/LoginApp.tsx.mustache b/src/main/resources/generator/client/react/security/jwt/src/main/webapp/app/common/primary/app/LoginApp.tsx.mustache
index b4afea18f..e3c68a1b4 100644
--- a/src/main/resources/generator/client/react/security/jwt/src/main/webapp/app/common/primary/app/LoginApp.tsx.mustache
+++ b/src/main/resources/generator/client/react/security/jwt/src/main/webapp/app/common/primary/app/LoginApp.tsx.mustache
@@ -1,13 +1,13 @@
 import LoginForm from '@/login/primary/loginForm';
 
-import './App.css';
+import './HomePage.css';
 
 import JHipsterLiteNeonBlue from '@assets/JHipster-Lite-neon-blue.png';
 import ReactLogo from '@assets/ReactLogo.png';
 
 import React from 'react';
 
-function App() {
+function HomePage() {
   return (
     <div>
       <div id="app">
@@ -39,4 +39,4 @@ function App() {
   );
 }
 
-export default App;
+export default HomePage;
diff --git a/src/main/resources/generator/dependencies/common/package.json b/src/main/resources/generator/dependencies/common/package.json
index 6c125c954..2d1fd0d06 100644
--- a/src/main/resources/generator/dependencies/common/package.json
+++ b/src/main/resources/generator/dependencies/common/package.json
@@ -7,7 +7,8 @@
     "i18next": "23.15.1",
     "i18next-browser-languagedetector": "8.0.0",
     "i18next-http-backend": "2.6.1",
-    "keycloak-js": "25.0.6"
+    "keycloak-js": "25.0.6",
+    "piqure": "2.0.0"
   },
   "devDependencies": {
     "@babel/cli": "7.25.6",
diff --git a/src/main/resources/generator/dependencies/vue/package.json b/src/main/resources/generator/dependencies/vue/package.json
index 9f6877cce..81a4301e3 100644
--- a/src/main/resources/generator/dependencies/vue/package.json
+++ b/src/main/resources/generator/dependencies/vue/package.json
@@ -8,7 +8,6 @@
     "i18next-vue": "5.0.0",
     "pinia": "2.2.2",
     "pinia-plugin-persistedstate": "4.0.2",
-    "piqure": "2.0.0",
     "vue": "3.5.9",
     "vue-router": "4.4.5"
   },


Test patch:
diff --git a/src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.spec.tsx.mustache b/src/main/resources/generator/client/react/core/src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx.mustache
similarity index 61%
rename from src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.spec.tsx.mustache
rename to src/main/resources/generator/client/react/core/src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx.mustache
index f5e87d503..00f8eaf48 100644
--- a/src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.spec.tsx.mustache
+++ b/src/main/resources/generator/client/react/core/src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx.mustache
@@ -1,11 +1,11 @@
 import { render } from '@testing-library/react';
 import { describe, it } from 'vitest';
 
-import App from '@/common/primary/app/App';
+import HomePage from '@/home/infrastructure/primary/HomePage';
 
-describe('App tests', () => {
+describe('Home tests', () => {
   it('renders without crashing', () => {
-    const { getByText } = render(<App />);
+    const { getByText } = render(<HomePage />);
     const title = getByText('React + TypeScript + Vite');
     expect(title).toBeTruthy();
   });
diff --git a/src/test/features/client/react.feature b/src/test/features/client/react.feature
index 51e6071f3..3a17349d9 100644
--- a/src/test/features/client/react.feature
+++ b/src/test/features/client/react.feature
@@ -6,5 +6,5 @@ Feature: React modules
       | prettier   |
       | typescript |
       | react-core |
-    Then I should have files in "src/main/webapp/app/common/primary/app"
-      | App.tsx |
+    Then I should have files in "src/main/webapp/app/home/infrastructure/primary"
+      | HomePage.tsx |
diff --git a/src/test/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.java
index 8a94a07af..b9a97624e 100644
--- a/src/test/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.java
@@ -35,6 +35,7 @@ class ReactCoreModulesFactoryTest {
       .containing(nodeDependency("vite"))
       .containing(nodeDependency("react"))
       .containing(nodeDependency("react-dom"))
+      .containing(nodeDependency("piqure"))
       .containing(nodeScript("dev", "npm-run-all --parallel dev:*"))
       .containing(nodeScript("dev:vite", "vite"))
       .containing(nodeScript("build", "npm-run-all build:*"))
@@ -64,12 +65,12 @@ class ReactCoreModulesFactoryTest {
       .and()
       .hasFiles("vite.config.ts")
       .hasFiles("src/main/webapp/index.html")
-      .hasPrefixedFiles("src/main/webapp/app", "index.css", "index.tsx", "vite-env.d.ts")
-      .hasFiles("src/test/webapp/unit/common/primary/app/App.spec.tsx")
-      .hasFile("src/main/webapp/app/common/primary/app/App.tsx")
-      .containing("import './App.css';")
+      .hasPrefixedFiles("src/main/webapp/app", "index.css", "index.tsx", "vite-env.d.ts", "injections.ts")
+      .hasFiles("src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx")
+      .hasFile("src/main/webapp/app/home/infrastructure/primary/HomePage.tsx")
+      .containing("import './HomePage.css';")
       .and()
-      .hasFiles("src/main/webapp/app/common/primary/app/App.css")
+      .hasFiles("src/main/webapp/app/home/infrastructure/primary/HomePage.css")
       .hasPrefixedFiles("src/main/webapp/assets", "ReactLogo.png", "JHipster-Lite-neon-blue.png");
   }
 
diff --git a/src/test/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactoryTest.java
index 97c31c5aa..a07c0a976 100644
--- a/src/test/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactoryTest.java
@@ -11,7 +11,7 @@ import tech.jhipster.lite.module.domain.JHipsterModulesFixture;
 @UnitTest
 class ReactI18nModuleFactoryTest {
 
-  private static final String APP_TSX = "src/main/webapp/app/common/primary/app/App.tsx";
+  private static final String HomePage_TSX = "src/main/webapp/app/home/infrastructure/primary/HomePage.tsx";
 
   private final ReactI18nModuleFactory factory = new ReactI18nModuleFactory();
 
@@ -34,22 +34,25 @@ class ReactI18nModuleFactoryTest {
       .hasFile("src/main/webapp/app/index.tsx")
       .containing("import './i18n'")
       .and()
-      .hasFile("src/main/webapp/app/common/primary/app/App.tsx")
+      .hasFile("src/main/webapp/app/home/infrastructure/primary/HomePage.tsx")
       .containing("import { useTranslation } from 'react-i18next")
       .containing("const { t } = useTranslation();")
       .containing("{t('translationEnabled')}")
       .and()
       .hasPrefixedFiles("src/main/webapp/assets/locales/", "en/translation.json", "fr/translation.json")
-      .hasFile("src/test/webapp/unit/common/primary/app/App.spec.tsx")
-      .containing("describe('App I18next', () => {");
+      .hasFile("src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx")
+      .containing("describe('Home I18next', () => {");
   }
 
   private ModuleFile app() {
-    return file("src/test/resources/projects/react-app/App.tsx", APP_TSX);
+    return file("src/test/resources/projects/react-app/HomePage.tsx", HomePage_TSX);
   }
 
   private ModuleFile appTest() {
-    return file("src/test/resources/projects/react-app/App.spec.tsx", "src/test/webapp/unit/common/primary/app/App.spec.tsx");
+    return file(
+      "src/test/resources/projects/react-app/HomePage.spec.tsx",
+      "src/test/webapp/unit/home/infrastructure/primary/HomePage.spec.tsx"
+    );
   }
 
   private ModuleFile index() {
diff --git a/src/test/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactoryTest.java
index d42247c95..a9df091bc 100644
--- a/src/test/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/client/react/security/jwt/domain/ReactJwtModuleFactoryTest.java
@@ -12,7 +12,7 @@ import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
 @UnitTest
 class ReactJwtModuleFactoryTest {
 
-  private static final String APP_TSX = "src/main/webapp/app/common/primary/app/App.tsx";
+  private static final String APP_TSX = "src/main/webapp/app/home/infrastructure/primary/HomePage.tsx";
 
   private static final ReactJwtModuleFactory factory = new ReactJwtModuleFactory();
 
@@ -24,7 +24,7 @@ class ReactJwtModuleFactoryTest {
 
     assertReactApp(asserter);
     asserter
-      .hasFile("src/main/webapp/app/common/primary/app/App.css")
+      .hasFile("src/main/webapp/app/home/infrastructure/primary/HomePage.css")
       .containing(
         """
           -moz-osx-font-smoothing: grayscale;
@@ -40,7 +40,7 @@ class ReactJwtModuleFactoryTest {
         """
           <React.StrictMode>
             <NextUIProvider>
-              <App />
+              <HomePage />
             </NextUIProvider>
           </React.StrictMode>,
         """
@@ -48,11 +48,11 @@ class ReactJwtModuleFactoryTest {
   }
 
   private ModuleFile app() {
-    return file("src/test/resources/projects/react-app/App.tsx", APP_TSX);
+    return file("src/test/resources/projects/react-app/HomePage.tsx", APP_TSX);
   }
 
   private ModuleFile appCss() {
-    return file("src/test/resources/projects/react-app/App.css", "src/main/webapp/app/common/primary/app/App.css");
+    return file("src/test/resources/projects/react-app/HomePage.css", "src/main/webapp/app/home/infrastructure/primary/HomePage.css");
   }
 
   private ModuleFile indexTsx() {
@@ -100,7 +100,7 @@ class ReactJwtModuleFactoryTest {
         "login/primary/loginModal/index.test.tsx",
         "common/services/storage.test.ts"
       )
-      .hasFile("src/main/webapp/app/common/primary/app/App.tsx")
+      .hasFile("src/main/webapp/app/home/infrastructure/primary/HomePage.tsx")
       .containing("import LoginForm from '@/login/primary/loginForm';")
       .containing("<LoginForm />");
   }
diff --git a/src/test/resources/projects/react-app/App.spec.tsx b/src/test/resources/projects/react-app/App.spec.tsx
deleted file mode 100644
index f5e87d503..000000000
--- a/src/test/resources/projects/react-app/App.spec.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { render } from '@testing-library/react';
-import { describe, it } from 'vitest';
-
-import App from '@/common/primary/app/App';
-
-describe('App tests', () => {
-  it('renders without crashing', () => {
-    const { getByText } = render(<App />);
-    const title = getByText('React + TypeScript + Vite');
-    expect(title).toBeTruthy();
-  });
-});
diff --git a/src/test/resources/projects/react-app/App.css b/src/test/resources/projects/react-app/HomePage.css
similarity index 100%
rename from src/test/resources/projects/react-app/App.css
rename to src/test/resources/projects/react-app/HomePage.css
diff --git a/src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.test.tsx.mustache b/src/test/resources/projects/react-app/HomePage.spec.tsx
similarity index 61%
rename from src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.test.tsx.mustache
rename to src/test/resources/projects/react-app/HomePage.spec.tsx
index f5e87d503..00f8eaf48 100644
--- a/src/main/resources/generator/client/react/core/src/test/webapp/unit/common/primary/app/App.test.tsx.mustache
+++ b/src/test/resources/projects/react-app/HomePage.spec.tsx
@@ -1,11 +1,11 @@
 import { render } from '@testing-library/react';
 import { describe, it } from 'vitest';
 
-import App from '@/common/primary/app/App';
+import HomePage from '@/home/infrastructure/primary/HomePage';
 
-describe('App tests', () => {
+describe('Home tests', () => {
   it('renders without crashing', () => {
-    const { getByText } = render(<App />);
+    const { getByText } = render(<HomePage />);
     const title = getByText('React + TypeScript + Vite');
     expect(title).toBeTruthy();
   });
diff --git a/src/test/resources/projects/react-app/App.tsx b/src/test/resources/projects/react-app/HomePage.tsx
similarity index 93%
rename from src/test/resources/projects/react-app/App.tsx
rename to src/test/resources/projects/react-app/HomePage.tsx
index 8573302f7..7342cd8b7 100644
--- a/src/test/resources/projects/react-app/App.tsx
+++ b/src/test/resources/projects/react-app/HomePage.tsx
@@ -1,9 +1,9 @@
-import './App.css';
+import './HomePage.css';
 
 import JHipsterLiteNeonBlue from '@assets/JHipster-Lite-neon-blue.png';
 import ReactLogo from '@assets/ReactLogo.png';
 
-function App() {
+function HomePage() {
   return (
     <div>
       <div id="app">
@@ -36,4 +36,4 @@ function App() {
   );
 }
 
-export default App;
+export default HomePage;
diff --git a/src/test/resources/projects/react-app/index.tsx b/src/test/resources/projects/react-app/index.tsx
index 0c99f1a20..8ba5e4e92 100644
--- a/src/test/resources/projects/react-app/index.tsx
+++ b/src/test/resources/projects/react-app/index.tsx
@@ -1,4 +1,4 @@
-import App from '@/common/primary/app/App';
+import HomePage from '@/home/infrastructure/primary/HomePage';
 import React from 'react';
 import { createRoot } from 'react-dom/client';
 import './index.css';
@@ -7,6 +7,6 @@ const container = document.getElementById('root');
 const root = createRoot(container!);
 root.render(
   <React.StrictMode>
-    <App />
+    <HomePage />
   </React.StrictMode>,
 );
diff --git a/src/test/resources/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.shouldBuildModuleWithStyle.vitest.config.ts.approved.txt b/src/test/resources/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.shouldBuildModuleWithStyle.vitest.config.ts.approved.txt
index b75e04ba3..c155fa131 100644
--- a/src/test/resources/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.shouldBuildModuleWithStyle.vitest.config.ts.approved.txt
+++ b/src/test/resources/tech/jhipster/lite/generator/client/react/core/domain/ReactCoreModulesFactoryTest.shouldBuildModuleWithStyle.vitest.config.ts.approved.txt
@@ -31,6 +31,7 @@ export default defineConfig({
       include: ['src/main/webapp/**/*.ts?(x)'],
       exclude: [
         ...configDefaults.coverage.exclude as string[],
+        'src/main/webapp/app/injections.ts',
         'src/main/webapp/app/index.tsx',
       ],
       provider: 'istanbul',