From 5104470aaad0861f07e4be01c9e17fc9f6811ef5 Mon Sep 17 00:00:00 2001 From: teleivo Date: Thu, 23 Jan 2025 09:26:02 +0100 Subject: [PATCH 1/3] chore: join code paths for serving one vs many TEs --- .../enrollment/DefaultEnrollmentService.java | 5 +- .../DefaultTrackedEntityService.java | 158 +++----- .../TrackedEntityServiceTest.java | 63 ++-- .../ExportControllerPaginationTest.java | 344 +++++++----------- .../TrackedEntitiesExportControllerTest.java | 2 +- 5 files changed, 213 insertions(+), 359 deletions(-) diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/DefaultEnrollmentService.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/DefaultEnrollmentService.java index 0ef7a2df408d..639629ba056b 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/DefaultEnrollmentService.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/DefaultEnrollmentService.java @@ -42,6 +42,7 @@ import org.hisp.dhis.feedback.BadRequestException; import org.hisp.dhis.feedback.ForbiddenException; import org.hisp.dhis.feedback.NotFoundException; +import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.program.Enrollment; import org.hisp.dhis.program.Event; import org.hisp.dhis.relationship.RelationshipItem; @@ -158,7 +159,9 @@ private Enrollment getEnrollment( trackedEntity.setUid(enrollment.getTrackedEntity().getUid()); result.setTrackedEntity(trackedEntity); } - result.setOrganisationUnit(enrollment.getOrganisationUnit()); + OrganisationUnit organisationUnit = new OrganisationUnit(); + organisationUnit.setUid(enrollment.getOrganisationUnit().getUid()); + result.setOrganisationUnit(organisationUnit); result.setGeometry(enrollment.getGeometry()); result.setCreated(enrollment.getCreated()); result.setCreatedAtClient(enrollment.getCreatedAtClient()); diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/DefaultTrackedEntityService.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/DefaultTrackedEntityService.java index e665670311ea..12336a5c35f1 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/DefaultTrackedEntityService.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/DefaultTrackedEntityService.java @@ -27,7 +27,6 @@ */ package org.hisp.dhis.tracker.export.trackedentity; -import static org.hisp.dhis.audit.AuditOperationType.READ; import static org.hisp.dhis.audit.AuditOperationType.SEARCH; import static org.hisp.dhis.user.CurrentUserUtil.getCurrentUserDetails; @@ -48,7 +47,6 @@ import org.hisp.dhis.fileresource.FileResource; import org.hisp.dhis.fileresource.FileResourceService; import org.hisp.dhis.fileresource.ImageFileDimension; -import org.hisp.dhis.program.Enrollment; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramService; import org.hisp.dhis.relationship.Relationship; @@ -66,7 +64,6 @@ import org.hisp.dhis.tracker.export.FileResourceStream; import org.hisp.dhis.tracker.export.Page; import org.hisp.dhis.tracker.export.PageParams; -import org.hisp.dhis.tracker.export.enrollment.EnrollmentOperationParams; import org.hisp.dhis.tracker.export.enrollment.EnrollmentService; import org.hisp.dhis.tracker.export.event.EventParams; import org.hisp.dhis.tracker.export.event.EventService; @@ -222,111 +219,22 @@ public TrackedEntity getTrackedEntity( @CheckForNull UID programIdentifier, @Nonnull TrackedEntityParams params) throws NotFoundException, ForbiddenException, BadRequestException { - Program program = null; - if (programIdentifier != null) { - program = programService.getProgram(programIdentifier.getValue()); - if (program == null) { - throw new NotFoundException(Program.class, programIdentifier); - } - } - - return getTrackedEntity(trackedEntityUid, program, params, getCurrentUserDetails()); - } - - /** - * Gets a tracked entity based on the program and org unit ownership. - * - * @return the TE object if found and accessible by the current user - * @throws NotFoundException if uid does not exist - * @throws ForbiddenException if TE owner is not in user's scope or not enough sharing access - */ - private TrackedEntity getTrackedEntity( - UID uid, Program program, TrackedEntityParams params, UserDetails user) - throws NotFoundException, ForbiddenException, BadRequestException { - TrackedEntity trackedEntity = trackedEntityStore.getByUid(uid.getValue()); - if (trackedEntity == null) { - throw new NotFoundException(TrackedEntity.class, uid); + TrackedEntityOperationParams operationParams = + TrackedEntityOperationParams.builder() + .trackedEntities(Set.of(trackedEntityUid)) + .program(programIdentifier) + .trackedEntityParams(params) + .build(); + // TODO(ivo) allow setting the audit to READ instead of SEARCH + // trackedEntityAuditService.addTrackedEntityAudit(READ, user.getUsername(), trackedEntity); + Page trackedEntities = + getTrackedEntities(operationParams, new PageParams(1, 1, false)); + + if (trackedEntities.getItems().isEmpty()) { + throw new NotFoundException(TrackedEntity.class, trackedEntityUid); } - trackedEntityAuditService.addTrackedEntityAudit(READ, user.getUsername(), trackedEntity); - - if (program != null) { - List errors = - trackerAccessManager.canReadProgramAndTrackedEntityType(user, trackedEntity, program); - if (!errors.isEmpty()) { - throw new ForbiddenException(errors.toString()); - } - - String error = - trackerAccessManager.canAccessProgramOwner(user, trackedEntity, program, false); - if (error != null) { - throw new ForbiddenException(error); - } - } else { - if (!trackerAccessManager.canRead(user, trackedEntity).isEmpty()) { - throw new ForbiddenException(TrackedEntity.class, uid); - } - } - - if (params.isIncludeEnrollments()) { - EnrollmentOperationParams enrollmentOperationParams = - mapToEnrollmentParams(uid, program, params); - List enrollments = enrollmentService.getEnrollments(enrollmentOperationParams); - trackedEntity.setEnrollments(new HashSet<>(enrollments)); - } - setRelationshipItems(trackedEntity, trackedEntity, params, false); - if (params.isIncludeProgramOwners()) { - trackedEntity.setProgramOwners(getTrackedEntityProgramOwners(trackedEntity, program)); - } - trackedEntity.setTrackedEntityAttributeValues( - getTrackedEntityAttributeValues(trackedEntity, program)); - return trackedEntity; - } - - private EnrollmentOperationParams mapToEnrollmentParams( - UID trackedEntity, Program program, TrackedEntityParams params) { - return EnrollmentOperationParams.builder() - .trackedEntity(trackedEntity) - .program(program) - .enrollmentParams(params.getEnrollmentParams()) - .build(); - } - - private static Set getTrackedEntityProgramOwners( - TrackedEntity trackedEntity, Program program) { - if (program == null) { - return trackedEntity.getProgramOwners(); - } - - return trackedEntity.getProgramOwners().stream() - .filter(te -> te.getProgram().getUid().equals(program.getUid())) - .collect(Collectors.toSet()); - } - - private Set getTrackedEntityAttributeValues( - TrackedEntity trackedEntity, Program program) { - TrackedEntityType trackedEntityType = trackedEntity.getTrackedEntityType(); - if (CollectionUtils.isEmpty(trackedEntityType.getTrackedEntityTypeAttributes())) { - // the TrackedEntityAggregate does not fetch the TrackedEntityTypeAttributes at the moment - // TODO(DHIS2-18541) bypass ACL as our controller test as the user must have access to the TET - // if it has access to the TE. - trackedEntityType = - trackedEntityTypeStore.getByUidNoAcl(trackedEntity.getTrackedEntityType().getUid()); - } - - Set teas = // tracked entity type attributes - trackedEntityType.getTrackedEntityAttributes().stream() - .map(IdentifiableObject::getUid) - .collect(Collectors.toSet()); - if (program != null) { // add program tracked entity attributes - teas.addAll( - program.getTrackedEntityAttributes().stream() - .map(IdentifiableObject::getUid) - .collect(Collectors.toSet())); - } - return trackedEntity.getTrackedEntityAttributeValues().stream() - .filter(av -> teas.contains(av.getAttribute().getUid())) - .collect(Collectors.toSet()); + return trackedEntities.getItems().get(0); } @Nonnull @@ -368,6 +276,7 @@ private List getTrackedEntities( operationParams.getTrackedEntityParams(), queryParams, queryParams.getOrgUnitMode()); + // TODO(ivo) clean this up setRelationshipItems( trackedEntities, operationParams.getTrackedEntityParams(), @@ -384,6 +293,43 @@ private List getTrackedEntities( return trackedEntities; } + private static Set getTrackedEntityProgramOwners( + TrackedEntity trackedEntity, Program program) { + if (program == null) { + return trackedEntity.getProgramOwners(); + } + + return trackedEntity.getProgramOwners().stream() + .filter(te -> te.getProgram().getUid().equals(program.getUid())) + .collect(Collectors.toSet()); + } + + private Set getTrackedEntityAttributeValues( + TrackedEntity trackedEntity, Program program) { + TrackedEntityType trackedEntityType = trackedEntity.getTrackedEntityType(); + if (CollectionUtils.isEmpty(trackedEntityType.getTrackedEntityTypeAttributes())) { + // the TrackedEntityAggregate does not fetch the TrackedEntityTypeAttributes at the moment + // TODO(DHIS2-18541) bypass ACL as our controller test as the user must have access to the TET + // if it has access to the TE. + trackedEntityType = + trackedEntityTypeStore.getByUidNoAcl(trackedEntity.getTrackedEntityType().getUid()); + } + + Set teas = // tracked entity type attributes + trackedEntityType.getTrackedEntityAttributes().stream() + .map(IdentifiableObject::getUid) + .collect(Collectors.toSet()); + if (program != null) { // add program tracked entity attributes + teas.addAll( + program.getTrackedEntityAttributes().stream() + .map(IdentifiableObject::getUid) + .collect(Collectors.toSet())); + } + return trackedEntity.getTrackedEntityAttributeValues().stream() + .filter(av -> teas.contains(av.getAttribute().getUid())) + .collect(Collectors.toSet()); + } + /** * We need to return the full models for relationship items (i.e. trackedEntity, enrollment and * event) in our API. The aggregate stores currently do not support that, so we need to fetch the diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java index 3697e0a2153e..745dad25cea0 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/trackedentity/TrackedEntityServiceTest.java @@ -1832,16 +1832,11 @@ void shouldReturnAllEntitiesWhenSuperuserAndModeAll() @Test void shouldFailWhenRequestingSingleTEAndProvidedProgramDoesNotExist() { - String programUid = "madeUpPrUid"; - NotFoundException exception = - assertThrows( - NotFoundException.class, - () -> - trackedEntityService.getTrackedEntity( - UID.of(trackedEntityA), UID.of(programUid), TrackedEntityParams.TRUE)); - assertEquals( - String.format("Program with id %s could not be found.", programUid), - exception.getMessage()); + assertThrows( + BadRequestException.class, + () -> + trackedEntityService.getTrackedEntity( + UID.of(trackedEntityA), UID.of("madeUpPrUid"), TrackedEntityParams.TRUE)); } @Test @@ -1874,7 +1869,7 @@ void shouldFailWhenRequestingSingleTEAndNoDataAccessToProvidedProgram() { trackedEntityService.getTrackedEntity( UID.of(trackedEntityA), UID.of(inaccessibleProgram), TrackedEntityParams.TRUE)); assertContains( - String.format("User has no data read access to program: %s", inaccessibleProgram.getUid()), + String.format("User has no access to program: %s", inaccessibleProgram.getUid()), exception.getMessage()); } @@ -1887,17 +1882,11 @@ void shouldFailWhenRequestingSingleTEAndTETNotAccessible() { trackedEntity.setTrackedEntityType(inaccessibleTrackedEntityType); manager.save(trackedEntity); - ForbiddenException exception = - assertThrows( - ForbiddenException.class, - () -> - trackedEntityService.getTrackedEntity( - UID.of(trackedEntity), UID.of(programA), TrackedEntityParams.TRUE)); - assertContains( - String.format( - "User has no data read access to tracked entity type: %s", - inaccessibleTrackedEntityType.getUid()), - exception.getMessage()); + assertThrows( + NotFoundException.class, + () -> + trackedEntityService.getTrackedEntity( + UID.of(trackedEntity), UID.of(programA), TrackedEntityParams.TRUE)); } @Test @@ -1954,16 +1943,11 @@ void shouldFailWhenRequestingSingleTEAndTETDoesNotMatchAnyProgram() { manager.update(programC); injectSecurityContextUser(user); - ForbiddenException exception = - assertThrows( - ForbiddenException.class, - () -> - trackedEntityService.getTrackedEntity( - UID.of(trackedEntityA), null, TrackedEntityParams.TRUE)); - - assertContains( - String.format("User has no access to TrackedEntity:%s", trackedEntityA.getUid()), - exception.getMessage()); + assertThrows( + NotFoundException.class, + () -> + trackedEntityService.getTrackedEntity( + UID.of(trackedEntityA), null, TrackedEntityParams.TRUE)); } @Test @@ -1993,16 +1977,11 @@ void shouldFailWhenRequestingSingleTEAndNoAccessToTET() { manager.update(trackedEntityA); injectSecurityContextUser(user); - ForbiddenException exception = - assertThrows( - ForbiddenException.class, - () -> - trackedEntityService.getTrackedEntity( - UID.of(trackedEntityA), null, TrackedEntityParams.TRUE)); - - assertEquals( - String.format("User has no access to TrackedEntity:%s", trackedEntityA.getUid()), - exception.getMessage()); + assertThrows( + BadRequestException.class, + () -> + trackedEntityService.getTrackedEntity( + UID.of(trackedEntityA), null, TrackedEntityParams.TRUE)); } @Test diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/ExportControllerPaginationTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/ExportControllerPaginationTest.java index 05924435a9f8..98784e84ad99 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/ExportControllerPaginationTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/ExportControllerPaginationTest.java @@ -28,39 +28,50 @@ package org.hisp.dhis.webapi.controller.tracker.export; import static org.hisp.dhis.test.utils.Assertions.assertContainsOnly; +import static org.hisp.dhis.test.utils.Assertions.assertNotEmpty; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertHasNoMember; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; -import java.util.Date; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; -import org.hisp.dhis.category.CategoryOptionCombo; -import org.hisp.dhis.category.CategoryService; -import org.hisp.dhis.common.CodeGenerator; +import java.util.function.Supplier; +import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; +import org.hisp.dhis.common.UidObject; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundle; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleMode; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleParams; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleService; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleValidationService; +import org.hisp.dhis.dxf2.metadata.objectbundle.feedback.ObjectBundleValidationReport; import org.hisp.dhis.http.HttpStatus; +import org.hisp.dhis.importexport.ImportStrategy; import org.hisp.dhis.jsontree.JsonList; -import org.hisp.dhis.organisationunit.OrganisationUnit; -import org.hisp.dhis.program.Enrollment; -import org.hisp.dhis.program.EnrollmentStatus; import org.hisp.dhis.program.Event; -import org.hisp.dhis.program.Program; -import org.hisp.dhis.program.ProgramStage; -import org.hisp.dhis.relationship.Relationship; -import org.hisp.dhis.relationship.RelationshipEntity; import org.hisp.dhis.relationship.RelationshipItem; -import org.hisp.dhis.relationship.RelationshipType; -import org.hisp.dhis.security.acl.AccessStringHelper; -import org.hisp.dhis.test.webapi.H2ControllerIntegrationTestBase; -import org.hisp.dhis.trackedentity.TrackedEntity; -import org.hisp.dhis.trackedentity.TrackedEntityType; +import org.hisp.dhis.render.RenderFormat; +import org.hisp.dhis.render.RenderService; +import org.hisp.dhis.test.webapi.PostgresControllerIntegrationTestBase; +import org.hisp.dhis.tracker.imports.TrackerImportParams; +import org.hisp.dhis.tracker.imports.TrackerImportService; +import org.hisp.dhis.tracker.imports.domain.TrackerObjects; +import org.hisp.dhis.tracker.imports.report.ImportReport; +import org.hisp.dhis.tracker.imports.report.Status; +import org.hisp.dhis.tracker.imports.report.ValidationReport; import org.hisp.dhis.user.User; -import org.hisp.dhis.user.sharing.UserAccess; import org.hisp.dhis.webapi.controller.tracker.JsonPage; import org.hisp.dhis.webapi.controller.tracker.JsonRelationship; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; import org.springframework.transaction.annotation.Transactional; /** @@ -70,75 +81,77 @@ * the export controllers. */ @Transactional -class ExportControllerPaginationTest extends H2ControllerIntegrationTestBase { +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class ExportControllerPaginationTest extends PostgresControllerIntegrationTestBase { + @Autowired private RenderService renderService; - @Autowired private IdentifiableObjectManager manager; - - @Autowired private CategoryService categoryService; - - private CategoryOptionCombo coc; - - private OrganisationUnit orgUnit; + @Autowired private ObjectBundleService objectBundleService; - private Program program; + @Autowired private ObjectBundleValidationService objectBundleValidationService; - private ProgramStage programStage; + @Autowired private TrackerImportService trackerImportService; - private User owner; - - private User user; - - private TrackedEntityType trackedEntityType; + @Autowired private IdentifiableObjectManager manager; - @BeforeEach - void setUp() { - owner = makeUser("o"); - manager.save(owner, false); + private User importUser; + + private Event event; + private Set relationshipItems; + + protected ObjectBundle setUpMetadata(String path) throws IOException { + Map, List> metadata = + renderService.fromMetadata(new ClassPathResource(path).getInputStream(), RenderFormat.JSON); + ObjectBundleParams params = new ObjectBundleParams(); + params.setObjectBundleMode(ObjectBundleMode.COMMIT); + params.setImportStrategy(ImportStrategy.CREATE); + params.setObjects(metadata); + ObjectBundle bundle = objectBundleService.create(params); + assertNoErrors(objectBundleValidationService.validate(bundle)); + objectBundleService.commit(bundle); + return bundle; + } - coc = categoryService.getDefaultCategoryOptionCombo(); + protected TrackerObjects fromJson(String path) throws IOException { + return renderService.fromJson( + new ClassPathResource(path).getInputStream(), TrackerObjects.class); + } - orgUnit = createOrganisationUnit('A'); - orgUnit.getSharing().setOwner(owner); - manager.save(orgUnit, false); + @BeforeAll + void setUp() throws IOException { + setUpMetadata("tracker/simple_metadata.json"); - OrganisationUnit anotherOrgUnit = createOrganisationUnit('B'); - anotherOrgUnit.getSharing().setOwner(owner); - manager.save(anotherOrgUnit, false); + importUser = userService.getUser("tTgjgobT1oS"); + injectSecurityContextUser(importUser); - user = createUserWithId("tester", CodeGenerator.generateUid()); - user.addOrganisationUnit(orgUnit); - user.setTeiSearchOrganisationUnits(Set.of(orgUnit)); - this.userService.updateUser(user); + TrackerImportParams params = TrackerImportParams.builder().build(); + assertNoErrors( + trackerImportService.importTracker(params, fromJson("tracker/event_and_enrollment.json"))); - program = createProgram('A'); - program.addOrganisationUnit(orgUnit); - program.getSharing().setOwner(owner); - program.getSharing().addUserAccess(userAccess()); - manager.save(program, false); + manager.flush(); + manager.clear(); - programStage = createProgramStage('A', program); - programStage.getSharing().setOwner(owner); - programStage.getSharing().addUserAccess(userAccess()); - manager.save(programStage, false); + event = get(Event.class, "pTzf9KYMk72"); + assertNotEmpty(event.getRelationshipItems(), "test expects an enrollment with one event"); + relationshipItems = event.getRelationshipItems(); + } - trackedEntityType = trackedEntityTypeAccessible(); + @BeforeEach + void setUpUser() { + switchContextToUser(importUser); } @Test void shouldGetPaginatedItemsWithDefaults() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - Relationship r1 = relationship(from1, to); - Relationship r2 = relationship(from2, to); - JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}", to.getUid()) + GET("/tracker/relationships?event={uid}", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); assertContainsOnly( - List.of(r1.getUid(), r2.getUid()), + relationshipItems.stream() + .map(RelationshipItem::getRelationship) + .map(UidObject::getUid) + .toList(), page.getList("relationships", JsonRelationship.class) .toList(JsonRelationship::getRelationship)); assertEquals(1, page.getPager().getPage()); @@ -155,19 +168,16 @@ void shouldGetPaginatedItemsWithDefaults() { @Test void shouldGetPaginatedItemsWithPagingSetToTrue() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - Relationship r1 = relationship(from1, to); - Relationship r2 = relationship(from2, to); - JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}&paging=true", to.getUid()) + GET("/tracker/relationships?event={uid}&paging=true", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); assertContainsOnly( - List.of(r1.getUid(), r2.getUid()), + relationshipItems.stream() + .map(RelationshipItem::getRelationship) + .map(UidObject::getUid) + .toList(), page.getList("relationships", JsonRelationship.class) .toList(JsonRelationship::getRelationship)); assertEquals(1, page.getPager().getPage()); @@ -184,19 +194,16 @@ void shouldGetPaginatedItemsWithPagingSetToTrue() { @Test void shouldGetPaginatedItemsWithDefaultsAndTotals() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - Relationship r1 = relationship(from1, to); - Relationship r2 = relationship(from2, to); - JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}&totalPages=true", to.getUid()) + GET("/tracker/relationships?event={uid}&totalPages=true", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); assertContainsOnly( - List.of(r1.getUid(), r2.getUid()), + relationshipItems.stream() + .map(RelationshipItem::getRelationship) + .map(UidObject::getUid) + .toList(), page.getList("relationships", JsonRelationship.class) .toList(JsonRelationship::getRelationship)); assertEquals(1, page.getPager().getPage()); @@ -213,14 +220,8 @@ void shouldGetPaginatedItemsWithDefaultsAndTotals() { @Test void shouldGetPaginatedItemsWithNonDefaults() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - relationship(from1, to); - relationship(from2, to); - JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}&page=2&pageSize=1", to.getUid()) + GET("/tracker/relationships?event={uid}&page=2&pageSize=1", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); @@ -245,16 +246,9 @@ void shouldGetPaginatedItemsWithNonDefaults() { @Test void shouldGetPaginatedItemsWithNonDefaultsAndTotals() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - relationship(from1, to); - relationship(from2, to); JsonPage page = - GET( - "/tracker/relationships?trackedEntity={uid}&page=2&pageSize=1&totalPages=true", - to.getUid()) + GET("/tracker/relationships?event={uid}&page=2&pageSize=1&totalPages=true", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); @@ -279,19 +273,17 @@ void shouldGetPaginatedItemsWithNonDefaultsAndTotals() { @Test void shouldGetNonPaginatedItemsWithSkipPaging() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - Relationship r1 = relationship(from1, to); - Relationship r2 = relationship(from2, to); JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}&skipPaging=true", to.getUid()) + GET("/tracker/relationships?event={uid}&skipPaging=true", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); assertContainsOnly( - List.of(r1.getUid(), r2.getUid()), + relationshipItems.stream() + .map(RelationshipItem::getRelationship) + .map(UidObject::getUid) + .toList(), page.getList("relationships", JsonRelationship.class) .toList(JsonRelationship::getRelationship)); assertHasNoMember(page, "pager"); @@ -305,19 +297,17 @@ void shouldGetNonPaginatedItemsWithSkipPaging() { @Test void shouldGetNonPaginatedItemsWithPagingSetToFalse() { - TrackedEntity to = trackedEntity(); - Event from1 = event(enrollment(to)); - Event from2 = event(enrollment(to)); - Relationship r1 = relationship(from1, to); - Relationship r2 = relationship(from2, to); JsonPage page = - GET("/tracker/relationships?trackedEntity={uid}&paging=false", to.getUid()) + GET("/tracker/relationships?event={uid}&paging=false", event.getUid()) .content(HttpStatus.OK) .asA(JsonPage.class); assertContainsOnly( - List.of(r1.getUid(), r2.getUid()), + relationshipItems.stream() + .map(RelationshipItem::getRelationship) + .map(UidObject::getUid) + .toList(), page.getList("relationships", JsonRelationship.class) .toList(JsonRelationship::getRelationship)); assertHasNoMember(page, "pager"); @@ -329,110 +319,46 @@ void shouldGetNonPaginatedItemsWithPagingSetToFalse() { assertHasNoMember(page, "pageCount"); } - private TrackedEntityType trackedEntityTypeAccessible() { - TrackedEntityType type = trackedEntityType(); - type.getSharing().addUserAccess(userAccess()); - manager.save(type, false); - return type; - } - - private TrackedEntityType trackedEntityType() { - TrackedEntityType type = createTrackedEntityType('A'); - type.getSharing().setOwner(owner); - type.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - return type; - } - - private TrackedEntity trackedEntity() { - TrackedEntity te = trackedEntity(orgUnit); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntity(OrganisationUnit orgUnit) { - TrackedEntity te = trackedEntity(orgUnit, trackedEntityType); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntity( - OrganisationUnit orgUnit, TrackedEntityType trackedEntityType) { - TrackedEntity te = createTrackedEntity(orgUnit); - te.setTrackedEntityType(trackedEntityType); - te.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - te.getSharing().setOwner(owner); - return te; - } - - private Enrollment enrollment(TrackedEntity te) { - Enrollment enrollment = new Enrollment(program, te, orgUnit); - enrollment.setAutoFields(); - enrollment.setEnrollmentDate(new Date()); - enrollment.setOccurredDate(new Date()); - enrollment.setStatus(EnrollmentStatus.COMPLETED); - manager.save(enrollment, false); - te.setEnrollments(Set.of(enrollment)); - manager.save(te, false); - return enrollment; - } - - private Event event(Enrollment enrollment) { - Event event = new Event(enrollment, programStage, orgUnit, coc); - event.setAutoFields(); - manager.save(event, false); - enrollment.setEvents(Set.of(event)); - manager.save(enrollment, false); - return event; - } - - private UserAccess userAccess() { - UserAccess a = new UserAccess(); - a.setUser(user); - a.setAccess(AccessStringHelper.FULL); - return a; + private T get(Class type, String uid) { + T t = manager.get(type, uid); + assertNotNull( + t, + () -> + String.format( + "'%s' with uid '%s' should have been created", type.getSimpleName(), uid)); + return t; } - private RelationshipType relationshipTypeAccessible() { - RelationshipType type = relationshipType(); - type.getSharing().addUserAccess(userAccess()); - manager.save(type, false); - return type; + public static void assertNoErrors(ImportReport report) { + assertNotNull(report); + assertEquals( + Status.OK, + report.getStatus(), + errorMessage( + "Expected import with status OK, instead got:%n", report.getValidationReport())); } - private RelationshipType relationshipType() { - RelationshipType type = createRelationshipType('A'); - type.getFromConstraint().setRelationshipEntity(RelationshipEntity.PROGRAM_STAGE_INSTANCE); - type.getToConstraint().setRelationshipEntity(RelationshipEntity.TRACKED_ENTITY_INSTANCE); - type.getSharing().setOwner(owner); - type.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - manager.save(type, false); - return type; + private static Supplier errorMessage(String errorTitle, ValidationReport report) { + return () -> { + StringBuilder msg = new StringBuilder(errorTitle); + report + .getErrors() + .forEach( + e -> { + msg.append(e.getErrorCode()); + msg.append(": "); + msg.append(e.getMessage()); + msg.append('\n'); + }); + return msg.toString(); + }; } - private Relationship relationship(Event from, TrackedEntity to) { - Relationship r = new Relationship(); - - RelationshipItem fromItem = new RelationshipItem(); - fromItem.setEvent(from); - from.getRelationshipItems().add(fromItem); - r.setFrom(fromItem); - fromItem.setRelationship(r); - - RelationshipItem toItem = new RelationshipItem(); - toItem.setTrackedEntity(to); - to.getRelationshipItems().add(toItem); - r.setTo(toItem); - toItem.setRelationship(r); - - RelationshipType type = relationshipTypeAccessible(); - r.setRelationshipType(type); - r.setKey(type.getUid()); - r.setInvertedKey(type.getUid()); - - r.setAutoFields(); - r.getSharing().setOwner(owner); - r.setCreatedAtClient(new Date()); - manager.save(r, false); - return r; + public static void assertNoErrors(ObjectBundleValidationReport report) { + assertNotNull(report); + List errors = new ArrayList<>(); + report.forEachErrorReport(err -> errors.add(err.toString())); + assertFalse( + report.hasErrorReports(), String.format("Expected no errors, instead got: %s%n", errors)); } } diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerTest.java index 89cea37bf476..22aa140d39f6 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/trackedentity/TrackedEntitiesExportControllerTest.java @@ -406,7 +406,7 @@ void getTrackedEntityByIdyWithFieldsRelationshipsNoAccessToTrackedEntityType() { this.switchContextToUser(user); GET("/tracker/trackedEntities/{id}?fields=relationships", from.getUid()) - .error(HttpStatus.FORBIDDEN); + .error(HttpStatus.NOT_FOUND); } @Test From 72ac29c0051f53e7b28f7e26286f22fa8a034327 Mon Sep 17 00:00:00 2001 From: teleivo Date: Thu, 23 Jan 2025 11:52:02 +0100 Subject: [PATCH 2/3] test: migrate some tests --- .../controller/tracker/JsonAssertions.java | 9 +- .../RelationshipsExportControllerTest.java | 1532 +++++++---------- 2 files changed, 661 insertions(+), 880 deletions(-) diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/JsonAssertions.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/JsonAssertions.java index b006553f812e..aa145430cd11 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/JsonAssertions.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/JsonAssertions.java @@ -39,6 +39,7 @@ import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import org.hisp.dhis.common.UidObject; import org.hisp.dhis.jsontree.JsonArray; import org.hisp.dhis.jsontree.JsonList; import org.hisp.dhis.jsontree.JsonObject; @@ -124,16 +125,16 @@ public static void assertTrackedEntityWithinRelationshipItem( jsonTe.getTrackedEntityType(), "trackedEntityType UID"); assertEquals(expected.getOrganisationUnit().getUid(), jsonTe.getOrgUnit(), "orgUnit UID"); - assertTrue(jsonTe.getAttributes().isEmpty(), "attributes should be empty"); + assertFalse(jsonTe.getAttributes().isEmpty(), "attributes should be empty"); assertFalse( jsonTe.has("relationships"), "relationships is not returned within relationship items"); } - public static void assertHasOnlyUid(String expectedUid, String member, JsonObject json) { + public static void assertHasOnlyUid(UidObject expected, String member, JsonObject json) { JsonObject j = json.getObject(member); assertFalse(j.isEmpty(), member + " should not be empty"); assertHasOnlyMembers(j, member); - assertEquals(expectedUid, j.getString(member).string(), member + " UID"); + assertEquals(expected.getUid(), j.getString(member).string(), member + " UID"); } public static void assertEnrollmentWithinRelationship( @@ -149,7 +150,7 @@ public static void assertEnrollmentWithinRelationship( assertEquals(expected.getFollowup(), jsonEnrollment.getFollowUp(), "followUp"); assertEquals( expected.getOrganisationUnit().getUid(), jsonEnrollment.getOrgUnit(), "orgUnit UID"); - assertTrue(jsonEnrollment.getArray("events").isEmpty(), "events should be empty"); + assertFalse(jsonEnrollment.getArray("events").isEmpty(), "events should be empty"); assertFalse( jsonEnrollment.has("relationships"), "relationships is not returned within relationship items"); diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java index fbcdd131e6d1..7e94d62f093b 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java @@ -27,204 +27,170 @@ */ package org.hisp.dhis.webapi.controller.tracker.export.relationship; -import static org.hisp.dhis.test.utils.Assertions.assertIsEmpty; import static org.hisp.dhis.test.utils.Assertions.assertStartsWith; -import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertContainsAll; +import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertContains; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertEnrollmentWithinRelationship; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertEventWithinRelationshipItem; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertFirstRelationship; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertHasOnlyMembers; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertHasOnlyUid; -import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertNoRelationships; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertRelationship; import static org.hisp.dhis.webapi.controller.tracker.JsonAssertions.assertTrackedEntityWithinRelationshipItem; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; -import java.util.Date; -import java.util.LinkedHashSet; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; -import java.util.Set; -import org.hisp.dhis.category.CategoryOptionCombo; -import org.hisp.dhis.category.CategoryService; +import java.util.Map; +import java.util.function.Supplier; +import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; -import org.hisp.dhis.dataelement.DataElement; -import org.hisp.dhis.eventdatavalue.EventDataValue; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundle; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleMode; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleParams; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleService; +import org.hisp.dhis.dxf2.metadata.objectbundle.ObjectBundleValidationService; +import org.hisp.dhis.dxf2.metadata.objectbundle.feedback.ObjectBundleValidationReport; import org.hisp.dhis.http.HttpStatus; +import org.hisp.dhis.importexport.ImportStrategy; import org.hisp.dhis.jsontree.JsonList; -import org.hisp.dhis.jsontree.JsonObject; -import org.hisp.dhis.note.Note; -import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.program.Enrollment; -import org.hisp.dhis.program.EnrollmentStatus; import org.hisp.dhis.program.Event; -import org.hisp.dhis.program.Program; -import org.hisp.dhis.program.ProgramStage; import org.hisp.dhis.relationship.Relationship; -import org.hisp.dhis.relationship.RelationshipConstraint; -import org.hisp.dhis.relationship.RelationshipEntity; -import org.hisp.dhis.relationship.RelationshipItem; -import org.hisp.dhis.relationship.RelationshipType; -import org.hisp.dhis.security.acl.AccessStringHelper; +import org.hisp.dhis.render.RenderFormat; +import org.hisp.dhis.render.RenderService; import org.hisp.dhis.test.webapi.PostgresControllerIntegrationTestBase; import org.hisp.dhis.trackedentity.TrackedEntity; -import org.hisp.dhis.trackedentity.TrackedEntityAttribute; -import org.hisp.dhis.trackedentity.TrackedEntityProgramOwner; -import org.hisp.dhis.trackedentity.TrackedEntityType; -import org.hisp.dhis.trackedentity.TrackedEntityTypeAttribute; -import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue; -import org.hisp.dhis.trackerdataview.TrackerDataView; +import org.hisp.dhis.tracker.imports.TrackerImportParams; +import org.hisp.dhis.tracker.imports.TrackerImportService; +import org.hisp.dhis.tracker.imports.domain.TrackerObjects; +import org.hisp.dhis.tracker.imports.report.ImportReport; +import org.hisp.dhis.tracker.imports.report.Status; +import org.hisp.dhis.tracker.imports.report.ValidationReport; import org.hisp.dhis.user.User; -import org.hisp.dhis.user.sharing.UserAccess; -import org.hisp.dhis.webapi.controller.tracker.JsonAttribute; -import org.hisp.dhis.webapi.controller.tracker.JsonDataValue; import org.hisp.dhis.webapi.controller.tracker.JsonNote; -import org.hisp.dhis.webapi.controller.tracker.JsonProgramOwner; import org.hisp.dhis.webapi.controller.tracker.JsonRelationship; -import org.hisp.dhis.webapi.controller.tracker.JsonRelationshipItem; -import org.hisp.dhis.webapi.controller.tracker.JsonUser; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; import org.springframework.transaction.annotation.Transactional; @Transactional +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class RelationshipsExportControllerTest extends PostgresControllerIntegrationTestBase { + @Autowired private RenderService renderService; - @Autowired private IdentifiableObjectManager manager; - - @Autowired private CategoryService categoryService; - - private CategoryOptionCombo coc; - - private OrganisationUnit orgUnit; - - private OrganisationUnit anotherOrgUnit; - - private Program program; - - private ProgramStage programStage; - - private User owner; - - private User user; + @Autowired private ObjectBundleService objectBundleService; - private TrackedEntityType trackedEntityType; + @Autowired private ObjectBundleValidationService objectBundleValidationService; - private TrackedEntityAttribute tea; + @Autowired private TrackerImportService trackerImportService; - private TrackedEntityAttribute tea2; - - private DataElement dataElement; - - @BeforeEach - void setUp() { - owner = makeUser("o"); - manager.save(owner, false); - - coc = categoryService.getDefaultCategoryOptionCombo(); + @Autowired private IdentifiableObjectManager manager; - orgUnit = createOrganisationUnit('A'); - orgUnit.getSharing().setOwner(owner); - manager.save(orgUnit, false); + private User importUser; - anotherOrgUnit = createOrganisationUnit('B'); - anotherOrgUnit.getSharing().setOwner(owner); - manager.save(anotherOrgUnit, false); + private Event relationship1To; + private Relationship relationship1; + private TrackedEntity relationship1From; + private Relationship relationship2; + private TrackedEntity relationship2From; + private Enrollment relationship2To; - user = createAndAddUser("tester", orgUnit); - user.setTeiSearchOrganisationUnits(Set.of(orgUnit)); - this.userService.updateUser(user); + protected ObjectBundle setUpMetadata(String path) throws IOException { + Map, List> metadata = + renderService.fromMetadata(new ClassPathResource(path).getInputStream(), RenderFormat.JSON); + ObjectBundleParams params = new ObjectBundleParams(); + params.setObjectBundleMode(ObjectBundleMode.COMMIT); + params.setImportStrategy(ImportStrategy.CREATE); + params.setObjects(metadata); + ObjectBundle bundle = objectBundleService.create(params); + assertNoErrors(objectBundleValidationService.validate(bundle)); + objectBundleService.commit(bundle); + return bundle; + } - tea = createTrackedEntityAttribute('A'); - tea.getSharing().setOwner(owner); - tea.getSharing().addUserAccess(userAccess()); - manager.save(tea, false); + protected TrackerObjects fromJson(String path) throws IOException { + return renderService.fromJson( + new ClassPathResource(path).getInputStream(), TrackerObjects.class); + } - tea2 = createTrackedEntityAttribute('B'); - tea2.getSharing().setOwner(owner); - tea2.getSharing().addUserAccess(userAccess()); - manager.save(tea2, false); + @BeforeAll + void setUp() throws IOException { + setUpMetadata("tracker/simple_metadata.json"); - trackedEntityType = trackedEntityTypeAccessible(); + importUser = userService.getUser("tTgjgobT1oS"); + injectSecurityContextUser(importUser); - TrackedEntityTypeAttribute trackedEntityTypeAttribute = - new TrackedEntityTypeAttribute(trackedEntityType, tea); - trackedEntityTypeAttribute.setMandatory(false); - trackedEntityTypeAttribute.getSharing().setOwner(owner); - trackedEntityTypeAttribute.getSharing().addUserAccess(userAccess()); - manager.save(trackedEntityTypeAttribute); + TrackerImportParams params = TrackerImportParams.builder().build(); + assertNoErrors( + trackerImportService.importTracker(params, fromJson("tracker/event_and_enrollment.json"))); - trackedEntityType.setTrackedEntityTypeAttributes(List.of(trackedEntityTypeAttribute)); - manager.save(trackedEntityType, false); + manager.flush(); + manager.clear(); - program = createProgram('A'); - program.addOrganisationUnit(orgUnit); - program.getSharing().setOwner(owner); - program.getSharing().addUserAccess(userAccess()); - program.setTrackedEntityType(trackedEntityType); - manager.save(program, false); + relationship1 = get(Relationship.class, "oLT07jKRu9e"); + relationship1From = relationship1.getFrom().getTrackedEntity(); + assertNotNull(relationship1From, "test expects 'from' to be a tracked entity"); + relationship1To = relationship1.getTo().getEvent(); + assertNotNull(relationship1To, "test expects 'to' to be an event"); - programStage = createProgramStage('A', program); - programStage.getSharing().setOwner(owner); - programStage.getSharing().addUserAccess(userAccess()); - manager.save(programStage, false); + relationship2 = get(Relationship.class, "p53a6314631"); + relationship2From = relationship2.getFrom().getTrackedEntity(); + assertNotNull(relationship2From, "test expects 'from' to be a tracked entity"); + relationship2To = relationship2.getTo().getEnrollment(); + assertNotNull(relationship2To, "test expects 'to' to be an enrollment"); + } - dataElement = createDataElement('A'); - manager.save(dataElement, false); + @BeforeEach + void setUpUser() { + switchContextToUser(importUser); } @Test void getRelationshipsById() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonRelationship relationship = - GET("/tracker/relationships/{uid}", r.getUid()) + JsonRelationship jsonRelationship = + GET("/tracker/relationships/{uid}", relationship1.getUid()) .content(HttpStatus.OK) .as(JsonRelationship.class); assertHasOnlyMembers( - relationship, "relationship", "relationshipType", "createdAtClient", "from", "to"); - assertRelationship(r, relationship); - assertHasOnlyUid(from.getUid(), "event", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + jsonRelationship, "relationship", "relationshipType", "createdAtClient", "from", "to"); + assertRelationship(relationship1, jsonRelationship); + assertHasOnlyUid(relationship1From, "trackedEntity", jsonRelationship.getObject("from")); + assertHasOnlyUid(relationship1To, "event", jsonRelationship.getObject("to")); } @Test void getRelationshipsByIdWithFieldsAll() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonRelationship relationship = - GET("/tracker/relationships/{uid}?fields=*", r.getUid()) + JsonRelationship jsonRelationship = + GET("/tracker/relationships/{uid}?fields=*", relationship1.getUid()) .content(HttpStatus.OK) .as(JsonRelationship.class); - assertRelationship(r, relationship); - assertEventWithinRelationshipItem(from, relationship.getFrom()); - assertTrackedEntityWithinRelationshipItem(to, relationship.getTo()); + assertRelationship(relationship1, jsonRelationship); + assertTrackedEntityWithinRelationshipItem(relationship1From, jsonRelationship.getFrom()); + assertEventWithinRelationshipItem(relationship1To, jsonRelationship.getTo()); } @Test void getRelationshipsByIdWithFields() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonRelationship relationship = - GET("/tracker/relationships/{uid}?fields=relationship,from[event]", r.getUid()) + JsonRelationship jsonRelationship = + GET("/tracker/relationships/{uid}?fields=relationship,to[event]", relationship1.getUid()) .content(HttpStatus.OK) .as(JsonRelationship.class); - assertHasOnlyMembers(relationship, "relationship", "from"); - assertEquals(r.getUid(), relationship.getRelationship(), "relationship UID"); - assertHasOnlyMembers(relationship.getObject("from"), "event"); - assertEquals(from.getUid(), relationship.getFrom().getEvent().getEvent(), "event UID"); + assertHasOnlyMembers(jsonRelationship, "relationship", "to"); + assertEquals(relationship1.getUid(), jsonRelationship.getRelationship(), "relationship UID"); + assertHasOnlyMembers(jsonRelationship.getObject("to"), "event"); + assertEquals( + relationship1To.getUid(), jsonRelationship.getTo().getEvent().getEvent(), "event UID"); } @Test @@ -252,132 +218,138 @@ void getRelationshipsBadRequestWithMultipleParams() { @Test void getRelationshipsByEvent() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?event={uid}", from.getUid()) + JsonList jsonRelationships = + GET("/tracker/relationships?event={uid}", relationship1To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers( - relationship, "relationship", "relationshipType", "createdAtClient", "from", "to"); - assertHasOnlyUid(from.getUid(), "event", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + JsonRelationship jsonRelationship = + assertContains( + jsonRelationships, + rel -> relationship1.getUid().equals(rel.getRelationship()), + "expected to find relationship " + relationship1.getUid()); + + assertRelationship(relationship1, jsonRelationship); + assertHasOnlyUid(relationship1From, "trackedEntity", jsonRelationship.getFrom()); + assertHasOnlyUid(relationship1To, "event", jsonRelationship.getTo()); } @Test void getRelationshipsByEventWithAllFields() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?event={uid}&fields=*", from.getUid()) + JsonList jsonRelationships = + GET("/tracker/relationships?event={uid}&fields=*", relationship1To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - JsonRelationship relationship = assertFirstRelationship(r, relationships); - assertEventWithinRelationshipItem(from, relationship.getFrom()); - assertTrackedEntityWithinRelationshipItem(to, relationship.getTo()); + JsonRelationship jsonRelationship = + assertContains( + jsonRelationships, + rel -> relationship1.getUid().equals(rel.getRelationship()), + "expected to find relationship " + relationship1.getUid()); + + assertRelationship(relationship1, jsonRelationship); + assertTrackedEntityWithinRelationshipItem(relationship1From, jsonRelationship.getFrom()); + assertEventWithinRelationshipItem(relationship1To, jsonRelationship.getTo()); } @Test void getRelationshipsByEventWithFields() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?event={uid}&fields=relationship,from[event]", from.getUid()) + JsonList jsonRelationships = + GET( + "/tracker/relationships?event={uid}&fields=relationship,to[event]", + relationship1To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - assertEquals(1, relationships.size(), "one relationship expected"); - JsonRelationship relationship = relationships.get(0).as(JsonRelationship.class); - assertHasOnlyMembers(relationship, "relationship", "from"); - assertEquals(r.getUid(), relationship.getRelationship(), "relationship UID"); - assertHasOnlyMembers(relationship.getObject("from"), "event"); - assertEquals(from.getUid(), relationship.getFrom().getEvent().getEvent(), "event UID"); - } - - @Test - void getRelationshipsByEventWithAssignedUser() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - from.setAssignedUser(owner); - relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?event={uid}&fields=from[event[assignedUser]]", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); + JsonRelationship jsonRelationship = + assertContains( + jsonRelationships, + rel -> relationship1.getUid().equals(rel.getRelationship()), + "expected to find relationship " + relationship1.getUid()); - JsonUser user = relationships.get(0).getFrom().getEvent().getAssignedUser(); - assertEquals(owner.getUid(), user.getUid()); - assertEquals(owner.getUsername(), user.getUsername()); - } + assertHasOnlyMembers(jsonRelationship, "relationship", "to"); + assertHasOnlyMembers(jsonRelationship.getTo(), "event"); + assertEquals( + relationship1To.getUid(), jsonRelationship.getTo().getEvent().getEvent(), "event UID"); + } + + // @Test + // void getRelationshipsByEventWithAssignedUser() { + // TrackedEntity to = trackedEntity(); + // Event from = event(enrollment(to)); + // from.setAssignedUser(owner); + // relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?event={uid}&fields=from[event[assignedUser]]", + // from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonUser user = relationships.get(0).getFrom().getEvent().getAssignedUser(); + // assertEquals(owner.getUid(), user.getUid()); + // assertEquals(owner.getUsername(), user.getUsername()); + // } + + // @Test + // void getRelationshipsByEventWithDataValues() { + // TrackedEntity to = trackedEntity(); + // Event from = event(enrollment(to)); + // from.setEventDataValues(Set.of(new EventDataValue(dataElement.getUid(), "12"))); + // Relationship relationship = relationship(from, to); + // RelationshipType type = relationship.getRelationshipType(); + // + // RelationshipConstraint toConstraint = new RelationshipConstraint(); + // + // TrackerDataView trackerDataView = new TrackerDataView(); + // trackerDataView.setDataElements(new LinkedHashSet<>(Set.of(dataElement.getUid()))); + // + // toConstraint.setTrackerDataView(trackerDataView); + // + // type.setFromConstraint(toConstraint); + // + // manager.update(type); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?event={uid}&fields=from[event[dataValues[dataElement,value]]]", + // from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonDataValue dataValue = relationships.get(0).getFrom().getEvent().getDataValues().get(0); + // assertEquals(dataElement.getUid(), dataValue.getDataElement()); + // assertEquals("12", dataValue.getValue()); + // } @Test - void getRelationshipsByEventWithDataValues() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - from.setEventDataValues(Set.of(new EventDataValue(dataElement.getUid(), "12"))); - Relationship relationship = relationship(from, to); - RelationshipType type = relationship.getRelationshipType(); - - RelationshipConstraint toConstraint = new RelationshipConstraint(); - - TrackerDataView trackerDataView = new TrackerDataView(); - trackerDataView.setDataElements(new LinkedHashSet<>(Set.of(dataElement.getUid()))); - - toConstraint.setTrackerDataView(trackerDataView); - - type.setFromConstraint(toConstraint); - - manager.update(type); - switchContextToUser(user); - - JsonList relationships = + void getRelationshipsByEventWithNotes() { + JsonList jsonRelationships = GET( - "/tracker/relationships?event={uid}&fields=from[event[dataValues[dataElement,value]]]", - from.getUid()) + "/tracker/relationships?event={uid}&fields=relationship,to[event[notes]]", + relationship1To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - JsonDataValue dataValue = relationships.get(0).getFrom().getEvent().getDataValues().get(0); - assertEquals(dataElement.getUid(), dataValue.getDataElement()); - assertEquals("12", dataValue.getValue()); - } - - @Test - void getRelationshipsByEventWithNotes() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - from.setNotes(List.of(note("oqXG28h988k", "my notes", owner.getUid()))); - relationship(from, to); - switchContextToUser(user); + JsonRelationship jsonRelationship = + assertContains( + jsonRelationships, + rel -> relationship1.getUid().equals(rel.getRelationship()), + "expected to find relationship " + relationship1.getUid()); - JsonList relationships = - GET("/tracker/relationships?event={uid}&fields=from[event[notes]]", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonNote note = relationships.get(0).getFrom().getEvent().getNotes().get(0); - assertEquals("oqXG28h988k", note.getNote()); - assertEquals("my notes", note.getValue()); - assertEquals(owner.getUid(), note.getStoredBy()); + JsonList notes = jsonRelationship.getTo().getEvent().getNotes(); + notes.forEach( + note -> { + assertHasOnlyMembers(note, "note", "value", "storedAt", "storedBy", "createdBy"); + }); } @Test void getRelationshipsByEventNotFound() { - switchContextToUser(user); + assertNull(manager.get(Event.class, "Hq3Kc6HK4OZ"), "test expects event not to exist"); assertStartsWith( "Event with id Hq3Kc6HK4OZ", @@ -386,114 +358,109 @@ void getRelationshipsByEventNotFound() { @Test void getRelationshipsByEnrollment() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?enrollment=" + from.getUid()) + JsonList jsonRelationships = + GET("/tracker/relationships?enrollment=" + relationship2To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + JsonRelationship jsonRelationship = assertFirstRelationship(relationship2, jsonRelationships); + assertHasOnlyMembers(jsonRelationship, "relationship", "relationshipType", "from", "to"); + assertHasOnlyUid(relationship2From, "trackedEntity", jsonRelationship.getFrom()); + assertHasOnlyUid(relationship2To, "enrollment", jsonRelationship.getTo()); } @Test void getRelationshipsByEnrollmentWithFieldsAll() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?enrollment={uid}&fields=*", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonRelationship relationship = assertFirstRelationship(r, relationships); - assertEnrollmentWithinRelationship(from, relationship.getFrom()); - assertTrackedEntityWithinRelationshipItem(to, relationship.getTo()); - } - - @Test - void getRelationshipsByEnrollmentWithEvents() { - Enrollment from = enrollment(trackedEntity()); - Event to = event(from); - relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET( - "/tracker/relationships?enrollment={uid}&fields=from[enrollment[events[enrollment,event]]]", - from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonRelationshipItem.JsonEvent event = - relationships.get(0).getFrom().getEnrollment().getEvents().get(0); - assertEquals(from.getUid(), event.getEnrollment()); - assertEquals(to.getUid(), event.getEvent()); - } - - @Test - void getRelationshipsByEnrollmentWithAttributes() { - TrackedEntity to = trackedEntity(); - to.setTrackedEntityAttributeValues(Set.of(attributeValue(tea, to, "12"))); - program.setProgramAttributes(List.of(createProgramTrackedEntityAttribute(program, tea))); - - Enrollment from = enrollment(to); - Relationship relationship = relationship(from, to); - - RelationshipType type = relationship.getRelationshipType(); - - RelationshipConstraint constraint = new RelationshipConstraint(); - - TrackerDataView trackerDataView = new TrackerDataView(); - trackerDataView.setAttributes(new LinkedHashSet<>(Set.of(tea.getUid()))); - - constraint.setTrackerDataView(trackerDataView); - - type.setFromConstraint(constraint); - switchContextToUser(user); - - JsonList relationships = - GET( - "/tracker/relationships?enrollment={uid}&fields=from[enrollment[attributes[attribute,value]]]", - from.getUid()) + JsonList jsonRelationships = + GET("/tracker/relationships?enrollment={uid}&fields=*", relationship2To.getUid()) .content(HttpStatus.OK) .getList("relationships", JsonRelationship.class); - JsonAttribute attribute = relationships.get(0).getFrom().getEnrollment().getAttributes().get(0); - assertEquals(tea.getUid(), attribute.getAttribute()); - assertEquals("12", attribute.getValue()); - } - - @Test - void getRelationshipsByEnrollmentWithNotes() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - from.setNotes(List.of(note("oqXG28h988k", "my notes", owner.getUid()))); - relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?enrollment={uid}&fields=from[enrollment[notes]]", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonNote note = relationships.get(0).getFrom().getEnrollment().getNotes().get(0); - assertEquals("oqXG28h988k", note.getNote()); - assertEquals("my notes", note.getValue()); - assertEquals(owner.getUid(), note.getStoredBy()); - } + JsonRelationship jsonRelationship = assertFirstRelationship(relationship2, jsonRelationships); + assertTrackedEntityWithinRelationshipItem(relationship2From, jsonRelationship.getFrom()); + assertEnrollmentWithinRelationship(relationship2To, jsonRelationship.getTo()); + } + + // @Test + // void getRelationshipsByEnrollmentWithEvents() { + // Enrollment from = enrollment(trackedEntity()); + // Event to = event(from); + // relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?enrollment={uid}&fields=from[enrollment[events[enrollment,event]]]", + // from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonRelationshipItem.JsonEvent event = + // relationships.get(0).getFrom().getEnrollment().getEvents().get(0); + // assertEquals(from.getUid(), event.getEnrollment()); + // assertEquals(to.getUid(), event.getEvent()); + // } + // + // @Test + // void getRelationshipsByEnrollmentWithAttributes() { + // TrackedEntity to = trackedEntity(); + // to.setTrackedEntityAttributeValues(Set.of(attributeValue(tea, to, "12"))); + // program.setProgramAttributes(List.of(createProgramTrackedEntityAttribute(program, tea))); + // + // Enrollment from = enrollment(to); + // Relationship relationship = relationship(from, to); + // + // RelationshipType type = relationship.getRelationshipType(); + // + // RelationshipConstraint constraint = new RelationshipConstraint(); + // + // TrackerDataView trackerDataView = new TrackerDataView(); + // trackerDataView.setAttributes(new LinkedHashSet<>(Set.of(tea.getUid()))); + // + // constraint.setTrackerDataView(trackerDataView); + // + // type.setFromConstraint(constraint); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?enrollment={uid}&fields=from[enrollment[attributes[attribute,value]]]", + // from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonAttribute attribute = + // relationships.get(0).getFrom().getEnrollment().getAttributes().get(0); + // assertEquals(tea.getUid(), attribute.getAttribute()); + // assertEquals("12", attribute.getValue()); + // } + // + // @Test + // void getRelationshipsByEnrollmentWithNotes() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // from.setNotes(List.of(note("oqXG28h988k", "my notes", owner.getUid()))); + // relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?enrollment={uid}&fields=from[enrollment[notes]]", + // from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonNote note = relationships.get(0).getFrom().getEnrollment().getNotes().get(0); + // assertEquals("oqXG28h988k", note.getNote()); + // assertEquals("my notes", note.getValue()); + // assertEquals(owner.getUid(), note.getStoredBy()); + // } @Test void getRelationshipsByEnrollmentNotFound() { - switchContextToUser(user); + assertNull(manager.get(Enrollment.class, "Hq3Kc6HK4OZ"), "test expects event not to exist"); + assertStartsWith( "Enrollment with id Hq3Kc6HK4OZ", GET("/tracker/relationships?enrollment=Hq3Kc6HK4OZ") @@ -501,558 +468,371 @@ void getRelationshipsByEnrollmentNotFound() { .getMessage()); } - @Test - void getRelationshipsByTrackedEntity() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?trackedEntity={trackedEntity}", to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); - } - - @Test - void shouldNotGetRelationshipsByTrackedEntityWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - assertNoRelationships( - GET("/tracker/relationships?trackedEntity={te}", to.getUid()).content(HttpStatus.OK)); - } - - @Test - void shouldNotGetRelationshipsByEnrollmentWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - assertNoRelationships( - GET("/tracker/relationships?enrollment={en}", from.getUid()).content(HttpStatus.OK)); - } - - @Test - void shouldNotGetRelationshipsByEventWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - assertNoRelationships( - GET("/tracker/relationships?event={ev}", from.getUid()).content(HttpStatus.OK)); - } - - @Test - void shouldGetRelationshipsByTrackedEntityWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?trackedEntity={te}&includeDeleted=true", to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - assertFirstRelationship(r, relationships); - } - - @Test - void shouldGetRelationshipsByEventWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Event from = event(enrollment(to)); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?event={ev}&includeDeleted=true", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - assertFirstRelationship(r, relationships); - } - - @Test - void shouldGetRelationshipsByEnrollmentWhenRelationshipIsDeleted() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - - r.setDeleted(true); - manager.update(r); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?enrollment={en}&includeDeleted=true", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - assertFirstRelationship(r, relationships); - } - - @Test - void getRelationshipsByDeprecatedTei() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?tei=" + to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); - } - - @Test - void getRelationshipsByTrackedEntityWithEnrollments() { - TrackedEntity to = trackedEntity(); - Enrollment from = enrollment(to); - relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET( - "/tracker/relationships?trackedEntity={trackedEntity}&fields=to[trackedEntity[enrollments[enrollment,trackedEntity]]", - to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonRelationshipItem.JsonEnrollment enrollment = - relationships.get(0).getTo().getTrackedEntity().getEnrollments().get(0); - assertEquals(from.getUid(), enrollment.getEnrollment()); - assertEquals(to.getUid(), enrollment.getTrackedEntity()); - } - - @Test - void getRelationshipsByTrackedEntityAndEnrollmentWithAttributesIsEmpty() { - // Tracked entity attribute values are owned by the tracked entity and only mapped onto the - // enrollment on export. Program tracked entity attributes are only returned by the underlying - // TE service if a program is - // provided which is not possible on the relationship endpoint. - TrackedEntity to = trackedEntity(orgUnit); - to.setTrackedEntityAttributeValues( - Set.of(attributeValue(tea, to, "12"), attributeValue(tea2, to, "24"))); - program.setProgramAttributes(List.of(createProgramTrackedEntityAttribute(program, tea2))); - Enrollment from = enrollment(to); - Relationship relationship = relationship(from, to); - - RelationshipType type = relationship.getRelationshipType(); - - RelationshipConstraint fromConstraint = new RelationshipConstraint(); - - TrackerDataView trackerDataView = new TrackerDataView(); - trackerDataView.setAttributes(new LinkedHashSet<>(Set.of(tea2.getUid()))); - - fromConstraint.setTrackerDataView(trackerDataView); - - RelationshipConstraint toConstraint = new RelationshipConstraint(); - - TrackerDataView dataView = new TrackerDataView(); - dataView.setAttributes(new LinkedHashSet<>(Set.of(tea.getUid(), tea2.getUid()))); - - toConstraint.setTrackerDataView(dataView); - - type.setFromConstraint(fromConstraint); - type.setToConstraint(toConstraint); - switchContextToUser(user); - - JsonList relationships = - GET( - "/tracker/relationships?trackedEntity={trackedEntity}&fields=from[enrollment[attributes[attribute,value]]],to[trackedEntity[attributes[attribute,value]]]", - to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonList enrollmentAttr = - relationships.get(0).getFrom().getEnrollment().getAttributes(); - assertIsEmpty( - enrollmentAttr.toList(JsonAttribute::getAttribute), - "program attributes should not be returned as no program can be provided"); - JsonList teAttributes = - relationships.get(0).getTo().getTrackedEntity().getAttributes(); - assertContainsAll(List.of(tea.getUid()), teAttributes, JsonAttribute::getAttribute); - assertContainsAll(List.of("12"), teAttributes, JsonAttribute::getValue); - } - - @Test - void getRelationshipsByTrackedEntityWithProgramOwners() { - TrackedEntity to = trackedEntity(orgUnit); - Enrollment from = enrollment(to); - to.setProgramOwners(Set.of(new TrackedEntityProgramOwner(to, from.getProgram(), orgUnit))); - relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET( - "/tracker/relationships?trackedEntity={trackedEntity}&fields=to[trackedEntity[programOwners]", - to.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonProgramOwner jsonProgramOwner = - relationships.get(0).getTo().getTrackedEntity().getProgramOwners().get(0); - assertEquals(orgUnit.getUid(), jsonProgramOwner.getOrgUnit()); - assertEquals(to.getUid(), jsonProgramOwner.getTrackedEntity()); - assertEquals(from.getProgram().getUid(), jsonProgramOwner.getProgram()); - } - - @Test - void getRelationshipsByTrackedEntityRelationshipTeToTe() { - TrackedEntity from = trackedEntity(); - TrackedEntity to = trackedEntity(); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - assertHasOnlyUid(from.getUid(), "trackedEntity", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); - } - - @Test - void shouldRetrieveRelationshipWhenUserHasAccessToRelationship() { - TrackedEntity from = trackedEntity(); - TrackedEntity to = trackedEntity(); - Relationship r = relationship(from, to); - switchContextToUser(user); - - JsonList relationships = - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) - .content(HttpStatus.OK) - .getList("relationships", JsonRelationship.class); - - JsonObject relationship = assertFirstRelationship(r, relationships); - assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - assertHasOnlyUid(from.getUid(), "trackedEntity", relationship.getObject("from")); - assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); - } - - @Test - void getRelationshipsByTrackedEntityRelationshipsNoAccessToRelationshipType() { - TrackedEntity from = trackedEntity(); - TrackedEntity to = trackedEntity(); - relationship(relationshipTypeNotAccessible(), from, to); - switchContextToUser(user); - - assertNoRelationships( - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) - .content(HttpStatus.OK)); - } - - @Test - void shouldRetrieveNoRelationshipsWhenUserHasNoAccessToRelationshipItemTo() { - TrackedEntity from = trackedEntity(); - TrackedEntity to = trackedEntityNotInSearchScope(); - relationship(from, to); - switchContextToUser(user); - - assertNoRelationships( - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) - .content(HttpStatus.OK)); - } - - @Test - void shouldReturnForbiddenWhenUserHasNoAccessToRelationshipItemFrom() { - TrackedEntity from = trackedEntityNotInSearchScope(); - TrackedEntity to = trackedEntity(); - relationship(from, to); - switchContextToUser(user); - - assertEquals( - HttpStatus.FORBIDDEN, - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()).status()); - } - - @Test - void - shouldReturnForbiddenWhenGetRelationshipsByTrackedEntityWithNotAccessibleTrackedEntityType() { - TrackedEntityType type = trackedEntityTypeNotAccessible(); - TrackedEntity from = trackedEntity(type); - TrackedEntity to = trackedEntity(type); - relationship(from, to); - switchContextToUser(user); - + // @Test + // void getRelationshipsByTrackedEntity() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?trackedEntity={trackedEntity}", to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonObject relationship = assertFirstRelationship(r, relationships); + // assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); + // assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); + // assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + // } + // + // @Test + // void shouldNotGetRelationshipsByTrackedEntityWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // assertNoRelationships( + // GET("/tracker/relationships?trackedEntity={te}", to.getUid()).content(HttpStatus.OK)); + // } + // + // @Test + // void shouldNotGetRelationshipsByEnrollmentWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // assertNoRelationships( + // GET("/tracker/relationships?enrollment={en}", from.getUid()).content(HttpStatus.OK)); + // } + // + // @Test + // void shouldNotGetRelationshipsByEventWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Event from = event(enrollment(to)); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // assertNoRelationships( + // GET("/tracker/relationships?event={ev}", from.getUid()).content(HttpStatus.OK)); + // } + // + // @Test + // void shouldGetRelationshipsByTrackedEntityWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?trackedEntity={te}&includeDeleted=true", to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // assertFirstRelationship(r, relationships); + // } + // + // @Test + // void shouldGetRelationshipsByEventWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Event from = event(enrollment(to)); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?event={ev}&includeDeleted=true", from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // assertFirstRelationship(r, relationships); + // } + // + // @Test + // void shouldGetRelationshipsByEnrollmentWhenRelationshipIsDeleted() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // + // r.setDeleted(true); + // manager.update(r); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?enrollment={en}&includeDeleted=true", from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // assertFirstRelationship(r, relationships); + // } + // + // @Test + // void getRelationshipsByDeprecatedTei() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // Relationship r = relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?tei=" + to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonObject relationship = assertFirstRelationship(r, relationships); + // assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); + // assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); + // assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + // } + // + // @Test + // void getRelationshipsByTrackedEntityWithEnrollments() { + // TrackedEntity to = trackedEntity(); + // Enrollment from = enrollment(to); + // relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?trackedEntity={trackedEntity}&fields=to[trackedEntity[enrollments[enrollment,trackedEntity]]", + // to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonRelationshipItem.JsonEnrollment enrollment = + // relationships.get(0).getTo().getTrackedEntity().getEnrollments().get(0); + // assertEquals(from.getUid(), enrollment.getEnrollment()); + // assertEquals(to.getUid(), enrollment.getTrackedEntity()); + // } + // + // @Test + // void getRelationshipsByTrackedEntityAndEnrollmentWithAttributesIsEmpty() { + // // Tracked entity attribute values are owned by the tracked entity and only mapped onto the + // // enrollment on export. Program tracked entity attributes are only returned by the + // underlying + // // TE service if a program is + // // provided which is not possible on the relationship endpoint. + // TrackedEntity to = trackedEntity(orgUnit); + // to.setTrackedEntityAttributeValues( + // Set.of(attributeValue(tea, to, "12"), attributeValue(tea2, to, "24"))); + // program.setProgramAttributes(List.of(createProgramTrackedEntityAttribute(program, tea2))); + // Enrollment from = enrollment(to); + // Relationship relationship = relationship(from, to); + // + // RelationshipType type = relationship.getRelationshipType(); + // + // RelationshipConstraint fromConstraint = new RelationshipConstraint(); + // + // TrackerDataView trackerDataView = new TrackerDataView(); + // trackerDataView.setAttributes(new LinkedHashSet<>(Set.of(tea2.getUid()))); + // + // fromConstraint.setTrackerDataView(trackerDataView); + // + // RelationshipConstraint toConstraint = new RelationshipConstraint(); + // + // TrackerDataView dataView = new TrackerDataView(); + // dataView.setAttributes(new LinkedHashSet<>(Set.of(tea.getUid(), tea2.getUid()))); + // + // toConstraint.setTrackerDataView(dataView); + // + // type.setFromConstraint(fromConstraint); + // type.setToConstraint(toConstraint); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?trackedEntity={trackedEntity}&fields=from[enrollment[attributes[attribute,value]]],to[trackedEntity[attributes[attribute,value]]]", + // to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonList enrollmentAttr = + // relationships.get(0).getFrom().getEnrollment().getAttributes(); + // assertIsEmpty( + // enrollmentAttr.toList(JsonAttribute::getAttribute), + // "program attributes should not be returned as no program can be provided"); + // JsonList teAttributes = + // relationships.get(0).getTo().getTrackedEntity().getAttributes(); + // assertContainsAll(List.of(tea.getUid()), teAttributes, JsonAttribute::getAttribute); + // assertContainsAll(List.of("12"), teAttributes, JsonAttribute::getValue); + // } + // + // @Test + // void getRelationshipsByTrackedEntityWithProgramOwners() { + // TrackedEntity to = trackedEntity(orgUnit); + // Enrollment from = enrollment(to); + // to.setProgramOwners(Set.of(new TrackedEntityProgramOwner(to, from.getProgram(), orgUnit))); + // relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET( + // + // "/tracker/relationships?trackedEntity={trackedEntity}&fields=to[trackedEntity[programOwners]", + // to.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonProgramOwner jsonProgramOwner = + // relationships.get(0).getTo().getTrackedEntity().getProgramOwners().get(0); + // assertEquals(orgUnit.getUid(), jsonProgramOwner.getOrgUnit()); + // assertEquals(to.getUid(), jsonProgramOwner.getTrackedEntity()); + // assertEquals(from.getProgram().getUid(), jsonProgramOwner.getProgram()); + // } + // + // @Test + // void getRelationshipsByTrackedEntityRelationshipTeToTe() { + // TrackedEntity from = trackedEntity(); + // TrackedEntity to = trackedEntity(); + // Relationship r = relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonObject relationship = assertFirstRelationship(r, relationships); + // assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); + // assertHasOnlyUid(from.getUid(), "trackedEntity", relationship.getObject("from")); + // assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + // } + // + // @Test + // void shouldRetrieveRelationshipWhenUserHasAccessToRelationship() { + // TrackedEntity from = trackedEntity(); + // TrackedEntity to = trackedEntity(); + // Relationship r = relationship(from, to); + // switchContextToUser(user); + // + // JsonList relationships = + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) + // .content(HttpStatus.OK) + // .getList("relationships", JsonRelationship.class); + // + // JsonObject relationship = assertFirstRelationship(r, relationships); + // assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); + // assertHasOnlyUid(from.getUid(), "trackedEntity", relationship.getObject("from")); + // assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); + // } + // + // @Test + // void getRelationshipsByTrackedEntityRelationshipsNoAccessToRelationshipType() { + // TrackedEntity from = trackedEntity(); + // TrackedEntity to = trackedEntity(); + // relationship(relationshipTypeNotAccessible(), from, to); + // switchContextToUser(user); + // + // assertNoRelationships( + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) + // .content(HttpStatus.OK)); + // } + // + // @Test + // void shouldRetrieveNoRelationshipsWhenUserHasNoAccessToRelationshipItemTo() { + // TrackedEntity from = trackedEntity(); + // TrackedEntity to = trackedEntityNotInSearchScope(); + // relationship(from, to); + // switchContextToUser(user); + // + // assertNoRelationships( + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()) + // .content(HttpStatus.OK)); + // } + // + // @Test + // void shouldReturnForbiddenWhenUserHasNoAccessToRelationshipItemFrom() { + // TrackedEntity from = trackedEntityNotInSearchScope(); + // TrackedEntity to = trackedEntity(); + // relationship(from, to); + // switchContextToUser(user); + // + // assertEquals( + // HttpStatus.FORBIDDEN, + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()).status()); + // } + // + // @Test + // void + // + // shouldReturnForbiddenWhenGetRelationshipsByTrackedEntityWithNotAccessibleTrackedEntityType() { + // TrackedEntityType type = trackedEntityTypeNotAccessible(); + // TrackedEntity from = trackedEntity(type); + // TrackedEntity to = trackedEntity(type); + // relationship(from, to); + // switchContextToUser(user); + // + // assertEquals( + // HttpStatus.FORBIDDEN, + // GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()).status()); + // } + // + // @Test + // void getRelationshipsByTrackedEntityNotFound() { + // assertStartsWith( + // "TrackedEntity with id Hq3Kc6HK4OZ", + // GET("/tracker/relationships?trackedEntity=Hq3Kc6HK4OZ") + // .error(HttpStatus.NOT_FOUND) + // .getMessage()); + // } + + private T get(Class type, String uid) { + T t = manager.get(type, uid); + assertNotNull( + t, + () -> + String.format( + "'%s' with uid '%s' should have been created", type.getSimpleName(), uid)); + return t; + } + + public static void assertNoErrors(ImportReport report) { + assertNotNull(report); assertEquals( - HttpStatus.FORBIDDEN, - GET("/tracker/relationships?trackedEntity={trackedEntity}", from.getUid()).status()); - } - - @Test - void getRelationshipsByTrackedEntityNotFound() { - assertStartsWith( - "TrackedEntity with id Hq3Kc6HK4OZ", - GET("/tracker/relationships?trackedEntity=Hq3Kc6HK4OZ") - .error(HttpStatus.NOT_FOUND) - .getMessage()); - } - - private TrackedEntityType trackedEntityTypeAccessible() { - TrackedEntityType type = trackedEntityType('A'); - type.getSharing().addUserAccess(userAccess()); - manager.save(type, false); - return type; - } - - private TrackedEntityType trackedEntityTypeNotAccessible() { - TrackedEntityType type = trackedEntityType('B'); - manager.save(type, false); - return type; - } - - private TrackedEntityType trackedEntityType(char uniqueChar) { - TrackedEntityType type = createTrackedEntityType(uniqueChar); - type.getSharing().setOwner(owner); - type.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - return type; - } - - private TrackedEntity trackedEntity() { - TrackedEntity te = trackedEntity(orgUnit); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntityNotInSearchScope() { - TrackedEntity te = trackedEntity(anotherOrgUnit); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntity(TrackedEntityType trackedEntityType) { - TrackedEntity te = trackedEntity(orgUnit, trackedEntityType); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntity(OrganisationUnit orgUnit) { - TrackedEntity te = trackedEntity(orgUnit, trackedEntityType); - manager.save(te, false); - return te; - } - - private TrackedEntity trackedEntity( - OrganisationUnit orgUnit, TrackedEntityType trackedEntityType) { - TrackedEntity te = createTrackedEntity(orgUnit); - te.setTrackedEntityType(trackedEntityType); - te.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - te.getSharing().setOwner(owner); - return te; - } - - private Enrollment enrollment(TrackedEntity te) { - Enrollment enrollment = new Enrollment(program, te, orgUnit); - enrollment.setAutoFields(); - enrollment.setEnrollmentDate(new Date()); - enrollment.setOccurredDate(new Date()); - enrollment.setStatus(EnrollmentStatus.COMPLETED); - manager.save(enrollment, false); - te.setEnrollments(Set.of(enrollment)); - manager.save(te, false); - return enrollment; - } - - private Event event(Enrollment enrollment) { - Event event = new Event(enrollment, programStage, orgUnit, coc); - event.setAutoFields(); - manager.save(event, false); - enrollment.setEvents(Set.of(event)); - manager.save(enrollment, false); - return event; - } - - private UserAccess userAccess() { - UserAccess a = new UserAccess(); - a.setUser(user); - a.setAccess(AccessStringHelper.FULL); - return a; - } - - private RelationshipType relationshipTypeAccessible( - RelationshipEntity from, RelationshipEntity to) { - RelationshipType type = relationshipType(from, to); - type.getSharing().addUserAccess(userAccess()); - manager.save(type, false); - return type; - } - - private RelationshipType relationshipTypeNotAccessible() { - return relationshipType( - RelationshipEntity.TRACKED_ENTITY_INSTANCE, RelationshipEntity.TRACKED_ENTITY_INSTANCE); - } - - private RelationshipType relationshipType(RelationshipEntity from, RelationshipEntity to) { - RelationshipType type = createRelationshipType('A'); - type.getFromConstraint().setRelationshipEntity(from); - type.getToConstraint().setRelationshipEntity(to); - type.getSharing().setOwner(owner); - type.getSharing().setPublicAccess(AccessStringHelper.DEFAULT); - manager.save(type, false); - return type; - } - - private Relationship relationship(TrackedEntity from, TrackedEntity to) { - - RelationshipType type = - relationshipTypeAccessible( - RelationshipEntity.TRACKED_ENTITY_INSTANCE, RelationshipEntity.TRACKED_ENTITY_INSTANCE); - return relationship(type, from, to); - } - - private Relationship relationship(RelationshipType type, TrackedEntity from, TrackedEntity to) { - Relationship r = new Relationship(); - - RelationshipItem fromItem = new RelationshipItem(); - fromItem.setTrackedEntity(from); - from.getRelationshipItems().add(fromItem); - r.setFrom(fromItem); - fromItem.setRelationship(r); - - RelationshipItem toItem = new RelationshipItem(); - toItem.setTrackedEntity(to); - to.getRelationshipItems().add(toItem); - r.setTo(toItem); - toItem.setRelationship(r); - - r.setRelationshipType(type); - r.setKey(type.getUid()); - r.setInvertedKey(type.getUid()); - r.setAutoFields(); - r.getSharing().setOwner(owner); - manager.save(r, false); - return r; - } - - private Relationship relationship(Event from, TrackedEntity to) { - Relationship r = new Relationship(); - - RelationshipItem fromItem = new RelationshipItem(); - fromItem.setEvent(from); - from.getRelationshipItems().add(fromItem); - r.setFrom(fromItem); - fromItem.setRelationship(r); - - RelationshipItem toItem = new RelationshipItem(); - toItem.setTrackedEntity(to); - to.getRelationshipItems().add(toItem); - r.setTo(toItem); - toItem.setRelationship(r); - - RelationshipType type = - relationshipTypeAccessible( - RelationshipEntity.PROGRAM_STAGE_INSTANCE, RelationshipEntity.TRACKED_ENTITY_INSTANCE); - r.setRelationshipType(type); - r.setKey(type.getUid()); - r.setInvertedKey(type.getUid()); - - r.setAutoFields(); - r.getSharing().setOwner(owner); - r.setCreatedAtClient(new Date()); - manager.save(r, false); - return r; - } - - private void relationship(Enrollment from, Event to) { - Relationship r = new Relationship(); - - RelationshipItem fromItem = new RelationshipItem(); - fromItem.setEnrollment(from); - from.getRelationshipItems().add(fromItem); - r.setFrom(fromItem); - fromItem.setRelationship(r); - - RelationshipItem toItem = new RelationshipItem(); - toItem.setEvent(to); - to.getRelationshipItems().add(toItem); - r.setTo(toItem); - toItem.setRelationship(r); - - RelationshipType type = - relationshipTypeAccessible( - RelationshipEntity.PROGRAM_INSTANCE, RelationshipEntity.PROGRAM_STAGE_INSTANCE); - r.setRelationshipType(type); - r.setKey(type.getUid()); - r.setInvertedKey(type.getUid()); - - r.setAutoFields(); - r.getSharing().setOwner(owner); - manager.save(r, false); - } - - private Relationship relationship(Enrollment from, TrackedEntity to) { - manager.save(from, false); - manager.save(to, false); - - Relationship r = new Relationship(); - - RelationshipItem fromItem = new RelationshipItem(); - fromItem.setEnrollment(from); - from.getRelationshipItems().add(fromItem); - r.setFrom(fromItem); - fromItem.setRelationship(r); - - RelationshipItem toItem = new RelationshipItem(); - toItem.setTrackedEntity(to); - to.getRelationshipItems().add(toItem); - r.setTo(toItem); - toItem.setRelationship(r); - - RelationshipType type = - relationshipTypeAccessible( - RelationshipEntity.PROGRAM_INSTANCE, RelationshipEntity.TRACKED_ENTITY_INSTANCE); - r.setRelationshipType(type); - r.setKey(type.getUid()); - r.setInvertedKey(type.getUid()); - - r.setAutoFields(); - r.getSharing().setOwner(owner); - manager.save(r, false); - return r; - } - - private TrackedEntityAttributeValue attributeValue( - TrackedEntityAttribute tea, TrackedEntity te, String value) { - return new TrackedEntityAttributeValue(tea, te, value); - } - - private Note note(String uid, String value, String storedBy) { - Note note = new Note(value, storedBy); - note.setUid(uid); - manager.save(note, false); - return note; + Status.OK, + report.getStatus(), + errorMessage( + "Expected import with status OK, instead got:%n", report.getValidationReport())); + } + + private static Supplier errorMessage(String errorTitle, ValidationReport report) { + return () -> { + StringBuilder msg = new StringBuilder(errorTitle); + report + .getErrors() + .forEach( + e -> { + msg.append(e.getErrorCode()); + msg.append(": "); + msg.append(e.getMessage()); + msg.append('\n'); + }); + return msg.toString(); + }; + } + + public static void assertNoErrors(ObjectBundleValidationReport report) { + assertNotNull(report); + List errors = new ArrayList<>(); + report.forEachErrorReport(err -> errors.add(err.toString())); + assertFalse( + report.hasErrorReports(), String.format("Expected no errors, instead got: %s%n", errors)); } } From e37ceae0565474f2b9b430301a41b4d41fb70ab2 Mon Sep 17 00:00:00 2001 From: teleivo Date: Thu, 23 Jan 2025 14:08:42 +0100 Subject: [PATCH 3/3] test: migrate/fix another test --- .../HibernateRelationshipStore.java | 2 +- .../TrackedEntityRowCallbackHandler.java | 1 + .../aggregates/query/TrackedEntityQuery.java | 1 + .../RelationshipsExportControllerTest.java | 51 ++++++++++--------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java index 90c1715f9e8c..c74c2628346f 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java @@ -195,7 +195,7 @@ private long countRelationships( whereConditionPredicates( entity, builder, criteriaQuery, root, queryParams.isIncludeDeleted())); - return entityManager.createQuery(criteriaQuery).getSingleResult().longValue(); + return entityManager.createQuery(criteriaQuery).getSingleResult(); } private CriteriaQuery criteriaQuery( diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/mapper/TrackedEntityRowCallbackHandler.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/mapper/TrackedEntityRowCallbackHandler.java index 912fafaea61b..84631eb27cc0 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/mapper/TrackedEntityRowCallbackHandler.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/mapper/TrackedEntityRowCallbackHandler.java @@ -52,6 +52,7 @@ public TrackedEntityRowCallbackHandler() { private TrackedEntity getTrackedEntity(ResultSet rs) throws SQLException { TrackedEntity te = new TrackedEntity(); + te.setId(rs.getLong(TrackedEntityQuery.getColumnName(COLUMNS.TRACKEDENTITYID))); te.setUid(rs.getString(TrackedEntityQuery.getColumnName(COLUMNS.UID))); TrackedEntityType trackedEntityType = new TrackedEntityType(); trackedEntityType.setUid(rs.getString(TrackedEntityQuery.getColumnName(COLUMNS.TYPE_UID))); diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/query/TrackedEntityQuery.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/query/TrackedEntityQuery.java index 90ba79835983..9dd3486ffd1e 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/query/TrackedEntityQuery.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/aggregates/query/TrackedEntityQuery.java @@ -35,6 +35,7 @@ */ public class TrackedEntityQuery { public enum COLUMNS { + ID, UID, CREATED, CREATEDCLIENT, diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java index 7e94d62f093b..d18df071a797 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/tracker/export/relationship/RelationshipsExportControllerTest.java @@ -146,6 +146,11 @@ void setUp() throws IOException { assertNotNull(relationship2From, "test expects 'from' to be a tracked entity"); relationship2To = relationship2.getTo().getEnrollment(); assertNotNull(relationship2To, "test expects 'to' to be an enrollment"); + // for some reason we get a LazyInit exception in an assertion when running all tests if we + // don't eagerly fetch like we do here + relationship2From.getUid(); + relationship2To.getUid(); + relationship2.getRelationshipType().getUid(); } @BeforeEach @@ -273,14 +278,9 @@ void getRelationshipsByEventWithFields() { relationship1To.getUid(), jsonRelationship.getTo().getEvent().getEvent(), "event UID"); } + // TODO(DHIS2-18883) migrate these tests // @Test // void getRelationshipsByEventWithAssignedUser() { - // TrackedEntity to = trackedEntity(); - // Event from = event(enrollment(to)); - // from.setAssignedUser(owner); - // relationship(from, to); - // switchContextToUser(user); - // // JsonList relationships = // GET("/tracker/relationships?event={uid}&fields=from[event[assignedUser]]", // from.getUid()) @@ -291,7 +291,6 @@ void getRelationshipsByEventWithFields() { // assertEquals(owner.getUid(), user.getUid()); // assertEquals(owner.getUsername(), user.getUsername()); // } - // @Test // void getRelationshipsByEventWithDataValues() { // TrackedEntity to = trackedEntity(); @@ -381,6 +380,7 @@ void getRelationshipsByEnrollmentWithFieldsAll() { assertEnrollmentWithinRelationship(relationship2To, jsonRelationship.getTo()); } + // TODO(DHIS2-18883) migrate these tests // @Test // void getRelationshipsByEnrollmentWithEvents() { // Enrollment from = enrollment(trackedEntity()); @@ -468,23 +468,26 @@ void getRelationshipsByEnrollmentNotFound() { .getMessage()); } - // @Test - // void getRelationshipsByTrackedEntity() { - // TrackedEntity to = trackedEntity(); - // Enrollment from = enrollment(to); - // Relationship r = relationship(from, to); - // switchContextToUser(user); - // - // JsonList relationships = - // GET("/tracker/relationships?trackedEntity={trackedEntity}", to.getUid()) - // .content(HttpStatus.OK) - // .getList("relationships", JsonRelationship.class); - // - // JsonObject relationship = assertFirstRelationship(r, relationships); - // assertHasOnlyMembers(relationship, "relationship", "relationshipType", "from", "to"); - // assertHasOnlyUid(from.getUid(), "enrollment", relationship.getObject("from")); - // assertHasOnlyUid(to.getUid(), "trackedEntity", relationship.getObject("to")); - // } + @Test + void getRelationshipsByTrackedEntity() { + JsonList jsonRelationships = + GET("/tracker/relationships?trackedEntity={trackedEntity}", relationship1From.getUid()) + .content(HttpStatus.OK) + .getList("relationships", JsonRelationship.class); + + JsonRelationship jsonRelationship = + assertContains( + jsonRelationships, + rel -> relationship1.getUid().equals(rel.getRelationship()), + "expected to find relationship " + relationship1.getUid()); + + assertRelationship(relationship1, jsonRelationship); + assertHasOnlyMembers( + jsonRelationship, "relationship", "relationshipType", "createdAtClient", "from", "to"); + assertHasOnlyUid(relationship1From, "trackedEntity", jsonRelationship.getFrom()); + assertHasOnlyUid(relationship1To, "event", jsonRelationship.getTo()); + } + // // @Test // void shouldNotGetRelationshipsByTrackedEntityWhenRelationshipIsDeleted() {