Skip to content

Commit

Permalink
Corrected pom file, updated sonar plugin and github actions configura…
Browse files Browse the repository at this point in the history
…tion; Improved code coverage as much as possible; Updated readme with instructions about usage of application
  • Loading branch information
MarkoDojkic committed Nov 8, 2024
1 parent 01361e9 commit dd83add
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 60 deletions.
20 changes: 13 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
name: Software-Development-Simulation-Main-Build
name: Build and Analyze with SonarQube

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
name: Build and analyze
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 22
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
java-version: 22
distribution: 'corretto'
- name: Cache SonarQube packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Pre-fetch Maven dependencies
run: mvn dependency:go-offline
- name: Cache Maven packages
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
Expand All @@ -34,4 +40,4 @@ jobs:
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=Software-Development-Simulation -Dsonar.projectName='Software Development Simulation' -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
run: mvn clean install -B verify sonar:sonar
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,31 @@
![SonarQube Quality Gate](https://img.shields.io/badge/SonarQube%20Quality%20Gate-Passed-brightgreen)
![SonarQube Duplicated Lines](https://img.shields.io/badge/SonarQube%20Duplicated%20Lines-0%25-brightgreen)
![SonarQube LOC](https://img.shields.io/badge/SonarQube%20LOC-2000-blue)
![JaCoCo Coverage](https://img.shields.io/badge/JaCoCo%20Coverage-93.1%25-brightgreen)
![JaCoCo Coverage](https://img.shields.io/badge/JaCoCo%20Coverage-95.8%25-brightgreen)

**Note:** SonarQube information is based on the last GitHub Action run and is generated locally. As such, there is no direct link available to the SonarQube dashboard.

## Overview

The Software Development Simulation project is a web-based application designed to simulate and manage software development tasks. It utilizes Spring Boot for backend services, Spring Integration for messaging, and integrates with Swagger for API documentation.

## Usage guide

This application is to be used from web interface that has two views:

1. Main view on index page, with fallowing features:
- Allows user input for desired number of randomly generated development Epics, which is given as range between MIN - MAX (to input exact number user should input same value for both).
- Allows saving those generated epics along with current development teams setup for future use, or manual change.
- Allows managing previously saved, i.e. predefined epics, and consequently user stories and technical tasks, with option to save without overriding previous data.
- Allows addition, editing and removal of epics, user stories and technical tasks in currently loaded predefined data.
- Provides view of informational output, error output as well as jira stream generated output during application flow.
- Provides options to change to "Developers page" view.
2. Developers page view, with fallowing features
- View of current development teams setups and details about each developer (their personal data, skill level, position, etc.).
- Allows managing of said data through editing developer data, adding, moving or removing individual developers from their development teams.
- Provide options to generate new batch of developers data with random data using predefined parameters (male/female gender ratio, MIN - MAX range of total possible number of developers and MIN - MAX possible number of developers assigned in each development team).
- Provides option to add previously mentioned generated developers data to existing or to create fresh data (by checking option to not retain previous development team setup)

## Features

- **Spring Boot Application**: Built with Spring Boot 3.3.5.
Expand Down
82 changes: 52 additions & 30 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,76 +37,88 @@
</issueManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-version>3.3.5</spring-version>
<spring-integration-version>6.3.5</spring-integration-version>
<jmockit-version>1.49.2</jmockit-version>
<junit-jupiter-version>5.11.3</junit-jupiter-version>
<spring.version>3.3.5</spring.version>
<spring-integration.version>6.3.5</spring-integration.version>
<jmockit.version>1.55.0</jmockit.version>
<junit-jupiter.version>5.11.3</junit-jupiter.version>
<mockito.version>5.14.2</mockito.version>
<application.version>${project.version}</application.version>
<jacoco.version>0.8.12</jacoco.version>
<sonar.projectKey>Software-Development-Simulation</sonar.projectKey>
<sonar.projectName>Software Development Simulation</sonar.projectName>
<sonar.projectVersion>${application.version}</sonar.projectVersion>
<sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
<sonar.token>${env.SONAR_TOKEN}</sonar.token>
<sonar.java.binaries>target/classes</sonar.java.binaries>
<sonar.coverage.exclusions>
src/main/java/dev/markodojkic/softwaredevelopmentsimulation/SoftwareDevelopmentSimulationApp.java
</sonar.coverage.exclusions>
<sonar.dynamic>reuseReports</sonar.dynamic>
</properties>

<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<!-- Spring integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring-integration-version}</version>
<version>${spring-integration.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
<version>${spring-integration-version}</version>
<version>${spring-integration.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
<version>${spring-integration-version}</version>
<version>${spring-integration.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
<version>${spring-integration-version}</version>
<version>${spring-integration.version}</version>
<scope>compile</scope>
</dependency>

Expand Down Expand Up @@ -159,37 +171,37 @@
<dependency>
<groupId>com.github.hazendaz.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>${jmockit-version}</version>
<version>${jmockit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter-version}</version>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter-version}</version>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter-version}</version>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite-api</artifactId>
<artifactId>junit-platform-suite</artifactId>
<version>1.11.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.14.2</version>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -230,7 +242,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-version}</version>
<version>${spring.version}</version>
<configuration>
<mainClass>dev.markodojkic.softwaredevelopmentsimulation.SoftwareDevelopmentSimulationApp</mainClass>
<layout>JAR</layout>
Expand All @@ -252,26 +264,27 @@
<target>22</target>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>5.0.0.4389</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<phase>test</phase>
<configuration>
<excludes>
<exclude>dev/markodojkic/softwaredevelopmentsimulation/SoftwareDevelopmentSimulationApp.class</exclude>
</excludes>
<destFile>${project.build.directory}/site/jacoco/jacoco.xml</destFile>
</configuration>
</execution>
</executions>
Expand All @@ -282,18 +295,27 @@
<version>3.5.1</version>
<configuration>
<argLine>
${argLine} <!-- Defines jacoco javaagent -->
-Dspring.profiles.active=test
-Xshare:off
-XX:+EnableDynamicAgentLoading
-javaagent:${user.home}/.m2/repository/com/github/hazendaz/jmockit/jmockit/${jmockit-version}/jmockit-${jmockit-version}.jar
-javaagent:${settings.localRepository}/com/github/hazendaz/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
-javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar
-javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar=destfile=target/jacoco.exec
</argLine>
<includes>dev/markodojkic/softwaredevelopmentsimulation/test/SoftwareDevelopmentSimulationAppTestsSuite</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.17.1</version>
<executions>
<execution>
<goals>
<goal>use-latest-versions</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public String toString() {
}

public void setAssignee(Developer assignee) {
this.assignee = this.assignee == null ? assignee : this.assignee;
this.assignee = assignee == null ? this.assignee : assignee;
}

public void setReporter(Developer reporter) {
this.reporter = this.reporter == null ? reporter : this.reporter;
this.reporter = reporter == null ? this.reporter : reporter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ public class Utilities {
static {
boolean isTesting = System.getProperty("spring.profiles.active", "default").equals("test");

Path base = isTesting ? Paths.get("src/test/resources", "dev.markodojkic.software_development_simulation.testing_data") : Paths.get(System.getProperty("user.home"), "dev.markodojkic", "software_development_simulation", "1.4.0");
currentApplicationDataPath = isTesting ? Paths.get("src/test/resources", "dev.markodojkic.software_development_simulation.testing_data") : Paths.get(System.getProperty("user.home"), "dev.markodojkic", "software_development_simulation", "1.4.0");

currentApplicationDataPath = base;
currentApplicationLogsPath = Paths.get(String.valueOf(base), "logs", isTesting ? "2012-12-12 00-00-00" : ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss")));
currentApplicationLogsPath = Paths.get(String.valueOf(currentApplicationDataPath), "logs", isTesting ? "2012-12-12 00-00-00" : ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss")));

if(isTesting){
if(!Files.exists(currentApplicationDataPath)){
try {
Files.createDirectories(currentApplicationDataPath);
Files.createDirectories(currentApplicationLogsPath);
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/banner.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
|___/_|_| |_| |_|\__,_|_|\__,_|\__\___/|_|

Application version: ${application.version}
Powered by Spring Boot (v${spring-version}) and Spring Integration (v${spring-integration-version})
Powered by Spring Boot (v${spring.version}) and Spring Integration (v${spring-integration.version})
Ⓒ Marko Dojkić 2024
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.markodojkic.softwaredevelopmentsimulation.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import dev.markodojkic.softwaredevelopmentsimulation.enums.Priority;
import dev.markodojkic.softwaredevelopmentsimulation.enums.DeveloperType;
import dev.markodojkic.softwaredevelopmentsimulation.model.BaseTask;
Expand All @@ -8,7 +9,9 @@
import org.junit.jupiter.api.Test;

import java.time.ZonedDateTime;
import java.util.ArrayList;

import static dev.markodojkic.softwaredevelopmentsimulation.util.Utilities.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand All @@ -25,6 +28,11 @@ void when_noArgsConstructorIsCalled_correctValuesAreSetAsDefault() {
assertNull(task.getAssignee());
assertNull(task.getReporter());
assertNull(task.getCreatedOn());

// Assertion for toString method
String expectedToString = "BaseTask{id='null', name='null', description='null', priority=null, assignee='UNASSIGNED', reporter='UNASSIGNED', createdOn=null}";

assertEquals(expectedToString, task.toString());
}

@Test
Expand Down Expand Up @@ -82,6 +90,7 @@ void when_equalsOrHashCodeIsCalled_onEqualObjectAreSame_onNonEqualObjectsAreDiff
// Test equality
assertEquals(task1, task2);
assertEquals(task1.hashCode(), task2.hashCode());
assertNotEquals(task1, assignee1);

// Create tasks with different IDs
BaseTask task3 = new BaseTask("2", "Task Name", "Task Description", Priority.NORMAL, assignee1, reporter1, ZonedDateTime.now());
Expand Down Expand Up @@ -134,6 +143,15 @@ void when_gettersAndSettersAreCalled_valuesAreCorrectlyRetrievedOrSet() {
assertEquals(Priority.CRITICAL, task.getPriority());
assertEquals("assignee 1", task.getAssignee().getDisplayName());
assertEquals("reporter 1", task.getReporter().getDisplayName());
task.setAssignee(null);
task.setReporter(null);
assertEquals("assignee 1", task.getAssignee().getDisplayName());
assertEquals("reporter 1", task.getReporter().getDisplayName());
assertNotNull(task.getCreatedOn());
}

@Test
void when_emptyListIsPassedToJSONSerializer_emptyJSONArrayIsRetrieved() throws JsonProcessingException {
assertEquals("[]", getObjectMapper().writeValueAsString(new ArrayList<>()));
}
}
Loading

0 comments on commit dd83add

Please sign in to comment.