Forráskód Böngészése

ajout du stage test unitaire

DESKTOP-SMCIPAV\falko 4 hónapja
szülő
commit
d310f8d68f

+ 36 - 25
Jenkinsfile

@@ -11,6 +11,8 @@ pipeline {
     }
 
     stages {
+
+        // 1. Déterminer l'environnement en fonction de la branche
         stage('Select Environment') {
             steps {
                 script {
@@ -37,15 +39,25 @@ pipeline {
             }
         }
 
-        // stage('Install Dependencies & Test') {
-        //     steps {
-        //         withEnv(["PATH=${tool 'NodeJS'}/bin:${env.PATH}"]) {
-        //             sh 'npm install --legacy-peer-deps'
-        //             sh 'npm run test -- --no-watch --no-progress --browsers=ChromeHeadless'
-        //         }
-        //     }
-        // }
+        // 2. Installation des dépendances et tests unitaires Angular
+        stage('Unit Tests') {
+            steps {
+                dir('angular-client') {
+                    sh 'npm install --legacy-peer-deps'
+                    sh 'npm run test -- --no-watch --no-progress --browsers=ChromeHeadless --code-coverage'
+                }
+            }
+            post {
+                always {
+                    junit 'angular-client/coverage/**/junit-report.xml'
+                }
+                unsuccessful {
+                    error "Tests unitaires échoués. Arrêt du pipeline."
+                }
+            }
+        }
 
+        // 3. Analyse SonarQube pour la qualité du code
         // stage('SonarQube Analysis') {
         //     steps {
         //         script {
@@ -63,31 +75,38 @@ pipeline {
         //     }
         // }
 
+        // 4. Arrêt et nettoyage des anciens conteneurs
         // stage('Stop & Clean Containers') {
         //     steps {
         //         sh """
-        //             docker ps | grep "workflow_" -v | awk '{if(NR>1) print \$1}' | xargs docker kill || true
         //             docker-compose -f ${env.COMPOSE_FILE} down || true
         //             docker system prune -f
         //         """
         //     }
         // }
 
+        // 5. Build et déploiement des services
         stage('Build & Deploy') {
             steps {
                 sh """
                     docker-compose -f ${env.COMPOSE_FILE} build --no-cache
                     docker-compose -f ${env.COMPOSE_FILE} up -d --force-recreate --remove-orphans
                 """
+            }
+        }
+
+        // 6. Lancement des backups après déploiement
+        stage('Backup') {
+            steps {
                 script {
                     echo "Lancement du backup sur le container ${env.BACKUP_CONTAINER}"
-                    def backupCmd = "docker exec ${env.BACKUP_CONTAINER} /backup.sh || echo '⚠️ Backup ${env.ENV.toUpperCase()} échoué'"
-                    sh backupCmd
+                    sh "docker exec ${env.BACKUP_CONTAINER} /backup.sh || echo '⚠️ Backup ${env.ENV.toUpperCase()} échoué'"
                 }
             }
         }
 
-        // stage('Push to Private Registry (Optional)') {
+        // 7. Push optionnel de l'image dans le registre Nexus
+        // stage('Push to Private Registry') {
         //     when {
         //         anyOf {
         //             branch 'dev'
@@ -97,17 +116,11 @@ pipeline {
         //     steps {
         //         script {
         //             docker.withRegistry("https://${DOCKER_REGISTRY}", 'nexus') {
-        //                 try {
-        //                     echo "Pull image from registry"
-        //                     docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").pull()
-        //                 } catch (Exception e) {
-        //                     echo "Build and push image"
-        //                     sh """
-        //                         docker pull ${IMAGE_NAME}:${IMAGE_TAG}
-        //                         docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
-        //                         docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
-        //                     """
-        //                 }
+        //                 sh """
+        //                     docker pull ${IMAGE_NAME}:${IMAGE_TAG} || true
+        //                     docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
+        //                     docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
+        //                 """
         //             }
         //         }
         //     }
@@ -125,8 +138,6 @@ pipeline {
 }
 
 
-
-
 // pipeline {
 //     agent any
 //     environment {

+ 19 - 1
angular-client/angular.json

@@ -114,7 +114,25 @@
               "/contact"
             ]
           }
-        }
+        },
+      "test": {
+        "builder": "@angular-devkit/build-angular:karma",
+        "options": {
+        "main": "src/test.ts",
+        "polyfills": "src/polyfills.ts",
+        "tsConfig": "tsconfig.spec.json",
+        "karmaConfig": "karma.conf.js",
+        "assets": [
+           "src/favicon.ico",
+           "src/assets"
+            ],
+        "styles": [
+           "src/styles.scss"
+          ],
+       "scripts": []
+  }
+}
+
       }
     }
   },

+ 10 - 4
angular-client/karma.conf.js

@@ -24,9 +24,15 @@ module.exports = function (config) {
     port: 9876,
     colors: true,
     logLevel: config.LOG_INFO,
-    autoWatch: true,
-    browsers: ['Chrome'],
-    singleRun: false,
-    restartOnFileChange: true
+    autoWatch: false,
+    browsers: ['ChromeHeadless'],
+    singleRun: true,
+    restartOnFileChange: false,
+
+    // Ajouts pour éviter les déconnexions ChromeHeadless
+    captureTimeout: 60000,
+    browserDisconnectTimeout: 60000,
+    browserDisconnectTolerance: 3,
+    browserNoActivityTimeout: 60000
   });
 };

+ 1 - 0
angular-client/package.json

@@ -6,6 +6,7 @@
     "start": "ng serve --host 0.0.0.0",
     "build": "ng build --prod",
     "test": "ng test",
+    "test-headless": "ng test --no-watch --no-progress --browsers=ChromeHeadless",
     "lint": "ng lint",
     "e2e": "ng e2e",
     "test-ci": "ng test --karma-config=karma-ci.conf.js --no-progress",

+ 0 - 9
angular-client/src/app/app.component.spec.ts

@@ -13,13 +13,4 @@ describe('AppComponent', () => {
     const app = fixture.componentInstance;
     expect(app).toBeTruthy();
   });
-
-  it(`should have as title 'fatboar'`, () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.componentInstance;
-    expect(app.title).toEqual('fatboar');
-  });
-
-  
-  
 });

+ 45 - 0
angular-client/src/test-material.module.ts

@@ -0,0 +1,45 @@
+import { NgModule } from '@angular/core';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+// Import des modules Angular Material nécessaires
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatButtonModule } from '@angular/material/button';
+import { MatIconModule } from '@angular/material/icon';
+import { MatToolbarModule } from '@angular/material/toolbar';
+import { MatCardModule } from '@angular/material/card';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatDialogModule } from '@angular/material/dialog';
+import { MatMenuModule } from '@angular/material/menu';
+import { MatTableModule } from '@angular/material/table';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatSortModule } from '@angular/material/sort';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+import { MatSelectModule } from '@angular/material/select';
+import { MatSidenavModule } from '@angular/material/sidenav';
+import { MatListModule } from '@angular/material/list';
+
+@NgModule({
+  exports: [
+    BrowserAnimationsModule,
+    MatFormFieldModule,
+    MatInputModule,
+    MatButtonModule,
+    MatIconModule,
+    MatToolbarModule,
+    MatCardModule,
+    MatSnackBarModule,
+    MatDialogModule,
+    MatMenuModule,
+    MatTableModule,
+    MatPaginatorModule,
+    MatSortModule,
+    MatProgressSpinnerModule,
+    MatCheckboxModule,
+    MatSelectModule,
+    MatSidenavModule,
+    MatListModule
+  ]
+})
+export class TestMaterialModule {}

+ 29 - 0
angular-client/src/test-setup.ts

@@ -0,0 +1,29 @@
+import { TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { TestMaterialModule } from './test-material.module';
+
+const originalConfigureTestingModule = TestBed.configureTestingModule;
+
+TestBed.configureTestingModule = function (moduleDef: any) {
+  moduleDef = moduleDef || {};
+  moduleDef.imports = moduleDef.imports || [];
+  moduleDef.schemas = moduleDef.schemas || [];
+
+  // Ajout global de RouterTestingModule
+  if (!moduleDef.imports.includes(RouterTestingModule)) {
+    moduleDef.imports.push(RouterTestingModule);
+  }
+
+  // Ajout global de TestMaterialModule
+  if (!moduleDef.imports.includes(TestMaterialModule)) {
+    moduleDef.imports.push(TestMaterialModule);
+  }
+
+  // Ajout global de CUSTOM_ELEMENTS_SCHEMA
+  if (!moduleDef.schemas.includes(CUSTOM_ELEMENTS_SCHEMA)) {
+    moduleDef.schemas.push(CUSTOM_ELEMENTS_SCHEMA);
+  }
+
+  return originalConfigureTestingModule.call(this, moduleDef);
+} as any;

+ 4 - 5
angular-client/src/test.ts

@@ -1,6 +1,5 @@
-// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-
 import 'zone.js/dist/zone-testing';
+import './test-setup'; // Patch global
 import { getTestBed } from '@angular/core/testing';
 import {
   BrowserDynamicTestingModule,
@@ -14,12 +13,12 @@ declare const require: {
   };
 };
 
-// First, initialize the Angular testing environment.
+// Initialisation Angular
 getTestBed().initTestEnvironment(
   BrowserDynamicTestingModule,
   platformBrowserDynamicTesting()
 );
-// Then we find all the tests.
+
+// Charger tous les tests
 const context = require.context('./', true, /\.spec\.ts$/);
-// And load the modules.
 context.keys().map(context);