From 9304de1f9916f3666de831eb777ecd53b5d0b614 Mon Sep 17 00:00:00 2001 From: moshi Date: Sat, 19 Oct 2024 16:24:57 -0400 Subject: [PATCH 01/56] App running - Leo --- pom.xml | 1 + selenium/Dockerfile | 10 ++-- testrail/.gitattributes | 2 + testrail/.gitignore | 33 ++++++++++++ testrail/pom.xml | 54 +++++++++++++++++++ .../etsmtl/testrail/TestrailApplication.java | 13 +++++ .../src/main/resources/application.properties | 1 + .../testrail/TestrailApplicationTests.java | 13 +++++ 8 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 testrail/.gitattributes create mode 100644 testrail/.gitignore create mode 100644 testrail/pom.xml create mode 100644 testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java create mode 100644 testrail/src/main/resources/application.properties create mode 100644 testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java diff --git a/pom.xml b/pom.xml index c607224..3eb197e 100644 --- a/pom.xml +++ b/pom.xml @@ -22,5 +22,6 @@ pom backend + testrail \ No newline at end of file diff --git a/selenium/Dockerfile b/selenium/Dockerfile index 7cea648..cbc483b 100644 --- a/selenium/Dockerfile +++ b/selenium/Dockerfile @@ -1,11 +1,13 @@ -FROM maven:3.8.6-eclipse-temurin-11 as builder +FROM maven:3.9.9-sapmachine-17 as builder + +ARG CHROME_VERSION="130.0.6723.58-1" RUN apt-get update # RUN apt-get install -y gconf-service libasound2 libatk1.0-0 libcairo2 libcups2 libfontconfig1 libgdk-pixbuf2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libxss1 fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils RUN apt-get install -y wget -RUN wget -q https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.198-1_amd64.deb -RUN apt-get install -y ./google-chrome-stable_114.0.5735.198-1_amd64.deb +RUN wget -q https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb +RUN apt-get install -y ./google-chrome-stable_${CHROME_VERSION}_amd64.deb WORKDIR / COPY pom.xml . @@ -13,4 +15,4 @@ COPY selenium ./selenium WORKDIR /selenium RUN mvn clean install EXPOSE 8090 -ENTRYPOINT ["mvn", "spring-boot:run" ] +ENTRYPOINT ["mvn", "spring-boot:run" ] \ No newline at end of file diff --git a/testrail/.gitattributes b/testrail/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/testrail/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/testrail/.gitignore b/testrail/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/testrail/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/testrail/pom.xml b/testrail/pom.xml new file mode 100644 index 0000000..64205ad --- /dev/null +++ b/testrail/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.4 + + + ca.etsmtl + testrail + 0.0.1-SNAPSHOT + testrail + testrail + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java b/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java new file mode 100644 index 0000000..8dfa20c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java @@ -0,0 +1,13 @@ +package ca.etsmtl.testrail; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class TestrailApplication { + + public static void main(String[] args) { + SpringApplication.run(TestrailApplication.class, args); + } + +} diff --git a/testrail/src/main/resources/application.properties b/testrail/src/main/resources/application.properties new file mode 100644 index 0000000..3909fca --- /dev/null +++ b/testrail/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=testrail diff --git a/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java b/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java new file mode 100644 index 0000000..ce6744c --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java @@ -0,0 +1,13 @@ +package ca.etsmtl.testrail; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class TestrailApplicationTests { + + @Test + void contextLoads() { + } + +} From 46292f90dc1e88fdbcf59c3b119e38c85ec321ef Mon Sep 17 00:00:00 2001 From: moshi Date: Mon, 21 Oct 2024 21:02:42 -0400 Subject: [PATCH 02/56] After tutorial : https://spring.io/guides/gs/multi-module --- .mvn/wrapper/maven-wrapper.jar | Bin 58727 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 2 - backend/pom.xml | 7 ++ pom.xml | 2 +- testrail/pom.xml | 71 ++++++------------ .../taf/testrail/service/MyService.java | 19 +++++ .../testrail/service/ServiceProperties.java | 21 ++++++ .../etsmtl/testrail/TestrailApplication.java | 13 ---- .../src/main/resources/application.properties | 1 - .../taf/testrail/service/MyServiceTest.java | 26 +++++++ .../testrail/TestrailApplicationTests.java | 13 ---- 11 files changed, 97 insertions(+), 78 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.jar delete mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java delete mode 100644 testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java delete mode 100644 testrail/src/main/resources/application.properties create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java delete mode 100644 testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index c1dd12f17644411d6e840bd5a10c6ecda0175f18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58727 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%0ANsA|A3-jj|r`KAo%oTajX3>^E` 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 YM{}PByk10KD_nuQ4E7Du?}+~TKh4V)`~Uy| diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index b7cb93e..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/backend/pom.xml b/backend/pom.xml index f285fd6..82fa2f6 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -88,6 +88,13 @@ opencsv 5.5 + + + + ca.etsmtl.taf + testrail + ${project.version} + diff --git a/pom.xml b/pom.xml index 3eb197e..f00da4a 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,6 @@ pom backend - testrail + testrail \ No newline at end of file diff --git a/testrail/pom.xml b/testrail/pom.xml index 64205ad..169b566 100644 --- a/testrail/pom.xml +++ b/testrail/pom.xml @@ -1,54 +1,29 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.3.4 - - - ca.etsmtl - testrail - 0.0.1-SNAPSHOT - testrail - testrail - - - - - - - - - - - - - - - 17 - - - - org.springframework.boot - spring-boot-starter - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + ca.etsmtl.taf + testrail + 1.0.0-SNAPSHOT + testrail + testrail - - org.springframework.boot - spring-boot-starter-test - test - - + + + org.springframework.boot + spring-boot-starter-test + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + org.springframework.boot + spring-boot-starter + + diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java new file mode 100644 index 0000000..0ce051a --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java @@ -0,0 +1,19 @@ +package ca.etsmtl.taf.testrail.service; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.stereotype.Service; + +@Service +@EnableConfigurationProperties(ServiceProperties.class) +public class MyService { + + private final ServiceProperties serviceProperties; + + public MyService(ServiceProperties serviceProperties) { + this.serviceProperties = serviceProperties; + } + + public String message() { + return this.serviceProperties.getMessage(); + } +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java new file mode 100644 index 0000000..5931a78 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java @@ -0,0 +1,21 @@ +package ca.etsmtl.taf.testrail.service; + + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties("service") +public class ServiceProperties { + + /** + * A message for the service. + */ + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java b/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java deleted file mode 100644 index 8dfa20c..0000000 --- a/testrail/src/main/java/ca/etsmtl/testrail/TestrailApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package ca.etsmtl.testrail; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class TestrailApplication { - - public static void main(String[] args) { - SpringApplication.run(TestrailApplication.class, args); - } - -} diff --git a/testrail/src/main/resources/application.properties b/testrail/src/main/resources/application.properties deleted file mode 100644 index 3909fca..0000000 --- a/testrail/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=testrail diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java new file mode 100644 index 0000000..ce78e54 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java @@ -0,0 +1,26 @@ +package ca.etsmtl.taf.testrail.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest("service.message=Hello") +public class MyServiceTest { + + @Autowired + private MyService myService; + + @Test + public void contextLoads() { + assertThat(myService.message()).isNotNull(); + } + + @SpringBootApplication + static class TestConfiguration { + } + +} \ No newline at end of file diff --git a/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java b/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java deleted file mode 100644 index ce6744c..0000000 --- a/testrail/src/test/java/ca/etsmtl/testrail/TestrailApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package ca.etsmtl.testrail; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class TestrailApplicationTests { - - @Test - void contextLoads() { - } - -} From 9a096df8c5e727c30a8d9146f9dd888cd5dac583 Mon Sep 17 00:00:00 2001 From: moshi Date: Tue, 22 Oct 2024 21:11:34 -0400 Subject: [PATCH 03/56] Add documentation to testrail module --- testrail/TestRail module Class Diagram.svg | 1 + ...ail module configuration documentation .md | 334 ++++++++++++++++++ testrail/TestRailImport Class Diagram.puml | 81 +++++ 3 files changed, 416 insertions(+) create mode 100644 testrail/TestRail module Class Diagram.svg create mode 100644 testrail/TestRail module configuration documentation .md create mode 100644 testrail/TestRailImport Class Diagram.puml diff --git a/testrail/TestRail module Class Diagram.svg b/testrail/TestRail module Class Diagram.svg new file mode 100644 index 0000000..303b6ac --- /dev/null +++ b/testrail/TestRail module Class Diagram.svg @@ -0,0 +1 @@ +ExportServiceInterfaceexportData()ExportServiceexportData()XCollectorcollectData()JmeterCollectorcollectData()SeleniumCollectorcollectData()GatlingCollectorcollectData()ExportAexportData()ExportBexportData()CollectDatacollectData()ParseDataparseData()JmeterParserparseData()SeleniumParserparseData()GatlingParserparseData()XParserparseData() \ No newline at end of file diff --git a/testrail/TestRail module configuration documentation .md b/testrail/TestRail module configuration documentation .md new file mode 100644 index 0000000..7a54d5f --- /dev/null +++ b/testrail/TestRail module configuration documentation .md @@ -0,0 +1,334 @@ + +[Spring multi-module projects](https://spring.io/guides/gs/multi-module) +[Getting Started | Creating a Multi Module Project](https://spring.io/guides/gs/multi-module) +## Lien utiles du projet + +[Github du projet](https://github.com/Yojda/TAF) + +## Commande utiles + +### Spring + +Pour compiler le projet +```bash +mvn clean install +``` + +Pour run le projet une fois compiler +```Bash +mvn spring-boot:run -pl backend +``` + +Pour compiler puis run le projet +```Bash +mvn clean install && mvn spring-boot:run -pl backend +``` + + +## Fichiers importants + +### Structure + +#### backend + +La structure du backend est une structure typique d'un application spring + +```txt +backend +├── src +│   ├── main +│   │   ├── java +│   │   │   └── ca +│   │   │   └── etsmtl +│   │   │   └── taf +│   │   │   ├── apiCommunication +│   │   │   ├── config +│   │   │   ├── controller +│   │   │   ├── dto +│   │   │   ├── entity +│   │   │   ├── jmeter +│   │   │   │   ├── controllers +│   │   │   │   ├── model +│   │   │   │   ├── provider +│   │   │   │   └── utils +│   │   │   ├── payload +│   │   │   │   ├── request +│   │   │   │   └── response +│   │   │   ├── provider +│   │   │   ├── repository +│   │   │   ├── security +│   │   │   │   ├── jwt +│   │   │   │   └── services +│   │   │   └── service +│   │   └── resources +│   │   ├── jmeter +│   │   │   └── results +│   │   ├── static +│   │   │   ├── css +│   │   │   ├── images +│   │   │   └── js +│   │   └── templates +│   │   └── edit +│   └── test +│   └── java +│   └── ca +│   └── etsmtl +│   └── taf +└── target + ├── classes + │   ├── META-INF + │   ├── ca + │   │   └── etsmtl + │   │   └── taf + │   │   ├── apiCommunication + │   │   ├── config + │   │   ├── controller + │   │   ├── dto + │   │   ├── entity + │   │   ├── jmeter + │   │   │   ├── controllers + │   │   │   ├── model + │   │   │   ├── provider + │   │   │   └── utils + │   │   ├── payload + │   │   │   ├── request + │   │   │   └── response + │   │   ├── provider + │   │   ├── repository + │   │   ├── security + │   │   │   ├── jwt + │   │   │   └── services + │   │   └── service + │   ├── jmeter + │   │   └── results + │   ├── static + │   │   ├── css + │   │   ├── images + │   │   └── js + │   └── templates + │   └── edit + ├── generated-sources + │   └── annotations + ├── generated-test-sources + │   └── test-annotations + ├── maven-archiver + ├── maven-status + │   └── maven-compiler-plugin + │   ├── compile + │   │   └── default-compile + │   └── testCompile + │   └── default-testCompile + ├── surefire-reports + └── test-classes + └── ca + └── etsmtl + └── taf + +``` + +#### testrail module + +Le module *testrail* reprend la structure classique d'un projet spring. Ci-dessous est donné sa structure partiel puisqu'elle ne précise pas encore la structure interne aux fichiers sources du module. + +```txt + testrail + ├── src + │   ├── main + │   │   ├── java + │   │   │   └── ca + │   │   │   └── etsmtl + │   │   │   └── testrail + │   │   └── resources + │   └── test + │   └── java + │   └── ca + │   └── etsmtl + │   └── testrail + └── target + ├── classes + │   └── ca + │   └── etsmtl + │   └── testrail + ├── generated-sources + │   └── annotations + ├── generated-test-sources + │   └── test-annotations + ├── maven-archiver + ├── maven-status + │   └── maven-compiler-plugin + │   ├── compile + │   │   └── default-compile + │   └── testCompile + │   └── default-testCompile + ├── surefire-reports + └── test-classes + └── ca + └── etsmtl + └── testrail + + +``` + + +#### packages + +##### controller + +gestion des requêtes HTTP + +##### service + +logique métier, notamment les interactions avec TestRail et les autres outils + +##### repository +Pour les interactions avec la base de données + +##### entity + +Les entités de la base de données JPA + +##### dto + +Les objets de transfert de données + +#### Structure + +![](TestRail%20module%20Class%20Diagram.svg) + +### Configuration +#### Java +##### /pom.xml + +> [!FILE] /pom.xml +> Contient les informations de configuration de tous les modules java du projet (backend, testrail). Il s'agit du fichier principal de configuration Java. + +Il faut décrire les modules du projet dans ce fichier pour qu'ils soient bien tous compiler + +```yml + + backend + testrail + +``` + +C'est aussi dans ce fichier que l'on retrouve la version de à utiliser + +```yml + + 17 + 1.18.24 + 2.6.6 + +``` +##### /backend/pom.xml + +> [!FILE] /backend/pom.xml +> Contient les informations de configuration propres au module java principal "backend" (ca.etsmtl.taf). +> + +##### /testrail/pom.xml + +> [!FIEL] /testrail/pom.xml +> Contient les informations de configuration propres au module java "testrail" (ca.etsmtl.testrail) + +#### Docker + +##### /docker-compose.yml + +> [!FILE] /docker-compose.yml +> Fichier utiliser pour spécifier quels docker crée pour faire tourner l'application. On retrouve aussi des informations comme le mapping des ports. + +##### /backend/Dockerfile + +> [!FILE] /backend/Dockerfile +> Fichier qui décris comment crée l'image docker du backend du projet. Cette image compile le projet avec tous les modules spécifier dans le fichier /pom.xml. + + +## Docker compose with dedicate database + + +**/docker-compose.yml** + +```yml +services: + backend: + image: back + container_name: back + build: + context: ./ + dockerfile: ./backend/Dockerfile + ports: + - "8083:8083" + env_file: + # Specifying the env file with necessaries values + - .docker_config.env + + frontend: + image: front + container_name: front + build: + context: ./frontend + ports: + - "4200:80" + depends_on: + - backend + + selenium: + image: selenium + container_name: selenium + build: + context: ./ + dockerfile: ./selenium/Dockerfile + ports: + - "8090:8090" + + + mariadb: + image: mariadb + container_name: mariadb-2 + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: taf-db + MYSQL_USER: taf + MYSQL_PASSWORD: taf + ports: + - "3306:3306" + networks: + - taf-network + +networks: + taf-network: + driver: bridge +``` + +**/.docker_config.env** + +```env +TEST_API_SERVICE_URL="http://127.0.0.1" +TEST_API_SERVICE_PORT="8082" +SPRING_DATASOURCE_URL="jdbc:mysql://127.0.0.1:3306/taf-db" +SPRING_DATASOURCE_USERNAME="taf" +SPRING_DATASOURCE_PASSWORD="taf" +``` + +**/backend/pom.xml** + +```xml + + org.mariadb.jdbc + mariadb-java-client + 3.4.1 + +``` + +**/backend/src/main/ressources/application.yml** + +```yml + spring: + datasource: + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://127.0.0.1:3306/taf-db + username: taf + password: taf +``` + diff --git a/testrail/TestRailImport Class Diagram.puml b/testrail/TestRailImport Class Diagram.puml new file mode 100644 index 0000000..6c1811f --- /dev/null +++ b/testrail/TestRailImport Class Diagram.puml @@ -0,0 +1,81 @@ +@startuml +'https://plantuml.com/class-diagram + +interface ExportServiceInterface { + + exportData() +} + +class ExportService implements ExportServiceInterface{ + + exportData() +} + +ExportService *-up- XCollector +ExportService *-up- JmeterCollector +ExportService *-up- SeleniumCollector +ExportService *-up- GatlingCollector + +class ExportA implements ExportServiceInterface { + + exportData() +} + +ExportA -up-* ExportService + +class ExportB implements ExportServiceInterface { + + exportData() +} +ExportB -up-* ExportService + +interface CollectData { + + collectData() +} + +class JmeterCollector implements CollectData { + + collectData() +} + +class SeleniumCollector implements CollectData { + + collectData() +} + +class GatlingCollector implements CollectData { + + collectData() +} + +class XCollector implements CollectData { + + collectData() +} + +interface ParseData { + + parseData() +} + + +class JmeterParser implements ParseData { + + parseData() +} + +JmeterParser --* JmeterCollector + +class SeleniumParser implements ParseData { + + parseData() +} + +SeleniumParser --* SeleniumCollector + +class GatlingParser implements ParseData { + + parseData() +} + +GatlingParser --* GatlingCollector + +class XParser implements ParseData { + + parseData() +} + +XParser --* XCollector + + + + + +@enduml \ No newline at end of file From 96d192741ac3db407449283217e80e0434f527e1 Mon Sep 17 00:00:00 2001 From: moshi Date: Fri, 25 Oct 2024 10:32:55 -0400 Subject: [PATCH 04/56] Docker database --- backend/pom.xml | 9 ++++----- backend/src/main/resources/application.yml | 8 ++++---- testrail/docker-compose.yaml | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 testrail/docker-compose.yaml diff --git a/backend/pom.xml b/backend/pom.xml index 82fa2f6..c7f0d28 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -35,10 +35,9 @@ true - mysql - mysql-connector-java - 8.0.31 - runtime + org.mariadb.jdbc + mariadb-java-client + 3.4.1 io.jsonwebtoken @@ -83,7 +82,7 @@ com.squareup.okhttp3 okhttp - + com.opencsv opencsv 5.5 diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 15eef96..8d0d887 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -1,9 +1,9 @@ spring: datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://nostrasoft.com:3306/nostr321_taf-db - username: nostr321_taf - password: JKaVLX75iHwtrHc + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://127.0.0.1:3306/taf-db + username: taf + password: taf jpa: defer-datasource-initialization: true hibernate: diff --git a/testrail/docker-compose.yaml b/testrail/docker-compose.yaml new file mode 100644 index 0000000..7904dba --- /dev/null +++ b/testrail/docker-compose.yaml @@ -0,0 +1,18 @@ +services: + mariadb: + image: mariadb:latest + container_name: mariadb-taf + environment: + MYSQL_ROOT_PASSWORD: taf-root + MYSQL_DATABASE: taf-db + MYSQL_USER: taf + MYSQL_PASSWORD: taf + ports: + - "3306:3306" + networks: + - taf-network + + +networks: + taf-network: + driver: bridge \ No newline at end of file From 59646971a35f9d9df7a1629cc2d1ae06736f0d72 Mon Sep 17 00:00:00 2001 From: yanth Date: Fri, 25 Oct 2024 11:17:32 -0400 Subject: [PATCH 05/56] [feat] ressources sample gatling --- .../resources/testrail/SimpleSimulation.java | 25 + .../src/main/resources/testrail/index.html | 1146 +++++++++++++++++ 2 files changed, 1171 insertions(+) create mode 100644 backend/src/main/resources/testrail/SimpleSimulation.java create mode 100644 backend/src/main/resources/testrail/index.html diff --git a/backend/src/main/resources/testrail/SimpleSimulation.java b/backend/src/main/resources/testrail/SimpleSimulation.java new file mode 100644 index 0000000..94edb46 --- /dev/null +++ b/backend/src/main/resources/testrail/SimpleSimulation.java @@ -0,0 +1,25 @@ +package computerdatabase; + +import static io.gatling.javaapi.core.CoreDsl.*; +import static io.gatling.javaapi.http.HttpDsl.*; + +import io.gatling.javaapi.core.*; +import io.gatling.javaapi.http.*; + +public class SimpleSimulation extends Simulation { + + HttpProtocolBuilder httpProtocol = + http.baseUrl("https://wikijs.fornoff.fr") + .acceptHeader("application/json") + .contentTypeHeader("application/json"); + + ScenarioBuilder Scenario = scenario("My First Scenario") + .exec(http("Request 1") + .get("/computers/")); + + { + setUp( + Scenario.injectOpen(rampUsers(10).during(5)) + ).protocols(httpProtocol); + } +} \ No newline at end of file diff --git a/backend/src/main/resources/testrail/index.html b/backend/src/main/resources/testrail/index.html new file mode 100644 index 0000000..0f8ed5e --- /dev/null +++ b/backend/src/main/resources/testrail/index.html @@ -0,0 +1,1146 @@ + + + + + + + + + + + + + + + + + + + +Gatling Stats - Global Information + + + +
+
+
+
+ + + Documentation +
+ + Try + Gatling Enterprise + Gatling Enterprise + + +
+
+ +
+
+
+
+ ComputerDatabaseSimulation +
+
+
+ + +
+
+
+
+
+
+ + +
+ +
+
+ +
+
+
+
+
+ Gatling Version + + Version: + 3.12.0 + + + Released: + 2024-09-09 + +
+
+ Run Information +
+ + Date: + 2024-10-03 15:34:38 UTC + + + Duration: + 16s + + + Description: + + + +
+
+
+
+ +
+ +
+ +
+
+
+
+
+ + + +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+ + From ce2d311a64a490beb0de12d163a628a9161f16be Mon Sep 17 00:00:00 2001 From: yanth Date: Fri, 25 Oct 2024 11:50:17 -0400 Subject: [PATCH 06/56] [feat] Temp test case object for gatling --- .../testrail/service/TempResultGatling.java | 5 +++ .../testrail/service/TempTestCaseGatling.java | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java new file mode 100644 index 0000000..5f2952b --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service; + +public class TempResultGatling { + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java new file mode 100644 index 0000000..ad1542e --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java @@ -0,0 +1,39 @@ +package ca.etsmtl.taf.testrail.service; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class TempTestCaseGatling { + private String baseUrl; + private String scenario; + private Map usersInjection = new HashMap<>(); + public static void main(String[] args) { + String SimulationPath = "backend/src/main/resources/testrail/SimpleSimulation.java"; + + try (BufferedReader reader = new BufferedReader(new FileReader(SimulationPath))) { + String line; + while ((line = reader.readLine()) != null) { + String[] words = line.split(" "); + if (words.length > 0) { + if (words[0].equals("HttpProtocolBuilder")) { + while (!line[-1].equals(";")) { + HttpProcotolBuilder.parse(line); + } + } + if (words[0].equals("Scenario")) { + System.out.println("scenario: " + words[1]); + } + if (words[0].equals("rampUsers")) { + System.out.println("usersInjection: " + words[1]); + } + } + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file From bcb341e634060c91adf2e8c3db252035c97d0498 Mon Sep 17 00:00:00 2001 From: moshi Date: Fri, 25 Oct 2024 21:12:34 -0400 Subject: [PATCH 07/56] Create Entities GatlingResult & GatlingTestCase --- backend/pom.xml | 1 + testrail/pom.xml | 18 +++++++-- .../taf/testrail/model/GatlingResult.java | 33 ++++++++++++++++ .../taf/testrail/model/GatlingTestCase.java | 39 +++++++++++++++++++ .../etsmtl/taf/testrail/model/TestModel.java | 20 ++++++++++ 5 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java diff --git a/backend/pom.xml b/backend/pom.xml index c7f0d28..1e6a5c4 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -6,6 +6,7 @@ taf 1.0.0-SNAPSHOT + ca.etsmtl.taf backend diff --git a/testrail/pom.xml b/testrail/pom.xml index 169b566..828d55b 100644 --- a/testrail/pom.xml +++ b/testrail/pom.xml @@ -3,10 +3,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.6.6 - + ca.etsmtl + taf + 1.0.0-SNAPSHOT ca.etsmtl.taf testrail @@ -24,6 +23,17 @@ org.springframework.boot spring-boot-starter + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.projectlombok + lombok + provided + + diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java new file mode 100644 index 0000000..423b354 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java @@ -0,0 +1,33 @@ +package ca.etsmtl.taf.testrail.model; + +import javax.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Table(name = "tr_gatling_result") +@Getter +@Setter +public class GatlingResult { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "status_id", nullable = false) + private Integer statusId; + + @Column(name = "comment") + private String comment; + + @Column(name = "version") + private String version; + + @Column(name = "elapsed") + private String elapsed; + + @Column(name = "defects") + private String defects; + + @Column(name = "assignedto_id") + private Integer assignedToId; +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java new file mode 100644 index 0000000..3b69785 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java @@ -0,0 +1,39 @@ +package ca.etsmtl.taf.testrail.model; + +import javax.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Table(name = "tr_gatling_test_case") +@Getter +@Setter +public class GatlingTestCase { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "section_id", nullable = false) + private Integer sectionId; + + @Column(name = "title", nullable = false) + private String title; + + @Column(name = "template_id") + private Integer templateId; + + @Column(name = "type_id") + private Integer typeId; + + @Column(name = "priority_id") + private Integer priorityId; + + @Column(name = "estimate") + private String estimate; + + @Column(name = "milestone_id") + private Integer milestoneId; + + @Column(name = "refs") + private String refs; +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java new file mode 100644 index 0000000..88e22f7 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java @@ -0,0 +1,20 @@ +package ca.etsmtl.taf.testrail.model; + + +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Table(name = "test_model") +@Getter +@Setter +public class TestModel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + +} + From a75c8d15369b222d3363c77989d181feef335934 Mon Sep 17 00:00:00 2001 From: moshi Date: Fri, 25 Oct 2024 21:25:17 -0400 Subject: [PATCH 08/56] Patch error due to dialect configuration of hibernate --- backend/src/main/resources/application.yml | 4 ++-- .../etsmtl/taf/testrail/service/MyServiceTest.java | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 8d0d887..5739947 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -11,14 +11,14 @@ spring: dialect : ${spring.jpa.properties.hibernate.dialect} properties: hibernate: - dialect: org.hibernate.dialect.MySQL8Dialect + dialect: org.hibernate.dialect.MariaDBDialect messages: basename: validation encoding: ISO-8859-1 sql: init: mode: always - platform: mysql + platform: mariadb taf: app: jwtSecret: bezKoderSecretKey diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java index ce78e54..407ca82 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java @@ -11,16 +11,4 @@ @SpringBootTest("service.message=Hello") public class MyServiceTest { - @Autowired - private MyService myService; - - @Test - public void contextLoads() { - assertThat(myService.message()).isNotNull(); - } - - @SpringBootApplication - static class TestConfiguration { - } - } \ No newline at end of file From cd2dc99a9d3e7c7b70c06a46af7fdf0ef41e844d Mon Sep 17 00:00:00 2001 From: moshi Date: Fri, 25 Oct 2024 21:25:41 -0400 Subject: [PATCH 09/56] Create Entities GatlingResult & GatlingTestCase --- .../etsmtl/taf/testrail/service/export/ExportGatling.java | 8 ++++++++ .../testrail/service/export/ExportServiceInterface.java | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java new file mode 100644 index 0000000..ea5350e --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java @@ -0,0 +1,8 @@ +package ca.etsmtl.taf.testrail.service.export; + +public class ExportGatling implements ExportServiceInterface { + @Override + public void exportData() { + System.out.println("Exporting Gatling data"); + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java new file mode 100644 index 0000000..d09c01b --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.export; + +public interface ExportServiceInterface { + void exportData(); +} From 305bbde80c4f1098f79489ad4782dbe2e6d1a87d Mon Sep 17 00:00:00 2001 From: moshi Date: Sat, 26 Oct 2024 15:37:51 -0400 Subject: [PATCH 10/56] Communication with TestRail API for project management. Not tested --- .../TestAutomationFrameworkApplication.java | 2 +- backend/src/main/resources/application.yml | 6 + .../model/{ => entity}/GatlingResult.java | 3 +- .../model/{ => entity}/GatlingTestCase.java | 2 +- .../model/{ => entity}/TestModel.java | 2 +- .../testrail/model/entity/TestRailData.java | 7 + .../model/entity/TestRailProject.java | 57 +++++++ .../testrail/model/entity/TestRailUser.java | 41 +++++ .../model/factory/TestRailProjectFactory.java | 71 ++++++++ .../taf/testrail/service/MyService.java | 19 --- .../testrail/service/ServiceProperties.java | 21 --- .../testrail/service/load/data/LoadData.java | 14 ++ .../service/load/data/LoadProject.java | 35 ++++ .../service/query/HttpSenderToTestRail.java | 64 +++++++ .../service/query/ProjectQueryTestRail.java | 159 ++++++++++++++++++ .../testrail/service/query/QueryTestRail.java | 21 +++ .../service/refresh/data/Refresh.java | 6 + .../service/refresh/data/RefreshProject.java | 18 ++ .../ca/etsmtl/taf/testrail/TestConfig.java | 9 + .../taf/testrail/service/MyServiceTest.java | 14 -- 20 files changed, 513 insertions(+), 58 deletions(-) rename testrail/src/main/java/ca/etsmtl/taf/testrail/model/{ => entity}/GatlingResult.java (93%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/model/{ => entity}/GatlingTestCase.java (94%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/model/{ => entity}/TestModel.java (85%) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailData.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java diff --git a/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java b/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java index ea3565e..e036c96 100644 --- a/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java +++ b/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java @@ -4,7 +4,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -@SpringBootApplication +@SpringBootApplication(scanBasePackages = {"ca.etsmtl.taf", "ca.etsmtl.taf.testrail"}) @EnableJpaAuditing public class TestAutomationFrameworkApplication { diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 5739947..6113458 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -28,5 +28,11 @@ taf: selenium_container_url: http://selenium selenium_container_port: 8090 +testrail: + base-url: "https://leofornoff.testrail.io/index.php?/api/v2/" + username: "leo.fornoff.1@ens.etsmtl.ca" + password: "Valid8-Outpost2-Caravan0-Unlovable9-Easter7" + + server: port: 8083 \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java similarity index 93% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java index 423b354..b48b620 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingResult.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.model; +package ca.etsmtl.taf.testrail.model.entity; import javax.persistence.*; import lombok.Getter; @@ -30,4 +30,5 @@ public class GatlingResult { @Column(name = "assignedto_id") private Integer assignedToId; + } \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java similarity index 94% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java index 3b69785..b4b3fec 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/GatlingTestCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.model; +package ca.etsmtl.taf.testrail.model.entity; import javax.persistence.*; import lombok.Getter; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java similarity index 85% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java index 88e22f7..19cf115 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/TestModel.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.model; +package ca.etsmtl.taf.testrail.model.entity; import lombok.Getter; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailData.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailData.java new file mode 100644 index 0000000..f88866c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailData.java @@ -0,0 +1,7 @@ +package ca.etsmtl.taf.testrail.model.entity; + +public abstract class TestRailData { + /* + * TODO : document this class + * */ +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java new file mode 100644 index 0000000..5e279c9 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -0,0 +1,57 @@ +package ca.etsmtl.taf.testrail.model.entity; + +import javax.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Entity +@Table(name = "tr_project") +@Getter +@Setter +public class TestRailProject extends TestRailData { + + /* + * Class to save projects from TestRail in TAF database to be used in the application. + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long tafId; + + @Column(name = "id") + private Integer id; + + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "announcement") + private String announcement; + + @Column(name = "show_announcement") + private Boolean showAnnouncement; + + @Column(name = "is_completed") + private Boolean isCompleted; + + @Column(name = "completed_on") + private String completedOn; + + @Column(name = "suite_mode") + private Integer suiteMode; + + @Column(name = "default_role_id") + private Integer defaultRoleId; + + @Column(name = "case_statuses_enabled") + private Boolean caseStatusesEnabled; + + @Column(name = "url") + private String url; + + @ManyToMany(mappedBy = "projects") + private List users; +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java new file mode 100644 index 0000000..2ccb0d2 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -0,0 +1,41 @@ +package ca.etsmtl.taf.testrail.model.entity; + + +import javax.persistence.*; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Entity +@Table(name = "tr_user") +@Getter +@Setter +public class TestRailUser extends TestRailData { + /* + * Class to save users from TestRail. + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long tafId; + + @Column(name = "username", nullable = false) + private String username; + + @Column(name = "password", nullable = false) + private String password; + + @Column(name = "email", nullable = false) + private String email; + + @ManyToMany + @JoinTable( + name = "tr_user_project", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "project_id")) + private List projects; + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java new file mode 100644 index 0000000..4bc937f --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java @@ -0,0 +1,71 @@ +package ca.etsmtl.taf.testrail.model.factory; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import org.json.JSONException; +import org.json.JSONObject; + +public class TestRailProjectFactory { + public static TestRailProject create(String name) { + TestRailProject project = new TestRailProject(); + project.setName(name); + return project; + } + + public static TestRailProject create(JSONObject projectJson) throws JSONException { + /* + * Create a TestRailProject object from a JSON object + * @param projectJson : JSON object containing the project data + * @return TestRailProject object + * @throws JSONException if the JSON object is not correct + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + TestRailProject project = new TestRailProject(); + + // nullable = false + if (projectJson.has("name") && !projectJson.isNull("name")) { + project.setName(projectJson.getString("name")); + } else { + throw new JSONException("name is required"); + } + + if (projectJson.has("id") && !projectJson.isNull("id")) { + project.setId(projectJson.getInt("id")); + } + + if (projectJson.has("announcement") && !projectJson.isNull("announcement")) { + project.setAnnouncement(projectJson.getString("announcement")); + } + + if (projectJson.has("show_announcement") && !projectJson.isNull("show_announcement")) { + project.setShowAnnouncement(projectJson.getBoolean("show_announcement")); + } + + if (projectJson.has("is_completed") && !projectJson.isNull("is_completed")) { + project.setIsCompleted(projectJson.getBoolean("is_completed")); + } + + if (projectJson.has("completed_on") && !projectJson.isNull("completed_on")) { + project.setCompletedOn(String.valueOf(projectJson.getLong("completed_on"))); + } + + if (projectJson.has("suite_mode") && !projectJson.isNull("suite_mode")) { + project.setSuiteMode(projectJson.getInt("suite_mode")); + } + + if (projectJson.has("default_role_id") && !projectJson.isNull("default_role_id")) { + project.setDefaultRoleId(projectJson.getInt("default_role_id")); + } + + if (projectJson.has("case_statuses_enabled") && !projectJson.isNull("case_statuses_enabled")) { + project.setCaseStatusesEnabled(projectJson.getBoolean("case_statuses_enabled")); + } + + if (projectJson.has("url") && !projectJson.isNull("url")) { + project.setUrl(projectJson.getString("url")); + } + + return project; + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java deleted file mode 100644 index 0ce051a..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/MyService.java +++ /dev/null @@ -1,19 +0,0 @@ -package ca.etsmtl.taf.testrail.service; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; - -@Service -@EnableConfigurationProperties(ServiceProperties.class) -public class MyService { - - private final ServiceProperties serviceProperties; - - public MyService(ServiceProperties serviceProperties) { - this.serviceProperties = serviceProperties; - } - - public String message() { - return this.serviceProperties.getMessage(); - } -} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java deleted file mode 100644 index 5931a78..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/ServiceProperties.java +++ /dev/null @@ -1,21 +0,0 @@ -package ca.etsmtl.taf.testrail.service; - - -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties("service") -public class ServiceProperties { - - /** - * A message for the service. - */ - private String message; - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java new file mode 100644 index 0000000..34c9f68 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java @@ -0,0 +1,14 @@ +package ca.etsmtl.taf.testrail.service.load.data; + +public interface LoadData { + /* + * Interface for loading data from TestRail. + * The methods need to be implemented in the classes that will load the data. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + void loadById(int id); + void loadByName(String name); + void loadAll(); +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java new file mode 100644 index 0000000..9218928 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java @@ -0,0 +1,35 @@ +package ca.etsmtl.taf.testrail.service.load.data; + + +import lombok.Getter; +import lombok.Setter; +import org.springframework.stereotype.Component; + +@Getter +@Setter +@Component +public class LoadProject implements LoadData { + /* + * TODO + * This class is used to load project data from TestRail. + * The methods need to be implemented in the classes that will load the data. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + + @Override + public void loadById(int id) { + // TODO + } + + @Override + public void loadByName(String name) { + // TODO + } + + @Override + public void loadAll() { + // TODO + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java new file mode 100644 index 0000000..65f8917 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java @@ -0,0 +1,64 @@ +package ca.etsmtl.taf.testrail.service.query; + +import org.springframework.stereotype.Component; + +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Optional; + + +public class HttpSenderToTestRail { + /* + * This class is used to send HTTP requests to TestRail. + * The static variables assignment need recoded to work with application properties. + * The logs methods needs to be re-implemented with stronger logging. + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + */ + + private static final String baseUrl = "https://leofornoff.testrail.io/index.php?/api/v2/"; + private static final String username = "leo.fornoff.1@ens.etsmtl.ca"; + private static final String password = "Valid8-Outpost2-Caravan0-Unlovable9-Easter7"; + + public HttpSenderToTestRail() { + // TODO : baseUrl, username and password will depend on the user + } + + private Optional send(HttpRequest request) { + try { + HttpClient client = HttpClient.newHttpClient(); + HttpResponse response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() == 200) { + return Optional.of(response.body()); + } else { + return Optional.empty(); + } + } catch (Exception e) { + e.printStackTrace(); // TODO : improve logging + return Optional.empty(); + } + } + + public Optional postSender(String route, String body) { + HttpRequest request = HttpRequest.newBuilder() + .uri(java.net.URI.create(baseUrl + route)) + .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((username + ":" + password).getBytes())) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(body)) + .build(); + + return send(request); + } + + public Optional getSender(String route) { + HttpRequest request = HttpRequest.newBuilder() + .uri(java.net.URI.create(baseUrl + route)) + .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((username + ":" + password).getBytes())) + .GET() + .build(); + + return send(request); + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java new file mode 100644 index 0000000..a0649b2 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java @@ -0,0 +1,159 @@ +package ca.etsmtl.taf.testrail.service.query; + +import ca.etsmtl.taf.testrail.model.entity.TestRailData; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.net.http.HttpResponse; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + + + +public class ProjectQueryTestRail implements QueryTestRail { + + /* + * Class that contains common requests about TestRail projects + * This class doesn't save the data, it only queries TestRail + * This class doesn't check if data is already loaded or in the database + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + private final HttpSenderToTestRail httpSenderToTestRail; + + public ProjectQueryTestRail(HttpSenderToTestRail httpSenderToTestRail) { + this.httpSenderToTestRail = httpSenderToTestRail; + } + + + @Override + public List getAll() { + /* + * Query TestRail to get all projects accessible to the user + * @return List of TestRailProject objects + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + String route = "get_projects"; + Optional body = httpSenderToTestRail.getSender(route); + + if (body.isEmpty()) { + return new ArrayList<>(); + } + + // If response is correct, Body is a JSON object with a list of projects + // It contains a list of projects which are converted to TestRailProject objects + + try { + JSONObject jsonResponse = new JSONObject(body.get()); + JSONArray projectsArray = jsonResponse.getJSONArray("projects"); + List projects = new ArrayList<>(); + + for (int i = 0; i < projectsArray.length(); i++) { + JSONObject projectJson = projectsArray.getJSONObject(i); + TestRailProject project = TestRailProjectFactory.create(projectJson); // Create a TestRailProject object from the JSON object + projects.add(project); + } + + return projects; + } catch (JSONException e) { + e.printStackTrace(); // TODO: improve logging + return new ArrayList<>(); + } + + } + + @Override + public TestRailData addNew(String projectName) { + /* + * Add a new project to TestRail + * @param projectName : name of the project to add + * @return TestRailProject object + * @Use getByName to get the project added + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + // Send a post request to add a new project + String route = "add_project"; + HttpResponse response = null; + Optional body = httpSenderToTestRail.postSender(route, "{\"name\":\"" + projectName + "\"}"); + + // Check if the response is successful + + if (body.isEmpty()) { + System.err.println("Erreur lors de l'ajout du projet"); + return null; + } + + // Use getByName to get the project added + return getByName(projectName); + } + + @Override + public TestRailData getById(int id) { + + /* + * Query TestRail to get a project by its ID + * @param id : ID of the project to get + * @return TestRailProject object + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + // Build the route for the API + String route = "get_project/" + id; + + // Send the GET request via httpSenderToTestRail + Optional body = httpSenderToTestRail.getSender(route); + + // Check if the response body is present + if (body.isEmpty()) { + System.err.println("Projet avec l'ID " + id + " non trouvé."); + return null; + } + + // Convert the JSON response to a TestRailData object + try { + JSONObject projectJson = new JSONObject(body.get()); + return TestRailProjectFactory.create(projectJson); // Crée un objet TestRailData (TestRailProject) à partir du JSON + } catch (JSONException e) { + e.printStackTrace(); // TODO: Améliorer la gestion des erreurs + return null; + } + } + + @Override + public TestRailData getByName(String name) { + /* + * Query TestRail to get a project by its name + * @param name : name of the project to get + * @return TestRailProject object + * Use getAll to get all projects and search the project by name + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + // Retrieve all projects + List allProjects = getAll(); + + // Search for the project with the desired name + for (TestRailData project : allProjects) { + if (((TestRailProject) project).getName().equals(name)) { + return project; + } + } + + // If no project with the given name is found, return null or throw an exception if necessary + System.err.println("Project with the name \"" + name + "\" not found."); // TODO: improve logging + return null; + } +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java new file mode 100644 index 0000000..fdbeb9e --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java @@ -0,0 +1,21 @@ +package ca.etsmtl.taf.testrail.service.query; + +import ca.etsmtl.taf.testrail.model.entity.TestRailData; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; + +import java.util.List; + +interface QueryTestRail { + /* + * Interface that contains common requests about TestRail data + * Those methods are implemented in the classes that will query TestRail + * */ + + TestRailData getById(int id); + + TestRailData getByName(String name); + + List getAll(); + + TestRailData addNew(String name); +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java new file mode 100644 index 0000000..468da1c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java @@ -0,0 +1,6 @@ +package ca.etsmtl.taf.testrail.service.refresh.data; + +public interface Refresh { + void refresh(String name); + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java new file mode 100644 index 0000000..1157d9f --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java @@ -0,0 +1,18 @@ +package ca.etsmtl.taf.testrail.service.refresh.data; + +public class RefreshProject implements Refresh { + /* + * Class to refresh data from TestRail. + * Class build assisted by IA (copilot & chatGPT & intellij) + * */ + + @Override + public void refresh(String name) { + /* + * Update a project in the database. + * */ + + // Search if the project exists in the database + //TODO + } +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java new file mode 100644 index 0000000..364858c --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java @@ -0,0 +1,9 @@ +package ca.etsmtl.taf.testrail; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = "ca.etsmtl.taf.testrail.service") +public class TestConfig { +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java deleted file mode 100644 index 407ca82..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/MyServiceTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package ca.etsmtl.taf.testrail.service; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest("service.message=Hello") -public class MyServiceTest { - -} \ No newline at end of file From 7eb8c629812051c6823d66948f07a54d2a3c1c47 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 13:39:01 -0400 Subject: [PATCH 11/56] Update architecture && create service and repository for TestRailProject --- .../repository/TestRailProjectRepository.java | 16 +++++++++ .../service/data/TestRailProjectService.java | 36 +++++++++++++++++++ .../{load/data => query/load}/LoadData.java | 2 +- .../data => query/load}/LoadProject.java | 2 +- .../data => query/refresh}/Refresh.java | 2 +- .../refresh}/RefreshProject.java | 2 +- .../unit/data/unitTestRailProject.java | 19 ++++++++++ 7 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{load/data => query/load}/LoadData.java (86%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{load/data => query/load}/LoadProject.java (92%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{refresh/data => query/refresh}/Refresh.java (57%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{refresh/data => query/refresh}/RefreshProject.java (87%) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java new file mode 100644 index 0000000..32586dc --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java @@ -0,0 +1,16 @@ +package ca.etsmtl.taf.testrail.repository; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface TestRailProjectRepository extends JpaRepository { + + Optional findByTafId(Long tafId); + + Optional findById(Integer id); + + Optional findByName(String name); + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java new file mode 100644 index 0000000..efe9b2c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java @@ -0,0 +1,36 @@ +package ca.etsmtl.taf.testrail.service.data; + + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class TestRailProjectService { + + @Autowired + private TestRailProjectRepository testRailProjectRepository; + + public TestRailProject save(TestRailProject project) { + return testRailProjectRepository.save(project); + } + + public Optional findByTafId(Long tafId) { + return testRailProjectRepository.findByTafId(tafId); + } + + public Optional findById(Integer id) { + return testRailProjectRepository.findById(id); + } + + public Optional findByName(String name) { + return testRailProjectRepository.findByName(name); + } + + public void deleteByTafId(Long tafId) { + testRailProjectRepository.deleteById(tafId); + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java similarity index 86% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java index 34c9f68..84a4870 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadData.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.load.data; +package ca.etsmtl.taf.testrail.service.query.load; public interface LoadData { /* diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java similarity index 92% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java index 9218928..89c3ae9 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/load/data/LoadProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.load.data; +package ca.etsmtl.taf.testrail.service.query.load; import lombok.Getter; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java similarity index 57% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java index 468da1c..18ce7c8 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/Refresh.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.refresh.data; +package ca.etsmtl.taf.testrail.service.query.refresh; public interface Refresh { void refresh(String name); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java similarity index 87% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java index 1157d9f..747ea47 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/refresh/data/RefreshProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.refresh.data; +package ca.etsmtl.taf.testrail.service.query.refresh; public class RefreshProject implements Refresh { /* diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java new file mode 100644 index 0000000..99b9935 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java @@ -0,0 +1,19 @@ +package ca.etsmtl.taf.testrail.unit.data; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class unitTestRailProject { + + private TestRailProject testRailProject; + + @BeforeEach + public void setUp() { + testRailProject = new TestRailProject(); + } + + + + +} \ No newline at end of file From 36c20080a7a96f8d6fdefd856e5205b4439d4516 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 13:51:04 -0400 Subject: [PATCH 12/56] create service and repository for GatlingResult --- .../testrail/model/entity/GatlingResult.java | 11 +++++ .../repository/GatlingResultRepository.java | 11 +++++ .../service/data/GatlingResultService.java | 41 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java index b48b620..f2fc5cd 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingResult.java @@ -4,11 +4,18 @@ import lombok.Getter; import lombok.Setter; +import java.util.Date; + @Entity @Table(name = "tr_gatling_result") @Getter @Setter public class GatlingResult { + /* + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -31,4 +38,8 @@ public class GatlingResult { @Column(name = "assignedto_id") private Integer assignedToId; + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "date") + private Date date; + } \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java new file mode 100644 index 0000000..8270e8e --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java @@ -0,0 +1,11 @@ +package ca.etsmtl.taf.testrail.repository; + +import ca.etsmtl.taf.testrail.model.entity.GatlingResult; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + +public interface GatlingResultRepository extends JpaRepository { + + // Search for GatlingResult by statusId + List findByStatusId(Integer statusId); +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java new file mode 100644 index 0000000..52ce5e3 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java @@ -0,0 +1,41 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.model.entity.GatlingResult; +import ca.etsmtl.taf.testrail.repository.GatlingResultRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class GatlingResultService { + + @Autowired + private GatlingResultRepository repository; + + // Save or update a GatlingResult entity + public GatlingResult save(GatlingResult result) { + return repository.save(result); + } + + // Find a GatlingResult by its unique ID + public Optional findById(Long id) { + return repository.findById(id); + } + + // Retrieve all GatlingResult entries + public List findAll() { + return repository.findAll(); + } + + // Delete a GatlingResult by its unique ID + public void deleteById(Long id) { + repository.deleteById(id); + } + + // Retrieve GatlingResults filtered by statusId + public List findByStatusId(Integer statusId) { + return repository.findByStatusId(statusId); + } +} From 2b5a7db81fdedd7f79048dbb1a4e83dcbd0ebd08 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 13:57:42 -0400 Subject: [PATCH 13/56] create service and repository for GatlingTestCase --- .../repository/GatlingTestCaseRepository.java | 20 ++++++++ .../service/data/GatlingTestCaseService.java | 46 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java new file mode 100644 index 0000000..5ad989d --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java @@ -0,0 +1,20 @@ +package ca.etsmtl.taf.testrail.repository; + +import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + +public interface GatlingTestCaseRepository extends JpaRepository { + /* + * TODO + * To be completed and tested + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + + // Find GatlingTestCase entries by sectionId + List findBySectionId(Integer sectionId); + + // Find GatlingTestCase entries by title + List findByTitle(String title); +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java new file mode 100644 index 0000000..6cb4cd7 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java @@ -0,0 +1,46 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; +import ca.etsmtl.taf.testrail.repository.GatlingTestCaseRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class GatlingTestCaseService { + + @Autowired + private GatlingTestCaseRepository repository; + + // Save or update a GatlingTestCase entity + public GatlingTestCase save(GatlingTestCase testCase) { + return repository.save(testCase); + } + + // Find a GatlingTestCase by its unique ID + public Optional findById(Long id) { + return repository.findById(id); + } + + // Retrieve all GatlingTestCase entries + public List findAll() { + return repository.findAll(); + } + + // Delete a GatlingTestCase by its unique ID + public void deleteById(Long id) { + repository.deleteById(id); + } + + // Retrieve GatlingTestCase entries filtered by sectionId + public List findBySectionId(Integer sectionId) { + return repository.findBySectionId(sectionId); + } + + // Retrieve GatlingTestCase entries filtered by title + public List findByTitle(String title) { + return repository.findByTitle(title); + } +} From a41bfa82b500cfb5ff905dfd0013e28232ceed47 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:01:24 -0400 Subject: [PATCH 14/56] create service and repository for TestRailUser --- .../repository/TestRailUserRepository.java | 14 ++++++ .../service/data/TestRailUserService.java | 46 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java new file mode 100644 index 0000000..0b2de1c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java @@ -0,0 +1,14 @@ +package ca.etsmtl.taf.testrail.repository; + +import ca.etsmtl.taf.testrail.model.entity.TestRailUser; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + +public interface TestRailUserRepository extends JpaRepository { + + // Find a TestRailUser by their unique username + Optional findByUsername(String username); + + // Find a TestRailUser by their unique email + Optional findByEmail(String email); +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java new file mode 100644 index 0000000..4a9a1ff --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java @@ -0,0 +1,46 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.model.entity.TestRailUser; +import ca.etsmtl.taf.testrail.repository.TestRailUserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class TestRailUserService { + + @Autowired + private TestRailUserRepository repository; + + // Save or update a TestRailUser entity + public TestRailUser save(TestRailUser user) { + return repository.save(user); + } + + // Find a TestRailUser by their unique ID (tafId) + public Optional findById(Long tafId) { + return repository.findById(tafId); + } + + // Find a TestRailUser by their unique username + public Optional findByUsername(String username) { + return repository.findByUsername(username); + } + + // Find a TestRailUser by their unique email + public Optional findByEmail(String email) { + return repository.findByEmail(email); + } + + // Retrieve all TestRailUser entries + public List findAll() { + return repository.findAll(); + } + + // Delete a TestRailUser by their unique ID (tafId) + public void deleteById(Long tafId) { + repository.deleteById(tafId); + } +} From f0408ce4fb85165d327fd1f1924425b475569ad0 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:04:14 -0400 Subject: [PATCH 15/56] Add class comments and TODO notes --- .../model/entity/GatlingTestCase.java | 6 ++++++ .../taf/testrail/model/entity/TestModel.java | 20 ------------------- .../repository/GatlingResultRepository.java | 5 +++++ .../repository/GatlingTestCaseRepository.java | 1 + .../repository/TestRailProjectRepository.java | 7 +++++++ .../repository/TestRailUserRepository.java | 5 +++++ .../service/data/GatlingResultService.java | 6 ++++++ .../service/data/GatlingTestCaseService.java | 7 +++++++ .../service/data/TestRailProjectService.java | 7 +++++++ .../service/data/TestRailUserService.java | 7 +++++++ 10 files changed, 51 insertions(+), 20 deletions(-) delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java index b4b3fec..83754db 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java @@ -9,6 +9,12 @@ @Getter @Setter public class GatlingTestCase { + + /* + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java deleted file mode 100644 index 19cf115..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestModel.java +++ /dev/null @@ -1,20 +0,0 @@ -package ca.etsmtl.taf.testrail.model.entity; - - -import lombok.Getter; -import lombok.Setter; - -import javax.persistence.*; - -@Entity -@Table(name = "test_model") -@Getter -@Setter -public class TestModel { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - private String name; - -} - diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java index 8270e8e..44377bc 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java @@ -5,6 +5,11 @@ import java.util.List; public interface GatlingResultRepository extends JpaRepository { + /* + * This interface is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ // Search for GatlingResult by statusId List findByStatusId(Integer statusId); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java index 5ad989d..9c94a62 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java @@ -6,6 +6,7 @@ public interface GatlingTestCaseRepository extends JpaRepository { /* + * This interface is used to interact with the GatlingTestCase table in the database. * TODO * To be completed and tested * Assisted by IA (copilot & chatGPT & intellij) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java index 32586dc..dd336d7 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java @@ -7,6 +7,13 @@ public interface TestRailProjectRepository extends JpaRepository { + /* + * This interface is used to interact with the TestRailProject table in the database. + * TODO + * To be completed and tested + * Assisted by IA (copilot & chatGPT & intellij) + * */ + Optional findByTafId(Long tafId); Optional findById(Integer id); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java index 0b2de1c..9870140 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java @@ -5,6 +5,11 @@ import java.util.Optional; public interface TestRailUserRepository extends JpaRepository { + /* + * This interface is used to interact with the TestRailUser table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ // Find a TestRailUser by their unique username Optional findByUsername(String username); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java index 52ce5e3..26100a8 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java @@ -10,6 +10,12 @@ @Service public class GatlingResultService { + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ @Autowired private GatlingResultRepository repository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java index 6cb4cd7..a40f1ee 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java @@ -10,6 +10,13 @@ @Service public class GatlingTestCaseService { + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ + @Autowired private GatlingTestCaseRepository repository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java index efe9b2c..ddbbd11 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java @@ -10,6 +10,13 @@ @Service public class TestRailProjectService { + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ + @Autowired private TestRailProjectRepository testRailProjectRepository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java index 4a9a1ff..9ec8d25 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java @@ -10,6 +10,13 @@ @Service public class TestRailUserService { + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ + @Autowired private TestRailUserRepository repository; From 492da56910a9569f163681689155846cf40a7173 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:23:34 -0400 Subject: [PATCH 16/56] Correcting type in database TestRailProject (completed_on) --- .../ca/etsmtl/taf/testrail/model/entity/TestRailProject.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 5e279c9..02c7479 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.Setter; +import java.sql.Timestamp; import java.util.List; @Entity @@ -38,7 +39,7 @@ public class TestRailProject extends TestRailData { private Boolean isCompleted; @Column(name = "completed_on") - private String completedOn; + private Timestamp completedOn; @Column(name = "suite_mode") private Integer suiteMode; From 3577d1e08d246ee63f8d2f73ca947aed1de6367b Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:26:49 -0400 Subject: [PATCH 17/56] Adding unique specification to TestRailUser and TestRailProject --- .../ca/etsmtl/taf/testrail/model/entity/TestRailProject.java | 4 ++-- .../ca/etsmtl/taf/testrail/model/entity/TestRailUser.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 02c7479..2423d52 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -23,10 +23,10 @@ public class TestRailProject extends TestRailData { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long tafId; - @Column(name = "id") + @Column(name = "id", unique = true) private Integer id; - @Column(name = "name", nullable = false) + @Column(name = "name", nullable = false, unique = true) private String name; @Column(name = "announcement") diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java index 2ccb0d2..9fa8e2c 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -28,7 +28,7 @@ public class TestRailUser extends TestRailData { @Column(name = "password", nullable = false) private String password; - @Column(name = "email", nullable = false) + @Column(name = "email", nullable = false, unique = true) private String email; @ManyToMany From ea930abd5e60ff8857a94a6283d55835e89218ff Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:33:51 -0400 Subject: [PATCH 18/56] Correcting TestRailUser and TestRailProject to have id (id from TR) tr_id --- .../taf/testrail/model/entity/TestRailProject.java | 4 ++-- .../taf/testrail/model/entity/TestRailUser.java | 3 +++ .../model/factory/TestRailProjectFactory.java | 2 +- .../repository/TestRailProjectRepository.java | 4 +--- .../testrail/repository/TestRailUserRepository.java | 3 +++ .../service/data/TestRailProjectService.java | 6 +++--- .../testrail/service/data/TestRailUserService.java | 12 ++++++++++++ 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 2423d52..b49d0a1 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -23,8 +23,8 @@ public class TestRailProject extends TestRailData { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long tafId; - @Column(name = "id", unique = true) - private Integer id; + @Column(name = "tr_id", unique = true) + private Integer TRId; @Column(name = "name", nullable = false, unique = true) private String name; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java index 9fa8e2c..67d9f1e 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -22,6 +22,9 @@ public class TestRailUser extends TestRailData { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long tafId; + @Column(name = "tr_id", unique = true) + private Integer TRId; + @Column(name = "username", nullable = false) private String username; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java index 4bc937f..a45df1f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java @@ -31,7 +31,7 @@ public static TestRailProject create(JSONObject projectJson) throws JSONExceptio } if (projectJson.has("id") && !projectJson.isNull("id")) { - project.setId(projectJson.getInt("id")); + project.setTRId(projectJson.getInt("id")); } if (projectJson.has("announcement") && !projectJson.isNull("announcement")) { diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java index dd336d7..227fa70 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java @@ -14,9 +14,7 @@ public interface TestRailProjectRepository extends JpaRepository findByTafId(Long tafId); - - Optional findById(Integer id); + Optional findByTRId(Integer id); Optional findByName(String name); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java index 9870140..7f4085f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java @@ -11,6 +11,9 @@ public interface TestRailUserRepository extends JpaRepository findByTRId(Integer id); + // Find a TestRailUser by their unique username Optional findByUsername(String username); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java index ddbbd11..d2dc6a2 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java @@ -26,11 +26,11 @@ public TestRailProject save(TestRailProject project) { } public Optional findByTafId(Long tafId) { - return testRailProjectRepository.findByTafId(tafId); + return testRailProjectRepository.findById(tafId); } - public Optional findById(Integer id) { - return testRailProjectRepository.findById(id); + public Optional findByTRId(Integer id) { + return testRailProjectRepository.findByTRId(id); } public Optional findByName(String name) { diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java index 9ec8d25..72ea1ab 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java @@ -31,6 +31,11 @@ public Optional findById(Long tafId) { return repository.findById(tafId); } + // Find a TestRailUser by their unique ID (TR id) + public Optional findByTRId(Integer id) { + return repository.findByTRId(id); + } + // Find a TestRailUser by their unique username public Optional findByUsername(String username) { return repository.findByUsername(username); @@ -50,4 +55,11 @@ public List findAll() { public void deleteById(Long tafId) { repository.deleteById(tafId); } + + // Delete all TestRailUser entries + public void deleteAll() { + repository.deleteAll(); + } + + } From 7ea66b111f430bb5c49214b968201b352e6cbaa4 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:37:35 -0400 Subject: [PATCH 19/56] Create TestRailSuite data with repo and service --- .../testrail/model/entity/TestRailSuite.java | 54 +++++++++++++++++++ .../repository/TestRAilSuiteRepository.java | 18 +++++++ .../service/data/TestRailSuiteService.java | 39 ++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java new file mode 100644 index 0000000..a4198e4 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java @@ -0,0 +1,54 @@ +package ca.etsmtl.taf.testrail.model.entity; + +import javax.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.sql.Timestamp; +import java.util.List; + +@Entity +@Table(name = "tr_suite") +@Getter +@Setter +public class TestRailSuite { + + /* + * Class to save suites from TestRail in TAF database to be used in the application. + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long tafId; + + @Column(name = "tr_id", unique = true) + private Integer TRId; + + @ManyToOne + @JoinColumn(name = "project_id", referencedColumnName = "id") + private TestRailProject project; + + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "description") + private String description; + + @Column(name = "is_master") + private Boolean isMaster; + + @Column(name = "is_baseline") + private Boolean isBaseline; + + @Column(name = "is_completed") + private Boolean isCompleted; + + @Column(name = "completed_on") + private Timestamp completedOn; + + @Column(name = "url") + private String url; + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java new file mode 100644 index 0000000..94dc93f --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java @@ -0,0 +1,18 @@ +package ca.etsmtl.taf.testrail.repository; + +import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface TestRAilSuiteRepository extends JpaRepository { + /* + * This interface is used to interact with the TestRailProject table in the database. + * TODO + * To be completed and tested + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + Optional findByTRId(Integer id); + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java new file mode 100644 index 0000000..9d82927 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java @@ -0,0 +1,39 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; +import ca.etsmtl.taf.testrail.repository.TestRAilSuiteRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class TestRailSuiteService { + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ + + @Autowired + private TestRAilSuiteRepository testRAilSuiteRepository; + + public TestRailSuite save(TestRailSuite suite) { + return testRAilSuiteRepository.save(suite); + } + + public Optional findByTafId(Long tafId) { + return testRAilSuiteRepository.findById(tafId); + } + + public Optional findByTRId(Integer id) { + return testRAilSuiteRepository.findByTRId(id); + } + + public void deleteByTafId(Long tafId) { + testRAilSuiteRepository.deleteById(tafId); + } + + +} From 4c74c0787cbe9c2b3d8c1d2941b2f6476efb0fb7 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:38:22 -0400 Subject: [PATCH 20/56] Correct error introduced by changing complete_on format --- .../taf/testrail/model/factory/TestRailProjectFactory.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java index a45df1f..df386ad 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java @@ -4,6 +4,8 @@ import org.json.JSONException; import org.json.JSONObject; +import java.sql.Timestamp; + public class TestRailProjectFactory { public static TestRailProject create(String name) { TestRailProject project = new TestRailProject(); @@ -47,7 +49,7 @@ public static TestRailProject create(JSONObject projectJson) throws JSONExceptio } if (projectJson.has("completed_on") && !projectJson.isNull("completed_on")) { - project.setCompletedOn(String.valueOf(projectJson.getLong("completed_on"))); + project.setCompletedOn(Timestamp.valueOf(String.valueOf(projectJson.getLong("completed_on")))); } if (projectJson.has("suite_mode") && !projectJson.isNull("suite_mode")) { From 0c192796e1e51240c193a2b2b22c09588ea268d9 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:42:09 -0400 Subject: [PATCH 21/56] Adding two factory method to implements TODO --- .../taf/testrail/model/factory/TestRailSuiteFactory.java | 5 +++++ .../taf/testrail/model/factory/TestRailUserFactory.java | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java new file mode 100644 index 0000000..e84c35d --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.model.factory; + +public class TestRailSuiteFactory { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java new file mode 100644 index 0000000..365c9f4 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.model.factory; + +public class TestRailUserFactory { + //TODO +} From f97a62f47390ab72e42a52bbadc8ee4a98aa03c4 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:44:12 -0400 Subject: [PATCH 22/56] Adding unit tests class to create TODO --- .../ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java | 5 +++++ .../etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java | 5 +++++ .../etsmtl/taf/testrail/unit/data/unitTestRailProject.java | 1 + .../ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java | 5 +++++ .../ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java | 5 +++++ 5 files changed, 21 insertions(+) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java new file mode 100644 index 0000000..b1bce6f --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.unit.data; + +public class unitGatlingResult { + // TODO +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java new file mode 100644 index 0000000..d1a8ca4 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.unit.data; + +public class unitGatlingTestCase { + // TODO +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java index 99b9935..59f61ee 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java @@ -13,6 +13,7 @@ public void setUp() { testRailProject = new TestRailProject(); } + // TODO diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java new file mode 100644 index 0000000..45384c5 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.unit.data; + +public class unitTestRailSuite { + // TODO +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java new file mode 100644 index 0000000..944f3a8 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.unit.data; + +public class unitTestRailUser { + // TODO +} From f9b3a08bac27e33a2c9d3e806a20fe1d9492d45a Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:45:18 -0400 Subject: [PATCH 23/56] Adding refresh class to create TODO --- .../taf/testrail/service/query/refresh/RefreshSuite.java | 5 +++++ .../taf/testrail/service/query/refresh/RefreshUser.java | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java new file mode 100644 index 0000000..c26770c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.refresh; + +public class RefreshSuite { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java new file mode 100644 index 0000000..3c062da --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.refresh; + +public class RefreshUser { + // TODO +} From 88c0a1dd2c2739ff75534e44dfc1aa2461318b98 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:46:02 -0400 Subject: [PATCH 24/56] Adding load classes to create TODO --- .../ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java | 5 +++++ .../ca/etsmtl/taf/testrail/service/query/load/LoadUser.java | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java new file mode 100644 index 0000000..e0b2acf --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.load; + +public class LoadSuite { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java new file mode 100644 index 0000000..d3ca3e3 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.load; + +public class LoadUser { + // TODO +} From 8746a8418a5a8d755ce6637ca8a750f63df4a2ca Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:46:46 -0400 Subject: [PATCH 25/56] Refactoring name misspell --- ...tRAilSuiteRepository.java => TestRailSuiteRepository.java} | 2 +- .../taf/testrail/service/data/TestRailSuiteService.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename testrail/src/main/java/ca/etsmtl/taf/testrail/repository/{TestRAilSuiteRepository.java => TestRailSuiteRepository.java} (88%) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java similarity index 88% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java index 94dc93f..991ec3f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRAilSuiteRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java @@ -5,7 +5,7 @@ import java.util.Optional; -public interface TestRAilSuiteRepository extends JpaRepository { +public interface TestRailSuiteRepository extends JpaRepository { /* * This interface is used to interact with the TestRailProject table in the database. * TODO diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java index 9d82927..0ff464f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java @@ -1,7 +1,7 @@ package ca.etsmtl.taf.testrail.service.data; import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; -import ca.etsmtl.taf.testrail.repository.TestRAilSuiteRepository; +import ca.etsmtl.taf.testrail.repository.TestRailSuiteRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,7 +17,7 @@ public class TestRailSuiteService { * */ @Autowired - private TestRAilSuiteRepository testRAilSuiteRepository; + private TestRailSuiteRepository testRAilSuiteRepository; public TestRailSuite save(TestRailSuite suite) { return testRAilSuiteRepository.save(suite); From e7a2bd83f1a8c85e3291dd931cd5700c4ee8cbb1 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:49:34 -0400 Subject: [PATCH 26/56] Creation files for TestRailTestCase TODO --- .../ca/etsmtl/taf/testrail/model/entity/TestRailCase.java | 5 +++++ .../taf/testrail/model/factory/TestRailCaseFactory.java | 4 ++++ .../taf/testrail/repository/TestRailCaseRepository.java | 5 +++++ .../taf/testrail/service/data/TestRailCaseService.java | 5 +++++ .../ca/etsmtl/taf/testrail/service/query/load/LoadCase.java | 5 +++++ .../taf/testrail/service/query/refresh/RefreshCase.java | 5 +++++ 6 files changed, 29 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java new file mode 100644 index 0000000..9c46488 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.model.entity; + +public class TestRailCase { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java new file mode 100644 index 0000000..0660928 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java @@ -0,0 +1,4 @@ +package ca.etsmtl.taf.testrail.model.factory; + +public class TestRailCaseFactory { +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java new file mode 100644 index 0000000..9769b5b --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.repository; + +public interface TestRailCaseRepository { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java new file mode 100644 index 0000000..8b7b7ba --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.data; + +public class TestRailCaseService { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java new file mode 100644 index 0000000..f14121a --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.load; + +public class LoadCase { + // TODO +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java new file mode 100644 index 0000000..29c762a --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.query.refresh; + +public class RefreshCase { + // TODO +} From 6c851b0ac9b9ad2071524a9126dc4da0de1e9867 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 27 Oct 2024 14:58:31 -0400 Subject: [PATCH 27/56] Patching bug hibernate about id name in database --- .../ca/etsmtl/taf/testrail/model/entity/TestRailProject.java | 2 +- .../ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java | 3 +-- .../java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index b49d0a1..724ebe3 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -21,7 +21,7 @@ public class TestRailProject extends TestRailData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long tafId; + private Long id; @Column(name = "tr_id", unique = true) private Integer TRId; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java index a4198e4..544d33d 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java @@ -5,7 +5,6 @@ import lombok.Setter; import java.sql.Timestamp; -import java.util.List; @Entity @Table(name = "tr_suite") @@ -21,7 +20,7 @@ public class TestRailSuite { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long tafId; + private Long id; @Column(name = "tr_id", unique = true) private Integer TRId; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java index 67d9f1e..b6c0759 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -20,7 +20,7 @@ public class TestRailUser extends TestRailData { * */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long tafId; + private Long id; @Column(name = "tr_id", unique = true) private Integer TRId; From 6ea5433d29a4e6235a80c2970a20fe3e951af80b Mon Sep 17 00:00:00 2001 From: yanth Date: Sun, 27 Oct 2024 23:51:07 -0400 Subject: [PATCH 28/56] [feat] Gatling script parser --- .../testrail/service/TempTestCaseGatling.java | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java index ad1542e..5654bf3 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java @@ -5,35 +5,61 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.logging.Logger; +import java.util.logging.Level; +import java.util.logging.ConsoleHandler; +import java.util.logging.FileHandler; +import java.util.logging.SimpleFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class TempTestCaseGatling { + private static final Logger logger = Logger.getLogger(TempTestCaseGatling.class.getName()); private String baseUrl; private String scenario; private Map usersInjection = new HashMap<>(); public static void main(String[] args) { String SimulationPath = "backend/src/main/resources/testrail/SimpleSimulation.java"; - + String gatlingScript = ""; try (BufferedReader reader = new BufferedReader(new FileReader(SimulationPath))) { String line; while ((line = reader.readLine()) != null) { - String[] words = line.split(" "); - if (words.length > 0) { - if (words[0].equals("HttpProtocolBuilder")) { - while (!line[-1].equals(";")) { - HttpProcotolBuilder.parse(line); - } - } - if (words[0].equals("Scenario")) { - System.out.println("scenario: " + words[1]); - } - if (words[0].equals("rampUsers")) { - System.out.println("usersInjection: " + words[1]); - } - } - System.out.println(line); + gatlingScript += line + "\n"; } } catch (IOException e) { e.printStackTrace(); } + + // Regex patterns to match the different elements + Pattern baseUrlPattern = Pattern.compile("baseUrl\\(\"([^\"]+)\"\\)"); + Pattern scenarioTitlePattern = Pattern.compile("scenario\\(\"([^\"]+)\"\\)"); + Pattern requestPattern = Pattern.compile("exec\\(http\\(\"([^\"]+)\"\\)\\s*\\.get\\(\"([^\"]+)\"\\)\\);"); + Pattern userInjectionPattern = Pattern.compile("setUp(\\(.*?);", Pattern.DOTALL); + + // Extract base URL + Matcher baseUrlMatcher = baseUrlPattern.matcher(gatlingScript); + if (baseUrlMatcher.find()) { + System.out.println("Base URL: " + baseUrlMatcher.group(1)); + } + + // Extract scenario title + Matcher scenarioTitleMatcher = scenarioTitlePattern.matcher(gatlingScript); + if (scenarioTitleMatcher.find()) { + System.out.println("Scenario Title: " + scenarioTitleMatcher.group(1)); + } + + // Extract scenario requests + Matcher requestMatcher = requestPattern.matcher(gatlingScript); + while (requestMatcher.find()) { + System.out.println("Request Title: " + requestMatcher.group(1)); + System.out.println("Request Path: " + requestMatcher.group(2)); + } + + // Extract user injection + Matcher userInjectionMatcher = userInjectionPattern.matcher(gatlingScript); + if (userInjectionMatcher.find()) { + System.out.println("User Injection: " + userInjectionMatcher.group(1)); + } } } \ No newline at end of file From 95d1d8762bf4c9198ea1776192be267b294dd8dd Mon Sep 17 00:00:00 2001 From: moshi Date: Mon, 28 Oct 2024 19:10:12 -0400 Subject: [PATCH 29/56] Meeting 28-10-24 --- testrail/pom.xml | 6 +++ .../testrail/model/entity/TestRailCase.java | 2 +- .../model/entity/TestRailProject.java | 2 +- .../testrail/model/entity/TestRailSuite.java | 2 +- .../model/factory/TestRailProjectFactory.java | 2 + .../repository/GatlingResultRepository.java | 3 ++ .../repository/GatlingTestCaseRepository.java | 3 ++ .../repository/TestRailCaseRepository.java | 3 ++ .../repository/TestRailProjectRepository.java | 2 + .../repository/TestRailSuiteRepository.java | 2 + .../repository/TestRailUserRepository.java | 4 ++ .../service/data/TestRailCaseService.java | 3 ++ .../service/data/TestRailProjectService.java | 2 +- .../service/query/ProjectQueryTestRail.java | 5 +- .../ca/etsmtl/taf/testrail/TestConfig.java | 16 ++++++- .../service/data/TestUnitTestRailProject.java | 48 +++++++++++++++++++ .../unit/data/unitTestRailProject.java | 20 -------- 17 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java diff --git a/testrail/pom.xml b/testrail/pom.xml index 828d55b..a4d6bb1 100644 --- a/testrail/pom.xml +++ b/testrail/pom.xml @@ -34,6 +34,12 @@ provided
+ + com.h2database + h2 + test + + diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java index 9c46488..020e119 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java @@ -1,5 +1,5 @@ package ca.etsmtl.taf.testrail.model.entity; -public class TestRailCase { +public class TestRailCase extends TestRailData{ // TODO } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 724ebe3..05cf9bd 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -23,7 +23,7 @@ public class TestRailProject extends TestRailData { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "tr_id", unique = true) + @Column(name = "tr_id", unique = true, nullable = true) private Integer TRId; @Column(name = "name", nullable = false, unique = true) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java index 544d33d..fcca966 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java @@ -10,7 +10,7 @@ @Table(name = "tr_suite") @Getter @Setter -public class TestRailSuite { +public class TestRailSuite extends TestRailData{ /* * Class to save suites from TestRail in TAF database to be used in the application. diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java index df386ad..6e4c271 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailProjectFactory.java @@ -3,9 +3,11 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import org.json.JSONException; import org.json.JSONObject; +import org.springframework.stereotype.Component; import java.sql.Timestamp; + public class TestRailProjectFactory { public static TestRailProject create(String name) { TestRailProject project = new TestRailProject(); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java index 44377bc..3ae3788 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingResultRepository.java @@ -2,8 +2,11 @@ import ca.etsmtl.taf.testrail.model.entity.GatlingResult; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + import java.util.List; +@Repository public interface GatlingResultRepository extends JpaRepository { /* * This interface is used to interact with the GatlingResult table in the database. diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java index 9c94a62..1f39491 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/GatlingTestCaseRepository.java @@ -2,8 +2,11 @@ import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + import java.util.List; +@Repository public interface GatlingTestCaseRepository extends JpaRepository { /* * This interface is used to interact with the GatlingTestCase table in the database. diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java index 9769b5b..cc8c28d 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java @@ -1,5 +1,8 @@ package ca.etsmtl.taf.testrail.repository; +import org.springframework.stereotype.Repository; + +@Repository public interface TestRailCaseRepository { // TODO } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java index 227fa70..9a60796 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java @@ -2,9 +2,11 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.util.Optional; +@Repository public interface TestRailProjectRepository extends JpaRepository { /* diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java index 991ec3f..ea39771 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java @@ -2,9 +2,11 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.util.Optional; +@Repository public interface TestRailSuiteRepository extends JpaRepository { /* * This interface is used to interact with the TestRailProject table in the database. diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java index 7f4085f..1fd51cf 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java @@ -2,8 +2,12 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailUser; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + import java.util.Optional; + +@Repository public interface TestRailUserRepository extends JpaRepository { /* * This interface is used to interact with the TestRailUser table in the database. diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java index 8b7b7ba..569b139 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java @@ -1,5 +1,8 @@ package ca.etsmtl.taf.testrail.service.data; +import org.springframework.stereotype.Service; + +@Service public class TestRailCaseService { // TODO } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java index d2dc6a2..9c49029 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java @@ -22,7 +22,7 @@ public class TestRailProjectService { private TestRailProjectRepository testRailProjectRepository; public TestRailProject save(TestRailProject project) { - return testRailProjectRepository.save(project); + return testRailProjectRepository.save(project); } public Optional findByTafId(Long tafId) { diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java index a0649b2..342f6b2 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java @@ -28,8 +28,9 @@ public class ProjectQueryTestRail implements QueryTestRail { private final HttpSenderToTestRail httpSenderToTestRail; - public ProjectQueryTestRail(HttpSenderToTestRail httpSenderToTestRail) { - this.httpSenderToTestRail = httpSenderToTestRail; + + public ProjectQueryTestRail() { + this.httpSenderToTestRail = new HttpSenderToTestRail(); // TODO : adapt to each user and environment } diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java index 364858c..3f9d058 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/TestConfig.java @@ -1,9 +1,23 @@ package ca.etsmtl.taf.testrail; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration -@ComponentScan(basePackages = "ca.etsmtl.taf.testrail.service") +@ComponentScan(basePackages = "ca.etsmtl.taf.testrail") +@EnableJpaRepositories(basePackages = "ca.etsmtl.taf.testrail.repository") +@EntityScan(basePackages = "ca.etsmtl.taf.testrail.model.entity") public class TestConfig { + + public static String getRandomString(int length) { + String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + StringBuilder result = new StringBuilder(); + for (int i = 0; i < length; i++) { + int index = (int) (Math.random() * characters.length()); + result.append(characters.charAt(index)); + } + return result.toString(); + } } diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java new file mode 100644 index 0000000..dc8ddcf --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java @@ -0,0 +1,48 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; +import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; + +import java.time.LocalDate; +import java.time.LocalTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ContextConfiguration(classes = TestConfig.class) +@DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" +}) +public class TestUnitTestRailProject { + + private TestRailProject testRailProject; + private String defaultName; + + @Autowired + private TestRailProjectService testRailProjectService; + + @BeforeEach + public void setUp() { + defaultName = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + testRailProject = TestRailProjectFactory.create(defaultName); + } + + @Test + public void testSave() { + testRailProject.setTRId(1); + TestRailProject savedTestRailProject = testRailProjectService.save(testRailProject); + System.out.println("savedTestRailProject : " + savedTestRailProject); + assertNotNull(savedTestRailProject); + assertEquals(testRailProject, savedTestRailProject); + assertEquals(defaultName, savedTestRailProject.getName()); + } +} \ No newline at end of file diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java deleted file mode 100644 index 59f61ee..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailProject.java +++ /dev/null @@ -1,20 +0,0 @@ -package ca.etsmtl.taf.testrail.unit.data; - -import ca.etsmtl.taf.testrail.model.entity.TestRailProject; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class unitTestRailProject { - - private TestRailProject testRailProject; - - @BeforeEach - public void setUp() { - testRailProject = new TestRailProject(); - } - - // TODO - - - -} \ No newline at end of file From c6b58169ae6f8320656d4ebce75d0a570825627a Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 29 Oct 2024 14:03:14 -0400 Subject: [PATCH 30/56] [fix] Logging and parsing gatling project --- .../testrail/service/TempResultGatling.java | 5 -- .../service/collector/TempResultGatling.java | 5 ++ .../{ => collector}/TempTestCaseGatling.java | 46 ++++++++++++++----- 3 files changed, 39 insertions(+), 17 deletions(-) delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempResultGatling.java rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => collector}/TempTestCaseGatling.java (58%) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java deleted file mode 100644 index 5f2952b..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempResultGatling.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service; - -public class TempResultGatling { - -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempResultGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempResultGatling.java new file mode 100644 index 0000000..3a8d873 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempResultGatling.java @@ -0,0 +1,5 @@ +package ca.etsmtl.taf.testrail.service.collector; + +public class TempResultGatling { + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java similarity index 58% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java index 5654bf3..f2b9e85 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java @@ -1,14 +1,13 @@ -package ca.etsmtl.taf.testrail.service; +package ca.etsmtl.taf.testrail.service.collector; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.logging.FileHandler; import java.util.logging.Logger; import java.util.logging.Level; -import java.util.logging.ConsoleHandler; -import java.util.logging.FileHandler; import java.util.logging.SimpleFormatter; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -16,11 +15,27 @@ public class TempTestCaseGatling { private static final Logger logger = Logger.getLogger(TempTestCaseGatling.class.getName()); + + static { + try { + FileHandler fileHandler = new FileHandler("logs/TempTestCaseGatling.log", true); + fileHandler.setFormatter(new SimpleFormatter()); + logger.addHandler(fileHandler); + } catch (Exception e) { + logger.severe("Erreur de configuration du FileHandler."); + } + } + + private String scenarioName; + private String requestName; private String baseUrl; - private String scenario; + private static String userInjection; + private Map usersInjection = new HashMap<>(); - public static void main(String[] args) { + public void parse() { + logger.setLevel(Level.INFO); String SimulationPath = "backend/src/main/resources/testrail/SimpleSimulation.java"; + logger.info("SimulationPath=" + SimulationPath); String gatlingScript = ""; try (BufferedReader reader = new BufferedReader(new FileReader(SimulationPath))) { String line; @@ -31,7 +46,6 @@ public static void main(String[] args) { e.printStackTrace(); } - // Regex patterns to match the different elements Pattern baseUrlPattern = Pattern.compile("baseUrl\\(\"([^\"]+)\"\\)"); Pattern scenarioTitlePattern = Pattern.compile("scenario\\(\"([^\"]+)\"\\)"); Pattern requestPattern = Pattern.compile("exec\\(http\\(\"([^\"]+)\"\\)\\s*\\.get\\(\"([^\"]+)\"\\)\\);"); @@ -40,26 +54,34 @@ public static void main(String[] args) { // Extract base URL Matcher baseUrlMatcher = baseUrlPattern.matcher(gatlingScript); if (baseUrlMatcher.find()) { - System.out.println("Base URL: " + baseUrlMatcher.group(1)); + logger.info("Base URL: " + baseUrlMatcher.group(1)); + } else { + logger.warning("Base URL not found in the Gatling script."); } // Extract scenario title Matcher scenarioTitleMatcher = scenarioTitlePattern.matcher(gatlingScript); if (scenarioTitleMatcher.find()) { - System.out.println("Scenario Title: " + scenarioTitleMatcher.group(1)); + logger.info("Scenario Title: " + scenarioTitleMatcher.group(1)); + } else { + logger.warning("Scenario title not found in the Gatling script."); } // Extract scenario requests Matcher requestMatcher = requestPattern.matcher(gatlingScript); - while (requestMatcher.find()) { - System.out.println("Request Title: " + requestMatcher.group(1)); - System.out.println("Request Path: " + requestMatcher.group(2)); + if (requestMatcher.find()) { + logger.info("Request: " + requestMatcher.group(1) + " - " + requestMatcher.group(2)); + } else { + logger.warning("Requests not found in the Gatling script."); } // Extract user injection Matcher userInjectionMatcher = userInjectionPattern.matcher(gatlingScript); if (userInjectionMatcher.find()) { - System.out.println("User Injection: " + userInjectionMatcher.group(1)); + userInjection = String sansEspaces = str.replaceAll("\\s", ""); + logger.info("User Injection: " + userInjectionMatcher.group(1)); + } else { + logger.warning("User injection not found in the Gatling script."); } } } \ No newline at end of file From 2a25bf009b4b18d69b3328c9d21fe48abff1f935 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 14:19:23 -0400 Subject: [PATCH 31/56] ajout code Entity/TestRailCase --- .../testrail/model/entity/TestRailCase.java | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java index 020e119..c106dfe 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java @@ -1,5 +1,69 @@ package ca.etsmtl.taf.testrail.model.entity; + +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table(name = "tr_case") +@Getter +@Setter public class TestRailCase extends TestRailData{ - // TODO + /* + * Class to save cases from TestRail in TAF database to be used in the application. + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + @Id@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "tr_id", unique = true, nullable = true) + private Integer TRId; + + @Column(name = "title", nullable = false, unique = true) + private String title; + + @Column(name = "section_id") + private Integer sectionId; + + @Column(name = "type_id") + private Integer typeId; + + @Column(name = "priority_id") + private Integer priorityId; + + @Column(name = "milestone_id") + private Integer milestoneId; + + @Column(name = "refs") + private String refs; + + @Column(name = "created_by") + private Integer createdBy; + + @Column(name = "created_on") + private Timestamp createdOn; + + @Column(name = "updated_by") + private Integer updatedBy; + + @Column(name = "updated_on") + private Timestamp updatedOn; + + @Column(name = "estimate") + private Timestamp estimate; + + @Column(name = "estimate_forecast") + private Timestamp estimateForecast; + + @Column(name = "suite_id") + private Integer suiteId; + + @Column(name = "template_id") + private Integer templateId; + } From c64145fbf5fd204bf59c90858cc7c2b72dd17d06 Mon Sep 17 00:00:00 2001 From: moshi Date: Tue, 29 Oct 2024 14:26:57 -0400 Subject: [PATCH 32/56] Exemples de tests --- .../service/data/TestRailProjectService.java | 4 + .../service/data/TestUnitTestRailProject.java | 112 +++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java index 9c49029..d25a1d8 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailProjectService.java @@ -40,4 +40,8 @@ public Optional findByName(String name) { public void deleteByTafId(Long tafId) { testRailProjectRepository.deleteById(tafId); } + + public void deleteAll() { + testRailProjectRepository.deleteAll(); + } } diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java index dc8ddcf..97a6e97 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java @@ -4,6 +4,7 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -11,6 +12,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; +import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalTime; @@ -32,17 +34,125 @@ public class TestUnitTestRailProject { @BeforeEach public void setUp() { + testRailProjectService.deleteAll(); // Drop all data from the table defaultName = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); testRailProject = TestRailProjectFactory.create(defaultName); + } @Test public void testSave() { + // Arrange testRailProject.setTRId(1); + + // Act TestRailProject savedTestRailProject = testRailProjectService.save(testRailProject); - System.out.println("savedTestRailProject : " + savedTestRailProject); + + // Assert assertNotNull(savedTestRailProject); assertEquals(testRailProject, savedTestRailProject); assertEquals(defaultName, savedTestRailProject.getName()); + } + + @Test + public void testUpdate() { + + // ID + + // Arrange + testRailProject.setTRId(2); + + // Act + TestRailProject savedTestRailProject = testRailProjectService.save(testRailProject); + + // Assert + assertNotNull(savedTestRailProject); + assertEquals(testRailProject, savedTestRailProject); + assertEquals(defaultName, savedTestRailProject.getName()); + assertEquals(2, savedTestRailProject.getTRId()); + + // Updated Name + + String updatedName = "updatedName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + savedTestRailProject.setName(updatedName); + TestRailProject updatedTestRailProject = testRailProjectService.save(savedTestRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + System.out.println("updatedTestRailProject : " + updatedTestRailProject); + + assertNotNull(updatedTestRailProject); + assertEquals(savedTestRailProject, updatedTestRailProject); + assertEquals(updatedName, updatedTestRailProject.getName()); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedTestRailProject, getTestRailProject); + + // Updated announcement + + String updatedAnnouncement = "updatedAnnouncement_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + updatedTestRailProject.setAnnouncement(updatedAnnouncement); + TestRailProject updatedTestRailProject2 = testRailProjectService.save(updatedTestRailProject); + TestRailProject getTestRailProject2 = testRailProjectService.findByTRId(2).get(); + + assertNotNull(updatedTestRailProject2); + assertEquals(updatedTestRailProject, updatedTestRailProject2); + assertEquals(updatedAnnouncement, updatedTestRailProject2.getAnnouncement()); + assertEquals(2, updatedTestRailProject2.getTRId()); + assertEquals(updatedTestRailProject2, getTestRailProject2); + + // Updated showAnnouncement + + boolean updatedShowAnnouncement = true; + updatedTestRailProject.setShowAnnouncement(updatedShowAnnouncement); + TestRailProject updatedTestRailProject3 = testRailProjectService.save(updatedTestRailProject2); + TestRailProject getTestRailProject3 = testRailProjectService.findByTRId(2).get(); + + assertNotNull(updatedTestRailProject3); + assertEquals(updatedTestRailProject2, updatedTestRailProject3); + assertEquals(updatedShowAnnouncement, updatedTestRailProject3.getShowAnnouncement()); + assertEquals(2, updatedTestRailProject3.getTRId()); + assertEquals(updatedTestRailProject3, getTestRailProject3); + + // Updated isCompleted + + boolean updatedIsCompleted = true; + updatedTestRailProject2.setIsCompleted(updatedIsCompleted); + TestRailProject updatedTestRailProject4 = testRailProjectService.save(updatedTestRailProject2); + TestRailProject getTestRailProject4 = testRailProjectService.findByTRId(2).get(); + + assertNotNull(updatedTestRailProject4); + assertEquals(updatedTestRailProject2, updatedTestRailProject4); + assertEquals(updatedIsCompleted, updatedTestRailProject4.getIsCompleted()); + assertEquals(2, updatedTestRailProject4.getTRId()); + assertEquals(updatedTestRailProject4, getTestRailProject3); + + // Updated completedOn + + Timestamp updatedCompletedOn = new Timestamp(System.currentTimeMillis()); + updatedTestRailProject2.setCompletedOn(updatedCompletedOn); + TestRailProject updatedTestRailProject5 = testRailProjectService.save(updatedTestRailProject2); + TestRailProject getTestRailProject5 = testRailProjectService.findByTRId(2).get(); + + assertNotNull(updatedTestRailProject5); + assertEquals(updatedTestRailProject2, updatedTestRailProject5); + assertEquals(updatedCompletedOn, updatedTestRailProject5.getCompletedOn()); + assertEquals(2, updatedTestRailProject5.getTRId()); + assertEquals(updatedTestRailProject5, getTestRailProject5); + + // Updated suiteMode + + int updatedSuiteMode = 1; + updatedTestRailProject2.setSuiteMode(updatedSuiteMode); + TestRailProject updatedTestRailProject6 = testRailProjectService.save(updatedTestRailProject2); + TestRailProject getTestRailProject6 = testRailProjectService.findByTRId(2).get(); + + assertNotNull(updatedTestRailProject6); + assertEquals(updatedTestRailProject2, updatedTestRailProject6); + assertEquals(updatedSuiteMode, updatedTestRailProject6.getSuiteMode()); + assertEquals(2, updatedTestRailProject6.getTRId()); + + + + + + } } \ No newline at end of file From 68e092dba89a27ab0ef29e1a8ded63810fb5c417 Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 29 Oct 2024 14:28:14 -0400 Subject: [PATCH 33/56] [fix] userInjection code --- .../service/collector/TempTestCaseGatling.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java index f2b9e85..6a5e42e 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java @@ -1,6 +1,7 @@ package ca.etsmtl.taf.testrail.service.collector; import java.io.BufferedReader; +import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; @@ -18,7 +19,12 @@ public class TempTestCaseGatling { static { try { - FileHandler fileHandler = new FileHandler("logs/TempTestCaseGatling.log", true); + File logDir = new File("./logs"); + if (!logDir.exists()) { + logDir.mkdirs(); // Crée le dossier "logs" si inexistant + } + + FileHandler fileHandler = new FileHandler("./logs/TempTestCaseGatling.log", true); fileHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); } catch (Exception e) { @@ -29,7 +35,7 @@ public class TempTestCaseGatling { private String scenarioName; private String requestName; private String baseUrl; - private static String userInjection; + private String userInjection; private Map usersInjection = new HashMap<>(); public void parse() { @@ -78,7 +84,7 @@ public void parse() { // Extract user injection Matcher userInjectionMatcher = userInjectionPattern.matcher(gatlingScript); if (userInjectionMatcher.find()) { - userInjection = String sansEspaces = str.replaceAll("\\s", ""); + this.userInjection = userInjectionMatcher.replaceAll("\\s"); logger.info("User Injection: " + userInjectionMatcher.group(1)); } else { logger.warning("User injection not found in the Gatling script."); From 6fdd35f08c16a8df14a77b309cbde1e26f546cc9 Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 29 Oct 2024 14:28:37 -0400 Subject: [PATCH 34/56] [test] simple TempTestCaseGatling (just exec) --- .../collector/TestTempTestCaseGatling.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java new file mode 100644 index 0000000..a0918c3 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java @@ -0,0 +1,38 @@ +package ca.etsmtl.taf.testrail.service.collector; + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; +import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; +import ca.etsmtl.taf.testrail.service.collector.TempTestCaseGatling; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; + +import java.time.LocalDate; +import java.time.LocalTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +//@ContextConfiguration(classes = TestConfig.class) +//@DataJpaTest(properties = { +// "spring.jpa.hibernate.ddl-auto=create-drop", +// "spring.datasource.url=jdbc:h2:mem:testdb" +//}) +public class TestTempTestCaseGatling { + private String defaultName; + + @BeforeEach + public void setUp() { + } + + @Test + public void test() { + TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); + tempTestCaseGatling.parse(); + } +} \ No newline at end of file From c2eeef6901aac76319af976637c6d876d130fcaf Mon Sep 17 00:00:00 2001 From: moshi Date: Tue, 29 Oct 2024 14:54:12 -0400 Subject: [PATCH 35/56] Tests unitaires update project --- testrail/Abstract classes.puml | 16 ++ .../service/data/TestUnitTestRailProject.java | 215 +++++++++++++----- 2 files changed, 170 insertions(+), 61 deletions(-) create mode 100644 testrail/Abstract classes.puml diff --git a/testrail/Abstract classes.puml b/testrail/Abstract classes.puml new file mode 100644 index 0000000..b1fdd2f --- /dev/null +++ b/testrail/Abstract classes.puml @@ -0,0 +1,16 @@ +@startuml +'https://plantuml.com/class-diagram + +abstract class TestRailData + +class TestRailProject extends TestRailData + +class TestRailSuite extends TestRailData + +class GenericClassThatUsesTestRailData + +GenericClassThatUsesTestRailData *-- TestRailData + + + +@enduml \ No newline at end of file diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java index 97a6e97..ba8e496 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java @@ -54,105 +54,198 @@ public void testSave() { assertEquals(defaultName, savedTestRailProject.getName()); } - @Test - public void testUpdate() { - - // ID - - // Arrange + public void beforeUpdate() { testRailProject.setTRId(2); + testRailProjectService.save(testRailProject); + } - // Act + @Test + public void testUpdateId() { + /* Arrange */ + beforeUpdate(); + testRailProject.setTRId(3); + + /* Act */ TestRailProject savedTestRailProject = testRailProjectService.save(testRailProject); - // Assert + /* Assert */ assertNotNull(savedTestRailProject); assertEquals(testRailProject, savedTestRailProject); assertEquals(defaultName, savedTestRailProject.getName()); - assertEquals(2, savedTestRailProject.getTRId()); - - // Updated Name + assertEquals(3, savedTestRailProject.getTRId()); + } + @Test + public void testUpdateName() { + /* Arrange */ + beforeUpdate(); String updatedName = "updatedName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); - savedTestRailProject.setName(updatedName); - TestRailProject updatedTestRailProject = testRailProjectService.save(savedTestRailProject); + + /* Act */ + testRailProject.setName(updatedName); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); - System.out.println("updatedTestRailProject : " + updatedTestRailProject); + /* Assert */ assertNotNull(updatedTestRailProject); - assertEquals(savedTestRailProject, updatedTestRailProject); - assertEquals(updatedName, updatedTestRailProject.getName()); assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedName, updatedTestRailProject.getName()); + assertEquals(testRailProject, updatedTestRailProject); assertEquals(updatedTestRailProject, getTestRailProject); + } - // Updated announcement - + @Test + public void testUpdateAnnouncement() { + /* Arrange */ + beforeUpdate(); String updatedAnnouncement = "updatedAnnouncement_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); - updatedTestRailProject.setAnnouncement(updatedAnnouncement); - TestRailProject updatedTestRailProject2 = testRailProjectService.save(updatedTestRailProject); - TestRailProject getTestRailProject2 = testRailProjectService.findByTRId(2).get(); - assertNotNull(updatedTestRailProject2); - assertEquals(updatedTestRailProject, updatedTestRailProject2); - assertEquals(updatedAnnouncement, updatedTestRailProject2.getAnnouncement()); - assertEquals(2, updatedTestRailProject2.getTRId()); - assertEquals(updatedTestRailProject2, getTestRailProject2); + /* Act */ + testRailProject.setAnnouncement(updatedAnnouncement); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); - // Updated showAnnouncement + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedAnnouncement, updatedTestRailProject.getAnnouncement()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + } + @Test + public void testUpdateShowAnnouncement() { + /* Arrange */ + beforeUpdate(); boolean updatedShowAnnouncement = true; - updatedTestRailProject.setShowAnnouncement(updatedShowAnnouncement); - TestRailProject updatedTestRailProject3 = testRailProjectService.save(updatedTestRailProject2); - TestRailProject getTestRailProject3 = testRailProjectService.findByTRId(2).get(); - assertNotNull(updatedTestRailProject3); - assertEquals(updatedTestRailProject2, updatedTestRailProject3); - assertEquals(updatedShowAnnouncement, updatedTestRailProject3.getShowAnnouncement()); - assertEquals(2, updatedTestRailProject3.getTRId()); - assertEquals(updatedTestRailProject3, getTestRailProject3); + /* Act */ + testRailProject.setShowAnnouncement(updatedShowAnnouncement); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); - // Updated isCompleted + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedShowAnnouncement, updatedTestRailProject.getShowAnnouncement()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + } + @Test + public void testUpdateIsCompleted() { + /* Arrange */ + beforeUpdate(); boolean updatedIsCompleted = true; - updatedTestRailProject2.setIsCompleted(updatedIsCompleted); - TestRailProject updatedTestRailProject4 = testRailProjectService.save(updatedTestRailProject2); - TestRailProject getTestRailProject4 = testRailProjectService.findByTRId(2).get(); - assertNotNull(updatedTestRailProject4); - assertEquals(updatedTestRailProject2, updatedTestRailProject4); - assertEquals(updatedIsCompleted, updatedTestRailProject4.getIsCompleted()); - assertEquals(2, updatedTestRailProject4.getTRId()); - assertEquals(updatedTestRailProject4, getTestRailProject3); + /* Act */ + testRailProject.setIsCompleted(updatedIsCompleted); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedIsCompleted, updatedTestRailProject.getIsCompleted()); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedTestRailProject, getTestRailProject); - // Updated completedOn + } + @Test + public void testUpdateCompletedOn() { + /* Arrange */ + beforeUpdate(); Timestamp updatedCompletedOn = new Timestamp(System.currentTimeMillis()); - updatedTestRailProject2.setCompletedOn(updatedCompletedOn); - TestRailProject updatedTestRailProject5 = testRailProjectService.save(updatedTestRailProject2); - TestRailProject getTestRailProject5 = testRailProjectService.findByTRId(2).get(); - assertNotNull(updatedTestRailProject5); - assertEquals(updatedTestRailProject2, updatedTestRailProject5); - assertEquals(updatedCompletedOn, updatedTestRailProject5.getCompletedOn()); - assertEquals(2, updatedTestRailProject5.getTRId()); - assertEquals(updatedTestRailProject5, getTestRailProject5); + /* Act */ + testRailProject.setCompletedOn(updatedCompletedOn); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); - // Updated suiteMode + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedCompletedOn, updatedTestRailProject.getCompletedOn()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + + } + @Test + public void testUpdateSuiteMode() { + /* Arrange */ + beforeUpdate(); int updatedSuiteMode = 1; - updatedTestRailProject2.setSuiteMode(updatedSuiteMode); - TestRailProject updatedTestRailProject6 = testRailProjectService.save(updatedTestRailProject2); - TestRailProject getTestRailProject6 = testRailProjectService.findByTRId(2).get(); - assertNotNull(updatedTestRailProject6); - assertEquals(updatedTestRailProject2, updatedTestRailProject6); - assertEquals(updatedSuiteMode, updatedTestRailProject6.getSuiteMode()); - assertEquals(2, updatedTestRailProject6.getTRId()); + /* Act */ + testRailProject.setSuiteMode(updatedSuiteMode); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedSuiteMode, updatedTestRailProject.getSuiteMode()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + } + @Test + public void testUpdateDefaultRoleId() { + /* Arrange */ + beforeUpdate(); + int updatedDefaultRoleId = 1; + + /* Act */ + testRailProject.setDefaultRoleId(updatedDefaultRoleId); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedDefaultRoleId, updatedTestRailProject.getDefaultRoleId()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + } + @Test + public void testUpdateCaseStatusesEnabled() { + /* Arrange */ + beforeUpdate(); + boolean updatedCaseStatusesEnabled = true; + + /* Act */ + testRailProject.setCaseStatusesEnabled(updatedCaseStatusesEnabled); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedCaseStatusesEnabled, updatedTestRailProject.getCaseStatusesEnabled()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); + } + @Test + public void testUpdateUrl() { + /* Arrange */ + beforeUpdate(); + String updatedUrl = "updatedUrl_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailProject.setUrl(updatedUrl); + TestRailProject updatedTestRailProject = testRailProjectService.save(testRailProject); + TestRailProject getTestRailProject = testRailProjectService.findByTRId(2).get(); + /* Assert */ + assertNotNull(updatedTestRailProject); + assertEquals(2, updatedTestRailProject.getTRId()); + assertEquals(updatedUrl, updatedTestRailProject.getUrl()); + assertEquals(testRailProject, updatedTestRailProject); + assertEquals(updatedTestRailProject, getTestRailProject); } + } \ No newline at end of file From e8ee1f3b60f7399739369b3b55e5eae842f4f374 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 14:54:53 -0400 Subject: [PATCH 36/56] ajout code Repository Case & Suite --- .../repository/TestRailCaseRepository.java | 17 ++++++++++++++++- .../repository/TestRailSuiteRepository.java | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java index cc8c28d..e1b298c 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java @@ -1,8 +1,23 @@ package ca.etsmtl.taf.testrail.repository; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface TestRailCaseRepository { - // TODO + /* + * This interface is used to interact with the TestRailProject table in the database. + * TODO + * To be completed and tested + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + Optional findByTRId(Integer id); + + Optional findByTitle(String title); + + + } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java index ea39771..1362386 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailSuiteRepository.java @@ -17,4 +17,6 @@ public interface TestRailSuiteRepository extends JpaRepository findByTRId(Integer id); + Optional findByName(String name); + } From a93cb1e027f2b40e97de2847773a9292b5575a3f Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 29 Oct 2024 15:05:40 -0400 Subject: [PATCH 37/56] [fix] the Test run with SimpleSimulation.java in testrail module ressources folder --- .../collector/TempTestCaseGatling.java | 31 +++++++++---------- .../src/main/resources/SimpleSimulation.java | 25 +++++++++++++++ 2 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 testrail/src/main/resources/SimpleSimulation.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java index 6a5e42e..6a0933d 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java @@ -1,9 +1,8 @@ package ca.etsmtl.taf.testrail.service.collector; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; +import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; + +import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.logging.FileHandler; @@ -19,6 +18,9 @@ public class TempTestCaseGatling { static { try { + String currentPath = System.getProperty("user.dir"); + logger.info("Chemin de l'exécution : " + currentPath); + File logDir = new File("./logs"); if (!logDir.exists()) { logDir.mkdirs(); // Crée le dossier "logs" si inexistant @@ -40,10 +42,11 @@ public class TempTestCaseGatling { private Map usersInjection = new HashMap<>(); public void parse() { logger.setLevel(Level.INFO); - String SimulationPath = "backend/src/main/resources/testrail/SimpleSimulation.java"; + String SimulationPath = "SimpleSimulation.java"; logger.info("SimulationPath=" + SimulationPath); String gatlingScript = ""; - try (BufferedReader reader = new BufferedReader(new FileReader(SimulationPath))) { + try (InputStream inputStream = TempTestCaseGatling.class.getClassLoader().getResourceAsStream(SimulationPath); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { String line; while ((line = reader.readLine()) != null) { gatlingScript += line + "\n"; @@ -54,7 +57,6 @@ public void parse() { Pattern baseUrlPattern = Pattern.compile("baseUrl\\(\"([^\"]+)\"\\)"); Pattern scenarioTitlePattern = Pattern.compile("scenario\\(\"([^\"]+)\"\\)"); - Pattern requestPattern = Pattern.compile("exec\\(http\\(\"([^\"]+)\"\\)\\s*\\.get\\(\"([^\"]+)\"\\)\\);"); Pattern userInjectionPattern = Pattern.compile("setUp(\\(.*?);", Pattern.DOTALL); // Extract base URL @@ -68,26 +70,23 @@ public void parse() { // Extract scenario title Matcher scenarioTitleMatcher = scenarioTitlePattern.matcher(gatlingScript); if (scenarioTitleMatcher.find()) { + this.scenarioName = scenarioTitleMatcher.group(1); logger.info("Scenario Title: " + scenarioTitleMatcher.group(1)); } else { logger.warning("Scenario title not found in the Gatling script."); } - // Extract scenario requests - Matcher requestMatcher = requestPattern.matcher(gatlingScript); - if (requestMatcher.find()) { - logger.info("Request: " + requestMatcher.group(1) + " - " + requestMatcher.group(2)); - } else { - logger.warning("Requests not found in the Gatling script."); - } // Extract user injection Matcher userInjectionMatcher = userInjectionPattern.matcher(gatlingScript); if (userInjectionMatcher.find()) { - this.userInjection = userInjectionMatcher.replaceAll("\\s"); - logger.info("User Injection: " + userInjectionMatcher.group(1)); + this.userInjection = userInjectionMatcher.group(1).replaceAll("\\s", ""); + logger.info("User Injection: " + this.userInjection); } else { logger.warning("User injection not found in the Gatling script."); } + + + } } \ No newline at end of file diff --git a/testrail/src/main/resources/SimpleSimulation.java b/testrail/src/main/resources/SimpleSimulation.java new file mode 100644 index 0000000..94edb46 --- /dev/null +++ b/testrail/src/main/resources/SimpleSimulation.java @@ -0,0 +1,25 @@ +package computerdatabase; + +import static io.gatling.javaapi.core.CoreDsl.*; +import static io.gatling.javaapi.http.HttpDsl.*; + +import io.gatling.javaapi.core.*; +import io.gatling.javaapi.http.*; + +public class SimpleSimulation extends Simulation { + + HttpProtocolBuilder httpProtocol = + http.baseUrl("https://wikijs.fornoff.fr") + .acceptHeader("application/json") + .contentTypeHeader("application/json"); + + ScenarioBuilder Scenario = scenario("My First Scenario") + .exec(http("Request 1") + .get("/computers/")); + + { + setUp( + Scenario.injectOpen(rampUsers(10).during(5)) + ).protocols(httpProtocol); + } +} \ No newline at end of file From 41a14f929e6f84b44df5826b92ede9a8eb6492b3 Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 29 Oct 2024 15:17:09 -0400 Subject: [PATCH 38/56] [fix] Parsing method return GatlingTestCase object with a gatling simulation code + TestRailCase changed --- .../model/entity/GatlingTestCase.java | 27 +++--------- .../testrail/model/entity/TestRailCase.java | 43 ++++++++++++++++++- .../collector/TempTestCaseGatling.java | 12 ++++-- .../collector/TestTempTestCaseGatling.java | 7 ++- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java index 83754db..91c500e 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java @@ -19,27 +19,12 @@ public class GatlingTestCase { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "section_id", nullable = false) - private Integer sectionId; + @Column(name = "scenario_name", nullable = false) + private String scenarioName; - @Column(name = "title", nullable = false) - private String title; + @Column(name = "base_url", nullable = false) + private String baseUrl; - @Column(name = "template_id") - private Integer templateId; - - @Column(name = "type_id") - private Integer typeId; - - @Column(name = "priority_id") - private Integer priorityId; - - @Column(name = "estimate") - private String estimate; - - @Column(name = "milestone_id") - private Integer milestoneId; - - @Column(name = "refs") - private String refs; + @Column(name = "user_injection") + private String userInjection; } \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java index 020e119..1fa156f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java @@ -1,5 +1,46 @@ package ca.etsmtl.taf.testrail.model.entity; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Table(name = "tr_gatling_test_case") +@Getter +@Setter + public class TestRailCase extends TestRailData{ - // TODO + /* + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "section_id", nullable = false) + private Integer sectionId; + + @Column(name = "title", nullable = false) + private String title; + + @Column(name = "template_id") + private Integer templateId; + + @Column(name = "type_id") + private Integer typeId; + + @Column(name = "priority_id") + private Integer priorityId; + + @Column(name = "estimate") + private String estimate; + + @Column(name = "milestone_id") + private Integer milestoneId; + + @Column(name = "refs") + private String refs; } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java index 6a0933d..17546f0 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java @@ -35,12 +35,11 @@ public class TempTestCaseGatling { } private String scenarioName; - private String requestName; private String baseUrl; private String userInjection; private Map usersInjection = new HashMap<>(); - public void parse() { + public GatlingTestCase parse() { logger.setLevel(Level.INFO); String SimulationPath = "SimpleSimulation.java"; logger.info("SimulationPath=" + SimulationPath); @@ -62,6 +61,7 @@ public void parse() { // Extract base URL Matcher baseUrlMatcher = baseUrlPattern.matcher(gatlingScript); if (baseUrlMatcher.find()) { + this.baseUrl = baseUrlMatcher.group(1); logger.info("Base URL: " + baseUrlMatcher.group(1)); } else { logger.warning("Base URL not found in the Gatling script."); @@ -86,7 +86,13 @@ public void parse() { logger.warning("User injection not found in the Gatling script."); } + // Stock in GatlingTestCase object + GatlingTestCase gatlingTestCase = new GatlingTestCase(); + gatlingTestCase.setScenarioName(this.scenarioName); + gatlingTestCase.setBaseUrl(this.baseUrl); + gatlingTestCase.setUserInjection(this.userInjection); + logger.info("GatlingTestCase: " + gatlingTestCase); - + return gatlingTestCase; } } \ No newline at end of file diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java index a0918c3..911b18a 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java @@ -1,6 +1,7 @@ package ca.etsmtl.taf.testrail.service.collector; import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; @@ -33,6 +34,10 @@ public void setUp() { @Test public void test() { TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); - tempTestCaseGatling.parse(); + GatlingTestCase gatlingTestCase = tempTestCaseGatling.parse(); + assertNotNull(gatlingTestCase); + assertEquals("My First Scenario", gatlingTestCase.getScenarioName()); + assertEquals("https://wikijs.fornoff.fr", gatlingTestCase.getBaseUrl()); + assertEquals("(Scenario.injectOpen(rampUsers(10).during(5))).protocols(httpProtocol)", gatlingTestCase.getUserInjection()); } } \ No newline at end of file From 59f8ea281feda3663f8a6c8b36b54faf3d8f4ae5 Mon Sep 17 00:00:00 2001 From: moshi Date: Tue, 29 Oct 2024 15:20:40 -0400 Subject: [PATCH 39/56] Unit Test project service --- .../service/data/TestUnitTestRailProject.java | 113 +++++++++++++++++- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java index ba8e496..db97e0e 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java @@ -15,9 +15,9 @@ import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalTime; +import java.util.Random; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.*; @ContextConfiguration(classes = TestConfig.class) @DataJpaTest(properties = { @@ -27,6 +27,8 @@ public class TestUnitTestRailProject { private TestRailProject testRailProject; + private TestRailProject testRailProject2; + private TestRailProject testRailProject3; private String defaultName; @Autowired @@ -37,7 +39,8 @@ public void setUp() { testRailProjectService.deleteAll(); // Drop all data from the table defaultName = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); testRailProject = TestRailProjectFactory.create(defaultName); - + testRailProject2 = TestRailProjectFactory.create(defaultName + "_2"); + testRailProject3 = TestRailProjectFactory.create(defaultName + "_3"); } @Test @@ -248,4 +251,108 @@ public void testUpdateUrl() { assertEquals(updatedTestRailProject, getTestRailProject); } + @Test + public void testFindByTafId() { + /* Arrange */ + testRailProjectService.save(testRailProject); + testRailProjectService.save(testRailProject2); + testRailProjectService.save(testRailProject3); + Long tafId = testRailProject.getId(); + Long tafId2 = testRailProject2.getId(); + Long tafId3 = testRailProject3.getId(); + + /* Act */ + TestRailProject getTestRailProject = testRailProjectService.findByTafId(tafId).get(); + TestRailProject getTestRailProject2 = testRailProjectService.findByTafId(tafId2).get(); + TestRailProject getTestRailProject3 = testRailProjectService.findByTafId(tafId3).get(); + + /* Assert */ + assertNotNull(getTestRailProject); + assertNotNull(getTestRailProject2); + assertNotNull(getTestRailProject3); + + assertEquals(testRailProject, getTestRailProject); + assertEquals(testRailProject2, getTestRailProject2); + assertEquals(testRailProject3, getTestRailProject3); + } + + @Test + public void testFindByTRId() { + /* Arrange */ + int trId = (new Random()).nextInt(Integer.MAX_VALUE); + int trId2 = (new Random()).nextInt(Integer.MAX_VALUE); + int trId3 = (new Random()).nextInt(Integer.MAX_VALUE); + + + testRailProject.setTRId(trId); + testRailProject2.setTRId(trId2); + testRailProject3.setTRId(trId3); + + testRailProjectService.save(testRailProject); + testRailProjectService.save(testRailProject2); + testRailProjectService.save(testRailProject3); + + /* Act */ + TestRailProject getTestRailProject = testRailProjectService.findByTRId(trId).get(); + TestRailProject getTestRailProject2 = testRailProjectService.findByTRId(trId2).get(); + TestRailProject getTestRailProject3 = testRailProjectService.findByTRId(trId3).get(); + + /* Assert */ + assertNotNull(getTestRailProject); + assertNotNull(getTestRailProject2); + assertNotNull(getTestRailProject3); + + assertEquals(trId, getTestRailProject.getTRId()); + assertEquals(trId2, getTestRailProject2.getTRId()); + assertEquals(trId3, getTestRailProject3.getTRId()); + + assertEquals(testRailProject, getTestRailProject); + assertEquals(testRailProject2, getTestRailProject2); + assertEquals(testRailProject3, getTestRailProject3); + } + + @Test + public void testFindByName() { + /* Arrange */ + testRailProjectService.save(testRailProject); + testRailProjectService.save(testRailProject2); + testRailProjectService.save(testRailProject3); + + /* Act */ + TestRailProject getTestRailProject = testRailProjectService.findByName(testRailProject.getName()).get(); + TestRailProject getTestRailProject2 = testRailProjectService.findByName(testRailProject2.getName()).get(); + TestRailProject getTestRailProject3 = testRailProjectService.findByName(testRailProject3.getName()).get(); + + /* Assert */ + assertNotNull(getTestRailProject); + assertNotNull(getTestRailProject2); + assertNotNull(getTestRailProject3); + + assertEquals(testRailProject, getTestRailProject); + assertEquals(testRailProject2, getTestRailProject2); + assertEquals(testRailProject3, getTestRailProject3); + } + + + @Test + public void testDeleteByTafId() { + /* Arrange */ + testRailProjectService.save(testRailProject); + testRailProjectService.save(testRailProject2); + testRailProjectService.save(testRailProject3); + + Long tafId = testRailProject.getId(); + Long tafId2 = testRailProject2.getId(); + Long tafId3 = testRailProject3.getId(); + + /* Act */ + testRailProjectService.deleteByTafId(tafId3); + testRailProjectService.deleteByTafId(tafId); + testRailProjectService.deleteByTafId(tafId2); + + /* Assert */ + assertTrue(testRailProjectService.findByTafId(tafId).isEmpty()); + assertTrue(testRailProjectService.findByTafId(tafId2).isEmpty()); + assertTrue(testRailProjectService.findByTafId(tafId3).isEmpty()); + } } \ No newline at end of file From 0e65ac1b22a1d3c43775d2002baaa3bcbcadc9a3 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 15:33:06 -0400 Subject: [PATCH 40/56] ajout code case repository & service --- .../repository/TestRailCaseRepository.java | 3 +- .../service/data/TestRailCaseService.java | 40 ++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java index e1b298c..69cfd85 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java @@ -1,12 +1,13 @@ package ca.etsmtl.taf.testrail.repository; import ca.etsmtl.taf.testrail.model.entity.TestRailCase; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; @Repository -public interface TestRailCaseRepository { +public interface TestRailCaseRepository extends JpaRepository { /* * This interface is used to interact with the TestRailProject table in the database. * TODO diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java index 569b139..e7ca753 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailCaseService.java @@ -1,8 +1,46 @@ package ca.etsmtl.taf.testrail.service.data; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; +import ca.etsmtl.taf.testrail.repository.TestRailCaseRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Optional; + @Service public class TestRailCaseService { - // TODO + /* + * This class is used to interact with the GatlingResult table in the database. + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * To be completed and tested + * */ + + + @Autowired + private TestRailCaseRepository testRailCaseRepository; + + public TestRailCase save(TestRailCase testRailCase) { + return testRailCaseRepository.save(testRailCase); + } + + public Optional findById(Long tafId) { + return testRailCaseRepository.findById(tafId); + } + + public Optional findByTRId(Integer id) { + return testRailCaseRepository.findByTRId(id); + } + + public Optional findByTitle(String title) { + return testRailCaseRepository.findByTitle(title); + } + + public void deleteById(Long tafId) { + testRailCaseRepository.deleteById(tafId); + } + + public void deleteAll() { + testRailCaseRepository.deleteAll(); + } } From 073887a22d803a7803de6978203c7cb59a4c016f Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 17:20:10 -0400 Subject: [PATCH 41/56] ajout Factory de Case, Suite, User --- .../model/factory/TestRailCaseFactory.java | 93 +++++++++++++++++++ .../model/factory/TestRailSuiteFactory.java | 61 ++++++++++++ .../model/factory/TestRailUserFactory.java | 55 ++++++++++- 3 files changed, 208 insertions(+), 1 deletion(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java index 0660928..52b5719 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailCaseFactory.java @@ -1,4 +1,97 @@ package ca.etsmtl.taf.testrail.model.factory; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; + +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.stereotype.Component; + +import java.sql.Timestamp; public class TestRailCaseFactory { + + public static TestRailCase create(String title) { + TestRailCase testRailCase = new TestRailCase(); + testRailCase.setTitle(title); + return testRailCase; + } + + public static TestRailCase create(JSONObject projectJson) throws JSONException { + /* + * Create a TestRailCase object from a JSON object + * @param caseJson : JSON object containing the case data + * @return TestRailCase object + * @throws JSONException if the JSON object is not correct + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + TestRailCase testRailCase = new TestRailCase(); + + // nullable = false + if (projectJson.has("title") && !projectJson.isNull("title")) { + testRailCase.setTitle(projectJson.getString("title")); + } else { + throw new JSONException("title is required"); + } + + if (projectJson.has("id") && !projectJson.isNull("id")) { + testRailCase.setTRId(projectJson.getInt("id")); + } + + if (projectJson.has("section_id") && !projectJson.isNull("section_id")) { + testRailCase.setSectionId(projectJson.getInt("section_id")); + } + + if (projectJson.has("type_id") && !projectJson.isNull("type_id")) { + testRailCase.setTypeId(projectJson.getInt("type_id")); + } + + if (projectJson.has("priority_id") && !projectJson.isNull("priority_id")) { + testRailCase.setPriorityId(projectJson.getInt("priority_id")); + } + + if (projectJson.has("milestone_id") && !projectJson.isNull("milestone_id")) { + testRailCase.setMilestoneId(projectJson.getInt("milestone_id")); + } + + if (projectJson.has("refs") && !projectJson.isNull("refs")) { + testRailCase.setRefs(projectJson.getString("refs")); + } + + if (projectJson.has("created_by") && !projectJson.isNull("created_by")) { + testRailCase.setCreatedBy(projectJson.getInt("created_by")); + } + + if (projectJson.has("created_on") && !projectJson.isNull("created_on")) { + testRailCase.setCreatedOn(Timestamp.valueOf(String.valueOf(projectJson.getLong("created_on")))); + } + + if (projectJson.has("updated_by") && !projectJson.isNull("updated_by")) { + testRailCase.setUpdatedBy(projectJson.getInt("updated_by")); + } + + if (projectJson.has("updated_on") && !projectJson.isNull("updated_on")) { + testRailCase.setUpdatedOn(Timestamp.valueOf(String.valueOf(projectJson.getLong("updated_on")))); + } + + if (projectJson.has("estimate") && !projectJson.isNull("estimate")) { + testRailCase.setEstimate(Timestamp.valueOf(String.valueOf(projectJson.getLong("estimate")))); + } + + if (projectJson.has("estimate_forecast") && !projectJson.isNull("estimate_forecast")) { + testRailCase.setEstimateForecast(Timestamp.valueOf(String.valueOf(projectJson.getLong("estimate_forecast")))); + } + + if (projectJson.has("suite_id") && !projectJson.isNull("suite_id")) { + testRailCase.setSuiteId(projectJson.getInt("suite_id")); + } + + if (projectJson.has("template_id") && !projectJson.isNull("template_id")) { + testRailCase.setTemplateId(projectJson.getInt("template_id")); + } + + return testRailCase; + } + + } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java index e84c35d..2dc4f60 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailSuiteFactory.java @@ -1,5 +1,66 @@ package ca.etsmtl.taf.testrail.model.factory; +import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; +import org.json.JSONException; +import org.json.JSONObject; + +import java.sql.Timestamp; + public class TestRailSuiteFactory { // TODO + public static TestRailSuite create(String name) { + TestRailSuite suite = new TestRailSuite(); + suite.setName(name); + return suite; + } + + public static TestRailSuite create(JSONObject projectJson) throws JSONException { + /* + * Create a TestRailSuite object from a JSON object + * @param projectJson : JSON object containing the project data + * @return TestRailSuite object + * @throws JSONException if the JSON object is not correct + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + TestRailSuite suite = new TestRailSuite(); + + // nullable = false + if (projectJson.has("name") && !projectJson.isNull("name")) { + suite.setName(projectJson.getString("name")); + } else { + throw new JSONException("name is required"); + } + + if (projectJson.has("id") && !projectJson.isNull("id")) { + suite.setTRId(projectJson.getInt("id")); + } + + if (projectJson.has("description") && !projectJson.isNull("description")) { + suite.setDescription(projectJson.getString("description")); + } + + if (projectJson.has("is_baseline") && !projectJson.isNull("is_baseline")) { + suite.setIsBaseline(projectJson.getBoolean("is_baseline")); + } + + if (projectJson.has("is_completed") && !projectJson.isNull("is_completed")) { + suite.setIsCompleted(projectJson.getBoolean("is_completed")); + } + + if (projectJson.has("completed_on") && !projectJson.isNull("completed_on")) { + suite.setCompletedOn(Timestamp.valueOf(String.valueOf(projectJson.getLong("completed_on")))); + } + + if (projectJson.has("url") && !projectJson.isNull("url")) { + suite.setUrl(projectJson.getString("url")); + } + + if (projectJson.has("is_master") && !projectJson.isNull("is_master")) { + suite.setIsMaster(projectJson.getBoolean("is_master")); + } + + return suite; + } } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java index 365c9f4..b28c799 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java @@ -1,5 +1,58 @@ package ca.etsmtl.taf.testrail.model.factory; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.entity.TestRailUser; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.stereotype.Component; + +import java.sql.Timestamp; + + public class TestRailUserFactory { - //TODO + public static TestRailUser create(String name) { + TestRailUser user = new TestRailUser(); + user.setUsername(name); + return user; + } + + public static TestRailUser create(JSONObject projectJson) throws JSONException { + /* + * Create a TestRailUser object from a JSON object + * @param projectJson : JSON object containing the user data + * @return TestRailUser object + * @throws JSONException if the JSON object is not correct + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + TestRailUser user = new TestRailUser(); + + // nullable = false + if (projectJson.has("username") && !projectJson.isNull("username")) { + user.setUsername(projectJson.getString("username")); + } else { + throw new JSONException("username is required"); + } + + if (projectJson.has("password") && !projectJson.isNull("password")) { + user.setPassword(projectJson.getString("password")); + } else { + throw new JSONException("password is required"); + } + + if (projectJson.has("email") && !projectJson.isNull("email")) { + user.setEmail(projectJson.getString("email")); + } else { + throw new JSONException("email is required"); + } + + if (projectJson.has("id") && !projectJson.isNull("id")) { + user.setTRId(projectJson.getInt("id")); + } else { + throw new JSONException("id is required"); + } + + return user; + } } From bfb69b456f07b2e77dd00ed184aeb75e4e496151 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 18:43:09 -0400 Subject: [PATCH 42/56] ajout Suite TestUnit; modification dans Suite Service --- .../service/data/TestRailSuiteService.java | 8 + .../service/data/TestUnitTestRailSuite.java | 314 ++++++++++++++++++ 2 files changed, 322 insertions(+) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java index 0ff464f..7f03b67 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailSuiteService.java @@ -31,9 +31,17 @@ public Optional findByTRId(Integer id) { return testRAilSuiteRepository.findByTRId(id); } + public Optional findByName(String name) { + return testRAilSuiteRepository.findByName(name); + } + public void deleteByTafId(Long tafId) { testRAilSuiteRepository.deleteById(tafId); } + public void deleteAll() { + testRAilSuiteRepository.deleteAll(); + } + } diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java new file mode 100644 index 0000000..7d4af73 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java @@ -0,0 +1,314 @@ +package ca.etsmtl.taf.testrail.service.data; + + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; +import ca.etsmtl.taf.testrail.model.factory.TestRailSuiteFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ContextConfiguration; + +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; + +@ContextConfiguration(classes = TestConfig.class) +@DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" +}) +public class TestUnitTestRailSuite { + + private TestRailSuite testRailSuite; + private TestRailSuite testRailSuite2; + private TestRailSuite testRailSuite3; + private String defaultName; + + @Autowired + private TestRailSuiteService testRailSuiteService; + + @BeforeEach + public void setUp() { + testRailSuiteService.deleteAll(); // Drop all data from the table + defaultName = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + testRailSuite = TestRailSuiteFactory.create(defaultName); + testRailSuite2 = TestRailSuiteFactory.create(defaultName + "_2"); + testRailSuite3 = TestRailSuiteFactory.create(defaultName + "_3"); + } + + @Test + public void testSave() { + // Arrange + testRailSuite.setTRId(1); + + // Act + TestRailSuite savedTestRailSuite = testRailSuiteService.save(testRailSuite); + + // Assert + assertNotNull(savedTestRailSuite); + assertEquals(testRailSuite, savedTestRailSuite); + assertEquals(defaultName, savedTestRailSuite.getName()); + } + + public void beforeUpdate() { + testRailSuite.setTRId(2); + testRailSuiteService.save(testRailSuite); + } + + @Test + public void testUpdateId() { + /* Arrange */ + beforeUpdate(); + testRailSuite.setTRId(3); + + /* Act */ + TestRailSuite savedTestRailSuite = testRailSuiteService.save(testRailSuite); + + /* Assert */ + assertNotNull(savedTestRailSuite); + assertEquals(testRailSuite, savedTestRailSuite); + assertEquals(defaultName, savedTestRailSuite.getName()); + assertEquals(3, savedTestRailSuite.getTRId()); + } + + @Test + public void testUpdateName() { + /* Arrange */ + beforeUpdate(); + String updatedName = "updatedName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailSuite.setName(updatedName); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedName, updatedTestRailSuite.getName()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateDescription() { + /* Arrange */ + beforeUpdate(); + String updatedDescription = "updatedDescription_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailSuite.setDescription(updatedDescription); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedDescription, updatedTestRailSuite.getDescription()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateIsMaster() { + /* Arrange */ + beforeUpdate(); + boolean updatedIsMaster = true; + + /* Act */ + testRailSuite.setIsMaster(updatedIsMaster); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedIsMaster, updatedTestRailSuite.getIsMaster()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateIsBaseline() { + /* Arrange */ + beforeUpdate(); + boolean updatedIsBaseline = true; + + /* Act */ + testRailSuite.setIsBaseline(updatedIsBaseline); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedIsBaseline, updatedTestRailSuite.getIsBaseline()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateIsCompleted() { + /* Arrange */ + beforeUpdate(); + boolean updatedIsCompleted = true; + + /* Act */ + testRailSuite.setIsCompleted(updatedIsCompleted); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedIsCompleted, updatedTestRailSuite.getIsCompleted()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateCompletedOn() { + /* Arrange */ + beforeUpdate(); + Timestamp updatedCompletedOn = new Timestamp(System.currentTimeMillis()); + + /* Act */ + testRailSuite.setCompletedOn(updatedCompletedOn); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedCompletedOn, updatedTestRailSuite.getCompletedOn()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testUpdateUrl() { + /* Arrange */ + beforeUpdate(); + String updatedUrl = "updatedUrl_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailSuite.setUrl(updatedUrl); + TestRailSuite updatedTestRailSuite = testRailSuiteService.save(testRailSuite); + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailSuite); + assertEquals(2, updatedTestRailSuite.getTRId()); + assertEquals(updatedUrl, updatedTestRailSuite.getUrl()); + assertEquals(testRailSuite, updatedTestRailSuite); + assertEquals(updatedTestRailSuite, getTestRailSuite); + } + + @Test + public void testFindByTafId() { + /* Arrange */ + testRailSuiteService.save(testRailSuite); + testRailSuiteService.save(testRailSuite2); + testRailSuiteService.save(testRailSuite3); + Long tafId = testRailSuite.getId(); + Long tafId2 = testRailSuite2.getId(); + Long tafId3 = testRailSuite3.getId(); + + /* Act */ + TestRailSuite getTestRailSuite = testRailSuiteService.findByTafId(tafId).get(); + TestRailSuite getTestRailSuite2 = testRailSuiteService.findByTafId(tafId2).get(); + TestRailSuite getTestRailSuite3 = testRailSuiteService.findByTafId(tafId3).get(); + + /* Assert */ + assertNotNull(getTestRailSuite); + assertNotNull(getTestRailSuite2); + assertNotNull(getTestRailSuite3); + + assertEquals(testRailSuite, getTestRailSuite); + assertEquals(testRailSuite2, getTestRailSuite2); + assertEquals(testRailSuite3, getTestRailSuite3); + } + + @Test + public void testFindByTRId() { + /* Arrange */ + int trId = (new Random()).nextInt(Integer.MAX_VALUE); + int trId2 = (new Random()).nextInt(Integer.MAX_VALUE); + int trId3 = (new Random()).nextInt(Integer.MAX_VALUE); + + testRailSuite.setTRId(trId); + testRailSuite2.setTRId(trId2); + testRailSuite3.setTRId(trId3); + + testRailSuiteService.save(testRailSuite); + testRailSuiteService.save(testRailSuite2); + testRailSuiteService.save(testRailSuite3); + + /* Act */ + TestRailSuite getTestRailSuite = testRailSuiteService.findByTRId(trId).get(); + TestRailSuite getTestRailSuite2 = testRailSuiteService.findByTRId(trId2).get(); + TestRailSuite getTestRailSuite3 = testRailSuiteService.findByTRId(trId3).get(); + + /* Assert */ + assertNotNull(getTestRailSuite); + assertNotNull(getTestRailSuite2); + assertNotNull(getTestRailSuite3); + + assertEquals(trId, getTestRailSuite.getTRId()); + assertEquals(trId2, getTestRailSuite2.getTRId()); + assertEquals(trId3, getTestRailSuite3.getTRId()); + + assertEquals(testRailSuite, getTestRailSuite); + assertEquals(testRailSuite2, getTestRailSuite2); + assertEquals(testRailSuite3, getTestRailSuite3); + } + + @Test + public void testFindByName() { + /* Arrange */ + testRailSuiteService.save(testRailSuite); + testRailSuiteService.save(testRailSuite2); + testRailSuiteService.save(testRailSuite3); + + /* Act */ + TestRailSuite getTestRailSuite = testRailSuiteService.findByName(testRailSuite.getName()).get(); + TestRailSuite getTestRailSuite2 = testRailSuiteService.findByName(testRailSuite2.getName()).get(); + TestRailSuite getTestRailSuite3 = testRailSuiteService.findByName(testRailSuite3.getName()).get(); + + /* Assert */ + assertNotNull(getTestRailSuite); + assertNotNull(getTestRailSuite2); + assertNotNull(getTestRailSuite3); + + assertEquals(testRailSuite, getTestRailSuite); + assertEquals(testRailSuite2, getTestRailSuite2); + assertEquals(testRailSuite3, getTestRailSuite3); + } + + @Test + public void testDeleteByTafId() { + /* Arrange */ + testRailSuiteService.save(testRailSuite); + testRailSuiteService.save(testRailSuite2); + testRailSuiteService.save(testRailSuite3); + Long tafId = testRailSuite.getId(); + Long tafId2 = testRailSuite2.getId(); + Long tafId3 = testRailSuite3.getId(); + + /* Act */ + testRailSuiteService.deleteByTafId(tafId); + testRailSuiteService.deleteByTafId(tafId2); + testRailSuiteService.deleteByTafId(tafId3); + + /* Assert */ + assertTrue(testRailSuiteService.findByTafId(tafId).isEmpty()); + assertTrue(testRailSuiteService.findByTafId(tafId2).isEmpty()); + assertTrue(testRailSuiteService.findByTafId(tafId3).isEmpty()); + } +} From bda15a31c636f05885757edef37e1b90e7da0f94 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 18:44:50 -0400 Subject: [PATCH 43/56] =?UTF-8?q?D=C3=A9placement=20des=20fichiers=20Test?= =?UTF-8?q?=20Unit=20Suite=20&=20User?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java | 5 ----- .../ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java deleted file mode 100644 index 45384c5..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailSuite.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.unit.data; - -public class unitTestRailSuite { - // TODO -} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java deleted file mode 100644 index 944f3a8..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitTestRailUser.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.unit.data; - -public class unitTestRailUser { - // TODO -} From 890775812bffde387125bb1f5a93e8d53b773961 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 20:53:00 -0400 Subject: [PATCH 44/56] Ajout Test Unit User et modifications en lien --- .../testrail/model/entity/TestRailUser.java | 2 +- .../model/factory/TestRailUserFactory.java | 6 +- .../service/data/TestRailUserService.java | 6 +- .../service/data/TestUnitTestRailUser.java | 224 ++++++++++++++++++ 4 files changed, 233 insertions(+), 5 deletions(-) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailUser.java diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java index b6c0759..5b5c779 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -22,7 +22,7 @@ public class TestRailUser extends TestRailData { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "tr_id", unique = true) + @Column(name = "tr_id", unique = true, nullable = true) private Integer TRId; @Column(name = "username", nullable = false) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java index b28c799..822209a 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/factory/TestRailUserFactory.java @@ -10,9 +10,11 @@ public class TestRailUserFactory { - public static TestRailUser create(String name) { + public static TestRailUser create(String name, String password, String email) { TestRailUser user = new TestRailUser(); user.setUsername(name); + user.setPassword(password); + user.setEmail(email); return user; } @@ -49,8 +51,6 @@ public static TestRailUser create(JSONObject projectJson) throws JSONException { if (projectJson.has("id") && !projectJson.isNull("id")) { user.setTRId(projectJson.getInt("id")); - } else { - throw new JSONException("id is required"); } return user; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java index 72ea1ab..daa22d1 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/TestRailUserService.java @@ -27,7 +27,7 @@ public TestRailUser save(TestRailUser user) { } // Find a TestRailUser by their unique ID (tafId) - public Optional findById(Long tafId) { + public Optional findByTafId(Long tafId) { return repository.findById(tafId); } @@ -56,6 +56,10 @@ public void deleteById(Long tafId) { repository.deleteById(tafId); } + public void deleteByTafId(Long tafId) { + repository.deleteById(tafId); + } + // Delete all TestRailUser entries public void deleteAll() { repository.deleteAll(); diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailUser.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailUser.java new file mode 100644 index 0000000..8c1cb88 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailUser.java @@ -0,0 +1,224 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailUser; +import ca.etsmtl.taf.testrail.model.factory.TestRailUserFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ContextConfiguration; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; + +@ContextConfiguration(classes = TestConfig.class) +@DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" +}) +public class TestUnitTestRailUser { + + private TestRailUser testRailUser; + private TestRailUser testRailUser2; + private TestRailUser testRailUser3; + private String defaultName; + private String defaultPassword; + private String defaultEmail; + + @Autowired + private TestRailUserService testRailUserService; + + @BeforeEach + public void setUp() { + testRailUserService.deleteAll(); // Drop all data from the table + defaultName = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + defaultPassword = "defaultPassword_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + defaultEmail = "defaultEmail_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + testRailUser = TestRailUserFactory.create(defaultName, defaultPassword, defaultEmail); + testRailUser2 = TestRailUserFactory.create(defaultName + "_2", defaultPassword + "_2", defaultEmail + "_2"); + testRailUser3 = TestRailUserFactory.create(defaultName + "_3", defaultPassword + "_3", defaultEmail + "_3"); + } + + @Test + public void testSave() { + /* Arrange */ + testRailUser.setTRId(1); + + /* Act */ + TestRailUser savedTestRailUser = testRailUserService.save(testRailUser); + + /* Assert */ + assertNotNull(savedTestRailUser); + assertEquals(testRailUser, savedTestRailUser); + assertEquals(defaultName, savedTestRailUser.getUsername()); + } + + public void beforeUpdate() { + testRailUser.setTRId(2); + testRailUserService.save(testRailUser); + } + + @Test + public void testUpdateUsername() { + /* Arrange */ + beforeUpdate(); + String updatedUsername = "newName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailUser.setUsername(updatedUsername); + TestRailUser updatedTestRailUser = testRailUserService.save(testRailUser); + TestRailUser getTestRailUser = testRailUserService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailUser); + assertEquals(2, updatedTestRailUser.getTRId()); + assertEquals(updatedUsername, updatedTestRailUser.getUsername()); + assertEquals(testRailUser, updatedTestRailUser); + assertEquals(updatedTestRailUser, getTestRailUser); + } + + @Test + public void testUpdatePassword() { + /* Arrange */ + beforeUpdate(); + String updatedPassword = "newPassword_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailUser.setPassword(updatedPassword); + TestRailUser updatedTestRailUser = testRailUserService.save(testRailUser); + TestRailUser getTestRailUser = testRailUserService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailUser); + assertEquals(2, updatedTestRailUser.getTRId()); + assertEquals(updatedPassword, updatedTestRailUser.getPassword()); + assertEquals(testRailUser, updatedTestRailUser); + assertEquals(updatedTestRailUser, getTestRailUser); + } + + @Test + public void testUpdateEmail() { + /* Arrange */ + beforeUpdate(); + String updatedEmail = "newEmail_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + /* Act */ + testRailUser.setEmail(updatedEmail); + TestRailUser updatedTestRailUser = testRailUserService.save(testRailUser); + TestRailUser getTestRailUser = testRailUserService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailUser); + assertEquals(2, updatedTestRailUser.getTRId()); + assertEquals(updatedEmail, updatedTestRailUser.getEmail()); + assertEquals(testRailUser, updatedTestRailUser); + assertEquals(updatedTestRailUser, getTestRailUser); + } + + @Test + public void testFindByTafId() { + + /* Arrange */ + testRailUserService.save(testRailUser); + testRailUserService.save(testRailUser2); + testRailUserService.save(testRailUser3); + Long tafId = testRailUser.getId(); + Long tafId2 = testRailUser2.getId(); + Long tafId3 = testRailUser3.getId(); + + /* Act */ + TestRailUser getTestRailUser = testRailUserService.findByTafId(tafId).get(); + TestRailUser getTestRailUser2 = testRailUserService.findByTafId(tafId2).get(); + TestRailUser getTestRailUser3 = testRailUserService.findByTafId(tafId3).get(); + + /* Assert */ + assertNotNull(getTestRailUser); + assertNotNull(getTestRailUser2); + assertNotNull(getTestRailUser3); + assertEquals(testRailUser, getTestRailUser); + assertEquals(testRailUser2, getTestRailUser2); + assertEquals(testRailUser3, getTestRailUser3); + } + + @Test + public void testFindByTRId() { + + /* Arrange */ + int trId = (new Random()).nextInt(Integer.MAX_VALUE); + int trId2 = (new Random()).nextInt(Integer.MAX_VALUE); + int trId3 = (new Random()).nextInt(Integer.MAX_VALUE); + testRailUser.setTRId(trId); + testRailUser2.setTRId(trId2); + testRailUser3.setTRId(trId3); + testRailUserService.save(testRailUser); + testRailUserService.save(testRailUser2); + testRailUserService.save(testRailUser3); + + /* Act */ + TestRailUser getTestRailUser = testRailUserService.findByTRId(trId).get(); + TestRailUser getTestRailUser2 = testRailUserService.findByTRId(trId2).get(); + TestRailUser getTestRailUser3 = testRailUserService.findByTRId(trId3).get(); + + /* Assert */ + assertNotNull(getTestRailUser); + assertNotNull(getTestRailUser2); + assertNotNull(getTestRailUser3); + + assertEquals(trId, getTestRailUser.getTRId()); + assertEquals(trId2, getTestRailUser2.getTRId()); + assertEquals(trId3, getTestRailUser3.getTRId()); + + assertEquals(testRailUser, getTestRailUser); + assertEquals(testRailUser2, getTestRailUser2); + assertEquals(testRailUser3, getTestRailUser3); + } + + @Test + public void testFindByUsername() { + + /* Arrange */ + testRailUserService.save(testRailUser); + testRailUserService.save(testRailUser2); + testRailUserService.save(testRailUser3); + + /* Act */ + TestRailUser getTestRailUser = testRailUserService.findByUsername(testRailUser.getUsername()).get(); + TestRailUser getTestRailUser2 = testRailUserService.findByUsername(testRailUser2.getUsername()).get(); + TestRailUser getTestRailUser3 = testRailUserService.findByUsername(testRailUser3.getUsername()).get(); + + /* Assert */ + assertNotNull(getTestRailUser); + assertNotNull(getTestRailUser2); + assertNotNull(getTestRailUser3); + + assertEquals(testRailUser, getTestRailUser); + assertEquals(testRailUser2, getTestRailUser2); + assertEquals(testRailUser3, getTestRailUser3); + } + + @Test + public void testDeleteByTafId(){ + /* Arrange */ + testRailUserService.save(testRailUser); + testRailUserService.save(testRailUser2); + testRailUserService.save(testRailUser3); + + Long tafId = testRailUser.getId(); + Long tafId2 = testRailUser2.getId(); + Long tafId3 = testRailUser3.getId(); + + /* Act */ + testRailUserService.deleteByTafId(tafId); + testRailUserService.deleteByTafId(tafId2); + testRailUserService.deleteByTafId(tafId3); + + /* Assert */ + assertTrue(testRailUserService.findByTafId(tafId).isEmpty()); + assertTrue(testRailUserService.findByTafId(tafId2).isEmpty()); + assertTrue(testRailUserService.findByTafId(tafId3).isEmpty()); + } +} From dfaff35b7b3ed91e1fb09df24440ee85d07fbd17 Mon Sep 17 00:00:00 2001 From: Marie2023 <12888813-mariepier2023@users.noreply.gitlab.com> Date: Tue, 29 Oct 2024 22:00:04 -0400 Subject: [PATCH 45/56] Ajout Test Unit Case --- .../service/data/TestUnitTestRailCase.java | 450 ++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailCase.java diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailCase.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailCase.java new file mode 100644 index 0000000..634de53 --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailCase.java @@ -0,0 +1,450 @@ +package ca.etsmtl.taf.testrail.service.data; + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; +import ca.etsmtl.taf.testrail.model.factory.TestRailCaseFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ContextConfiguration; + +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ContextConfiguration(classes = TestConfig.class) +@DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" +}) +public class TestUnitTestRailCase { + + private TestRailCase testRailCase; + private TestRailCase testRailCase2; + private TestRailCase testRailCase3; + private String defaultTitle; + + @Autowired + private TestRailCaseService testRailCaseService; + + @BeforeEach + public void setUp() { + testRailCaseService.deleteAll(); // Drop all data from the table + defaultTitle = "defaultName_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + testRailCase = TestRailCaseFactory.create(defaultTitle); + testRailCase2 = TestRailCaseFactory.create(defaultTitle + "_2"); + testRailCase3 = TestRailCaseFactory.create(defaultTitle + "_3"); + } + + @Test + public void testSave() { + // Arrange + testRailCase.setTRId(1); + + // Act + TestRailCase savedTestRailCase = testRailCaseService.save(testRailCase); + + // Assert + assertNotNull(savedTestRailCase); + assertEquals(testRailCase, savedTestRailCase); + assertEquals(defaultTitle, savedTestRailCase.getTitle()); + } + + public void beforeUpdate() { + testRailCase.setTRId(2); + testRailCaseService.save(testRailCase); + } + + @Test + public void testUpdateId() { + // Arrange + beforeUpdate(); + testRailCase.setTRId(3); + + // Act + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(defaultTitle, updatedTestRailCase.getTitle()); + assertEquals(3, updatedTestRailCase.getTRId()); + } + + @Test + public void testUpdateTitle() { + // Arrange + beforeUpdate(); + String newTitle = "defaultTitle_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + // Act + testRailCase.setTitle(newTitle); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(newTitle, updatedTestRailCase.getTitle()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateSectionId(){ + // Arrange + beforeUpdate(); + int newSectionId = 4; + + // Act + testRailCase.setSectionId(newSectionId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getSectionId()); + assertEquals(newSectionId, getTestRailCase.getSectionId()); + } + + @Test + public void testUpdateTypeId(){ + // Arrange + beforeUpdate(); + int newTypeId = 4; + + // Act + testRailCase.setTypeId(newTypeId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getTypeId()); + assertEquals(newTypeId, getTestRailCase.getTypeId()); + } + + @Test + public void testUpdatePriorityId(){ + // Arrange + beforeUpdate(); + int newPriorityId = 4; + + // Act + testRailCase.setPriorityId(newPriorityId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getPriorityId()); + assertEquals(newPriorityId, getTestRailCase.getPriorityId()); + } + + @Test + public void testUpdateMilestoneId(){ + // Arrange + beforeUpdate(); + int newMilestoneId = 4; + + // Act + testRailCase.setMilestoneId(newMilestoneId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getMilestoneId()); + assertEquals(newMilestoneId, getTestRailCase.getMilestoneId()); + } + + @Test + public void testUpdateRefs() { + // Arrange + beforeUpdate(); + String newRefs = "defaultRefs_" + LocalDate.now() + LocalTime.now() + TestConfig.getRandomString(16); + + // Act + testRailCase.setTitle(newRefs); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(newRefs, updatedTestRailCase.getTitle()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateCreatedBy(){ + // Arrange + beforeUpdate(); + int newCreatedBy = 4; + + // Act + testRailCase.setCreatedBy(newCreatedBy); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getCreatedBy()); + assertEquals(newCreatedBy, getTestRailCase.getCreatedBy()); + } + + @Test + public void testUpdateCreatedOn() { + /* Arrange */ + beforeUpdate(); + Timestamp updatedCompletedOn = new Timestamp(System.currentTimeMillis()); + + /* Act */ + testRailCase.setCreatedOn(updatedCompletedOn); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase= testRailCaseService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(updatedCompletedOn, updatedTestRailCase.getCreatedOn()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateUpdatedBy(){ + // Arrange + beforeUpdate(); + int newUpdatedBy = 4; + + // Act + testRailCase.setUpdatedBy(newUpdatedBy); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getUpdatedBy()); + assertEquals(newUpdatedBy, getTestRailCase.getUpdatedBy()); + } + + @Test + public void testUpdateUpdatedOn() { + /* Arrange */ + beforeUpdate(); + Timestamp updatedUpdatedOn = new Timestamp(System.currentTimeMillis()); + + /* Act */ + testRailCase.setUpdatedOn(updatedUpdatedOn); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase= testRailCaseService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(updatedUpdatedOn, updatedTestRailCase.getUpdatedOn()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateEstimate() { + /* Arrange */ + beforeUpdate(); + Timestamp updatedEstimate = new Timestamp(System.currentTimeMillis()); + + /* Act */ + testRailCase.setEstimate(updatedEstimate); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase= testRailCaseService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(updatedEstimate, updatedTestRailCase.getEstimate()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateEstimateForecast() { + /* Arrange */ + beforeUpdate(); + Timestamp updatedEstimateForecast = new Timestamp(System.currentTimeMillis()); + + /* Act */ + testRailCase.setEstimateForecast(updatedEstimateForecast); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase= testRailCaseService.findByTRId(2).get(); + + /* Assert */ + assertNotNull(updatedTestRailCase); + assertEquals(2, updatedTestRailCase.getTRId()); + assertEquals(updatedEstimateForecast, updatedTestRailCase.getEstimateForecast()); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + } + + @Test + public void testUpdateSuiteId(){ + // Arrange + beforeUpdate(); + int newSuiteId = 4; + + // Act + testRailCase.setSuiteId(newSuiteId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getSuiteId()); + assertEquals(newSuiteId, getTestRailCase.getSuiteId()); + } + + @Test + public void testUpdateTemplateId(){ + // Arrange + beforeUpdate(); + int newTemplateId = 4; + + // Act + testRailCase.setTemplateId(newTemplateId); + TestRailCase updatedTestRailCase = testRailCaseService.save(testRailCase); + TestRailCase getTestRailCase = testRailCaseService.findByTRId(2).get(); + + // Assert + assertNotNull(updatedTestRailCase); + assertEquals(testRailCase, updatedTestRailCase); + assertEquals(updatedTestRailCase, getTestRailCase); + assertEquals(4, updatedTestRailCase.getTemplateId()); + assertEquals(newTemplateId, getTestRailCase.getTemplateId()); + } + + @Test + public void testFindByTafId() { + /* Arrange */ + testRailCaseService.save(testRailCase); + testRailCaseService.save(testRailCase2); + testRailCaseService.save(testRailCase3); + Long tafId = testRailCase.getId(); + Long tafId2 = testRailCase2.getId(); + Long tafId3 = testRailCase3.getId(); + + /* Act */ + TestRailCase getTestRailCase = testRailCaseService.findById(tafId).get(); + TestRailCase getTestRailCase2 = testRailCaseService.findById(tafId2).get(); + TestRailCase getTestRailCase3 = testRailCaseService.findById(tafId3).get(); + + /* Assert */ + assertNotNull(getTestRailCase); + assertNotNull(getTestRailCase2); + assertNotNull(getTestRailCase3); + + assertEquals(testRailCase, getTestRailCase); + assertEquals(testRailCase2, getTestRailCase2); + assertEquals(testRailCase3, getTestRailCase3); + } + + @Test + public void testFindByTRId() { + /* Arrange */ + int trId = (new Random()).nextInt(Integer.MAX_VALUE); + int trId2 = (new Random()).nextInt(Integer.MAX_VALUE); + int trId3 = (new Random()).nextInt(Integer.MAX_VALUE); + + + testRailCase.setTRId(trId); + testRailCase2.setTRId(trId2); + testRailCase3.setTRId(trId3); + + testRailCaseService.save(testRailCase); + testRailCaseService.save(testRailCase2); + testRailCaseService.save(testRailCase3); + + /* Act */ + TestRailCase getTestRailCase = testRailCaseService.findByTRId(trId).get(); + TestRailCase getTestRailCase2 = testRailCaseService.findByTRId(trId2).get(); + TestRailCase getTestRailCase3 = testRailCaseService.findByTRId(trId3).get(); + + /* Assert */ + assertNotNull(getTestRailCase); + assertNotNull(getTestRailCase2); + assertNotNull(getTestRailCase3); + + assertEquals(trId, getTestRailCase.getTRId()); + assertEquals(trId2, getTestRailCase2.getTRId()); + assertEquals(trId3, getTestRailCase3.getTRId()); + + assertEquals(testRailCase, getTestRailCase); + assertEquals(testRailCase2, getTestRailCase2); + assertEquals(testRailCase3, getTestRailCase3); + } + + @Test + public void testFindByTitle() { + /* Arrange */ + testRailCaseService.save(testRailCase); + testRailCaseService.save(testRailCase2); + testRailCaseService.save(testRailCase3); + + /* Act */ + TestRailCase getTestRailCase = testRailCaseService.findByTitle(testRailCase.getTitle()).get(); + TestRailCase getTestRailCase2 = testRailCaseService.findByTitle(testRailCase2.getTitle()).get(); + TestRailCase getTestRailCase3 = testRailCaseService.findByTitle(testRailCase3.getTitle()).get(); + + /* Assert */ + assertNotNull(getTestRailCase); + assertNotNull(getTestRailCase2); + assertNotNull(getTestRailCase3); + + assertEquals(testRailCase, getTestRailCase); + assertEquals(testRailCase2, getTestRailCase2); + assertEquals(testRailCase3, getTestRailCase3); + } + + @Test + public void testDeleteByTafId() { + /* Arrange */ + testRailCaseService.save(testRailCase); + testRailCaseService.save(testRailCase2); + testRailCaseService.save(testRailCase3); + + Long tafId = testRailCase.getId(); + Long tafId2 = testRailCase2.getId(); + Long tafId3 = testRailCase3.getId(); + + /* Act */ + testRailCaseService.deleteById(tafId3); + testRailCaseService.deleteById(tafId); + testRailCaseService.deleteById(tafId2); + + /* Assert */ + assertTrue(testRailCaseService.findById(tafId).isEmpty()); + assertTrue(testRailCaseService.findById(tafId2).isEmpty()); + assertTrue(testRailCaseService.findById(tafId3).isEmpty()); + } +} From 3006f967cc6ef93ef38b574f73a0eae8b258bc77 Mon Sep 17 00:00:00 2001 From: moshi Date: Wed, 30 Oct 2024 16:30:50 -0400 Subject: [PATCH 46/56] Update tests TODO status --- .../ca/etsmtl/taf/testrail/model/entity/TestRailCase.java | 4 +++- .../ca/etsmtl/taf/testrail/model/entity/TestRailProject.java | 4 +++- .../ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java | 4 +++- .../ca/etsmtl/taf/testrail/model/entity/TestRailUser.java | 4 +++- .../taf/testrail/repository/TestRailCaseRepository.java | 3 +-- .../taf/testrail/repository/TestRailProjectRepository.java | 3 +-- .../taf/testrail/repository/TestRailSuiteRepository.java | 3 +-- .../taf/testrail/repository/TestRailUserRepository.java | 2 +- .../etsmtl/taf/testrail/service/data/TestRailCaseService.java | 3 +-- .../taf/testrail/service/data/TestRailProjectService.java | 3 +-- .../taf/testrail/service/data/TestRailSuiteService.java | 3 +-- .../etsmtl/taf/testrail/service/data/TestRailUserService.java | 3 +-- 12 files changed, 20 insertions(+), 19 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java index c106dfe..e132d78 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailCase.java @@ -15,7 +15,9 @@ public class TestRailCase extends TestRailData{ /* * Class to save cases from TestRail in TAF database to be used in the application. * Class build assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO + * Tests : + * - Unit tests : TestUnitTestRailCase + * - Integration tests : TODO * */ @Id@GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 05cf9bd..2e01c55 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -16,7 +16,9 @@ public class TestRailProject extends TestRailData { /* * Class to save projects from TestRail in TAF database to be used in the application. * Class build assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO + * Tests : + * - Unit tests : TestUnitTestRailProject + * - Integration tests : TODO * */ @Id diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java index fcca966..edcddb2 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailSuite.java @@ -15,7 +15,9 @@ public class TestRailSuite extends TestRailData{ /* * Class to save suites from TestRail in TAF database to be used in the application. * Class build assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO + * Tests : + * - Unit tests : TestUnitTestRailSuite + * - Integration tests : TODO * */ @Id diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java index 5b5c779..3fb1b89 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailUser.java @@ -16,7 +16,9 @@ public class TestRailUser extends TestRailData { /* * Class to save users from TestRail. * Class build assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO + * Tests : + * - Unit tests : TestUnitTestRailUser + * - Integration tests : TODO * */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java index 69cfd85..8f4eda4 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailCaseRepository.java @@ -10,8 +10,7 @@ public interface TestRailCaseRepository extends JpaRepository { /* * This interface is used to interact with the TestRailProject table in the database. - * TODO - * To be completed and tested + * Tests : TestUnitTestRailCase * Assisted by IA (copilot & chatGPT & intellij) * */ diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java index 9a60796..f6297b4 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailProjectRepository.java @@ -11,8 +11,7 @@ public interface TestRailProjectRepository extends JpaRepository { /* * This interface is used to interact with the TestRailProject table in the database. - * TODO - * To be completed and tested + * Tests : TestUnitTestRailProject * Assisted by IA (copilot & chatGPT & intellij) * */ diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java index 1fd51cf..6a8abb0 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/repository/TestRailUserRepository.java @@ -12,7 +12,7 @@ public interface TestRailUserRepository extends JpaRepository Date: Fri, 1 Nov 2024 16:21:03 -0400 Subject: [PATCH 47/56] Adapting backend after meeting of 1st November 2024 --- testrail/DataSavingSequence.puml | 114 +++++++++++++ .../model/entity/TestRailProject.java | 3 + .../{data => }/GatlingResultService.java | 2 +- .../{data => }/GatlingTestCaseService.java | 2 +- .../service/manager/DataResponseFromTR.java | 18 ++ .../service/manager/GeneralSavingManager.java | 29 ++++ .../service/manager/ProjectSavingManager.java | 86 ++++++++++ .../{ => manager}/export/ExportGatling.java | 2 +- .../export/ExportServiceInterface.java | 2 +- .../query/HttpSenderToTestRail.java | 15 +- .../manager/query/ProjectQueryTestRail.java | 87 ++++++++++ .../service/manager/query/QueryTestRail.java | 17 ++ .../service/manager/query/SendResultData.java | 21 +++ .../service/query/ProjectQueryTestRail.java | 160 ------------------ .../testrail/service/query/QueryTestRail.java | 21 --- .../testrail/service/query/load/LoadCase.java | 5 - .../testrail/service/query/load/LoadData.java | 14 -- .../service/query/load/LoadProject.java | 35 ---- .../service/query/load/LoadSuite.java | 5 - .../testrail/service/query/load/LoadUser.java | 5 - .../service/query/refresh/Refresh.java | 6 - .../service/query/refresh/RefreshCase.java | 5 - .../service/query/refresh/RefreshProject.java | 18 -- .../service/query/refresh/RefreshSuite.java | 5 - .../service/query/refresh/RefreshUser.java | 5 - .../service/data/TestUnitTestRailProject.java | 3 - .../service/data/TestUnitTestRailSuite.java | 1 - .../manager/TestGeneralSavingManager.java | 42 +++++ .../testrail/unit/data/unitGatlingResult.java | 5 - .../unit/data/unitGatlingTestCase.java | 5 - 30 files changed, 428 insertions(+), 310 deletions(-) create mode 100644 testrail/DataSavingSequence.puml rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{data => }/GatlingResultService.java (96%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{data => }/GatlingTestCaseService.java (97%) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => manager}/export/ExportGatling.java (75%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => manager}/export/ExportServiceInterface.java (55%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => manager}/query/HttpSenderToTestRail.java (82%) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/SendResultData.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java delete mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java create mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java delete mode 100644 testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java diff --git a/testrail/DataSavingSequence.puml b/testrail/DataSavingSequence.puml new file mode 100644 index 0000000..90b1427 --- /dev/null +++ b/testrail/DataSavingSequence.puml @@ -0,0 +1,114 @@ +@startuml +'https://plantuml.com/sequence-diagram + + + +actor User +entity TRData +participant TRDataFactory #yellowgreen +participant DataInterface #red +participant ErrorHandler #red +participant DataSavingService #orange +participant TAFDataSavingService #orange +participant TRDataSavingService #orange +participant DataSender #lightblue +database DataStorage +collections TestRailAPI + + +== Creating From TAF to TestRail == +User -> DataInterface : new(...) + +activate DataInterface + +group Create TRData + DataInterface -> TRDataFactory : new(...) + + activate TRDataFactory + + TRDataFactory -> TRData : new(...) + + activate TRData + + TRData --> TRDataFactory : TRData + + deactivate TRData + + TRDataFactory --> DataInterface : TRData + + deactivate TRDataFactory +end + + + +DataInterface -> DataSavingService : saveData(TRData) + +activate DataSavingService + +DataSavingService -> DataSavingService : setDataUnSaved(Data) + +DataSavingService -> TRDataSavingService : saveData(TRData) + +activate TRDataSavingService + +TRDataSavingService -> DataSender : send(TRData) + +activate DataSender + +DataSender -> TestRailAPI : send(TRData) + +activate TestRailAPI +alt Success + TestRailAPI --> DataSender : success http code 200 + response + DataSender --> TRDataSavingService : success code 0 + response + TRDataSavingService -> TRDataSavingService : Update TRData with response + TRDataSavingService -> TRDataSavingService : setTRSaved(TRData) + TRDataSavingService --> DataSavingService : success code 0 + TRData + + + group Save Locally + + DataSavingService -> TAFDataSavingService : saveData(Data) + + activate TAFDataSavingService + + TAFDataSavingService -> DataStorage : send(Data) + + activate DataStorage + + DataStorage -> DataStorage : save(Data) + + DataStorage --> TAFDataSavingService : Data + + deactivate DataStorage + + TAFDataSavingService --> DataSavingService : Data + + deactivate TAFDataSavingService + end + + DataSavingService -> DataSavingService : setSaved(Data) + + +else Error + + TestRailAPI --> DataSender : error + response + deactivate TestRailAPI + + DataSender --> TRDataSavingService : error + response + + deactivate DataSender + + TRDataSavingService -> ErrorHandler : sendTRConnexionError(error, response) + + TRDataSavingService --> DataSavingService : error + TRData + + deactivate + + note over DataSavingService : Save Locally + DataSavingService -> DataSavingService : setLocallySaved(Data) +end + +DataSavingService --> DataInterface : code + TRData + +@enduml \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java index 2e01c55..b6c3523 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/TestRailProject.java @@ -55,6 +55,9 @@ public class TestRailProject extends TestRailData { @Column(name = "url") private String url; + @Column(name="is_saved") + private Boolean isSaved=false; + @ManyToMany(mappedBy = "projects") private List users; } diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java similarity index 96% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java index 26100a8..4f5d07f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.data; +package ca.etsmtl.taf.testrail.service; import ca.etsmtl.taf.testrail.model.entity.GatlingResult; import ca.etsmtl.taf.testrail.repository.GatlingResultRepository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java similarity index 97% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java index a40f1ee..f4d57d3 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.data; +package ca.etsmtl.taf.testrail.service; import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; import ca.etsmtl.taf.testrail.repository.GatlingTestCaseRepository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java new file mode 100644 index 0000000..1355ea0 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java @@ -0,0 +1,18 @@ +package ca.etsmtl.taf.testrail.service.manager; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import lombok.Getter; +import lombok.Setter; + + +@Getter +@Setter +public class DataResponseFromTR { + private int statusCode; + private TestRailProject data; + + public DataResponseFromTR(int statusCode, TestRailProject data) { + this.statusCode = statusCode; + this.data = data; + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java new file mode 100644 index 0000000..f99dc2c --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java @@ -0,0 +1,29 @@ +package ca.etsmtl.taf.testrail.service.manager; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class GeneralSavingManager { + + @Autowired + private ProjectSavingManager projectSavingManager; + + public TestRailProject createProject(String projectName) { + // Create the project + return TestRailProjectFactory.create(projectName); + } + + public void saveData(TestRailProject project) { + // Save the project + DataResponseFromTR dataResponseFromTR = projectSavingManager.saveData(project); + } + + public void deleteData(TestRailProject project) { + // Delete the project + DataResponseFromTR dataResponseFromTR = projectSavingManager.deleteData(project); + } + +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java new file mode 100644 index 0000000..a8a401e --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java @@ -0,0 +1,86 @@ +package ca.etsmtl.taf.testrail.service.manager; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.service.data.TestRailProjectService; +import ca.etsmtl.taf.testrail.service.manager.query.ProjectQueryTestRail; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class ProjectSavingManager { + + @Autowired + private ProjectQueryTestRail projectQueryTestRail; + + @Autowired + private TestRailProjectService testRailProjectService; + + private DataResponseFromTR newData(TestRailProject project) { + // Send the project to the TestRail + + TestRailProject trProject; + + DataResponseFromTR response = projectQueryTestRail.add(project.getName()); // TODO : Improve by adding other fields + + if (response.getStatusCode() == 0) { + trProject = response.getData(); + trProject.setIsSaved(true); + trProject = testRailProjectService.save(trProject);// Save the project in the database + return new DataResponseFromTR(0, trProject); + } else { + /* + * Even if the project is not added to TestRail, we can save it in the database to allow the user to add it later + * */ + trProject = project; + trProject.setIsSaved(false); + testRailProjectService.save(trProject); // Save the project in the database + return new DataResponseFromTR(1, trProject); // TODO : Améliorer la gestion des erreurs + } + } + + protected DataResponseFromTR saveData(TestRailProject project) { + // Check if the project already exists in the database + Optional trProject = testRailProjectService.findByName(project.getName()); + + if (trProject.isPresent()) { + // The project already exists in the database + // TODO : depending on if the project is the same or if the project isn't saved in TestRail, we can update the project + return new DataResponseFromTR(2, trProject.get()); + } else { + // The project doesn't exist in the database + return newData(project); + } + + } + + protected DataResponseFromTR deleteData(TestRailProject project) { + // Check if the project already exists in the database + Optional trProject = testRailProjectService.findByName(project.getName()); + + if (trProject.isPresent()) { + // The project already exists in the database + if (trProject.get().getTRId() != null && trProject.get().getIsSaved()) { + // The project is saved in TestRail delete it + DataResponseFromTR response = projectQueryTestRail.delete(trProject.get().getTRId()); + if (response.getStatusCode() == 0) { + // The project is deleted from TestRail + testRailProjectService.deleteByTafId(trProject.get().getId()); + return new DataResponseFromTR(0, null); + } else { + // The project is not deleted from TestRail + // TODO : Améliorer la gestion des erreurs + System.err.println("Erreur lors de la suppression du projet dans TR " + response.getStatusCode()); + return new DataResponseFromTR(1, null); + } + } else { + // The project is not saved in TestRail + testRailProjectService.deleteByTafId(trProject.get().getId()); + return new DataResponseFromTR(0, null); + } + } + // The project doesn't exist in the database + return new DataResponseFromTR(2, null); + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportGatling.java similarity index 75% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportGatling.java index ea5350e..0dd0042 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportGatling.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.export; +package ca.etsmtl.taf.testrail.service.manager.export; public class ExportGatling implements ExportServiceInterface { @Override diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportServiceInterface.java similarity index 55% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportServiceInterface.java index d09c01b..70ddc30 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/export/ExportServiceInterface.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/export/ExportServiceInterface.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.export; +package ca.etsmtl.taf.testrail.service.manager.export; public interface ExportServiceInterface { void exportData(); diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/HttpSenderToTestRail.java similarity index 82% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/HttpSenderToTestRail.java index 65f8917..86ea7da 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/HttpSenderToTestRail.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/HttpSenderToTestRail.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.query; +package ca.etsmtl.taf.testrail.service.manager.query; import org.springframework.stereotype.Component; @@ -25,23 +25,22 @@ public HttpSenderToTestRail() { // TODO : baseUrl, username and password will depend on the user } - private Optional send(HttpRequest request) { + private SendResultData send(HttpRequest request) { try { HttpClient client = HttpClient.newHttpClient(); HttpResponse response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { - return Optional.of(response.body()); + return new SendResultData(null, 200, response); } else { - return Optional.empty(); + return new SendResultData(null, response.statusCode(), response); } } catch (Exception e) { - e.printStackTrace(); // TODO : improve logging - return Optional.empty(); + return new SendResultData(e, 500, null); } } - public Optional postSender(String route, String body) { + public SendResultData postSender(String route, String body) { HttpRequest request = HttpRequest.newBuilder() .uri(java.net.URI.create(baseUrl + route)) .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((username + ":" + password).getBytes())) @@ -52,7 +51,7 @@ public Optional postSender(String route, String body) { return send(request); } - public Optional getSender(String route) { + public SendResultData getSender(String route) { HttpRequest request = HttpRequest.newBuilder() .uri(java.net.URI.create(baseUrl + route)) .header("Authorization", "Basic " + java.util.Base64.getEncoder().encodeToString((username + ":" + password).getBytes())) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java new file mode 100644 index 0000000..be2b6e6 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java @@ -0,0 +1,87 @@ +package ca.etsmtl.taf.testrail.service.manager.query; + +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; +import ca.etsmtl.taf.testrail.service.manager.DataResponseFromTR; + +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.stereotype.Service; + + +@Service +public class ProjectQueryTestRail implements QueryTestRail { + + /* + * Class that contains common requests about TestRail projects + * This class doesn't save the data, it only queries TestRail + * This class doesn't check if data is already loaded or in the database + * Class build assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ + + private final HttpSenderToTestRail httpSenderToTestRail; + + + public ProjectQueryTestRail() { + this.httpSenderToTestRail = new HttpSenderToTestRail(); // TODO : adapt to each user and environment + } + + + @Override + public DataResponseFromTR add(String projectName) { + /* + * Add a new project to TestRail + * @param projectName : name of the project to add + * @return TestRailProject object + * @Use getByName to get the project added + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + // Send a post request to add a new project + String route = "add_project"; + SendResultData result = httpSenderToTestRail.postSender(route, "{\"name\":\"" + projectName + "\"}"); + + // Check if the response is successful + + if (result.getStatusCode() != 200) { + System.err.println("Erreur lors de l'ajout du projet dans TR"); + return new DataResponseFromTR(1, null); + } + + // Convert the JSON response to a TestRailData object + try { + JSONObject projectJson = new JSONObject(result.getResponse().body()); + TestRailProject project = TestRailProjectFactory.create(projectJson); // Create a TestRailData object (TestRailProject) from the JSON* + return new DataResponseFromTR(0, project); // Return the project and the status code of the response + } catch (JSONException e) { + e.printStackTrace(); // TODO: Améliorer la gestion des erreurs + return new DataResponseFromTR(2, null); + } + } + + @Override + public DataResponseFromTR delete(int projectId) { + /* + * Delete a project from TestRail + * @param projectId : id of the project to delete + * @return TestRailProject object + * Tests : TODO + * Assisted by IA (copilot & chatGPT & intellij) + * */ + + // Send a post request to delete a project + String route = "delete_project/" + projectId; + SendResultData result = httpSenderToTestRail.postSender(route, ""); + + // Check if the response is successful + if (result.getStatusCode() != 200) { + System.err.println("Erreur lors de la suppression du projet dans TR"); + return new DataResponseFromTR(1, null); + } + + return new DataResponseFromTR(0, null); + } + +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java new file mode 100644 index 0000000..052696d --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java @@ -0,0 +1,17 @@ +package ca.etsmtl.taf.testrail.service.manager.query; + + +import ca.etsmtl.taf.testrail.service.manager.DataResponseFromTR; + +interface QueryTestRail { + /* + * Interface that contains common requests about TestRail data + * Those methods are implemented in the classes that will query TestRail + * */ + + + DataResponseFromTR add(String name); + + + DataResponseFromTR delete(int projectId); +} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/SendResultData.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/SendResultData.java new file mode 100644 index 0000000..b36d31f --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/SendResultData.java @@ -0,0 +1,21 @@ +package ca.etsmtl.taf.testrail.service.manager.query; + +import lombok.Getter; +import lombok.Setter; + +import java.net.http.HttpResponse; + + +@Getter +@Setter +public class SendResultData { + private Exception exception; + private int statusCode; + private HttpResponse response; + + public SendResultData(Exception exception, int statusCode, HttpResponse response) { + this.exception = exception; + this.statusCode = statusCode; + this.response = response; + } +} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java deleted file mode 100644 index 342f6b2..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/ProjectQueryTestRail.java +++ /dev/null @@ -1,160 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query; - -import ca.etsmtl.taf.testrail.model.entity.TestRailData; -import ca.etsmtl.taf.testrail.model.entity.TestRailProject; -import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.net.http.HttpResponse; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - - - -public class ProjectQueryTestRail implements QueryTestRail { - - /* - * Class that contains common requests about TestRail projects - * This class doesn't save the data, it only queries TestRail - * This class doesn't check if data is already loaded or in the database - * Class build assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO - * */ - - private final HttpSenderToTestRail httpSenderToTestRail; - - - public ProjectQueryTestRail() { - this.httpSenderToTestRail = new HttpSenderToTestRail(); // TODO : adapt to each user and environment - } - - - @Override - public List getAll() { - /* - * Query TestRail to get all projects accessible to the user - * @return List of TestRailProject objects - * Tests : TODO - * Assisted by IA (copilot & chatGPT & intellij) - * */ - - String route = "get_projects"; - Optional body = httpSenderToTestRail.getSender(route); - - if (body.isEmpty()) { - return new ArrayList<>(); - } - - // If response is correct, Body is a JSON object with a list of projects - // It contains a list of projects which are converted to TestRailProject objects - - try { - JSONObject jsonResponse = new JSONObject(body.get()); - JSONArray projectsArray = jsonResponse.getJSONArray("projects"); - List projects = new ArrayList<>(); - - for (int i = 0; i < projectsArray.length(); i++) { - JSONObject projectJson = projectsArray.getJSONObject(i); - TestRailProject project = TestRailProjectFactory.create(projectJson); // Create a TestRailProject object from the JSON object - projects.add(project); - } - - return projects; - } catch (JSONException e) { - e.printStackTrace(); // TODO: improve logging - return new ArrayList<>(); - } - - } - - @Override - public TestRailData addNew(String projectName) { - /* - * Add a new project to TestRail - * @param projectName : name of the project to add - * @return TestRailProject object - * @Use getByName to get the project added - * Tests : TODO - * Assisted by IA (copilot & chatGPT & intellij) - * */ - - // Send a post request to add a new project - String route = "add_project"; - HttpResponse response = null; - Optional body = httpSenderToTestRail.postSender(route, "{\"name\":\"" + projectName + "\"}"); - - // Check if the response is successful - - if (body.isEmpty()) { - System.err.println("Erreur lors de l'ajout du projet"); - return null; - } - - // Use getByName to get the project added - return getByName(projectName); - } - - @Override - public TestRailData getById(int id) { - - /* - * Query TestRail to get a project by its ID - * @param id : ID of the project to get - * @return TestRailProject object - * Tests : TODO - * Assisted by IA (copilot & chatGPT & intellij) - * */ - - // Build the route for the API - String route = "get_project/" + id; - - // Send the GET request via httpSenderToTestRail - Optional body = httpSenderToTestRail.getSender(route); - - // Check if the response body is present - if (body.isEmpty()) { - System.err.println("Projet avec l'ID " + id + " non trouvé."); - return null; - } - - // Convert the JSON response to a TestRailData object - try { - JSONObject projectJson = new JSONObject(body.get()); - return TestRailProjectFactory.create(projectJson); // Crée un objet TestRailData (TestRailProject) à partir du JSON - } catch (JSONException e) { - e.printStackTrace(); // TODO: Améliorer la gestion des erreurs - return null; - } - } - - @Override - public TestRailData getByName(String name) { - /* - * Query TestRail to get a project by its name - * @param name : name of the project to get - * @return TestRailProject object - * Use getAll to get all projects and search the project by name - * Tests : TODO - * Assisted by IA (copilot & chatGPT & intellij) - * */ - - // Retrieve all projects - List allProjects = getAll(); - - // Search for the project with the desired name - for (TestRailData project : allProjects) { - if (((TestRailProject) project).getName().equals(name)) { - return project; - } - } - - // If no project with the given name is found, return null or throw an exception if necessary - System.err.println("Project with the name \"" + name + "\" not found."); // TODO: improve logging - return null; - } -} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java deleted file mode 100644 index fdbeb9e..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/QueryTestRail.java +++ /dev/null @@ -1,21 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query; - -import ca.etsmtl.taf.testrail.model.entity.TestRailData; -import ca.etsmtl.taf.testrail.model.entity.TestRailProject; - -import java.util.List; - -interface QueryTestRail { - /* - * Interface that contains common requests about TestRail data - * Those methods are implemented in the classes that will query TestRail - * */ - - TestRailData getById(int id); - - TestRailData getByName(String name); - - List getAll(); - - TestRailData addNew(String name); -} \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java deleted file mode 100644 index f14121a..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadCase.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.load; - -public class LoadCase { - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java deleted file mode 100644 index 84a4870..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadData.java +++ /dev/null @@ -1,14 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.load; - -public interface LoadData { - /* - * Interface for loading data from TestRail. - * The methods need to be implemented in the classes that will load the data. - * Assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO - * */ - - void loadById(int id); - void loadByName(String name); - void loadAll(); -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java deleted file mode 100644 index 89c3ae9..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadProject.java +++ /dev/null @@ -1,35 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.load; - - -import lombok.Getter; -import lombok.Setter; -import org.springframework.stereotype.Component; - -@Getter -@Setter -@Component -public class LoadProject implements LoadData { - /* - * TODO - * This class is used to load project data from TestRail. - * The methods need to be implemented in the classes that will load the data. - * Assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO - * */ - - - @Override - public void loadById(int id) { - // TODO - } - - @Override - public void loadByName(String name) { - // TODO - } - - @Override - public void loadAll() { - // TODO - } -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java deleted file mode 100644 index e0b2acf..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadSuite.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.load; - -public class LoadSuite { - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java deleted file mode 100644 index d3ca3e3..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/load/LoadUser.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.load; - -public class LoadUser { - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java deleted file mode 100644 index 18ce7c8..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/Refresh.java +++ /dev/null @@ -1,6 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.refresh; - -public interface Refresh { - void refresh(String name); - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java deleted file mode 100644 index 29c762a..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshCase.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.refresh; - -public class RefreshCase { - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java deleted file mode 100644 index 747ea47..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshProject.java +++ /dev/null @@ -1,18 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.refresh; - -public class RefreshProject implements Refresh { - /* - * Class to refresh data from TestRail. - * Class build assisted by IA (copilot & chatGPT & intellij) - * */ - - @Override - public void refresh(String name) { - /* - * Update a project in the database. - * */ - - // Search if the project exists in the database - //TODO - } -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java deleted file mode 100644 index c26770c..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshSuite.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.refresh; - -public class RefreshSuite { - // TODO -} diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java deleted file mode 100644 index 3c062da..0000000 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/query/refresh/RefreshUser.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.service.query.refresh; - -public class RefreshUser { - // TODO -} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java index db97e0e..571a786 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailProject.java @@ -3,13 +3,10 @@ import ca.etsmtl.taf.testrail.TestConfig; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; -import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; import java.sql.Timestamp; diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java index 7d4af73..15975e6 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/data/TestUnitTestRailSuite.java @@ -2,7 +2,6 @@ import ca.etsmtl.taf.testrail.TestConfig; -import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.entity.TestRailSuite; import ca.etsmtl.taf.testrail.model.factory.TestRailSuiteFactory; import org.junit.jupiter.api.BeforeEach; diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java new file mode 100644 index 0000000..f1b9f4f --- /dev/null +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java @@ -0,0 +1,42 @@ +package ca.etsmtl.taf.testrail.service.manager; + + +import ca.etsmtl.taf.testrail.TestConfig; +import ca.etsmtl.taf.testrail.model.entity.TestRailProject; +import ca.etsmtl.taf.testrail.service.data.TestRailProjectService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.*; + +@ContextConfiguration(classes = TestConfig.class) +@DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" +}) +public class TestGeneralSavingManager { + @Autowired + private GeneralSavingManager generalSavingManager; + + @Autowired + private TestRailProjectService testRailProjectService; + + @Test + public void mainStory() { + String name = "GeneralSavingManager" + System.currentTimeMillis(); + generalSavingManager.saveData(generalSavingManager.createProject(name)); + TestRailProject project = testRailProjectService.findByName(name).orElse(null); + assertNotNull(project); + assertEquals(name, project.getName()); + assertEquals(true, project.getIsSaved()); // TODO : Only if the connection to TestRail is successful + + generalSavingManager.deleteData(project); + project = testRailProjectService.findByName(name).orElse(null); + assertNull(project); + + + } + +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java deleted file mode 100644 index b1bce6f..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingResult.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.unit.data; - -public class unitGatlingResult { - // TODO -} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java deleted file mode 100644 index d1a8ca4..0000000 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/unit/data/unitGatlingTestCase.java +++ /dev/null @@ -1,5 +0,0 @@ -package ca.etsmtl.taf.testrail.unit.data; - -public class unitGatlingTestCase { - // TODO -} From 34f9366072ca270cd7a338190f2317d6e05c7aa3 Mon Sep 17 00:00:00 2001 From: moshi Date: Fri, 1 Nov 2024 18:57:52 -0400 Subject: [PATCH 48/56] Adapting backend after meeting of 1st November 2024 --- testrail/Abstract classes.puml | 16 -- testrail/README.md | 243 ++++++++++++++++++ .../{ => data}/GatlingResultService.java | 2 +- .../{ => data}/GatlingTestCaseService.java | 2 +- .../manager/query/ProjectQueryTestRail.java | 2 +- .../service/manager/query/QueryTestRail.java | 3 +- .../{ => saving}/DataResponseFromTR.java | 2 +- .../{ => saving}/GeneralSavingManager.java | 2 +- .../{ => saving}/ProjectSavingManager.java | 2 +- .../manager/TestGeneralSavingManager.java | 1 + 10 files changed, 251 insertions(+), 24 deletions(-) delete mode 100644 testrail/Abstract classes.puml create mode 100644 testrail/README.md rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => data}/GatlingResultService.java (96%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/{ => data}/GatlingTestCaseService.java (97%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/{ => saving}/DataResponseFromTR.java (86%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/{ => saving}/GeneralSavingManager.java (94%) rename testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/{ => saving}/ProjectSavingManager.java (98%) diff --git a/testrail/Abstract classes.puml b/testrail/Abstract classes.puml deleted file mode 100644 index b1fdd2f..0000000 --- a/testrail/Abstract classes.puml +++ /dev/null @@ -1,16 +0,0 @@ -@startuml -'https://plantuml.com/class-diagram - -abstract class TestRailData - -class TestRailProject extends TestRailData - -class TestRailSuite extends TestRailData - -class GenericClassThatUsesTestRailData - -GenericClassThatUsesTestRailData *-- TestRailData - - - -@enduml \ No newline at end of file diff --git a/testrail/README.md b/testrail/README.md new file mode 100644 index 0000000..2f51f55 --- /dev/null +++ b/testrail/README.md @@ -0,0 +1,243 @@ +# TestRail module of TAF project + +## Summary + +This module is responsible for the integration of the TestRail tool with the TAF project. +It provides the possibility to exchange information with TestRail, a test management app. + +It is build as a Spring Boot multi-module application with backend as the main module. + +## Getting Started + +### Prerequisites + +- Java 17 +- Spring Boot 2.6.6 +- Maven + +### Build the project + +To build the project, run the following command: + +```bash +mvn clean install +``` + +### Run the project + +To run the project, run the following command: + +```bash +mvn spring-boot:run -pl backend +``` + + +## For developers + +As we don't have access to a proper documentation system, we will use this README file to document the project. +Like this, we are sure that the next developers will have access to the information. + +### Useful links + +#### Multi-module Spring projects + +- [Spring multi-module projects](https://spring.io/guides/gs/multi-module) +- [Getting Started | Creating a Multi Module Project](https://spring.io/guides/gs/multi-module) + +--- + +--- + +### Project structure + +--- +#### Sub-module configuration + +The submodule configuration is done in the [pom.xml](pom.xml) file and also inherited from the parent [TAF/pom.xml](../pom.xml) file. +The submodule is also declared in the main module configuration file [TAF/backend/pom.xml](../backend/pom.xml). + +The spring-boot application configuration should only be defined once in the main module configuration file [application.yml](../backend/src/main/resources/application.yml). + +--- +#### Database + +--- + +##### Database configuration + +In order to facilitate the development process, we used a docker hosted MariaDB database. + +A docker-compose file is available in the [docker-compose.yaml](./docker-compose.yaml) file. + +To adapt the spring-boot application to the database, the configuration is done in the [application.yml](../backend/src/main/resources/application.yml) file. You may need to adapt "datasource", "jpa" and "sql" properties. +You may also need to add to the pom.xml file the dependency to the MariaDB driver (or whatever database you are using). + +- pom.xml +```xml + + org.mariadb.jdbc + mariadb-java-client + 3.4.1 + +``` + +- application.yml +```yaml + +spring: + datasource: + url: jdbc:mariadb://localhost:3306/taf + username: root + password: root + jpa: + hibernate: + ddl-auto: update + properties: + hibernate: + dialect: org.hibernate.dialect.MariaDBDialect + sql: + init: + platform: mariadb +``` + +- docker-compose.yaml +```yaml + services: + mariadb: + image: mariadb:latest + container_name: mariadb-taf + environment: + MYSQL_ROOT_PASSWORD: taf-root + MYSQL_DATABASE: taf-db + MYSQL_USER: taf + MYSQL_PASSWORD: taf + ports: + - "3306:3306" + networks: + - taf-network + + + networks: + taf-network: + driver: bridge +``` + +#### Database schema + +The database schema dedicated to the TestRail module is automatically generated by Hibernate. The schema is generated in the database at the application startup. +The tables corresponding to the entities are created in the database. + +#### Database for tests + +For the tests, we use an in-memory H2 database which is automatically created and destroyed at the beginning and end of the tests. + +To use it, you should create proper test files in the [src/test/java/ca.etsmtl.taf.testrail](./src/test/java/ca.etsmtl.taf.testrail) subdirectories. The next code shows an example of a test file: + +```java + import org.junit.jupiter.api.Test; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + import org.springframework.test.context.ContextConfiguration; + + @ContextConfiguration(classes = TestConfig.class) + @DataJpaTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:testdb" + }) + public class TestUnitTestRailProject { + @Autowired + private TestRailRepository testRailRepository; + + // Your tests here + @Test + public void test() { + // Your test here + } + } +``` + +--- + +#### Module structure + +--- + +This section describes the structure of the module. +##### controller +> Contains the controllers of the module. The controllers are the classes that handle the HTTP requests. They are the entry point of the module. + +##### model +###### model/entity +>Contains the entities of the module. +>Each entity is a table in the database. Those class are meant to be used with the JPA repository. They only contain the fields of the table and the getters and setters. + +>All the data that are saved locally but are meant to be sent or received from the TestRail API start with "TestRail" followed by the name of the entity. The corresponding tables are the tables that start with "tr_". + +###### model/factory + +>Contains the factories of the entities. Those factories are used to create entities. They can be used to create entities from JSON objects. + +##### repository + +>Contains the repositories of the module. The repositories are the interfaces that handle the database operations. They are used to save, update, delete and retrieve entities from the database. + +##### service +###### service/data + +>Contains the services that handle the data of the module. They are classes to interact with the TAF database and not the TestRail API. + +###### service/manager + +>Contains the services that handle the data gesture. + +service/manager/saving + +>Those class are interfaces the user can interact with to save data. They handle the data saving between the database and the API. + +service/manager/query + +>Those class are interfaces the user can interact with to query data. They are used to send and receive data from the API and **not** the database. + +--- + +#### How the module handle data saving between the database and the API + +We consider that we have multiple constraints concerning the data. As we are never sure to be able to publish data to TestRail immediately, we need to save the data in the database and then publish it to TestRail. +But this can lead to duplication or loss of data. To avoid this, we have implemented a system that allows us to save the data in the database and then publish it to TestRail. That's why we decided to gesture that data like in the following diagram: + +- Example when user wants to add a new data (not depending on the data type) +![Data saving](./DataSavingSequence.svg) + +The module try to save the data remotely and then locally. If the remote saving fails, the local saving ensure that the data is saved and the user can continue to work. The data will be published to TestRail later. + +--- + +#### Limitations + +##### TestRail API + +As we had a limited time we haven't covered all the TestRail data. We have only covered the data that we needed to start the module. But more types can be added easily when following the same classes structures. + +We also haven't covered all the failure cases. We have only covered the more frequent and basic ones. + +##### Failure cases and reports + +Handling errors is something very important and this project doesn't report and save errors. Dedicated classes that can handle errors can be a good addition to the project and help a lot of debugging. + +##### Data from TAF + +As none of the other groups have yet a structure to save their data after testing, we had issue to use their data and to export them. That's why we focused more on TestRail API than that. Nevertheless, we started to develop interactions with gatling output. In order to do that, we simulated a potential structure for Gatling output data (entity). + +--- +#### Tests + +We have done some tests especially for entity. +Each entity have a dedicated test file that test each of the interactions with the entity. + +We also have done some integration tests to validate data creation and deletion in the database and TestRail API through the managing classes. + +--- + +#### Job to be done + +We wrote "TODO" comments in the code to indicate missing parts or parts that need to be improved. We also wrote some comments to indicate what we have done and what we have not done. \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java similarity index 96% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java index 4f5d07f..26100a8 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingResultService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingResultService.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service; +package ca.etsmtl.taf.testrail.service.data; import ca.etsmtl.taf.testrail.model.entity.GatlingResult; import ca.etsmtl.taf.testrail.repository.GatlingResultRepository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java similarity index 97% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java index f4d57d3..a40f1ee 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/GatlingTestCaseService.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/data/GatlingTestCaseService.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service; +package ca.etsmtl.taf.testrail.service.data; import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; import ca.etsmtl.taf.testrail.repository.GatlingTestCaseRepository; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java index be2b6e6..9759fb1 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/ProjectQueryTestRail.java @@ -2,7 +2,7 @@ import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; -import ca.etsmtl.taf.testrail.service.manager.DataResponseFromTR; +import ca.etsmtl.taf.testrail.service.manager.saving.DataResponseFromTR; import org.json.JSONException; import org.json.JSONObject; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java index 052696d..3a4bac5 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/query/QueryTestRail.java @@ -1,7 +1,7 @@ package ca.etsmtl.taf.testrail.service.manager.query; -import ca.etsmtl.taf.testrail.service.manager.DataResponseFromTR; +import ca.etsmtl.taf.testrail.service.manager.saving.DataResponseFromTR; interface QueryTestRail { /* @@ -12,6 +12,5 @@ interface QueryTestRail { DataResponseFromTR add(String name); - DataResponseFromTR delete(int projectId); } \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/DataResponseFromTR.java similarity index 86% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/DataResponseFromTR.java index 1355ea0..6d9e0ac 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/DataResponseFromTR.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/DataResponseFromTR.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.manager; +package ca.etsmtl.taf.testrail.service.manager.saving; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import lombok.Getter; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java similarity index 94% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java index f99dc2c..b81da06 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/GeneralSavingManager.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.manager; +package ca.etsmtl.taf.testrail.service.manager.saving; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/ProjectSavingManager.java similarity index 98% rename from testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java rename to testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/ProjectSavingManager.java index a8a401e..4c2b89f 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/ProjectSavingManager.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/ProjectSavingManager.java @@ -1,4 +1,4 @@ -package ca.etsmtl.taf.testrail.service.manager; +package ca.etsmtl.taf.testrail.service.manager.saving; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.service.data.TestRailProjectService; diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java index f1b9f4f..77a72f5 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/manager/TestGeneralSavingManager.java @@ -4,6 +4,7 @@ import ca.etsmtl.taf.testrail.TestConfig; import ca.etsmtl.taf.testrail.model.entity.TestRailProject; import ca.etsmtl.taf.testrail.service.data.TestRailProjectService; +import ca.etsmtl.taf.testrail.service.manager.saving.GeneralSavingManager; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; From ef4c32620f8e4cc65c55aadf81781f6a12d8ae03 Mon Sep 17 00:00:00 2001 From: moshi Date: Sun, 3 Nov 2024 14:33:12 -0500 Subject: [PATCH 49/56] Meeting --- testrail/DataSavingSequence.svg | 1 + testrail/README.md | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 testrail/DataSavingSequence.svg diff --git a/testrail/DataSavingSequence.svg b/testrail/DataSavingSequence.svg new file mode 100644 index 0000000..510cd2f --- /dev/null +++ b/testrail/DataSavingSequence.svg @@ -0,0 +1 @@ +UserUserTRDataTRDataTRDataFactoryTRDataFactoryDataInterfaceDataInterfaceErrorHandlerErrorHandlerDataSavingServiceDataSavingServiceTAFDataSavingServiceTAFDataSavingServiceTRDataSavingServiceTRDataSavingServiceDataSenderDataSenderDataStorageDataStorageTestRailAPITestRailAPICreating From TAF to TestRailnew(...)Create TRDatanew(...)new(...)TRDataTRDatasaveData(TRData)setDataUnSaved(Data)saveData(TRData)send(TRData)send(TRData)alt[Success]success http code 200 + responsesuccess code 0 + responseUpdate TRData with responsesetTRSaved(TRData)success code 0 + TRDataSave LocallysaveData(Data)send(Data)save(Data)DataDatasetSaved(Data)[Error]error + responseerror + responsesendTRConnexionError(error, response)error + TRDataSave LocallysetLocallySaved(Data)code + TRData \ No newline at end of file diff --git a/testrail/README.md b/testrail/README.md index 2f51f55..b411526 100644 --- a/testrail/README.md +++ b/testrail/README.md @@ -17,7 +17,7 @@ It is build as a Spring Boot multi-module application with backend as the main m ### Build the project -To build the project, run the following command: +To build the project, run the following command in the root directory of the project: ```bash mvn clean install @@ -25,7 +25,7 @@ mvn clean install ### Run the project -To run the project, run the following command: +To run the project, run the following command in the root directory of the project: ```bash mvn spring-boot:run -pl backend @@ -236,8 +236,16 @@ Each entity have a dedicated test file that test each of the interactions with t We also have done some integration tests to validate data creation and deletion in the database and TestRail API through the managing classes. +Tests can be run with the following command when you are in the taf directory: + +```bash +mvn test +``` + --- #### Job to be done -We wrote "TODO" comments in the code to indicate missing parts or parts that need to be improved. We also wrote some comments to indicate what we have done and what we have not done. \ No newline at end of file +We wrote "TODO" comments in the code to indicate missing parts or parts that need to be improved. We also wrote some comments to indicate what we have done and what we have not done. + +It will also be necessary to create and then link the backend with frontend pages. \ No newline at end of file From 96868ab5482e4ceb472f4f6b297ebcd40cc91628 Mon Sep 17 00:00:00 2001 From: yanth Date: Sun, 3 Nov 2024 15:13:23 -0500 Subject: [PATCH 50/56] [test] Test creation of TestRailCase with Simulation.java gatling file success --- .../collector/TempTestCaseGatling.java | 22 ++++++++---- .../collector/TestTempTestCaseGatling.java | 35 ++++++++++++++----- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java index 17546f0..730d7dd 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/collector/TempTestCaseGatling.java @@ -1,6 +1,7 @@ package ca.etsmtl.taf.testrail.service.collector; import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; import java.io.*; import java.util.HashMap; @@ -17,6 +18,7 @@ public class TempTestCaseGatling { private static final Logger logger = Logger.getLogger(TempTestCaseGatling.class.getName()); static { + logger.setLevel(Level.OFF); try { String currentPath = System.getProperty("user.dir"); logger.info("Chemin de l'exécution : " + currentPath); @@ -37,14 +39,11 @@ public class TempTestCaseGatling { private String scenarioName; private String baseUrl; private String userInjection; - - private Map usersInjection = new HashMap<>(); - public GatlingTestCase parse() { + public GatlingTestCase parse(String SimulationFile) { logger.setLevel(Level.INFO); - String SimulationPath = "SimpleSimulation.java"; - logger.info("SimulationPath=" + SimulationPath); + logger.info("SimulationFile=" + SimulationFile); String gatlingScript = ""; - try (InputStream inputStream = TempTestCaseGatling.class.getClassLoader().getResourceAsStream(SimulationPath); + try (InputStream inputStream = TempTestCaseGatling.class.getClassLoader().getResourceAsStream(SimulationFile); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { String line; while ((line = reader.readLine()) != null) { @@ -95,4 +94,15 @@ public GatlingTestCase parse() { return gatlingTestCase; } + + public GatlingTestCase parse() { + return parse("SimpleSimulation.java"); + } + + public TestRailCase toTestRailCase(GatlingTestCase gatlingTestCase) { + TestRailCase testRailCase = new TestRailCase(); + testRailCase.setTitle(gatlingTestCase.getScenarioName()); + testRailCase.setSectionId(1); // Default section + return testRailCase; + } } \ No newline at end of file diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java index 911b18a..b167819 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java @@ -1,18 +1,12 @@ package ca.etsmtl.taf.testrail.service.collector; -import ca.etsmtl.taf.testrail.TestConfig; import ca.etsmtl.taf.testrail.model.entity.GatlingTestCase; -import ca.etsmtl.taf.testrail.model.entity.TestRailProject; -import ca.etsmtl.taf.testrail.model.factory.TestRailProjectFactory; -import ca.etsmtl.taf.testrail.repository.TestRailProjectRepository; -import ca.etsmtl.taf.testrail.service.collector.TempTestCaseGatling; +import ca.etsmtl.taf.testrail.model.entity.TestRailCase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.context.ContextConfiguration; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.LocalDate; import java.time.LocalTime; @@ -40,4 +34,27 @@ public void test() { assertEquals("https://wikijs.fornoff.fr", gatlingTestCase.getBaseUrl()); assertEquals("(Scenario.injectOpen(rampUsers(10).during(5))).protocols(httpProtocol)", gatlingTestCase.getUserInjection()); } + + @Test + public void testWithFileInRessources() { + String fileName = "SimpleSimulation.java"; + TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); + GatlingTestCase gatlingTestCase = tempTestCaseGatling.parse(fileName); + assertNotNull(gatlingTestCase); + assertEquals("My First Scenario", gatlingTestCase.getScenarioName()); + assertEquals("https://wikijs.fornoff.fr", gatlingTestCase.getBaseUrl()); + assertEquals("(Scenario.injectOpen(rampUsers(10).during(5))).protocols(httpProtocol)", gatlingTestCase.getUserInjection()); + } + + @Test + public void testToTestRailCase() { + TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); + GatlingTestCase gatlingTestCase = tempTestCaseGatling.parse(); + assertNotNull(gatlingTestCase); + + TestRailCase testRailCase = tempTestCaseGatling.toTestRailCase(gatlingTestCase); + assertEquals("My First Scenario", testRailCase.getTitle()); + assertEquals(1, testRailCase.getSectionId()); + } + } \ No newline at end of file From 636d7c14a80930b831bfdab58502efd9d6ec07a9 Mon Sep 17 00:00:00 2001 From: moshi Date: Tue, 5 Nov 2024 15:43:32 -0500 Subject: [PATCH 51/56] Meeting --- .../testrail/model/entity/DataClassUsage.puml | 69 +++++++++++++++++++ .../testrail/model/entity/GatlingClasses.puml | 36 ++++++++++ .../manager/saving/GeneralSavingManager.java | 1 + 3 files changed, 106 insertions(+) create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/DataClassUsage.puml create mode 100644 testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingClasses.puml diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/DataClassUsage.puml b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/DataClassUsage.puml new file mode 100644 index 0000000..7ee3bcd --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/DataClassUsage.puml @@ -0,0 +1,69 @@ +@startuml +'https://plantuml.com/class-diagram + +class TestRailXXX extends TestRailData { + @Entity + @Getter & Setter + @Table tr_xxx +} + +class TestRailXXXFactory { + @Component + + + create(String name): TestRailXXX + + create(JSONObject xxxJson) : TestRailXXX +} + +interface TestRailxxxRepository extends JpaRepository { + @Repository + Optional findByTRId(Integer id); + + Optional findByName(String name); + ... +} + +class TestRailxxxService { + @Service + + - TestRailxxxRepository testRailxxxRepository + - TestRailxxxFactory testRailxxxFactory + + + create(String name): TestRailXXX + + create(JSONObject xxxJson) : TestRailXXX + + save(TestRailXXX xxx): TestRailXXX + + findById(Long id): Optional + + findByTRId(Integer id): Optional + + findByName(String name): Optional + ... +} + +class xxxSavingManager { + @Service + + - TestRailxxxService testRailxxxService + - xxxQueryTestRail xxxQueryTestRail + + + save(TestRailXXX xxx): DataResponseFromTR + + delete(TestRailXXX xxx): DataResponseFromTR + ... +} + +class xxxQueryTestRail { + @Static class + - HttpSenderToTR httpSenderToTR + + + add(String (String name) : DataResponseFromTR + + + delete(String name) : DataResponseFromTR +} + +class GeneralSavingManager { + @Service + + - xxxSavingManager xxxSavingManager + + + saveXXX(TestRailXXX xxx): void + + deleteXXX(TestRailXXX xxx): void +} + +@enduml \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingClasses.puml b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingClasses.puml new file mode 100644 index 0000000..9d12c03 --- /dev/null +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingClasses.puml @@ -0,0 +1,36 @@ +@startuml +'https://plantuml.com/class-diagram + + +class GatlingTestCase { + @Entity + @Getter & Setter + @Table tr_gatling_test_case + + - id: Long + - sectionId: int + - title: String + - templateId: int + - typeId: int + - priorityId: int + - estimate: TimeStamp + - milestoneId: int + - refs: String + +} +class GatlingResult { + @Entity + @Getter & Setter + @Table tr_gatling_result + + - id: Long + - statusId: int + - comment: String + - version: String + - elapsed: String + - defects: String + - assignedToId: int + - date: TimeStamp +} + +@enduml \ No newline at end of file diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java index b81da06..952137c 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/service/manager/saving/GeneralSavingManager.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; + @Service public class GeneralSavingManager { From 7355a9b7f0b25cc99d9dc2292945874e6c96342b Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 5 Nov 2024 15:44:34 -0500 Subject: [PATCH 52/56] [test] New tests --- .../resources/ComputerDatabaseSimulation.java | 92 ++++++++++++++ .../main/resources/RecordedSimulation.java | 116 ++++++++++++++++++ .../collector/TestTempTestCaseGatling.java | 21 ++++ 3 files changed, 229 insertions(+) create mode 100644 testrail/src/main/resources/ComputerDatabaseSimulation.java create mode 100644 testrail/src/main/resources/RecordedSimulation.java diff --git a/testrail/src/main/resources/ComputerDatabaseSimulation.java b/testrail/src/main/resources/ComputerDatabaseSimulation.java new file mode 100644 index 0000000..aff8024 --- /dev/null +++ b/testrail/src/main/resources/ComputerDatabaseSimulation.java @@ -0,0 +1,92 @@ +package computerdatabase; + +import io.gatling.javaapi.core.*; +import io.gatling.javaapi.http.*; + +import java.util.concurrent.ThreadLocalRandom; + +import static io.gatling.javaapi.core.CoreDsl.*; +import static io.gatling.javaapi.http.HttpDsl.*; + +/** + * This sample is based on our official tutorials: + * + */ +public class ComputerDatabaseSimulation extends Simulation { + + FeederBuilder feeder = csv("search.csv").random(); + + ChainBuilder search = exec( + http("Home").get("/"), + pause(1), + feed(feeder), + http("Search") + .get("/computers?f=#{searchCriterion}") + .check( + css("a:contains('#{searchComputerName}')", "href").saveAs("computerUrl") + ), + pause(1), + http("Select") + .get("#{computerUrl}") + .check(status().is(200)), + pause(1) + ); + + // repeat is a loop resolved at RUNTIME + ChainBuilder browse = + // Note how we force the counter name, so we can reuse it + repeat(4, "i").on( + http("Page #{i}").get("/computers?p=#{i}"), + pause(1) + ); + + // Note we should be using a feeder here + // let's demonstrate how we can retry: let's make the request fail randomly and retry a given + // number of times + + ChainBuilder edit = + // let's try at max 2 times + tryMax(2) + .on( + http("Form").get("/computers/new"), + pause(1), + http("Post") + .post("/computers") + .formParam("name", "Beautiful Computer") + .formParam("introduced", "2012-05-30") + .formParam("discontinued", "") + .formParam("company", "37") + .check( + status().is( + // we do a check on a condition that's been customized with + // a lambda. It will be evaluated every time a user executes + // the request + session -> 200 + ThreadLocalRandom.current().nextInt(2) + ) + ) + ) + // if the chain didn't finally succeed, have the user exit the whole scenario + .exitHereIfFailed(); + + HttpProtocolBuilder httpProtocol = + http.baseUrl("https://computer-database.gatling.io") + .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + .acceptLanguageHeader("en-US,en;q=0.5") + .acceptEncodingHeader("gzip, deflate") + .userAgentHeader( + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0" + ); + + ScenarioBuilder users = scenario("Users").exec(search, browse); + ScenarioBuilder admins = scenario("Admins").exec(search, browse, edit); + + { + setUp( + users.injectOpen(rampUsers(10).during(10)), + admins.injectOpen(rampUsers(2).during(10)) + ).protocols(httpProtocol); + } +} diff --git a/testrail/src/main/resources/RecordedSimulation.java b/testrail/src/main/resources/RecordedSimulation.java new file mode 100644 index 0000000..e98c5b5 --- /dev/null +++ b/testrail/src/main/resources/RecordedSimulation.java @@ -0,0 +1,116 @@ +package computerdatabase; + +import io.gatling.javaapi.core.*; +import io.gatling.javaapi.http.*; +import io.gatling.javaapi.jdbc.*; + +import java.util.Map; + +import static io.gatling.javaapi.core.CoreDsl.*; +import static io.gatling.javaapi.core.CoreDsl.AllowList; +import static io.gatling.javaapi.core.CoreDsl.DenyList; +import static io.gatling.javaapi.core.CoreDsl.RawFileBody; +import static io.gatling.javaapi.core.CoreDsl.atOnceUsers; +import static io.gatling.javaapi.core.CoreDsl.pause; +import static io.gatling.javaapi.core.CoreDsl.scenario; +import static io.gatling.javaapi.http.HttpDsl.*; +import static io.gatling.javaapi.http.HttpDsl.http; +import static io.gatling.javaapi.jdbc.JdbcDsl.*; + +public class RecordedSimulation extends Simulation { + + private HttpProtocolBuilder httpProtocol = http + .baseUrl("https://computer-database.gatling.io") + .inferHtmlResources(AllowList(), DenyList(".*\\.js", ".*\\.css", ".*\\.gif", ".*\\.jpeg", ".*\\.jpg", ".*\\.ico", ".*\\.woff", ".*\\.woff2", ".*\\.(t|o)tf", ".*\\.png", ".*\\.svg", ".*detectportal\\.firefox\\.com.*")) + .userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"); + + private Map headers_0 = Map.ofEntries( + Map.entry("Accept-Encoding", "gzip, deflate"), + Map.entry("Content-Type", "application/json"), + Map.entry("Proxy-Connection", "keep-alive"), + Map.entry("User-Agent", "Mozilla/5.0 (Windows NT 10.0.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.190 Safari/537.36 CreativeCloud/6.4.0.361"), + Map.entry("X-Goog-Update-AppId", "oimompecagnajdejgnnjijobebaeigek"), + Map.entry("X-Goog-Update-Interactivity", "bg"), + Map.entry("X-Goog-Update-Updater", "chromium-116.0.5845.190") + ); + + private Map headers_1 = Map.ofEntries( + Map.entry("Accept", "*/*"), + Map.entry("Accept-Encoding", "identity"), + Map.entry("Proxy-Connection", "Keep-Alive"), + Map.entry("User-Agent", "Microsoft BITS/7.8") + ); + + private Map headers_2 = Map.ofEntries( + Map.entry("Accept", "*/*"), + Map.entry("Accept-Encoding", "identity"), + Map.entry("If-Unmodified-Since", "Wed, 04 Sep 2024 02:15:41 GMT"), + Map.entry("Proxy-Connection", "Keep-Alive"), + Map.entry("User-Agent", "Microsoft BITS/7.8") + ); + + private Map headers_3 = Map.ofEntries( + Map.entry("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"), + Map.entry("Accept-Encoding", "gzip, deflate, br, zstd"), + Map.entry("Accept-Language", "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"), + Map.entry("Sec-Fetch-Dest", "document"), + Map.entry("Sec-Fetch-Mode", "navigate"), + Map.entry("Sec-Fetch-Site", "same-origin"), + Map.entry("Sec-Fetch-User", "?1"), + Map.entry("Upgrade-Insecure-Requests", "1"), + Map.entry("sec-ch-ua", "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\""), + Map.entry("sec-ch-ua-mobile", "?0"), + Map.entry("sec-ch-ua-platform", "\"Windows\"") + ); + + private Map headers_4 = Map.ofEntries( + Map.entry("Connection", "Close"), + Map.entry("User-Agent", "Microsoft NCSI") + ); + + private String uri1 = "http://www.msftconnecttest.com/connecttest.txt"; + + private String uri3 = "http://update.googleapis.com/service/update2/json"; + + private String uri4 = "http://msedge.b.tlu.dl.delivery.mp.microsoft.com/filestreamingservice/files/0c12dff9-696d-48d4-bbe8-7d8bdad98e65"; + + private ScenarioBuilder scn = scenario("RecordedSimulation") + .exec( + http("request_0") + .post(uri3 + "?cup2key=13:ETSC62eQPBdzjDvWT1nXYDpHCMJXLXm2vUlMeDZN_kI&cup2hreq=1066f8336924ff1f28a0742fff9d87b0f91dac3ab2ff0fea9b0799dc1c981fda") + .headers(headers_0) + .body(RawFileBody("computerdatabase/recordedsimulation/0000_request.json")) + .resources( + http("request_1") + .head(uri4 + "?P1=1728104938&P2=404&P3=2&P4=KUdccXgREyurgJYdWoh42hOnQj1XBpkNDhYQiYUam19le6BbBS7%2fnP2llZRqz4libseByWx%2fQWUl%2f%2bbl6g%2fuvQ%3d%3d") + .headers(headers_1), + http("request_2") + .get(uri4 + "?P1=1728104938&P2=404&P3=2&P4=KUdccXgREyurgJYdWoh42hOnQj1XBpkNDhYQiYUam19le6BbBS7%2fnP2llZRqz4libseByWx%2fQWUl%2f%2bbl6g%2fuvQ%3d%3d") + .headers(headers_2) + ), + pause(7), + http("request_3") + .get("/computers") + .headers(headers_3), + pause(4), + http("request_4") + .get(uri1) + .headers(headers_4), + pause(1), + http("request_5") + .get("/computers") + .headers(headers_3), + pause(5), + http("request_6") + .get("/computers?f=apple") + .headers(headers_3), + pause(10), + http("request_7") + .get("/computers?p=1&f=apple") + .headers(headers_3) + ); + + { + setUp(scn.injectOpen(atOnceUsers(20))).protocols(httpProtocol); + } +} diff --git a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java index b167819..cee153d 100644 --- a/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java +++ b/testrail/src/test/java/ca/etsmtl/taf/testrail/service/collector/TestTempTestCaseGatling.java @@ -57,4 +57,25 @@ public void testToTestRailCase() { assertEquals(1, testRailCase.getSectionId()); } + @Test + public void testRecordedSimulation() { + String fileName = "RecordedSimulation.java"; + TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); + GatlingTestCase gatlingTestCase = tempTestCaseGatling.parse(fileName); + assertNotNull(gatlingTestCase); + assertEquals("RecordedSimulation", gatlingTestCase.getScenarioName()); + assertEquals("https://computer-database.gatling.io", gatlingTestCase.getBaseUrl()); + assertEquals("(scn.injectOpen(atOnceUsers(20))).protocols(httpProtocol)", gatlingTestCase.getUserInjection()); + } + + @Test + public void testComputerDatabaseSimulation() { + String fileName = "ComputerDatabaseSimulation.java"; + TempTestCaseGatling tempTestCaseGatling = new TempTestCaseGatling(); + GatlingTestCase gatlingTestCase = tempTestCaseGatling.parse(fileName); + assertNotNull(gatlingTestCase); + assertEquals("Users", gatlingTestCase.getScenarioName()); + assertEquals("https://computer-database.gatling.io", gatlingTestCase.getBaseUrl()); + assertEquals("(users.injectOpen(rampUsers(10).during(10)),admins.injectOpen(rampUsers(2).during(10))).protocols(httpProtocol)", gatlingTestCase.getUserInjection()); + } } \ No newline at end of file From 9f2ea0cb27cb144262f45ed566772ec72e3a50dd Mon Sep 17 00:00:00 2001 From: yanth Date: Sat, 9 Nov 2024 10:10:23 -0500 Subject: [PATCH 53/56] [fix] maven test build --- .../model/entity/GatlingTestCase.java | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java index 91c500e..653205c 100644 --- a/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java +++ b/testrail/src/main/java/ca/etsmtl/taf/testrail/model/entity/GatlingTestCase.java @@ -4,6 +4,8 @@ import lombok.Getter; import lombok.Setter; +import java.sql.Timestamp; + @Entity @Table(name = "tr_gatling_test_case") @Getter @@ -11,14 +13,59 @@ public class GatlingTestCase { /* - * Assisted by IA (copilot & chatGPT & intellij) - * Tests : TODO - * */ + * Assisted by IA (copilot & chatGPT & intellij) + * Tests : TODO + * */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "tr_id", unique = true, nullable = true) + private Integer TRId; + + @Column(name = "title", nullable = false, unique = true) + private String title; + + @Column(name = "section_id") + private Integer sectionId; + + @Column(name = "type_id") + private Integer typeId; + + @Column(name = "priority_id") + private Integer priorityId; + + @Column(name = "milestone_id") + private Integer milestoneId; + + @Column(name = "refs") + private String refs; + + @Column(name = "created_by") + private Integer createdBy; + + @Column(name = "created_on") + private Timestamp createdOn; + + @Column(name = "updated_by") + private Integer updatedBy; + + @Column(name = "updated_on") + private Timestamp updatedOn; + + @Column(name = "estimate") + private Timestamp estimate; + + @Column(name = "estimate_forecast") + private Timestamp estimateForecast; + + @Column(name = "suite_id") + private Integer suiteId; + + @Column(name = "template_id") + private Integer templateId; + @Column(name = "scenario_name", nullable = false) private String scenarioName; From ec6ed4f3bc91d0a3d953a86a01834a566330a980 Mon Sep 17 00:00:00 2001 From: yanth Date: Sat, 9 Nov 2024 10:36:25 -0500 Subject: [PATCH 54/56] [fix] dependencies javax --- testrail/pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/testrail/pom.xml b/testrail/pom.xml index a4d6bb1..32e879c 100644 --- a/testrail/pom.xml +++ b/testrail/pom.xml @@ -40,6 +40,16 @@ test
+ + javax.persistence + persistence-api + 1.0.2 + provided + + + + + From 46b32c13456d697e9c7bdd9ae08e21918bbaa4e7 Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 12 Nov 2024 16:08:18 -0500 Subject: [PATCH 55/56] [fix] javax import in backend classes instead of jakarta (because type conflicts with interface --- backend/pom.xml | 28 +++++++++++++++++++ .../taf/security/WebSecurityConfig.java | 3 +- .../taf/security/jwt/AuthEntryPointJwt.java | 6 ++-- .../taf/security/jwt/AuthTokenFilter.java | 8 +++--- testrail/pom.xml | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index 4b451e2..37ce890 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -52,6 +52,34 @@ 1.18.24 provided + + + jakarta.validation + jakarta.validation-api + 3.0.0 + + + + + jakarta.persistence + jakarta.persistence-api + 3.1.0 + + + + + jakarta.servlet + jakarta.servlet-api + [5.0.0,) + + + + + org.hibernate.validator + hibernate-validator + 7.0.2.Final + + org.springframework.boot diff --git a/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java b/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java index 7df0caf..fff336e 100644 --- a/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java +++ b/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java @@ -17,6 +17,7 @@ import ca.etsmtl.taf.security.jwt.AuthEntryPointJwt; import ca.etsmtl.taf.security.jwt.AuthTokenFilter; import ca.etsmtl.taf.security.services.UserDetailsServiceImpl; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity @@ -51,7 +52,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeHttpRequests((authz) -> authz - .requestMatchers("/**").permitAll() // جایگزین antMatchers + .requestMatchers(new AntPathRequestMatcher("/**")).permitAll() // جایگزین antMatchers ); http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); diff --git a/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwt.java b/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwt.java index 4f000a4..189cda9 100644 --- a/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwt.java +++ b/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwt.java @@ -4,9 +4,9 @@ import java.util.HashMap; import java.util.Map; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthTokenFilter.java b/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthTokenFilter.java index 849943a..5f57b7c 100644 --- a/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthTokenFilter.java +++ b/backend/src/main/java/ca/etsmtl/taf/security/jwt/AuthTokenFilter.java @@ -2,10 +2,10 @@ import java.io.IOException; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/testrail/pom.xml b/testrail/pom.xml index 32e879c..4e1e7b8 100644 --- a/testrail/pom.xml +++ b/testrail/pom.xml @@ -44,7 +44,7 @@ javax.persistence persistence-api 1.0.2 - provided + import From 87f0f2948c85188594bde5f0df57b1fb45f64b38 Mon Sep 17 00:00:00 2001 From: yanth Date: Tue, 12 Nov 2024 16:09:48 -0500 Subject: [PATCH 56/56] [fix] delete empty test --- .../etsmtl/taf/TestAutomationFrameworkApplicationTests.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java b/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java index 691ad31..f4138ff 100644 --- a/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java +++ b/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java @@ -6,8 +6,4 @@ @SpringBootTest class TestAutomationFrameworkApplicationTests { - @Test - void contextLoads() { - } - }