From fe30bd54d7f2feeddbf97aee2f53313338057c3e Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Sun, 10 May 2026 22:14:15 -0500 Subject: [PATCH 1/6] fix: mapView should not be exported at root level --- .../dhis/schema/DefaultSchemaService.java | 2 - .../MetadataExportWithDependenciesTest.java | 43 +++++++++++++++++++ .../controller/ProgramControllerTest.java | 15 +++++-- .../controller/mapping/MapViewController.java | 8 ++-- 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/dhis-2/dhis-services/dhis-service-schema/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java b/dhis-2/dhis-services/dhis-service-schema/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java index 2d6055267373..aced7e59ed57 100644 --- a/dhis-2/dhis-services/dhis-service-schema/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java +++ b/dhis-2/dhis-services/dhis-service-schema/src/main/java/org/hisp/dhis/schema/DefaultSchemaService.java @@ -118,7 +118,6 @@ import org.hisp.dhis.schema.descriptors.LegendSchemaDescriptor; import org.hisp.dhis.schema.descriptors.LegendSetSchemaDescriptor; import org.hisp.dhis.schema.descriptors.MapSchemaDescriptor; -import org.hisp.dhis.schema.descriptors.MapViewSchemaDescriptor; import org.hisp.dhis.schema.descriptors.MessageConversationSchemaDescriptor; import org.hisp.dhis.schema.descriptors.MetadataVersionSchemaDescriptor; import org.hisp.dhis.schema.descriptors.MinMaxDataElementSchemaDescriptor; @@ -251,7 +250,6 @@ private void init() { register(new LegendSetSchemaDescriptor()); register(new ExternalMapLayerSchemaDescriptor()); register(new MapSchemaDescriptor()); - register(new MapViewSchemaDescriptor()); register(new MessageConversationSchemaDescriptor()); register(new MetadataVersionSchemaDescriptor()); register(new OAuth2ClientSchemaDescriptor()); diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java index 9a4258b8b393..1be0f8366789 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java @@ -28,22 +28,33 @@ package org.hisp.dhis.metadata.export; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.hisp.dhis.common.IdentifiableObject; +import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.common.ValueType; import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dxf2.metadata.MetadataExportParams; import org.hisp.dhis.dxf2.metadata.MetadataExportService; +import org.hisp.dhis.dxf2.metadata.MetadataImportService; +import org.hisp.dhis.mapping.MapView; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramSection; import org.hisp.dhis.program.ProgramStage; import org.hisp.dhis.program.ProgramStageDataElement; import org.hisp.dhis.program.ProgramTrackedEntityAttribute; import org.hisp.dhis.test.integration.SingleSetupIntegrationTestBase; +import org.hisp.dhis.render.RenderService; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -54,6 +65,14 @@ class MetadataExportWithDependenciesTest extends SingleSetupIntegrationTestBase @PersistenceContext private EntityManager entityManager; @Autowired private MetadataExportService metadataExportService; + @Autowired private MetadataImportService metadataImportService; + + @Autowired private IdentifiableObjectManager manager; + + @Autowired private RenderService renderService; + + @Autowired private ObjectMapper jsonMapper; + @Test void testExportProgramWithProgramSection() { Program program = createProgram('A'); @@ -117,4 +136,28 @@ private Program setUpProgramAndDependencies() { entityManager.merge(programStage); return program; } + + @Test + @DisplayName("MapView should not be exported at root level when exporting Map with dependencies") + void exportMetadataShouldNotContainMapView() throws IOException { + MapView mapView = createMapView("A"); + org.hisp.dhis.mapping.Map map = new org.hisp.dhis.mapping.Map(); + map.setName("MapA"); + map.setMapViews(List.of(mapView)); + map.setAutoFields(); + manager.save(map); + + MetadataExportParams exportParams = new MetadataExportParams(); + exportParams.addClass(org.hisp.dhis.mapping.Map.class); + exportParams.addClass(MapView.class); + ObjectNode exported = metadataExportService.getMetadataAsObjectNode(exportParams); + + Map, List> metadata = + renderService.fromMetadata( + new ByteArrayInputStream(jsonMapper.writeValueAsBytes(exported)), RenderFormat.JSON); + assertNull(metadata.get(org.hisp.dhis.mapping.MapView.class)); + org.hisp.dhis.mapping.Map exportMap = + (org.hisp.dhis.mapping.Map) metadata.get(org.hisp.dhis.mapping.Map.class).get(0); + assertNotNull(exportMap.getMapViews()); + } } diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java index 011a141c8ebd..c584816e0851 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java @@ -366,13 +366,17 @@ void testCopyProgramWithNoPublicSharing() { @Test void testDeleteWithMapView() { - String mapViewJson = + + String mapJson = """ + { + "name": "test map", + "id": "mAPVRd23Jm9", + "mapViews": [ { "name": "test mapview", "id": "mVIVRd23Jm9", "organisationUnitLevels": [], - "maps": [], "layer": "event", "program": { "id": "PrZMWi7rBga" @@ -381,8 +385,11 @@ void testDeleteWithMapView() { "id": "PSzMWi7rBga" } } - """; - POST("/mapViews", mapViewJson).content(HttpStatus.CREATED); + ] + } + """; + POST("/maps", mapJson).content(HttpStatus.CREATED); + assertStatus(HttpStatus.OK, DELETE("/programs/%s".formatted(PROGRAM_UID))); assertStatus(HttpStatus.NOT_FOUND, GET("/programs/%s".formatted(PROGRAM_UID))); JsonMixed mapview = GET("/mapViews/mVIVRd23Jm9").content().as(JsonMixed.class); diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java index e6990b453f31..2d20dbc231a3 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java @@ -46,8 +46,7 @@ import org.hisp.dhis.query.Order; import org.hisp.dhis.query.Query; import org.hisp.dhis.query.QueryParserException; -import org.hisp.dhis.schema.descriptors.MapViewSchemaDescriptor; -import org.hisp.dhis.webapi.controller.AbstractCrudController; +import org.hisp.dhis.webapi.controller.AbstractFullReadOnlyController; import org.hisp.dhis.webapi.utils.ContextUtils; import org.hisp.dhis.webapi.webdomain.WebMetadata; import org.hisp.dhis.webapi.webdomain.WebOptions; @@ -64,8 +63,9 @@ */ @OpenApi.Tags("metadata") @Controller -@RequestMapping(value = MapViewSchemaDescriptor.API_ENDPOINT) -public class MapViewController extends AbstractCrudController { +@RequestMapping("/api/mapViews") +public class MapViewController + extends AbstractFullReadOnlyController { @Autowired private MappingService mappingService; @Autowired private OrganisationUnitService organisationUnitService; From 94ba5e10b2751e10d7bd1a9cd03611a94a3988de Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Tue, 19 May 2026 04:54:23 -0500 Subject: [PATCH 2/6] fix conflict --- .../metadata/export/MetadataExportWithDependenciesTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java index 1be0f8366789..95e987366e1f 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java @@ -53,8 +53,9 @@ import org.hisp.dhis.program.ProgramStage; import org.hisp.dhis.program.ProgramStageDataElement; import org.hisp.dhis.program.ProgramTrackedEntityAttribute; -import org.hisp.dhis.test.integration.SingleSetupIntegrationTestBase; +import org.hisp.dhis.render.RenderFormat; import org.hisp.dhis.render.RenderService; +import org.hisp.dhis.test.integration.SingleSetupIntegrationTestBase; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 01cc64c8e685748aa37e7546a108bef9a59db9df Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Tue, 19 May 2026 04:56:36 -0500 Subject: [PATCH 3/6] format --- .../hisp/dhis/webapi/controller/mapping/MapViewController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java index 2d20dbc231a3..547d3a358a24 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java @@ -64,8 +64,7 @@ @OpenApi.Tags("metadata") @Controller @RequestMapping("/api/mapViews") -public class MapViewController - extends AbstractFullReadOnlyController { +public class MapViewController extends AbstractFullReadOnlyController { @Autowired private MappingService mappingService; @Autowired private OrganisationUnitService organisationUnitService; From 4438a3f3d8f6f9d8c0a8b8a78342acb6148b8eac Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Tue, 2 Jun 2026 14:07:52 -0500 Subject: [PATCH 4/6] fix user uid --- .../src/main/java/org/hisp/dhis/DhisConvenienceTest.java | 2 +- .../export/MetadataExportWithDependenciesTest.java | 9 +++++++++ .../dhis/webapi/controller/ProgramControllerTest.java | 5 +---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java index c5cf1c4ec0a9..ff5a041f52e1 100644 --- a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java +++ b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java @@ -2995,7 +2995,7 @@ public static User createRandomAdminUserWithEntityManager(EntityManager entityMa entityManager.persist(role); User user = new User(); - user.setUid("A_" + CodeGenerator.generateUid().substring(2)); + user.setUid(CodeGenerator.generateUid()); user.setFirstName("Admin"); user.setSurname("User"); user.setUsername(DEFAULT_USERNAME + "_test_" + CodeGenerator.generateUid()); diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java index 95e987366e1f..101ea674255e 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java @@ -57,6 +57,8 @@ import org.hisp.dhis.render.RenderService; import org.hisp.dhis.test.integration.SingleSetupIntegrationTestBase; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; +import org.hisp.dhis.user.UserService; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -74,6 +76,13 @@ class MetadataExportWithDependenciesTest extends SingleSetupIntegrationTestBase @Autowired private ObjectMapper jsonMapper; + @Autowired private UserService _userService; + + @BeforeAll + void init() { + this.userService = _userService; + } + @Test void testExportProgramWithProgramSection() { Program program = createProgram('A'); diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java index c584816e0851..a345598c676d 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java @@ -32,7 +32,6 @@ import static org.hisp.dhis.web.WebClientUtils.assertStatus; import static org.hisp.dhis.webapi.utils.TestUtils.getMatchingGroupFromPattern; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import com.fasterxml.jackson.core.JsonProcessingException; @@ -42,7 +41,6 @@ import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.feedback.ErrorCode; import org.hisp.dhis.jsontree.JsonList; -import org.hisp.dhis.jsontree.JsonMixed; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; import org.hisp.dhis.user.User; import org.hisp.dhis.web.HttpStatus; @@ -392,7 +390,6 @@ void testDeleteWithMapView() { assertStatus(HttpStatus.OK, DELETE("/programs/%s".formatted(PROGRAM_UID))); assertStatus(HttpStatus.NOT_FOUND, GET("/programs/%s".formatted(PROGRAM_UID))); - JsonMixed mapview = GET("/mapViews/mVIVRd23Jm9").content().as(JsonMixed.class); - assertFalse(mapview.has("program")); + assertStatus(HttpStatus.NOT_FOUND, GET("/mapViews/%s".formatted("mVIVRd23Jm9"))); } } From ac3df3d8e94e0e226b032cdd1d722c1e9a3323a9 Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Tue, 2 Jun 2026 16:31:48 -0500 Subject: [PATCH 5/6] fix test --- .../hisp/dhis/webapi/controller/ProgramControllerTest.java | 6 +++++- .../dhis/webapi/controller/mapping/MapViewController.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java index a345598c676d..91d67e587bc2 100644 --- a/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java +++ b/dhis-2/dhis-test-web-api/src/test/java/org/hisp/dhis/webapi/controller/ProgramControllerTest.java @@ -32,6 +32,7 @@ import static org.hisp.dhis.web.WebClientUtils.assertStatus; import static org.hisp.dhis.webapi.utils.TestUtils.getMatchingGroupFromPattern; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import com.fasterxml.jackson.core.JsonProcessingException; @@ -41,6 +42,7 @@ import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.feedback.ErrorCode; import org.hisp.dhis.jsontree.JsonList; +import org.hisp.dhis.jsontree.JsonMixed; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; import org.hisp.dhis.user.User; import org.hisp.dhis.web.HttpStatus; @@ -390,6 +392,8 @@ void testDeleteWithMapView() { assertStatus(HttpStatus.OK, DELETE("/programs/%s".formatted(PROGRAM_UID))); assertStatus(HttpStatus.NOT_FOUND, GET("/programs/%s".formatted(PROGRAM_UID))); - assertStatus(HttpStatus.NOT_FOUND, GET("/mapViews/%s".formatted("mVIVRd23Jm9"))); + JsonMixed mapview = GET("/mapViews/mVIVRd23Jm9").content().as(JsonMixed.class); + assertFalse(mapview.has("program")); + assertFalse(mapview.has("programStage")); } } diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java index 547d3a358a24..9ef68a5a886a 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/mapping/MapViewController.java @@ -63,7 +63,7 @@ */ @OpenApi.Tags("metadata") @Controller -@RequestMapping("/api/mapViews") +@RequestMapping("/mapViews") public class MapViewController extends AbstractFullReadOnlyController { @Autowired private MappingService mappingService; From 982b9f0515a96011a1bb3df3f9cf854d3b7fa3f2 Mon Sep 17 00:00:00 2001 From: vietnguyen Date: Tue, 2 Jun 2026 16:34:20 -0500 Subject: [PATCH 6/6] revert debug --- .../export/MetadataExportWithDependenciesTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java index 101ea674255e..95e987366e1f 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/metadata/export/MetadataExportWithDependenciesTest.java @@ -57,8 +57,6 @@ import org.hisp.dhis.render.RenderService; import org.hisp.dhis.test.integration.SingleSetupIntegrationTestBase; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; -import org.hisp.dhis.user.UserService; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -76,13 +74,6 @@ class MetadataExportWithDependenciesTest extends SingleSetupIntegrationTestBase @Autowired private ObjectMapper jsonMapper; - @Autowired private UserService _userService; - - @BeforeAll - void init() { - this.userService = _userService; - } - @Test void testExportProgramWithProgramSection() { Program program = createProgram('A');