diff --git a/.github/workflows/master-build.yml b/.github/workflows/master-build.yml
index 79c87fd6a60..a6400af651b 100644
--- a/.github/workflows/master-build.yml
+++ b/.github/workflows/master-build.yml
@@ -9,22 +9,16 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Build
run: mvn clean verify -DskipTests=true
@@ -36,7 +30,7 @@ jobs:
timeout-minutes: 90
services:
mongo:
- image: mongo:4.4
+ image: mongo:6
ports:
- 27017:27017
@@ -46,7 +40,7 @@ jobs:
- 6379:6379
elasticsearch:
- image: elasticsearch:7.17.3
+ image: elasticsearch:7.17.28
ports:
- 9200:9200
- 9300:9300
@@ -67,15 +61,16 @@ jobs:
echo $ELASTIC_SEARCH_URL
curl -fsSL "$ELASTIC_SEARCH_URL/_cat/health?h=status"
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
+ distribution: 'temurin'
+ cache: maven
# - name: Cache SonarCloud packages
# uses: actions/cache@v3
@@ -84,13 +79,6 @@ jobs:
# key: ${{ runner.os }}-sonar
# restore-keys: ${{ runner.os }}-sonar
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
-
- name: Generate certificates
run: cd src/main/resources/certificates && openssl genrsa -out keypair.pem 4096 && openssl rsa -in keypair.pem -pubout -out public.crt && openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in keypair.pem -out private.der && cd ../../../..
@@ -113,23 +101,17 @@ jobs:
needs: test
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
token: ${{ secrets.PUSH_DOCS }}
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Build
run: mvn clean package install -DskipTests=true
@@ -139,7 +121,7 @@ jobs:
mvn javadoc:javadoc
cp -r ./target/apidocs/* ./docs/javadoc/
- - uses: EndBug/add-and-commit@v8
+ - uses: EndBug/add-and-commit@v9
with:
add: docs
pathspec_error_handling: exitImmediately
diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml
index 0005231f061..ff3edb08caa 100644
--- a/.github/workflows/pr-build.yml
+++ b/.github/workflows/pr-build.yml
@@ -8,22 +8,16 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Build
run: mvn clean verify -DskipTests=true
@@ -35,7 +29,7 @@ jobs:
timeout-minutes: 200
services:
mongo:
- image: mongo:4.4
+ image: mongo:6
ports:
- 27017:27017
@@ -45,7 +39,7 @@ jobs:
- 6379:6379
elasticsearch:
- image: elasticsearch:7.17.3
+ image: elasticsearch:7.17.28
ports:
- 9200:9200
- 9300:9300
@@ -66,15 +60,16 @@ jobs:
echo $ELASTIC_SEARCH_URL
curl -fsSL "$ELASTIC_SEARCH_URL/_cat/health?h=status"
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
+ distribution: 'temurin'
+ cache: maven
# - name: Cache SonarCloud packages
# uses: actions/cache@v3
@@ -83,13 +78,6 @@ jobs:
# key: ${{ runner.os }}-sonar
# restore-keys: ${{ runner.os }}-sonar
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
-
- name: Generate certificates
run: cd src/main/resources/certificates && openssl genrsa -out keypair.pem 4096 && openssl rsa -in keypair.pem -pubout -out public.crt && openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in keypair.pem -out private.der && cd ../../../..
diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml
index b5fdc3067e1..64f8d110c21 100644
--- a/.github/workflows/release-build.yml
+++ b/.github/workflows/release-build.yml
@@ -9,27 +9,21 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
+ distribution: 'temurin'
+ cache: maven
- name: Get Project Version from pom.xml
uses: entimaniac/read-pom-version-action@1.0.0
id: getVersion
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
-
- name: Build
run: mvn clean verify -DskipTests=true
@@ -71,22 +65,16 @@ jobs:
echo $ELASTIC_SEARCH_URL
curl -fsSL "$ELASTIC_SEARCH_URL/_cat/health?h=status"
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Generate certificates
run: cd src/main/resources/certificates && openssl genrsa -out keypair.pem 4096 && openssl rsa -in keypair.pem -pubout -out public.crt && openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in keypair.pem -out private.der && cd ../../../..
@@ -108,7 +96,7 @@ jobs:
contents: read
packages: write
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
- id: install-secret-key
name: Install gpg secret key
@@ -117,10 +105,11 @@ jobs:
gpg --list-secret-keys --keyid-format LONG
- name: Set up Maven Central Repository
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
+ distribution: 'temurin'
+ cache: maven
server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
@@ -141,26 +130,20 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v5
with:
java-version: 11
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Build
run: mvn -P docker-build clean package install -DskipTests=true
- name: Log in to Docker Hub
- uses: docker/login-action@v1
+ uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_AUTH_TOKEN }}
@@ -170,14 +153,14 @@ jobs:
id: getVersion
- name: Push Version ${{ steps.getVersion.outputs.version }}
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v7
with:
push: true
tags: netgrif/application-engine:${{ steps.getVersion.outputs.version }}
- name: Push Latest
if: ${{ !contains(steps.getVersion.outputs.version, '-SNAPSHOT') }}
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v7
with:
push: true
tags: netgrif/application-engine:latest
@@ -190,19 +173,13 @@ jobs:
contents: read
packages: write
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
- - uses: actions/setup-java@v3
+ - uses: actions/setup-java@v5
with:
java-version: '11'
- distribution: 'adopt'
-
- - name: Cache Maven packages
- uses: actions/cache@v3
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
+ distribution: 'temurin'
+ cache: maven
- name: Publish artifact on GitHub Packages
run: mvn -B -P github-publish clean deploy -DskipTests
@@ -219,7 +196,7 @@ jobs:
id-token: write
security-events: write
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v6
- name: Build
run: mvn clean package install -DskipTests=true
diff --git a/pom.xml b/pom.xml
index e57436ea5cc..470b48b79fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,27 @@
+
+ central
+ https://repo.maven.apache.org/maven2
+
+ true
+
+
+ false
+
+
+
+ Central Portal Snapshots
+ central-portal-snapshots
+ https://central.sonatype.com/repository/maven-snapshots/
+
+ false
+
+
+ true
+
+
jitpack.io
https://jitpack.io
@@ -315,6 +336,11 @@
batik-all
1.17
+
+ xml-apis
+ xml-apis-ext
+ 1.3.04
+
commons-io
commons-io
diff --git a/src/main/groovy/com/netgrif/application/engine/migration/MigrationOrderedCommandLineRunner.groovy b/src/main/groovy/com/netgrif/application/engine/migration/MigrationOrderedCommandLineRunner.groovy
index 8fc940ac528..7c0c52d9bc1 100644
--- a/src/main/groovy/com/netgrif/application/engine/migration/MigrationOrderedCommandLineRunner.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/migration/MigrationOrderedCommandLineRunner.groovy
@@ -1,6 +1,7 @@
package com.netgrif.application.engine.migration
-
+import com.netgrif.application.engine.configuration.ApplicationShutdownProvider
+import com.netgrif.application.engine.configuration.properties.MigrationProperties
import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService
import com.netgrif.application.engine.startup.AbstractOrderedCommandLineRunner
import org.slf4j.Logger
@@ -14,26 +15,55 @@ abstract class MigrationOrderedCommandLineRunner extends AbstractOrderedCommandL
private static final Logger log = LoggerFactory.getLogger(MigrationOrderedCommandLineRunner)
private String title = this.class.simpleName
+ private boolean shutdownAfterFinish = false
@Autowired
private MigrationRepository repository
+ @Autowired
+ private MigrationProperties migrationProperties
+
@Autowired
private IPetriNetService service
+ @Autowired
+ private ApplicationShutdownProvider shutdownProvider
+
@Override
void run(String... strings) throws Exception {
if (repository.existsByTitle(title)) {
log.info("Migration ${title} was already applied")
return
}
+ if (migrationProperties.getSkip().contains(title)) {
+ log.info("Migration ${title} is skipped according to property nae.migration.skip")
+ return
+ }
log.info("Applying migration ${title}")
migrate()
repository.save(new Migration(title))
- service.evictAllCaches()
+ if (migrationProperties.isEvictCaches()) {
+ log.info("Evicting all caches after migration")
+ service.evictAllCaches()
+ }
log.info("Migration ${title} applied")
+ if (shutdownAfterFinish || migrationProperties.isShutdownAfterMigration()) {
+ // sleep is for elastic executor and other things to flush their work after migration.
+ // the number was chosen arbitrary by feeling 😅
+ sleep(333)
+ shutdownProvider.shutdown(this.class)
+ }
+ }
+
+ protected void enableShutdownAfterFinish() {
+ this.shutdownAfterFinish = true;
+ }
+
+ protected void disableShutdownAfterFinish() {
+ this.shutdownAfterFinish = false;
}
abstract void migrate()
-}
\ No newline at end of file
+
+}
diff --git a/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy b/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
index f02d30e1c8f..d653c4c4d30 100644
--- a/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
+++ b/src/main/groovy/com/netgrif/application/engine/startup/RunnerController.groovy
@@ -43,4 +43,4 @@ class RunnerController {
}
return runnerOrder
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/netgrif/application/engine/auth/service/AbstractUserService.java b/src/main/java/com/netgrif/application/engine/auth/service/AbstractUserService.java
index 2a3be9d5ed7..d9e68491cf2 100644
--- a/src/main/java/com/netgrif/application/engine/auth/service/AbstractUserService.java
+++ b/src/main/java/com/netgrif/application/engine/auth/service/AbstractUserService.java
@@ -53,6 +53,11 @@ public void addDefaultAuthorities(IUser user) {
}
}
+ @Override
+ public boolean existsById(String id) {
+ return repository.existsById(id);
+ }
+
@Override
public IUser assignAuthority(String userId, String authorityId) {
IUser user = resolveById(userId, true);
diff --git a/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserService.java b/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserService.java
index 01956bc2b8b..989062f7585 100644
--- a/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserService.java
+++ b/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserService.java
@@ -49,6 +49,8 @@ public interface IUserService {
void addDefaultAuthorities(IUser user);
+ boolean existsById(String id);
+
IUser assignAuthority(String userId, String authorityId);
IUser getLoggedOrSystem();
diff --git a/src/main/java/com/netgrif/application/engine/configuration/ApplicationShutdownProvider.java b/src/main/java/com/netgrif/application/engine/configuration/ApplicationShutdownProvider.java
new file mode 100644
index 00000000000..db24485e5d9
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/configuration/ApplicationShutdownProvider.java
@@ -0,0 +1,39 @@
+package com.netgrif.application.engine.configuration;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class ApplicationShutdownProvider {
+
+ private final ApplicationContext applicationContext;
+ private final TaskExecutor taskExecutor;
+
+ public void shutdown(Class> calledBy, int exitCode) {
+ String className = calledBy == null ? "unknown" : calledBy.getSimpleName();
+ log.info("Application was signalled by {} to shutdown; exit code: {}", className, exitCode);
+ if (taskExecutor != null && taskExecutor instanceof ThreadPoolTaskExecutor) {
+ log.info("Shutting down thread pool executor");
+ ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) taskExecutor;
+ executor.shutdown();
+ }
+ int ec = SpringApplication.exit(applicationContext, () -> exitCode);
+ System.exit(ec);
+ }
+
+ public void shutdown(Class> calledBy) {
+ shutdown(calledBy, 0);
+ }
+
+ public void shutdown() {
+ shutdown(null, 0);
+ }
+
+}
diff --git a/src/main/java/com/netgrif/application/engine/configuration/properties/MigrationProperties.java b/src/main/java/com/netgrif/application/engine/configuration/properties/MigrationProperties.java
new file mode 100644
index 00000000000..aeba1845e06
--- /dev/null
+++ b/src/main/java/com/netgrif/application/engine/configuration/properties/MigrationProperties.java
@@ -0,0 +1,39 @@
+package com.netgrif.application.engine.configuration.properties;
+
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "nae.migration")
+public class MigrationProperties {
+
+ /**
+ * A list of migration process identifiers or names that should be skipped when applying migration logic.
+ * This property allows you to configure specific migrations that should be ignored,
+ * typically useful for excluding unnecessary or problematic migrations.
+ */
+ private Set skip = new LinkedHashSet<>();
+
+ /**
+ * Indicates whether caches should be evicted as part of the migration process.
+ * This property allows enabling or disabling the cache eviction mechanism, which
+ * is useful in ensuring consistency and up-to-date data during migration operations.
+ * Default value is {@code true}.
+ */
+ private boolean evictCaches = true;
+
+ /**
+ * Specifies whether the application should automatically shut down once the migration process is completed.
+ * This property can be used to terminate the application after the migration, ensuring a clean exit
+ * if no further operations are intended post-migration.
+ * Default value is {@code false}.
+ */
+ private boolean shutdownAfterMigration = false;
+
+}
diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
index 58c7db6f9d9..910e7590002 100644
--- a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
+++ b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
@@ -772,12 +772,9 @@ public List save(List tasks) {
}
@Override
- public void resolveUserRef(Case useCase) {
- useCase.getTasks().forEach(taskPair -> {
- Optional taskOptional = taskRepository.findById(taskPair.getTask());
- taskOptional.ifPresent(task -> resolveUserRef(task, useCase));
- });
-
+ public List resolveUserRef(Case useCase) {
+ List tasks = taskRepository.findAllBy_idIn(useCase.getTasks().stream().map(TaskPair::getTask).collect(Collectors.toList()));
+ return tasks.stream().map(task -> resolveUserRef(task, useCase)).collect(Collectors.toList());
}
@Override
@@ -786,9 +783,9 @@ public Task resolveUserRef(Task task, Case useCase) {
task.getNegativeViewUsers().clear();
task.getUserRefs().forEach((id, permission) -> {
List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(id).getValue());
- if (userIds != null && userIds.size() != 0 && permission.containsKey("view") && !permission.get("view")) {
+ if (userIds != null && !userIds.isEmpty() && permission.containsKey("view") && !permission.get("view")) {
task.getNegativeViewUsers().addAll(userIds);
- } else if (userIds != null && userIds.size() != 0) {
+ } else if (userIds != null && !userIds.isEmpty()) {
task.addUsers(new HashSet<>(userIds), permission);
}
});
diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java
index 3d9ac2dd2b3..2cae7ed9203 100644
--- a/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java
+++ b/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java
@@ -228,7 +228,7 @@ public Case resolveUserRef(Case useCase) {
private void resolveUserRefPermissions(Case useCase, String userListId, Map permission) {
List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(userListId).getValue());
- if (userIds != null && userIds.size() != 0) {
+ if (userIds != null && !userIds.isEmpty()) {
if (permission.containsKey("view") && !permission.get("view")) {
useCase.getNegativeViewUsers().addAll(userIds);
} else {
@@ -241,7 +241,7 @@ private List getExistingUsers(UserListFieldValue userListValue) {
if (userListValue == null)
return null;
return userListValue.getUserValues().stream().map(UserFieldValue::getId)
- .filter(id -> userService.resolveById(id, false) != null)
+ .filter(id -> userService.existsById(id))
.collect(Collectors.toList());
}
diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java b/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java
index f7b867eb79c..691b2de4a9b 100644
--- a/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java
+++ b/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java
@@ -15,7 +15,6 @@
import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
-import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Locale;
@@ -106,7 +105,7 @@ public interface ITaskService {
DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId, Map params) throws TransitionNotExecutableException;
- void resolveUserRef(Case useCase);
+ List resolveUserRef(Case useCase);
Task resolveUserRef(Task task, Case useCase);
@@ -127,4 +126,4 @@ public interface ITaskService {
List save(List tasks);
SetDataEventOutcome getMainOutcome(Map outcomes, String taskId);
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/netgrif/application/engine/auth/service/UserServiceTest.java b/src/test/java/com/netgrif/application/engine/auth/service/UserServiceTest.java
new file mode 100644
index 00000000000..874e29fd24e
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/auth/service/UserServiceTest.java
@@ -0,0 +1,41 @@
+package com.netgrif.application.engine.auth.service;
+
+import com.netgrif.application.engine.TestHelper;
+import com.netgrif.application.engine.auth.domain.IUser;
+import com.netgrif.application.engine.auth.service.interfaces.IUserService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@SpringBootTest
+@ActiveProfiles({"test"})
+@ExtendWith(SpringExtension.class)
+public class UserServiceTest {
+
+ @Autowired
+ private IUserService service;
+
+ @Autowired
+ private TestHelper testHelper;
+
+ @BeforeEach
+ void before() {
+ testHelper.truncateDbs();
+ }
+
+ @Test
+ public void shouldUserExist() {
+ IUser user = service.findByEmail("super@netgrif.com", true);
+ assertNotNull(user);
+ boolean userExists = service.existsById(user.getStringId());
+ assertTrue(userExists);
+ }
+
+}