From 1fbe27e7108d43111a9bb95a95bbf6fcae72f283 Mon Sep 17 00:00:00 2001 From: "Rym.Ghosn" Date: Tue, 18 Aug 2026 15:00:00 +0300 Subject: [PATCH] FINERACT-2762: Add integration coverage for checker-only approval via the action endpoint A user holding only the "_CHECKER" permission for a maker-checker task can approve an identical pending submission by calling the action's normal endpoint. The behaviour itself landed with FINERACT-2753; this adds the end-to-end test for it: a maker's client activation is queued, a checker-only call with a different payload is refused with 403, and the same call with the identical payload approves the pending entry and activates the client. Assisted-By: claude-opus-5-5 --- .../integrationtests/MakercheckerTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MakercheckerTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MakercheckerTest.java index 817c6e4bde9..c03a68f231c 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MakercheckerTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MakercheckerTest.java @@ -428,6 +428,48 @@ public void testDuplicatePendingSubmissionAndCheckerOnlyInitiationAreRefusedWith } } + @Test + public void testCheckerOnlyUserApprovesAnIdenticalPendingSubmissionThroughTheActionEndpoint() { + globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.MAKER_CHECKER, + new PutGlobalConfigurationsRequest().enabled(true)); + try { + Integer clientId = Utils.performServerPost(requestSpec, responseSpec, CLIENTS_URL + "?" + Utils.TENANT_IDENTIFIER, + ClientHelper.getTestClientAsJSONPending(START_DATE_STRING, "1"), "clientId"); + rolesHelper.updatePermissions(new PutPermissionsRequest().putPermissionsItem("ACTIVATE_CLIENT", true)); + + Integer makerRoleId = RolesHelper.createRole(requestSpec, responseSpec); + RolesHelper.addPermissionsToRole(requestSpec, responseSpec, makerRoleId, Map.of("ACTIVATE_CLIENT", true)); + Integer checkerOnlyRoleId = RolesHelper.createRole(requestSpec, responseSpec); + RolesHelper.addPermissionsToRole(requestSpec, responseSpec, checkerOnlyRoleId, Map.of("ACTIVATE_CLIENT_CHECKER", true)); + Integer staffId = StaffHelper.createStaff(requestSpec, responseSpec); + String password = "A1b2c3d4e5f$"; + String maker = Utils.uniqueRandomStringGenerator("user", 8); + Integer makerUserId = (Integer) UserHelper.createUser(requestSpec, responseSpec, makerRoleId, staffId, maker, password, + "resourceId"); + String checkerOnly = Utils.uniqueRandomStringGenerator("user", 8); + UserHelper.createUser(requestSpec, responseSpec, checkerOnlyRoleId, staffId, checkerOnly, password, "resourceId"); + RequestSpecification checkerOnlySpec = userRequestSpec(checkerOnly, password); + ResponseSpecification forbidden = new ResponseSpecBuilder().expectStatusCode(403).build(); + + assertNull(activateClient(userRequestSpec(maker, password), responseSpec, clientId, TRANSACTION_DATE_STRING, "clientId"), + "The maker's activation should be queued for approval"); + + activateClient(checkerOnlySpec, forbidden, clientId, "06 June 2023", ""); + + assertEquals(clientId, activateClient(checkerOnlySpec, responseSpec, clientId, TRANSACTION_DATE_STRING, "clientId")); + assertEquals(Boolean.TRUE, Utils.performServerGet(requestSpec, responseSpec, + CLIENTS_URL + "/" + clientId + "?" + Utils.TENANT_IDENTIFIER, "active")); + assertEquals(0, + makercheckersHelper.getMakerCheckerList( + Map.of("actionName", "ACTIVATE", "entityName", "CLIENT", "makerId", makerUserId.toString())).size(), + "The pending activation should have been approved"); + } finally { + globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.MAKER_CHECKER, + new PutGlobalConfigurationsRequest().enabled(false)); + rolesHelper.updatePermissions(new PutPermissionsRequest().putPermissionsItem("ACTIVATE_CLIENT", false)); + } + } + private static T activateClient(RequestSpecification requestSpec, ResponseSpecification responseSpec, Integer clientId, String activationDate, String jsonAttributeToGetBack) { String body = "{\"activationDate\":\"" + activationDate + "\",\"dateFormat\":\"dd MMMM yyyy\",\"locale\":\"en\"}";