diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0d0f354f48..6d38c069a1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,6 +35,7 @@ jobs: uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@a0837df06d10de2cae8a99319e8e101a6cbe9083 # v8.4.0 with: skip_checkout: true + auto-commit: true - name: Ensure SHA pinned actions uses: zgosalvez/github-actions-ensure-sha-pinned-actions@5d6ac37a4cef8b8df67f482a8e384987766f0213 # v3.0.17 diff --git a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/main/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImpl.java b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/main/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImpl.java index d401e27ae6..c1aea71521 100644 --- a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/main/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImpl.java +++ b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/main/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImpl.java @@ -18,11 +18,13 @@ import com.querydsl.jpa.JPQLQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; + import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; + import org.activiti.cloud.api.process.model.QueryCloudSubprocessInstance; import org.activiti.cloud.services.query.model.ProcessInstanceEntity; import org.activiti.cloud.services.query.model.QProcessInstanceEntity; @@ -36,8 +38,11 @@ public class CustomizedProcessInstanceRepositoryImpl extends QuerydslRepositorySupport implements CustomizedProcessInstanceRepository { - public CustomizedProcessInstanceRepositoryImpl() { + private final JPAQueryFactory queryFactory; + + public CustomizedProcessInstanceRepositoryImpl(EntityManager entityManager) { super(ProcessInstanceEntity.class); + this.queryFactory = new JPAQueryFactory(entityManager); } @Override @@ -116,8 +121,6 @@ public void setSubprocesses( public Page findSubprocessesByParentIds(List parentIds, Pageable pageable) { QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; - EntityManager entityManager = getEntityManager(); - JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager); Querydsl querydsl = getQuerydsl(); JPQLQuery subprocessQuery = queryFactory @@ -135,9 +138,6 @@ public Page findSubprocessesByParentIds(List pare public List findSubprocessesByParentId(String parentId) { QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; - EntityManager entityManager = getEntityManager(); - JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager); - return queryFactory .selectFrom(processInstanceEntity) .where(processInstanceEntity.parentId.eq(parentId)) diff --git a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImplTest.java b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImplTest.java index 78b7a99e99..a7f29de721 100644 --- a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImplTest.java +++ b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/CustomizedProcessInstanceRepositoryImplTest.java @@ -16,29 +16,55 @@ package org.activiti.cloud.services.query.app.repository; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; import java.util.*; + +import com.querydsl.jpa.JPQLQuery; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; import org.activiti.cloud.api.process.model.QueryCloudSubprocessInstance; +import org.activiti.cloud.services.query.app.repository.utils.ProcessInstanceHelper; import org.activiti.cloud.services.query.model.ProcessInstanceEntity; +import org.activiti.cloud.services.query.model.QProcessInstanceEntity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.support.Querydsl; +import org.springframework.test.util.ReflectionTestUtils; class CustomizedProcessInstanceRepositoryImplTest { + @Mock + private EntityManager entityManager; + @Mock + private JPAQueryFactory queryFactory; + @Mock + private JPAQuery jpaQuery; + @Mock + private JPQLQuery jpqlQuery; + @Mock + private Querydsl querydsl; + private CustomizedProcessInstanceRepositoryImpl repository; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - repository = new CustomizedProcessInstanceRepositoryImpl(); + repository = new CustomizedProcessInstanceRepositoryImpl(entityManager); + ReflectionTestUtils.setField(repository, "queryFactory", queryFactory); + ReflectionTestUtils.setField(repository, "querydsl", querydsl); } @Test void testGetQueryCloudSubprocessInstance() { - ProcessInstanceEntity subprocess = createProcessInstance(UUID.randomUUID().toString()); + ProcessInstanceEntity subprocess = new ProcessInstanceHelper().createProcessInstance(UUID.randomUUID().toString()); QueryCloudSubprocessInstance result = repository.getQueryCloudSubprocessInstance(subprocess); assertNotNull(result); @@ -48,7 +74,7 @@ void testGetQueryCloudSubprocessInstance() { @Test void testGetParentIds() { - List processInstancesList = createParentProcessInstances(3); + List processInstancesList = new ProcessInstanceHelper().createParentProcessInstances(3); Page processInstances = new PageImpl<>(processInstancesList); List result = repository.getParentIds(processInstances); @@ -59,11 +85,11 @@ void testGetParentIds() { @Test void testGroupSubprocesses() { - List processInstancesList = createParentProcessInstances(4); + List processInstancesList = new ProcessInstanceHelper().createParentProcessInstances(4); String parentIdOne = processInstancesList.getFirst().getId(); String parentIdTwo = processInstancesList.getLast().getId(); - List subprocessesList = createSubprocessInstances(2, parentIdOne); - subprocessesList.addAll(createSubprocessInstances(3, parentIdTwo)); + List subprocessesList = new ProcessInstanceHelper().createSubprocessInstances(2, parentIdOne); + subprocessesList.addAll(new ProcessInstanceHelper().createSubprocessInstances(3, parentIdTwo)); Page subprocesses = new PageImpl<>(subprocessesList); @@ -77,28 +103,99 @@ void testGroupSubprocesses() { assertEquals(3, result.get(parentIdTwo).size()); } - private ProcessInstanceEntity createProcessInstance(String parentId) { - ProcessInstanceEntity entity = new ProcessInstanceEntity(); - entity.setId(UUID.randomUUID().toString()); - entity.setName(UUID.randomUUID().toString()); - entity.setProcessDefinitionName("process-definition"); - entity.setParentId(parentId.equals("1") ? null : parentId); - return entity; + @Test + void testFindSubprocessesByParentId() { + String parentId = UUID.randomUUID().toString(); + List expectedSubprocesses = new ProcessInstanceHelper().createSubprocessInstances(2, parentId); + + QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; + + when(queryFactory.selectFrom(processInstanceEntity)).thenReturn(jpaQuery); + when(jpaQuery.where(processInstanceEntity.parentId.eq(parentId))).thenReturn(jpaQuery); + when(jpaQuery.fetch()).thenReturn(expectedSubprocesses); + + List result = repository.findSubprocessesByParentId(parentId); + + assertNotNull(result); + assertEquals(2, result.size()); + assertNotNull(result.get(0).getId()); + assertNotNull(result.get(1).getId()); + + verify(queryFactory).selectFrom(processInstanceEntity); + verify(jpaQuery).where(processInstanceEntity.parentId.eq(parentId)); + verify(jpaQuery).fetch(); } - private List createParentProcessInstances(int count) { - List instances = new ArrayList<>(); - for (int i = 0; i < count; i++) { - instances.add(createProcessInstance("1")); - } - return instances; + @Test + void testFindSubprocessesByParentIds() { + List parentIds = Arrays.asList("parent1", "parent2"); + Pageable pageable = PageRequest.of(0, 10); + + List expectedSubprocesses = new ProcessInstanceHelper().createSubprocessInstances(2, "parent1"); + expectedSubprocesses.addAll(new ProcessInstanceHelper().createSubprocessInstances(3, "parent2")); + + QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; + + when(queryFactory.selectFrom(processInstanceEntity)).thenReturn(jpaQuery); + when(jpaQuery.where(processInstanceEntity.parentId.in(parentIds))).thenReturn(jpaQuery); + when(jpaQuery.fetch()).thenReturn(expectedSubprocesses); + when(querydsl.applyPagination(pageable, jpaQuery)).thenReturn(jpaQuery); + + Page result = repository.findSubprocessesByParentIds(parentIds, pageable); + + assertNotNull(result); + assertEquals(5, result.getTotalElements()); + assertEquals(5, result.getContent().size()); + assertNotNull(result.getContent().get(0).getId()); + assertNotNull(result.getContent().get(1).getId()); + + verify(queryFactory).selectFrom(processInstanceEntity); + verify(jpaQuery).where(processInstanceEntity.parentId.in(parentIds)); + verify(jpaQuery).fetch(); } - private List createSubprocessInstances(int count, String parentId) { - List instances = new ArrayList<>(); - for (int i = 0; i < count; i++) { - instances.add(createProcessInstance(parentId)); - } - return instances; + @Test + void testMapSubprocesses() { + List processInstancesList = new ProcessInstanceHelper().createParentProcessInstances(2); + List parentIds = Arrays.asList(processInstancesList.getFirst().getId(),processInstancesList.getLast().getId()); + Page processInstances = new PageImpl<>(processInstancesList); + Pageable pageable = PageRequest.of(0, 10); + + List subprocessesList = new ProcessInstanceHelper().createSubprocessInstances(2, + processInstancesList.get(0).getId()); + subprocessesList.addAll(new ProcessInstanceHelper().createSubprocessInstances(3, processInstancesList.get(1).getId())); + + QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; + + when(queryFactory.selectFrom(processInstanceEntity)).thenReturn(jpaQuery); + when(jpaQuery.where(processInstanceEntity.parentId.in(parentIds))).thenReturn(jpaQuery); + when(jpaQuery.fetch()).thenReturn(subprocessesList); + when(querydsl.applyPagination(pageable, jpaQuery)).thenReturn(jpaQuery); + + Page result = repository.mapSubprocesses(processInstances, pageable); + + assertNotNull(result); + assertEquals(2, result.getTotalElements()); + assertEquals(2, result.getContent().size()); + assertNotNull(result.getContent().get(0).getSubprocesses()); + assertNotNull(result.getContent().get(1).getSubprocesses()); + } + + @Test + void testMapSubprocessesForProcessInstance() { + ProcessInstanceEntity entity = new ProcessInstanceHelper().createProcessInstance("1"); + String parentId = entity.getId(); + List expectedSubprocesses = new ProcessInstanceHelper().createSubprocessInstances(2, parentId); + + QProcessInstanceEntity processInstanceEntity = QProcessInstanceEntity.processInstanceEntity; + + when(queryFactory.selectFrom(processInstanceEntity)).thenReturn(jpaQuery); + when(jpaQuery.where(processInstanceEntity.parentId.eq(parentId))).thenReturn(jpaQuery); + when(jpaQuery.fetch()).thenReturn(expectedSubprocesses); + + ProcessInstanceEntity result = repository.mapSubprocesses(entity); + + assertNotNull(result); + assertEquals(2, result.getSubprocesses().size()); } } diff --git a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/utils/ProcessInstanceHelper.java b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/utils/ProcessInstanceHelper.java new file mode 100644 index 0000000000..dbdd6d84c5 --- /dev/null +++ b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-repo/src/test/java/org/activiti/cloud/services/query/app/repository/utils/ProcessInstanceHelper.java @@ -0,0 +1,49 @@ +/* + * Copyright 2017-2020 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.activiti.cloud.services.query.app.repository.utils; + +import org.activiti.cloud.services.query.model.ProcessInstanceEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class ProcessInstanceHelper { + public ProcessInstanceEntity createProcessInstance(String parentId) { + ProcessInstanceEntity entity = new ProcessInstanceEntity(); + entity.setId(UUID.randomUUID().toString()); + entity.setName(UUID.randomUUID().toString()); + entity.setProcessDefinitionName("process-definition"); + entity.setParentId(parentId.equals("1") ? null : parentId); + return entity; + } + + public List createParentProcessInstances(int count) { + List instances = new ArrayList<>(); + for (int i = 0; i < count; i++) { + instances.add(createProcessInstance("1")); + } + return instances; + } + + public List createSubprocessInstances(int count, String parentId) { + List instances = new ArrayList<>(); + for (int i = 0; i < count; i++) { + instances.add(createProcessInstance(parentId)); + } + return instances; + } +} diff --git a/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-rest/src/test/java/org/activiti/cloud/repos/CustomizedProcessInstanceRepositoryImplIT.java b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-rest/src/test/java/org/activiti/cloud/repos/CustomizedProcessInstanceRepositoryImplIT.java new file mode 100644 index 0000000000..6f1ca04357 --- /dev/null +++ b/activiti-cloud-query-service/activiti-cloud-services-query/activiti-cloud-services-query-rest/src/test/java/org/activiti/cloud/repos/CustomizedProcessInstanceRepositoryImplIT.java @@ -0,0 +1,140 @@ +/* + * Copyright 2017-2020 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.activiti.cloud.repos; + +import jakarta.persistence.EntityManager; +import org.activiti.QueryRestTestApplication; +import org.activiti.cloud.services.query.app.repository.CustomizedProcessInstanceRepositoryImpl; +import org.activiti.cloud.services.query.app.repository.ProcessInstanceRepository; +import org.activiti.cloud.services.query.model.ProcessInstanceEntity; +import org.activiti.cloud.services.query.util.ProcessInstanceTestUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.test.context.TestPropertySource; +import org.springframework.transaction.annotation.Transactional; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest( + classes = { QueryRestTestApplication.class }, + properties = { + "spring.main.banner-mode=off", + "spring.jpa.properties.hibernate.enable_lazy_load_no_trans=false", + "spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect", + } +) +@TestPropertySource("classpath:application-test.properties") +@Testcontainers +@Transactional +class CustomizedProcessInstanceRepositoryImplIT { + @Container + @ServiceConnection + static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:15-alpine"); + + @Autowired + private CustomizedProcessInstanceRepositoryImpl repository; + + @Autowired + private ProcessInstanceRepository processInstanceRepository; + + @Autowired + private EntityManager entityManager; + + @BeforeEach + void setUp() { + processInstanceRepository.deleteAll(); + } + + @Test + void testMapSubprocessesForPage() { + Pageable pageable = PageRequest.of(0, 10); + List processInstancesList = buildDefaultProcessInstances(3); + String parentId1 = processInstancesList.getFirst().getId(); + List subprocesses1 = buildDefaultProcessInstances(2); + setSubprocesses(subprocesses1,parentId1); + String parentId2 = processInstancesList.getLast().getId(); + List subprocesses2 = buildDefaultProcessInstances(3); + setSubprocesses(subprocesses2,parentId2); + + entityManager.flush(); + + Page processInstances = new PageImpl<>(processInstancesList, pageable, processInstancesList.size()); + + Page result = repository.mapSubprocesses(processInstances, pageable); + + assertNotNull(result); + assertEquals(3, result.getTotalElements()); + + ProcessInstanceEntity parentInstance1 = result.getContent().stream() + .filter(instance -> instance.getId().equals(parentId1)) + .findFirst() + .orElse(null); + assertNotNull(parentInstance1); + assertEquals(2, parentInstance1.getSubprocesses().size()); + + ProcessInstanceEntity parentInstance2 = result.getContent().stream() + .filter(instance -> instance.getId().equals(parentId2)) + .findFirst() + .orElse(null); + assertNotNull(parentInstance2); + assertEquals(3, parentInstance2.getSubprocesses().size()); + + } + + @Test + void testMapSubprocessesForProcessInstance() { + List processInstances = buildDefaultProcessInstances(5); + List subprocesses = buildDefaultProcessInstances(2); + ProcessInstanceEntity entity = processInstances.getFirst(); + String parentId = entity.getId(); + setSubprocesses(subprocesses,parentId); + + ProcessInstanceEntity result = repository.mapSubprocesses(entity); + + assertNotNull(result); + assertNotNull(result.getSubprocesses().stream().toList().getLast().getId()); + } + + private List buildDefaultProcessInstances(int count) { + List entities = new ArrayList<>(); + for(int i=1;i<=count;i++ ){ + entities.add(new ProcessInstanceTestUtils().buildProcessInstanceEntity()); + } + processInstanceRepository.saveAll(entities); + return entities; + } + + private void setSubprocesses(List subprocesses,String parentId){ + for(ProcessInstanceEntity subprocess:subprocesses){ + subprocess.setParentId(parentId); + processInstanceRepository.save(subprocess); + } + } +}