Skip to content

Commit

Permalink
chore: get one trackedEntity via path and query param is identical
Browse files Browse the repository at this point in the history
  • Loading branch information
teleivo committed Jan 8, 2025
1 parent c5a6a4c commit 07cca51
Show file tree
Hide file tree
Showing 10 changed files with 549 additions and 555 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
import org.hisp.dhis.trackedentity.TrackedEntityAttributeService;
import org.hisp.dhis.trackedentity.TrackedEntityAudit;
import org.hisp.dhis.trackedentity.TrackedEntityProgramOwner;
import org.hisp.dhis.trackedentity.TrackedEntityType;
import org.hisp.dhis.trackedentity.TrackedEntityTypeService;
import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue;
Expand Down Expand Up @@ -217,83 +216,35 @@ public TrackedEntity getTrackedEntity(@Nonnull UID uid)
UserDetails currentUser = getCurrentUserDetails();
TrackedEntity trackedEntity =
mapTrackedEntity(
getTrackedEntity(uid, currentUser),
TrackedEntityParams.FALSE,
currentUser,
null,
false);
getTrackedEntity(uid, currentUser), TrackedEntityParams.FALSE, currentUser, false);
mapTrackedEntityTypeAttributes(trackedEntity);
return trackedEntity;
}

@Override
public TrackedEntity getTrackedEntity(
@Nonnull UID trackedEntityUid,
@CheckForNull UID programIdentifier,
@Nonnull TrackedEntityParams params)
@Nonnull UID trackedEntity, @CheckForNull UID program, @Nonnull TrackedEntityParams params)
throws NotFoundException, ForbiddenException {
Program program = null;
Page<TrackedEntity> trackedEntities;

if (programIdentifier != null) {
program = programService.getProgram(programIdentifier.getValue());
if (program == null) {
throw new NotFoundException(Program.class, programIdentifier);
}
}

TrackedEntity trackedEntity;
if (program != null) {
trackedEntity = getTrackedEntity(trackedEntityUid.getValue(), program, params);

if (params.isIncludeProgramOwners()) {
Set<TrackedEntityProgramOwner> filteredProgramOwners =
trackedEntity.getProgramOwners().stream()
.filter(te -> te.getProgram().getUid().equals(programIdentifier.getValue()))
.collect(Collectors.toSet());
trackedEntity.setProgramOwners(filteredProgramOwners);
}
} else {
UserDetails userDetails = getCurrentUserDetails();

trackedEntity =
mapTrackedEntity(
getTrackedEntity(trackedEntityUid, userDetails), params, userDetails, null, false);

mapTrackedEntityTypeAttributes(trackedEntity);
}
return trackedEntity;
}

/**
* 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(String uid, Program program, TrackedEntityParams params)
throws NotFoundException, ForbiddenException {
TrackedEntity trackedEntity = trackedEntityStore.getByUid(uid);
trackedEntityAuditService.addTrackedEntityAudit(trackedEntity, getCurrentUsername(), READ);
if (trackedEntity == null) {
throw new NotFoundException(TrackedEntity.class, uid);
}

UserDetails userDetails = getCurrentUserDetails();
List<String> errors =
trackerAccessManager.canReadProgramAndTrackedEntityType(
userDetails, trackedEntity, program);
if (!errors.isEmpty()) {
throw new ForbiddenException(errors.toString());
try {
TrackedEntityOperationParams operationParams =
TrackedEntityOperationParams.builder()
.trackedEntities(Set.of(trackedEntity))
.program(program)
.trackedEntityParams(params)
.build();
trackedEntities = getTrackedEntities(operationParams, new PageParams(1, 1, false));
} catch (BadRequestException e) {
throw new IllegalArgumentException(
"this must be a bug in how the TrackedEntityOperationParams are built");
}

String error =
trackerAccessManager.canAccessProgramOwner(userDetails, trackedEntity, program, false);
if (error != null) {
throw new ForbiddenException(error);
if (trackedEntities.getItems().isEmpty()) {
throw new NotFoundException(TrackedEntity.class, trackedEntity.getValue());
}

return mapTrackedEntity(trackedEntity, params, userDetails, program, false);
return trackedEntities.getItems().get(0);
}

/**
Expand Down Expand Up @@ -338,7 +289,6 @@ private TrackedEntity mapTrackedEntity(
TrackedEntity trackedEntity,
TrackedEntityParams params,
UserDetails user,
Program program,
boolean includeDeleted) {
TrackedEntity result = new TrackedEntity();
result.setId(trackedEntity.getId());
Expand All @@ -361,13 +311,13 @@ private TrackedEntity mapTrackedEntity(
result.setRelationshipItems(getRelationshipItems(trackedEntity, user, includeDeleted));
}
if (params.isIncludeEnrollments()) {
result.setEnrollments(getEnrollments(trackedEntity, user, includeDeleted, program));
result.setEnrollments(getEnrollments(trackedEntity, user, includeDeleted));
}
if (params.isIncludeProgramOwners()) {
result.setProgramOwners(trackedEntity.getProgramOwners());
}

result.setTrackedEntityAttributeValues(getTrackedEntityAttributeValues(trackedEntity, program));
result.setTrackedEntityAttributeValues(getTrackedEntityAttributeValues(trackedEntity));

return result;
}
Expand All @@ -388,9 +338,8 @@ private Set<RelationshipItem> getRelationshipItems(
}

private Set<Enrollment> getEnrollments(
TrackedEntity trackedEntity, UserDetails user, boolean includeDeleted, Program program) {
TrackedEntity trackedEntity, UserDetails user, boolean includeDeleted) {
return trackedEntity.getEnrollments().stream()
.filter(e -> program == null || program.getUid().equals(e.getProgram().getUid()))
.filter(e -> includeDeleted || !e.isDeleted())
.filter(e -> trackerAccessManager.canRead(user, e, false).isEmpty())
.map(
Expand All @@ -409,19 +358,12 @@ private Set<Enrollment> getEnrollments(
}

private Set<TrackedEntityAttributeValue> getTrackedEntityAttributeValues(
TrackedEntity trackedEntity, Program program) {
TrackedEntity trackedEntity) {
Set<String> readableAttributes =
trackedEntity.getTrackedEntityType().getTrackedEntityAttributes().stream()
.map(IdentifiableObject::getUid)
.collect(Collectors.toSet());

if (program != null) {
readableAttributes.addAll(
program.getTrackedEntityAttributes().stream()
.map(IdentifiableObject::getUid)
.collect(Collectors.toSet()));
}

return trackedEntity.getTrackedEntityAttributeValues().stream()
.filter(av -> readableAttributes.contains(av.getAttribute().getUid()))
.collect(Collectors.toSet());
Expand Down Expand Up @@ -484,10 +426,11 @@ private RelationshipItem getTrackedEntityInRelationshipItem(
}

relationshipItem.setTrackedEntity(
mapTrackedEntity(trackedEntity, params, currentUser, null, includeDeleted));
mapTrackedEntity(trackedEntity, params, currentUser, includeDeleted));
return relationshipItem;
}

@Nonnull
@Override
public List<TrackedEntity> getTrackedEntities(
@Nonnull TrackedEntityOperationParams operationParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public class TrackedEntityOperationParams {
/** Tracked entity type to fetch. */
private UID trackedEntityType;

private OrganisationUnitSelectionMode orgUnitMode;
@Builder.Default
private OrganisationUnitSelectionMode orgUnitMode = OrganisationUnitSelectionMode.ACCESSIBLE;

@Getter @Builder.Default
private AssignedUserQueryParam assignedUserQueryParam = AssignedUserQueryParam.ALL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Multimap<String, Event> findByEnrollmentIds(List<Long> ids, Context ctx) {
Multimap<String, RelationshipItem> relationships = relationshipAsync.join();

for (Event event : events.values()) {
if (ctx.getParams().isIncludeRelationships()) {
if (ctx.getParams().getEventParams().isIncludeRelationships()) {
event.setRelationshipItems(new HashSet<>(relationships.get(event.getUid())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,59 @@ public static void assertNotEmpty(Collection<?> actual, String message) {
assertFalse(actual.isEmpty(), message);
}

/**
* Asserts that the given collection is not null and not empty.
*
* @param actual the collection.
* @param messageSupplier fails with this supplied message
*/
public static void assertNotEmpty(Collection<?> actual, Supplier<String> messageSupplier) {
assertNotNull(actual, messageSupplier);
assertFalse(actual.isEmpty(), messageSupplier);
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
*/
public static void assertHasSize(int expected, Collection<?> actual) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(
assertHasSize(
expected,
actual.size(),
actual,
() ->
String.format(
"expected collection to contain %d elements, it has %d instead: '%s'",
expected, actual.size(), actual));
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
* @param messageSupplier fails with this supplied message
*/
public static void assertHasSize(
int expected, Collection<?> actual, Supplier<String> messageSupplier) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(expected, actual.size(), messageSupplier);
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
* @param message fails with this message
*/
public static void assertHasSize(int expected, Collection<?> actual, String message) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(expected, actual.size(), message);
}

/**
* Asserts that the given string starts with the expected prefix.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@
"attribute": {
"id": "j45AR9cBQKc"
},
"value": "programStage qLZC0lvvxQH"
"value": "multi-program-stage-attribute"
}
],
"autoGenerateEvent": true,
Expand Down Expand Up @@ -1126,15 +1126,7 @@
}
],
"validationStrategy": "ON_UPDATE_AND_INSERT",
"featureType": "POINT",
"attributeValues": [
{
"attribute": {
"id": "j45AR9cBQKc"
},
"value": "multi-program-stage-attribute"
}
]
"featureType": "POINT"
},
{
"id": "SKNvpoLioON",
Expand Down Expand Up @@ -1851,6 +1843,29 @@
},
"relationshipEntity": "PROGRAM_STAGE_INSTANCE"
}
},
{
"id": "m1575931405",
"displayFromToName": "Parent Of",
"displayName": "Parent to Child",
"fromConstraint": {
"relationshipEntity": "TRACKED_ENTITY_INSTANCE",
"trackedEntityType": {
"id": "ja8NY4PW7Xm"
}
},
"fromToName": "Child Of",
"name": "Tracked entity to tracked entity",
"sharing": {
"owner": null,
"public": "r-------"
},
"toConstraint": {
"relationshipEntity": "TRACKED_ENTITY_INSTANCE",
"trackedEntityType": {
"id": "ja8NY4PW7Xm"
}
}
}
],
"trackedEntityAttributes": [
Expand Down Expand Up @@ -2230,6 +2245,41 @@
],
"username": "trackeradmin"
},
{
"id": "Z7870757a75",
"access": {
"delete": true,
"externalize": true,
"manage": true,
"read": true,
"update": true,
"write": true
},
"dataViewOrganisationUnits": [
{
"id": "h4w96yEMlzO"
}
],
"displayName": "basicuser",
"email": "[email protected]",
"firstName": "basic",
"name": "user",
"organisationUnits": [
{
"id": "h4w96yEMlzO"
}
],
"password": "Test123###...",
"passwordLastUpdated": "2020-05-31T08:57:59.060",
"phoneNumber": "+4740332255",
"surname": "basic",
"userRoles": [
{
"id": "UbhT3bXWUyb"
}
],
"username": "basicuser"
},
{
"id": "o1HMTIzBGo7",
"access": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@
import org.hisp.dhis.webapi.controller.tracker.JsonRelationshipItem;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class EventsExportControllerTest extends PostgresControllerIntegrationTestBase {
private static final String DATA_ELEMENT_VALUE = "value";

Expand Down
Loading

0 comments on commit 07cca51

Please sign in to comment.