Commit ad9e26bc authored by Radek Ošlejšek's avatar Radek Ošlejšek
Browse files

Merge branch 'Webapp-integration-tests' into 'master'

Webapp-integration-tests

See merge request grp-fidentis/analyst2!271
parents 531ac27d 8c1d937e
Loading
Loading
Loading
Loading
+2 −9
Original line number Diff line number Diff line
image: maven:3-openjdk-18-slim

services:
  - postgres:15

variables:
  # FTP_* and some other variables are also defined in the CI condiguration of the gitlab. 
  # FTP_* and some other variables are also defined in the CI configuration of the gitlab.
  LANG: C.UTF-8
  LC_ALL: C.UTF-8
  PROJECT_ARTIFACT_ID: FIDENTIS-Analyst-app
  DEPLOYMENT_INFO_VERSION_FILE: VERSION.txt
  POSTGRES_DB: fidentis
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: "postgres"
  POSTGRES_HOST_AUTH_METHOD: trust
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -Dcheckstyle.fail=false"
  MAVEN_JAVADOC_OPTS: "-Dauthor=false -DadditionalJOption=-Xdoclint:none"

@@ -69,7 +62,7 @@ staging-job:
    - ssh-keyscan $STAGING_IPADDRESS >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - ssh $SSH_STAGING_USER@$STAGING_IPADDRESS "chmod u+x /opt/fidentis-analyst/analyst2/scripts/staging.sh; /opt/fidentis-analyst/analyst2/scripts/staging.sh"
    - ssh $SSH_STAGING_USER@$STAGING_IPADDRESS "chmod u+x /opt/fidentis-analyst/analyst2/scripts/staging.sh; /opt/fidentis-analyst/analyst2/scripts/staging.sh $STAGING_POSTGRESQL_DB_NAME $STAGING_POSTGRESQL_USER $STAGING_POSTGRESQL_PASSWORD"
    - eval $(ssh-agent -k)
  tags:
    - shared-fi
+25 −14
Original line number Diff line number Diff line
@@ -19,25 +19,23 @@ Frontend dependencies:

## Installation and running

To build whole module run `mvn clean install`. This command also copy FE part of application to output `.jar`. <br>
To run application from command line you have to set your database (if running locally - see developer\`s guide) and run command `mvn spring-boot:run -{profile}`.
To build whole module run `mvn clean install`. This command also copy frontend part of the application to output `.jar`. <br>
To run application from command line, you have to set your database (see developer\`s guide how to run it locally) and run command `mvn spring-boot:run {profile}`.

Application supports 3 profiles:
* production `-Pprod`
* development `-Pdev`
* testing (mainly for Gitlab CI tests) `-Ptest`
Application supports 2 profiles:
* production: `-Pprod`
* development: `-Pdev`

---

## Developer\`s guide

Application is divided into frontend application via [React](https://reactjs.org/) library, [THREE.js](https://threejs.org/) and other supplement packages. 
Application is divided into the frontend application via [React](https://reactjs.org/) library, [THREE.js](https://threejs.org/) and other supplement packages. 
Backend is written in [Spring Boot](https://spring.io/projects/spring-boot) (version 2.7.5).

### Frontend application

Can be found inside `frontend` folder in `Web` module. There are also environment files that determine if application is used in production or development mode (`.env.development` and `.env.production`).
There are defined backend base URLs and other specific variables. For tooling is used [Vite](https://vitejs.dev/).
Can be found inside `frontend` folder in `Web` module. Proxy servers for development are set in: `vite.config.ts`. For tooling is used [Vite](https://vitejs.dev/).

Main language is [Typescript](https://www.typescriptlang.org/) so everything has to be correctly typed (no usage of `any`). And UI component library is [MUI](https://mui.com/). 

@@ -61,12 +59,12 @@ and after every change and save content is reloaded.

### Backend application

Firstly we have to set up `application.properties` more precisely development properties that will match our local setup. Go inside folder: `./src/main/resources`. Here open file: `application-dev.properties`.
This file should contain only your local values (aka postgres database name, username and password). So after creating local database fill these attributes correctly and **!DO NOT PULL THIS FILE TO ORIGIN!**.
Firstly, we have to set up `application.yml` more precisely development properties that will match our local setup. Go inside folder: `./src/main/resources`. Here open file: `application-dev.yml`.
This file should contain only your local values (aka postgres database name, username and password). So after creating local database fill these attributes correctly and **!DO NOT PUSH THIS FILE TO ORIGIN!**.

After this setup we can run command: `mvn clean install -Pdev` if we didn't before for whole project. This will create runnable `.jar` file with frontend application bundled in.
After this setup we can run command: `mvn clean install` if we didn't before for whole project. This will create runnable `.jar` file with frontend application bundled in.
<br>
To start server run command: `mvn spring-boot:run -Pdev` (notice all commands are run with `-Pdev` argument to say application that we want to start it in development profile, so it will pick development properties).
To start server run command: `mvn spring-boot:run` (`-Pdev` profile is default profile set in `pom.xml` it will start it in development profile, so it will pick development properties).

#### Manipulating database

@@ -75,12 +73,25 @@ that will run at the start of application (only changelogs that didn't already r
inside folder: `./src/main/resources/db/changelog`. Naming convention is: `changelog-{id}` where id is integer incrementing by 1 (it has to be unique) and this file is after included into main
file `master-changelog.xml`. Each changelog can contain multiple `<changeSet>` tags where each have to have unique id starting with id of file.

#### Running tests

To run tests, the developer has to have installed [Docker](https://www.docker.com/). No registration or running special images are needed only start docker. Tests will create `@Testcontainer` with PostgreSQL database to have
the same environment as in production. `AbstractIntegratrionTest` contains all setup and `@MockBean` necessary. This implementation has one limitation that is impossibility running all tests at once because
the container is not shared across classes. Developer has to start each test class manually.

#### Mail service

To test mail service in development, install NPM package [maildev](https://www.npmjs.com/package/maildev) which provide simple GUI and mail server. All properties for Spring Boot application are already
implemented in `application-dev.yml` file. If you want to run mail server on different ports you have to change these settings also.

#### Folder system:
* `config` - all configuration files (Spring security, Jwt tokens etc.)
* `controllers` - all REST API controllers
* `dto` - special data classes used for mapping objects for transport between FE and BE
* `filter` - used for Spring security (authentication, authorization...)
* `exceptions` - all custom exceptions and main `@ControllerAdvice` are defined here
* `mail` - classes for mail service
* `models` - application models (database follows these object as tables)
* `repostory` - folder for files to handle operations with models (deletion, update etc)
* `security` - all classes for Spring Security - filters, permission evaluators
* `services` - folder for business logic of every endpoint
* `utils`
 No newline at end of file
+4 −3
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ const AnalyzeButton: FC<AnalyzeButtonProps> = ({ text, onClick, disabled }) => (

const ProjectToolbar = () => {
	const confirm = useConfirm();
	const { createTask } = useContext(TaskContext);
	const { createTask, getTasksOnProject } = useContext(TaskContext);
	const { selectedProjectId } = useContext(ProjectsContext);
	const { saveFiles, deleteFilesFromProject, fileSelection } =
		useContext(FilesContext);
@@ -43,8 +43,9 @@ const ProjectToolbar = () => {
				'This delete selected files. Already created tasks within these files will remain',
			confirmationButtonProps: { variant: 'contained' }
		})
			.then(() => {
				deleteFilesFromProject(fileSelection as number[]);
			.then(async () => {
				await deleteFilesFromProject(fileSelection as number[]);
				await getTasksOnProject(Number(selectedProjectId));
			})
			.catch(() => null);
	};
+23 −3
Original line number Diff line number Diff line
@@ -49,15 +49,29 @@
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>1.17.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <version>1.17.6</version>
            <scope>test</scope>
        </dependency>

        <!-- Database dependencies -->
@@ -112,6 +126,12 @@
            </resource>
        </resources>

        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
+10 −6
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import cz.fidentis.web.services.ProjectsService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
@@ -33,20 +34,23 @@ public class ProjectsController {
    }

    @PostMapping("/open-project")
    public ResponseEntity<?> setOpenToProjects(HttpServletRequest request, @RequestParam Long id) {
        projectsService.setStatusToProject(request, id, true);
    @PreAuthorize("hasPermission(#id, 'PROJECTS', 'update')")
    public ResponseEntity<?> setOpenToProjects(@RequestParam Long id) {
        projectsService.setStatusToProject(id, true);
        return ResponseEntity.ok().build();
    }

    @PostMapping("/close-project")
    public ResponseEntity<?> closeProject(HttpServletRequest request, @RequestParam Long id) {
        projectsService.setStatusToProject(request, id, false);
    @PreAuthorize("hasPermission(#id, 'PROJECTS', 'update')")
    public ResponseEntity<?> closeProject(@RequestParam Long id) {
        projectsService.setStatusToProject(id, false);
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Object> deleteProject(HttpServletRequest request, @PathVariable String id) {
        projectsService.deleteProject(request, Long.valueOf(id));
    @PreAuthorize("hasPermission(#id, 'PROJECTS', 'delete')")
    public ResponseEntity<Object> deleteProject(@PathVariable String id) {
        projectsService.deleteProject(Long.valueOf(id));
        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
    }
}
Loading