/** * The contents of this file are subject to the OpenMRS Public License * Version 1.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://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.report; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.openmrs.Program; import org.openmrs.api.CohortService; import org.openmrs.api.ReportService; import org.openmrs.api.context.Context; import org.openmrs.report.impl.TsvReportRenderer; import org.openmrs.reporting.PatientCharacteristicFilter; import org.openmrs.reporting.PatientSearch; import org.openmrs.reporting.PatientSearchReportObject; import org.openmrs.reporting.ProgramStatePatientFilter; import org.openmrs.test.BaseContextSensitiveTest; import org.openmrs.xml.OpenmrsCycleStrategy; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.load.Persister; /** * */ public class PepfarReportFromXmlTest extends BaseContextSensitiveTest { Log log = LogFactory.getLog(getClass()); DateFormat ymd = new SimpleDateFormat("yyyy-MM-dd"); Map<Parameter, Object> getUserEnteredParameters(Collection<Parameter> params) throws ParseException { Map<Parameter, Object> ret = new HashMap<Parameter, Object>(); if (params != null) { for (Parameter p : params) { if (p.getName().equals("report.startDate")) ret.put(p, ymd.parse("2007-09-01")); else if (p.getName().equals("report.endDate")) ret.put(p, ymd.parse("2007-09-30")); } } return ret; } @Test public void shouldFromXml() throws Exception { executeDataSet("org/openmrs/report/include/PepfarReportTest.xml"); StringBuilder xml = new StringBuilder(); xml.append("<reportSchema id=\"1\">\n"); xml.append(" <name>PEPFAR report</name>\n"); xml.append(" <description>\n"); xml.append(" Sample monthly PEPFAR report, modelled after the lesotho one\n"); xml.append(" </description>\n"); xml.append(" <parameters class=\"java.util.ArrayList\">\n"); xml .append(" <parameter clazz=\"java.util.Date\"><name>report.startDate</name><label>When does the report period start?</label></parameter>/>\n"); xml .append(" <parameter clazz=\"java.util.Date\"><name>report.endDate</name><label>When does the report period end?</label></parameter>\n"); xml .append(" <parameter clazz=\"org.openmrs.Location\"><name>report.location</name><label>For which clinic is this report?</label></parameter>\n"); xml.append(" </parameters>\n"); xml.append(" <dataSets class=\"java.util.ArrayList\">\n"); xml.append(" <dataSetDefinition class=\"org.openmrs.report.CohortDataSetDefinition\" name=\"Cohorts\">\n"); xml.append(" <strategies class=\"java.util.LinkedHashMap\">\n"); xml.append(" <entry>\n"); xml.append(" <string>1.a</string>\n"); xml.append(" <cohortDefinition class=\"org.openmrs.reporting.PatientSearch\">\n"); xml.append(" <specification>[Male]</specification>\n"); xml.append(" </cohortDefinition>\n"); xml.append(" </entry>\n"); xml.append(" <entry>\n"); xml.append(" <string>1.b</string>\n"); xml.append(" <cohortDefinition class=\"org.openmrs.reporting.PatientSearch\">\n"); xml .append(" <specification>[Male] and [Adult] and [EnrolledOnDate|untilDate=${report.startDate-1d}]</specification>\n"); xml.append(" </cohortDefinition>\n"); xml.append(" </entry>\n"); xml.append(" </strategies>\n"); xml.append(" </dataSetDefinition>\n"); xml.append(" </dataSets>\n"); xml.append("</reportSchema>\n"); //System.out.println("xml\n" + xml); // Try to get HIV PROGRAM, or else, just the first program Program hivProgram = Context.getProgramWorkflowService().getProgramByName("HIV PROGRAM"); if (hivProgram == null) hivProgram = Context.getProgramWorkflowService().getProgram(1); assertNotNull("Need at least one program defined to run this test", hivProgram); // Make sure we have all required PatientSearches if (Context.getReportObjectService().getPatientSearch("Male") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("gender", "m", String.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Male", ps)); } if (Context.getReportObjectService().getPatientSearch("Female") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("gender", "f", String.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Female", ps)); } if (Context.getReportObjectService().getPatientSearch("Adult") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("minAge", "15", Integer.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Adult", ps)); } if (Context.getReportObjectService().getPatientSearch("Child") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("maxAge", "15", Integer.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Child", ps)); } if (Context.getReportObjectService().getPatientSearch("EnrolledOnDate") == null) { PatientSearch ps = PatientSearch.createFilterSearch(ProgramStatePatientFilter.class); ps.addArgument("program", hivProgram.getProgramId().toString(), Integer.class); ps.addArgument("untilDate", "${date}", Date.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("EnrolledOnDate", ps)); } Serializer serializer = new Persister(new OpenmrsCycleStrategy()); ReportSchema schema = serializer.read(ReportSchema.class, xml.toString()); log.info("Creating EvaluationContext"); EvaluationContext evalContext = new EvaluationContext(); for (Map.Entry<Parameter, Object> e : getUserEnteredParameters(schema.getReportParameters()).entrySet()) { log.info("adding parameter value " + e.getKey()); evalContext.addParameterValue(e.getKey(), e.getValue()); } ReportService rs = (ReportService) Context.getService(ReportService.class); ReportData data = rs.evaluate(schema, null, evalContext); TsvReportRenderer renderer = new TsvReportRenderer(); //System.out.println("Rendering output as TSV:"); //renderer.render(data, null, System.out); } @Test public void shouldBooleansInPatientSearch() throws Exception { executeDataSet("org/openmrs/report/include/ReportTests-patients.xml"); // Make sure we have all required PatientSearches if (Context.getReportObjectService().getPatientSearch("Male") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("gender", "m", String.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Male", ps)); } if (Context.getReportObjectService().getPatientSearch("Female") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("gender", "f", String.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Female", ps)); } if (Context.getReportObjectService().getPatientSearch("Adult") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("minAge", "15", Integer.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Adult", ps)); } if (Context.getReportObjectService().getPatientSearch("Child") == null) { PatientSearch ps = PatientSearch.createFilterSearch(PatientCharacteristicFilter.class); ps.addArgument("maxAge", "15", Integer.class); Context.getReportObjectService().saveReportObject(new PatientSearchReportObject("Child", ps)); } EvaluationContext evalContext = new EvaluationContext(); evalContext.addParameterValue(new Parameter("report.startDate", "Start Date", Date.class, null), ymd .parse("2007-09-01")); evalContext .addParameterValue(new Parameter("report.endDate", "End Date", Date.class, null), ymd.parse("2007-09-30")); CohortService cs = Context.getCohortService(); PatientSearch male = new PatientSearch(); PatientSearch female = new PatientSearch(); PatientSearch maleAndFemale = new PatientSearch(); PatientSearch maleOrFemale = new PatientSearch(); male.setSpecificationString("[Male]"); female.setSpecificationString("[Female]"); maleAndFemale.setSpecificationString("[Male] and [Female]"); maleOrFemale.setSpecificationString("[Male] or [Female]"); int numMale = cs.evaluate(male, evalContext).size(); int numFemale = cs.evaluate(female, evalContext).size(); int numMaleAndFemale = cs.evaluate(maleAndFemale, evalContext).size(); int numMaleOrFemale = cs.evaluate(maleOrFemale, evalContext).size(); assertEquals("AND should be zero", 0, numMaleAndFemale); assertEquals("OR should be the sum", numMale + numFemale, numMaleOrFemale); PatientSearch complex1 = new PatientSearch(); complex1.setSpecificationString("([Male] and [Child]) or ([Female] and [Adult])"); assertNotSame("Should not be zero", 0, cs.evaluate(complex1, evalContext).size()); PatientSearch complex2 = new PatientSearch(); PatientSearch complex3 = new PatientSearch(); complex2.setSpecificationString("[Male] or [Female]"); complex3.setSpecificationString("(([Male] and [Child]) or [Female])"); // this assertion will fail 15 years after 2008-07-01 because the birthdates are // set to that in the dataset for the two "children" assertNotSame("Complex2 and Complex3 should be different sizes", cs.evaluate(complex2, evalContext).size(), cs .evaluate(complex3, evalContext).size()); } }