diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/AuditIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/AuditIntegrationTest.java new file mode 100644 index 000000000..b9570b5b3 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/AuditIntegrationTest.java @@ -0,0 +1,105 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests; + +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.util.HashMap; +import java.util.List; +import org.apache.fineract.integrationtests.common.AuditHelper; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.OfficeHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * + * @author Manthan Surkar + * + */ +public class AuditIntegrationTest { + + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + private ClientHelper clientHelper; + private AuditHelper auditHelper; + + /** + * Sets up the essential settings for the TEST like contentType, expectedStatusCode. It uses the '@BeforeEach' + * annotation provided by jUnit. + */ + @BeforeEach + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + this.auditHelper = new AuditHelper(this.requestSpec, this.responseSpec); + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + } + + /** + * Here we Create/Update different Entities and verify an audit is generated for each action. This can be further + * extened with more entities and actions in similiar way. + */ + @SuppressWarnings("unchecked") + @Test + public void auditShouldbeCreated() { + // Audits recieved after all actions are performed. + List> auditsRecieved; + + // Audits recieved before any action is performed, needed in special + // cases eg: reactivate client, close client + List> auditsRecievedInitial; + + // When Client is created: Count should be "1" + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assertions.assertNotNull(clientId); + auditsRecieved = auditHelper.getAuditDetails(clientId, "CREATE", "CLIENT"); + auditHelper.verifyOneAuditOnly(auditsRecieved, clientId, "CREATE", "CLIENT"); + + // Performs multiple close and reactivate on client + + for (int i = 0; i < 4; i++) { + // Close + auditsRecievedInitial = auditHelper.getAuditDetails(clientId, "CLOSE", "CLIENT"); + this.clientHelper.closeClient(clientId); + auditsRecieved = auditHelper.getAuditDetails(clientId, "CLOSE", "CLIENT"); + auditHelper.verifyMultipleAuditsOnserver(auditsRecievedInitial, auditsRecieved, clientId, "CLOSE", "CLIENT"); + + // Activate + auditsRecievedInitial = auditHelper.getAuditDetails(clientId, "REACTIVATE", "CLIENT"); + this.clientHelper.reactivateClient(clientId); + auditsRecieved = auditHelper.getAuditDetails(clientId, "REACTIVATE", "CLIENT"); + auditHelper.verifyMultipleAuditsOnserver(auditsRecievedInitial, auditsRecieved, clientId, "REACTIVATE", "CLIENT"); + } + + // When Office is created + OfficeHelper officeHelper = new OfficeHelper(requestSpec, responseSpec); + int officeId = officeHelper.createOffice("22 June 2020"); + auditsRecieved = auditHelper.getAuditDetails(officeId, "CREATE", "OFFICE"); + auditHelper.verifyOneAuditOnly(auditsRecieved, officeId, "CREATE", "OFFICE"); + } + +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/AuditHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/AuditHelper.java new file mode 100644 index 000000000..cc995c637 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/AuditHelper.java @@ -0,0 +1,89 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests.common; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Manthan Surkar + * + */ + +public class AuditHelper { + + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + + private static final Logger LOG = LoggerFactory.getLogger(AuditHelper.class); + private static final String AUDIT_BASE_URL = "/fineract-provider/api/v1/audits?" + Utils.TENANT_IDENTIFIER; + + public AuditHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + this.requestSpec = requestSpec; + this.responseSpec = responseSpec; + } + + public List getAuditDetails(final Integer resourceId, final String actionName, final String entityName) { + final String AUDIT_URL = "/fineract-provider/api/v1/audits/?" + "entityName=" + entityName + "&resourceId=" + resourceId + + "&actionName=" + actionName + "&orderBy=id&sortBy=DSC&" + Utils.TENANT_IDENTIFIER; + List> responseAudits = Utils.performServerGet(requestSpec, responseSpec, AUDIT_URL, ""); + return responseAudits; + } + + /** + * Some audit actions can only be done once Eg: Creation of a client with id 123, hence we verify number of audits + * For such operations is "equal" to 1 always + */ + public void verifyOneAuditOnly(List> auditsToCheck, Integer id, String actionName, String entityType) { + LOG.info("------------------------------CHECK IF AUDIT CREATED------------------------------------\n"); + assertEquals(1, auditsToCheck.size(), "More than one audit created"); + HashMap auditToCheck = auditsToCheck.get(0); + String actual = auditToCheck.get("actionName").toString() + " is done on " + auditToCheck.get("entityName").toString() + " with id " + + auditToCheck.get("resourceId").toString(); + String expected = actionName + " is done on " + entityType + " with id " + id; + assertEquals(expected, actual, "Error in creating audit!"); + } + + public void verifyMultipleAuditsOnserver(List> auditsRecievedInitial, + List> auditsRecieved, Integer id, String actionName, String entityType) { + LOG.info("------------------------------CHECK IF AUDIT CREATED------------------------------------\n"); + assertEquals(auditsRecievedInitial.size() + 1, auditsRecieved.size(), "Audit is not Created"); + + Comparator> compareById = (HashMap a, HashMap b) -> a.get("id").toString() + .compareTo(b.get("id").toString()); + Collections.sort(auditsRecieved, compareById.reversed()); + + // First element is new audit created(Sorted DESC by Id) + HashMap auditToCheck = auditsRecieved.get(0); + String actual = auditToCheck.get("actionName").toString() + " is done on " + auditToCheck.get("entityName").toString() + " with id " + + auditToCheck.get("resourceId").toString(); + String expected = actionName + " is done on " + entityType + " with id " + id; + assertEquals(expected, actual, "Error in creating audit!"); + } + +}