Package org.openmrs.module.htmlformentry

Source Code of org.openmrs.module.htmlformentry.RegressionTestHelper

package org.openmrs.module.htmlformentry;

import org.junit.Assert;
import org.openmrs.Encounter;
import org.openmrs.Form;
import org.openmrs.Obs;
import org.openmrs.Patient;
import org.openmrs.api.context.Context;
import org.openmrs.module.ModuleUtil;
import org.openmrs.module.htmlformentry.FormEntryContext.Mode;
import org.openmrs.util.OpenmrsConstants;
import org.openmrs.util.OpenmrsUtil;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class RegressionTestHelper {
 
  private static final String XML_DATASET_PATH = "org/openmrs/module/htmlformentry/include/";

  /**
   * @return will be used to look up the file test/.../include/{formName}.xml
   */
  public abstract String getFormName();
 
  /**
   * you probably want to override this
   *
   * @return the labels before all widgets you want to set values for (allows you to refer to
   *         "Date:" instead of "w1" in setupRequest)
   */
  public String[] widgetLabels() {
    return new String[0];
  }

  /**
   * Override this if you want to test what the generated html of the blank form looks like.
   * @param html
   */
  public void testBlankFormHtml(String html) {
  }
 
  /**
   * (Override this if you want to test the submission of a form.) Set any request parameters that
   * will be sent in the form submission
   *
   * @param request an empty request for you to populate
   * @param widgets map from the label you provided in widgetLabels() to the name that form
   *            element should submit as (which was autogenerated by the html form, e.g. "w3")
   */
  public void setupRequest(MockHttpServletRequest request, Map<String, String> widgets) {
  }
 
  /**
   * (Override this if you want to test the submission of a form.)
   *
   * @param results the results of having submitted the request you set up in setupRequest. This
   *            will contain either validationErrors, or else an encounterCreated
   */
  public void testResults(SubmissionResults results) {
  }
 
  /**
   * Optionally override this if you want to generate the form for a different patient, or if you
   * are testing a patient creation form
   *
   * @return
   */
  public Patient getPatient() {
    return Context.getPatientService().getPatient(2);
  }
 
  /**
   * Optionally override this if you want to test out viewing a specific patient rather than the
   * one that was used earlier in this test case to fill out a form
   *
   * @return
   * @throws Exception
   */
  public Patient getPatientToView() throws Exception {
    return null;
  }
 
  /**
   * Override this and return true if you want to have testViewingPatient run. (If you override
   * getPatientToView to return something non-null, then you do not need to override this method
   * -- testViewingPatient will be called anyway.)
   */
  public boolean doViewPatient() {
    return false;
  }
 
  /**
   * Override this if you want to test out viewing a patient without an encounter
   *
   * @param patient
   * @param html
   */
  public void testViewingPatient(Patient patient, String html) {
  }

  /**
   * Optionally override this if you want to test out viewing a specific encounter rather than the
   * one that was created earlier in this test case.
   *
   * @return
   * @throws Exception
   */
  public Encounter getEncounterToView() throws Exception {
    return null;
  }
   
  /**
   * Override this and return true if you want to have testViewingEncounter run. (If you override
   * getEncounterToView to return something non-null, then you do not need to override this method
   * -- testViewingEncounter will be called anyway.)
   */
  public boolean doViewEncounter() {
    return false;
  }
 
  /**
   * Override this if you want to test out viewing an encounter
   *
   * @param encounter
   * @param html
   */
  public void testViewingEncounter(Encounter encounter, String html) {
  }
 
  /**
   * Override this and return true if you want to have testEditFormHtml, testEditEncounter, etc run.
   * (If you override {@link #getEncounterToEdit()} to return a non-null value, you don't need to override
   * this one.)
   */
  public boolean doEditEncounter() {
    return false;
  }
 
  /**
   * Override this and return true if you want to have testEditFormHtml, testEditPatient, etc run.
   * (If you override {@link #getPatientToEdit()} to return a non-null value, you don't need to override
   * this one.)
   */
  public boolean doEditPatient() {
    return false;
  }
 
  /**
   * Override this if you want to edit a different encounter than the one created in the first part
   * of the test or viewed in the second part. (Returning a non-null value implies doEditEncounter = true.)
   * @return
   */
  public Encounter getEncounterToEdit() {
    return null;
  }
 
  /**
   * Override this if you want to edit a Patient than the one created in the first part
   * of the test or viewed in the second part. (Returning a non-null value implies doEditPatient = true.)
   * @return
   */
  public Patient getPatientToEdit() {
    return null;
  }
 
  /**
   * Override this if you want to test what the generated html of the edit form looks like.
   * @param html
   */
  public void testEditFormHtml(String html) {
  }
 
  /**
   * (Override this if you want to test the submission of editing a form.) Set any request parameters
   * that will be sent in the form submission
   *
   * @param request an empty request for you to populate
   * @param widgets map from the label you provided in widgetLabelsForEdit() to the name that form
   *            element should submit as (which was autogenerated by the html form, e.g. "w3")
   */
  public void setupEditRequest(MockHttpServletRequest request, Map<String, String> widgets) {
  }
 
  /**
   * @return the labels before all widgets you want to set values for in the edit form
   * @see #widgetLabels()
   */
  public String[] widgetLabelsForEdit() {
    return new String[0];
  }
 
  /**
   * Override this if you want to test out editing
   *
   * @param encounter
   * @param html
   */
  public void testEditEncounter(Encounter encounter, String html) {
  }
 
  /**
   * (Override this if you want to test the submission of editing a form.)
   *
   * @param results the results of having submitted the request you set up in setupEditRequest. This
   *            will contain either validationErrors, or else an encounterCreated
   */
  public void testEditedResults(SubmissionResults results) {
  }

  /**
   * (Override this if you want to test the an attribute of FormEntrySession in
   * form entry (ENTER) mode.)
   *
   * @param formEntrySession object, useful in test state of session object
   */
  public void testFormEntrySessionAttribute(FormEntrySession formEntrySession){
  }
 
  /**
   * (Override this if you want to test the an attribute of FormEntrySession in
   * form view mode.)
   *
   * @param formEntrySession object, useful in test state of session object
   */
  public void testFormViewSessionAttribute(FormEntrySession formEntrySession) {
  }
 
  /**
   * (Override this if you want to test the an attribute of FormEntrySession in
   * form edit mode.)
   *
   * @param formEntrySession object, useful in test state of session object
   */
  public void testFormEditSessionAttribute(FormEntrySession formEntrySession) {
  }

  public void run() throws Exception {
    // setup the blank form for the specified patient
    Patient patient = getPatient();
    FormEntrySession session = setupFormEntrySession(patient, getFormName());
    testFormEntrySessionAttribute(session);
    String html = session.getHtmlToDisplay();
    testBlankFormHtml(html);

    // submit some initial data and test it
    Map<String, String> labeledWidgets = getLabeledWidgets(html, widgetLabels());
    MockHttpServletRequest request = new MockHttpServletRequest();
        request.setSession(session.getHttpSession());
    setupRequest(request, labeledWidgets);
    Patient patientToView = null;
    Encounter encounterToView = null;
    if (request.getParameterMap().size() > 0) {
      SubmissionResults results = doSubmission(session, request);
      testResults(results);
      patientToView = results.getPatient();
      encounterToView = results.getEncounterCreated();
    }

    // view that patient and run tests on it
    Patient overridePatient = getPatientToView();
    boolean doViewPatient = overridePatient != null || doViewPatient();
    if (doViewPatient) {
      if (overridePatient != null)
        patientToView = overridePatient;
      session = setupFormViewSession(patientToView, null, getFormName());
      testFormViewSessionAttribute(session);
      html = session.getHtmlToDisplay();
      testViewingPatient(patientToView, html);
    }

    // view that encounter and run tests on that
    Encounter override = getEncounterToView();
    boolean doViewEncounter = override != null || doViewEncounter();
    if (doViewEncounter) {
      if (override != null)
        encounterToView = override;

      session = setupFormViewSession(patientToView, encounterToView, getFormName());
      testFormViewSessionAttribute(session);
      html = session.getHtmlToDisplay();
      testViewingEncounter(encounterToView, html);
    }

    // edit the encounter, and run tests on that
    override = getEncounterToEdit();
    boolean doEditEncounter = override != null || doEditEncounter();

    overridePatient = getPatientToEdit();
    boolean doEditPatient = overridePatient != null || doEditPatient();

    if (doEditEncounter || doEditPatient) {
      Encounter toEdit = encounterToView;
      if (override != null)
        toEdit = override;

      Patient patientToEdit = patientToView;
      if (overridePatient != null)
        patientToEdit = overridePatient;

      session = setupFormEditSession(patientToEdit, toEdit, getFormName());
      testFormEditSessionAttribute(session);
      String editHtml = session.getHtmlToDisplay();
      testEditFormHtml(editHtml);

      Map<String, String> labeledWidgetsForEdit = getLabeledWidgets(editHtml, widgetLabelsForEdit());
      MockHttpServletRequest editRequest = createEditRequest(editHtml, session.getHttpSession());
      setupEditRequest(editRequest, labeledWidgetsForEdit);
      if (editRequest.getParameterMap().size() > 0) {
        SubmissionResults results = doSubmission(session, editRequest);
        testEditedResults(results);
        results.getEncounterCreated();
        results.getPatient();
      }
    }

  }

    private String formatObsValueDate(Date date){
        if(date == null){
            return null;
        }
        String valueAsString = TestUtil.valueAsStringHelper(date);
        //The date format used by Obs.getValueAsString changed in 1.9.9
        if(ModuleUtil.compareVersion(OpenmrsConstants.OPENMRS_VERSION_SHORT, "1.9.9") > -1){
            valueAsString = new SimpleDateFormat("yyyy-MM-dd").format(date);
        }
        return valueAsString;
    }

  private MockHttpServletRequest createEditRequest(String html, HttpSession httpSession) {
    MockHttpServletRequest ret = new MockHttpServletRequest();
        ret.setSession(httpSession);
   
    // used for input and for select option
    Pattern forValue = Pattern.compile("value=\"(.*?)\"");
   
    // <input ... name="something" ...>
    {
      Pattern forInput = Pattern.compile("<input.*?name=\"(.*?)\".*?>");
      Matcher matcher = forInput.matcher(html);
      while (matcher.find()) {
        String element = matcher.group();
        String name = matcher.group(1);
        Matcher lookForValue = forValue.matcher(element);
        if (lookForValue.find()) {
          String value = lookForValue.group(1);
          ret.addParameter(name, value);
        }
      }
    }
   
    // <textarea ... name="something" ...>value</textarea>
    {
      Pattern forTextarea = Pattern.compile("<textarea.*?name=\"(.*?)\".*?>(.*?)</textarea>");
      Matcher matcher = forTextarea.matcher(html);
      while (matcher.find()) {
        String name = matcher.group(1);
        String value = matcher.group(2);
        ret.addParameter(name, value);
      }
    }
   
    // <select ... name="something" ...>(options)</select> (DOTALL makes . match line terminator too)
    {
      Pattern forSelect = Pattern.compile("<select.*?name=\"(.*?)\".*?>.*?(<option[^>]*selected[^>]*>).*?</select>", Pattern.DOTALL);
      Matcher matcher = forSelect.matcher(html);
      while (matcher.find()) {
        String name = matcher.group(1);
        String selectedOption = matcher.group(2);
        Matcher lookForValue = forValue.matcher(selectedOption);
        if (lookForValue.find()) {
          String value = lookForValue.group(1);
          ret.addParameter(name, value);
        } else {
          ret.addParameter(name, "");
        }
      }
    }
   
    // setupDatePicker(jsDateFormat, jsLocale, displaySelector, '#something', '2012-01-30')
    {
      Pattern forDatePicker = Pattern.compile("setupDatePicker\\(.*?, .*?, .*?, '#(.+?)', '(.+?)'\\)");
      Matcher matcher = forDatePicker.matcher(html);
      while (matcher.find()) {
        String name = matcher.group(1);
        String value = matcher.group(2);
        ret.addParameter(name, value);
      }
    }
   
    return ret;
  }
 
  /**
   * Override this if you need to load your form's xml from somewhere other than the standard location
   * defined by {@link RegressionTest#XML_DATASET_PATH}. For example you should override this for any
   * tests in modules that depend on HTML Form Entry.
   */
  protected String getXmlDatasetPath() {
    return RegressionTestHelper.XML_DATASET_PATH;
  }

    /**
     * Override this if you want to populate the FormEntrySession with extra attributes.
     * This will be applied for Enter, Edit, and View.
     * @return map of attributes to be set on the FormEntrySession
     */
    public Map<String, Object> getFormEntrySessionAttributes() {
        return null;
    }

  private FormEntrySession setupFormEntrySession(Patient patient, String filename) throws Exception {
    String xml = loadXmlFromFile(getXmlDatasetPath() + filename + ".xml");
   
    HtmlForm fakeForm = new HtmlForm();
    fakeForm.setXmlData(xml);
    fakeForm.setForm(new Form(1));
    FormEntrySession session = new FormEntrySession(patient, null, FormEntryContext.Mode.ENTER, fakeForm, new MockHttpSession());
        session.setAttributes(getFormEntrySessionAttributes());
        session.getHtmlToDisplay();
    return session;
  }
 
  private FormEntrySession setupFormViewSession(Patient patient, Encounter encounter, String filename) throws Exception {
    String xml = loadXmlFromFile(getXmlDatasetPath() + filename + ".xml");
   
    HtmlForm fakeForm = new HtmlForm();
    fakeForm.setXmlData(xml);
    fakeForm.setForm(new Form(1));
    FormEntrySession session = new FormEntrySession(patient, encounter, FormEntryContext.Mode.VIEW, fakeForm, new MockHttpSession());
        session.setAttributes(getFormEntrySessionAttributes());
        session.getHtmlToDisplay();
    return session;
  }
 
  private FormEntrySession setupFormEditSession(Patient patient, Encounter encounter, String filename) throws Exception {
    String xml = loadXmlFromFile(getXmlDatasetPath() + filename + ".xml");
   
    HtmlForm fakeForm = new HtmlForm();
    fakeForm.setXmlData(xml);
    fakeForm.setForm(new Form(1));
    FormEntrySession session = new FormEntrySession(patient, encounter, FormEntryContext.Mode.EDIT, fakeForm, new MockHttpSession());
        session.setAttributes(getFormEntrySessionAttributes());
        session.getHtmlToDisplay();
    return session;
  }
 
  private String loadXmlFromFile(String filename) throws Exception {
    InputStream fileInInputStreamFormat = null;
   
    // try to load the file if its a straight up path to the file or
    // if its a classpath path to the file
    if (new File(filename).exists()) {
      fileInInputStreamFormat = new FileInputStream(filename);
    } else {
      fileInInputStreamFormat = getClass().getClassLoader().getResourceAsStream(filename);
      if (fileInInputStreamFormat == null)
        throw new FileNotFoundException("Unable to find '" + filename + "' in the classpath");
    }
    StringBuilder sb = new StringBuilder();
    BufferedReader r = new BufferedReader(new InputStreamReader(fileInInputStreamFormat, Charset.forName("UTF-8")));
    while (true) {
      String line = r.readLine();
      if (line == null)
        break;
      sb.append(line).append("\n");
    }
    return sb.toString();
  }
 
  public String dateAsString(Date date) {
    return new SimpleDateFormat("yyyy-MM-dd").format(date);
  }
   
  public Date ymdToDate(String dateString) {
    try {
      return new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
    } catch (ParseException ex) {
      throw new RuntimeException(ex);
    }
    }
 
  public String dateTodayAsString() {
    return dateAsString(new Date());
  }
 
  /**
   * Finds the name of the first widget after each of the given labels. I.e. the first name="w#".
   */
  private Map<String, String> getLabeledWidgets(String html, String... labels) {
    Map<String, String> ret = new HashMap<String, String>();
    for (String label : labels) {
      int toSkip = 0;
      // something like EncounterAndRole!!1 means the *second* widget after "EncounterAndRole"
      String origLabel = label;
      if (label.indexOf("!!") > 0) {
        String[] temp = label.split("!!");
        toSkip = Integer.valueOf(temp[1]);
        label = temp[0];
      }
      int index = html.indexOf(label);
      if (index < 0)
        continue;
      try {
        for (int i = 0; i < toSkip + 1; ++i) {
          index = html.indexOf("name=\"w", index);
          index = html.indexOf('"', index) + 1;
        }
        String val = html.substring(index, html.indexOf('"', index + 1));
        ret.put(origLabel, val);
      }
      catch (Exception ex) {
        // do nothing
      }
    }
    return ret;
  }

  private SubmissionResults doSubmission(FormEntrySession session, HttpServletRequest request) throws Exception {
    SubmissionResults results = new SubmissionResults();
    session.prepareForSubmit();
    List<FormSubmissionError> validationErrors = session.getSubmissionController().validateSubmission(
        session.getContext(), request);
    if (validationErrors != null && validationErrors.size() > 0) {
      results.setValidationErrors(validationErrors);
      return results;
    }
    session.getSubmissionController().handleFormSubmission(session, request);

    if (session.getContext().getMode() == Mode.ENTER
            && session.hasEncouterTag() && (session.getSubmissionActions().getEncountersToCreate() == null || session.getSubmissionActions()
                    .getEncountersToCreate().size() == 0))
      throw new IllegalArgumentException("This form is not going to create an encounter");
    Context.getService(HtmlFormEntryService.class).applyActions(session);
    results.setPatient(session.getPatient());
    results.setEncounterCreated(session.getEncounter());
        results.setFormEntrySession(session);
    return results;
  }
 
  private Encounter getLastEncounter(Patient patient) {
    List<Encounter> encs = Context.getEncounterService().getEncounters(patient, null, null, null, null, null, null,
        true);
    if (encs == null || encs.size() == 0)
      return null;
    if (encs.size() == 1)
      return encs.get(0);
    Collections.sort(encs, new Comparator<Encounter>() {
      @Override
            public int compare(Encounter left, Encounter right) {
        return OpenmrsUtil.compareWithNullAsEarliest(left.getEncounterDatetime(), right.getEncounterDatetime());
      }
    });
    return encs.get(encs.size() - 1);
  }
 
  public class SubmissionResults {
   
    private List<FormSubmissionError> validationErrors;

    private Patient patient;
   
    private Encounter encounterCreated;

        private FormEntrySession formEntrySession;

        public void setFormEntrySession(FormEntrySession formEntrySession) {
            this.formEntrySession = formEntrySession;
        }

        public FormEntrySession getFormEntrySession() {
            return formEntrySession;
        }

    public void assertNoEncounterCreated() {
      Assert.assertNull(encounterCreated);
    }
   
    public void assertEncounterCreated() {
      Assert.assertNotNull(encounterCreated);
    }
   
    public void assertEncounterEdited() {
      Assert.assertNotNull("No encounter found", encounterCreated);
      Assert.assertNotNull("Encounter date changed not set on edit", encounterCreated.getDateChanged());
    }
   
    public void assertEncounterVoided() {
      Assert.assertTrue("Encounter not voided", encounterCreated.isVoided());
    }
   
    public void assertEncounterNotVoided() {
      Assert.assertFalse("Encounter voided", encounterCreated.isVoided());
    }
   
    public void assertNoErrors() {
      Assert.assertTrue("" + validationErrors, validationErrors == null || validationErrors.size() == 0);
    }
   
    public void assertErrors() {
      Assert.assertTrue(validationErrors != null && validationErrors.size() > 0);
    }
   
    public void assertErrors(int numberOfErrors) {
      Assert.assertTrue(validationErrors != null && validationErrors.size() == numberOfErrors);
    }
   
    public void printErrors() {
      if (validationErrors == null || validationErrors.size() == 0) {
        System.out.println("No Errors");
      } else {
        for (FormSubmissionError error : validationErrors)
          System.out.println(error.getId() + " -> " + error.getError());
      }
    }
   
    public void print() {
      printErrors();
      printEncounterCreated();
    }
   
    public void printEncounterCreated() {
      if (encounterCreated == null) {
        System.out.println("No encounter created");
      } else {
        System.out.println("=== Encounter created ===");
        System.out.println("Created: " + encounterCreated.getDateCreated() + "  Edited: " + encounterCreated.getDateChanged());
        System.out.println("Date: " + encounterCreated.getEncounterDatetime());
        System.out.println("Location: " + encounterCreated.getLocation().getName());
        System.out.println("Provider: " + encounterCreated.getProvider().getPersonName());
        System.out.println("    (obs)");
        Collection<Obs> obs = encounterCreated.getAllObs(false);
        if (obs == null) {
          System.out.println("None");
        } else {
          for (Obs o : obs) {
            System.out.println(o.getConcept().getName() + " -> " + o.getValueAsString(Context.getLocale()));
          }
        }
      }
    }
   
    public List<FormSubmissionError> getValidationErrors() {
      return validationErrors;
    }
   
    public void setValidationErrors(List<FormSubmissionError> validationErrors) {
      this.validationErrors = validationErrors;
    }
   
    public Encounter getEncounterCreated() {
      return encounterCreated;
    }
       
    public void setEncounterCreated(Encounter encounterCreated) {
      this.encounterCreated = encounterCreated;
    }
   
    public Patient getPatient() {
      return patient;
    }
   
    public void setPatient(Patient patient) {
      this.patient = patient;
    }

    /**
     * Fails if there is a patient (one was initially selected or one was created)
     */
    public void assertNoPatient() {
      Assert.assertNull(patient);
    }
   
    /**
     * Fails if there is no patient (none was initially selected and none was created), or the patient
     * doesn't have a patientId assigned.
     */
    public void assertPatient() {
      Assert.assertNotNull(patient);
      Assert.assertNotNull(patient.getPatientId());
    }
   
    /**
     * Fails if there is no provider with an assigned id associated with the encounter
     */
    public void assertProvider() {
      assertEncounterCreated();
      Assert.assertNotNull(getEncounterCreated().getProvider());
      Assert.assertNotNull(getEncounterCreated().getProvider().getPersonId());
    }
   
    /**
     * Fails if there is no provider or if the provider id does not match the expected id
     */
    public void assertProvider(Integer expectedProviderId) {
      assertProvider();
      Assert.assertEquals(expectedProviderId, getEncounterCreated().getProvider().getPersonId());
    }
   
    /**
     * Fails if there is no location with an assigned id associated with the encounter
     */
    public void assertLocation() {
      assertEncounterCreated();
      Assert.assertNotNull(getEncounterCreated().getLocation());
      Assert.assertNotNull(getEncounterCreated().getLocation().getLocationId());
    }
   
    /**
     * Fails if there is no location or if the location id does not match the expected location id
     */
    public void assertLocation(Integer expectedLocationId) {
      assertLocation();
      Assert.assertEquals(expectedLocationId, getEncounterCreated().getLocation().getLocationId());
    }
   
    public void assertEncounterType() {
      assertEncounterCreated();
      Assert.assertNotNull(getEncounterCreated().getEncounterType());
      Assert.assertNotNull(getEncounterCreated().getEncounterType().getEncounterTypeId());
    }

    public void assertEncounterType(Integer expectedEncounterTypeId) {
      assertEncounterType();
      Assert.assertEquals(expectedEncounterTypeId, getEncounterCreated().getEncounterType().getEncounterTypeId());
    }

        public void assertEncounterDatetime() {
            assertEncounterCreated();
            Assert.assertNotNull(getEncounterCreated().getEncounterDatetime());
        }

        public void assertEncounterDatetime(Date expectedEncounterDate) {
            assertEncounterDatetime();
            Assert.assertEquals(expectedEncounterDate, getEncounterCreated().getEncounterDatetime());
        }

    /**
     * Fails if the number of obs in encounterCreated is not 'expected'
     *
     * @param expected
     */
    public void assertObsCreatedCount(int expected) {
      int found = getObsCreatedCount();
      Assert.assertEquals("Expected to create " + expected + " obs but got " + found, expected, found);
    }
   
    /**
     * Fails if the number of obs groups in encounterCreated is not 'expected'
     *
     * @param expected
     */
    public void assertObsGroupCreatedCount(int expected) {
      int found = getObsGroupCreatedCount();
      Assert.assertEquals("Expected to create " + expected + " obs groups but got " + found, expected, found);
    }
   
    /**
     * Fails if the number of obs leaves (i.e. obs that aren't groups) in encounterCreated is
     * not 'expected'
     *
     * @param expected
     */
    public void assertObsLeafCreatedCount(int expected) {
      int found = getObsLeafCreatedCount();
      Assert.assertEquals("Expected to create " + expected + " non-group obs but got " + found, expected, found);
    }
   
    /**
     * @return the number of obs in encounterCreated (0 if no encounter was created)
     */
    public int getObsCreatedCount() {
      if (encounterCreated == null)
        return 0;
      Collection<Obs> temp = encounterCreated.getAllObs();
      if (temp == null)
        return 0;
      return temp.size();
    }
   
    /**
     * @return the number of obs groups in encounterCreated (0 if no encounter was created)
     */
    public int getObsGroupCreatedCount() {
      if (encounterCreated == null)
        return 0;
      Collection<Obs> temp = encounterCreated.getAllObs();
      if (temp == null)
        return 0;
      int count = 0;
      for (Obs o : temp) {
        if (o.isObsGrouping())
          ++count;
      }
      return count;
    }
   
    /**
     * @return the number of non-group obs in encounterCreated (0 if no encounter was created)
     */
    public int getObsLeafCreatedCount() {
      if (encounterCreated == null)
        return 0;
      Collection<Obs> temp = encounterCreated.getObs();
      if (temp == null)
        return 0;
      return temp.size();
    }
   
    private void assertObsExists(boolean lookForVoided, int conceptId, Object value) {
      // quick checks
      Assert.assertNotNull(encounterCreated);
      Collection<Obs> temp = encounterCreated.getAllObs(lookForVoided);
      Assert.assertNotNull(temp);

      String valueAsString = null;
            if(value instanceof Date){
                valueAsString = formatObsValueDate((Date)value);
            }else{
                valueAsString = TestUtil.valueAsStringHelper(value);
            }
      for (Obs obs : temp) {
        if (lookForVoided && !obs.isVoided())
          continue;
        if (obs.getConcept().getConceptId() == conceptId) {
          if (valueAsString == null)
            return;
          if (valueAsString.equals(obs.getValueAsString(Context.getLocale())))
            return;
        }
      }
      Assert.fail("Could not find obs with conceptId " + conceptId + " and value " + valueAsString);
    }
   
    /**
     * Fails if encounterCreated doesn't have an obs with the given conceptId and value
     *
     * @param conceptId
     * @param value may be null
     */
    public void assertObsCreated(int conceptId, Object value) {
      assertObsExists(false, conceptId, value);
    }
   
    /**
     * Fails if encounterCreated doesn't have a voided obs with the given conceptId and value
     *
     * @param conceptId
     * @param value
     */
    public void assertObsVoided(int conceptId, Object value) {
      assertObsExists(true, conceptId, value);
    }
   
    /**
     * Fails if there isn't an obs group with these exact characteristics
     *
     * @param groupingConceptId the concept id of the grouping obs
     * @param conceptIdsAndValues these parameters must be given in pairs, the first element of
     *            which is the conceptId of a child obs (Integer) and the second element of
     *            which is the value of the child obs
     */
    public void assertObsGroupCreated(int groupingConceptId, Object... conceptIdsAndValues) {
      // quick checks
      Assert.assertNotNull(encounterCreated);
      Collection<Obs> temp = encounterCreated.getAllObs();
      Assert.assertNotNull(temp);
     
      List<ObsValue> expected = new ArrayList<ObsValue>();
      for (int i = 0; i < conceptIdsAndValues.length; i += 2) {
        int conceptId = (Integer) conceptIdsAndValues[i];
        Object value = conceptIdsAndValues[i + 1];
        expected.add(new ObsValue(conceptId, value));
      }
     
      for (Obs o : temp) {
        if (o.getConcept().getConceptId() == groupingConceptId) {
          if (o.getValueCoded() != null || o.getValueComplex() != null || o.getValueDatetime() != null
                  || o.getValueDrug() != null || o.getValueNumeric() != null || o.getValueText() != null) {
            Assert
                    .fail("Obs group with groupingConceptId " + groupingConceptId
                            + " should has a non-null value");
          }
          if (TestUtil.isMatchingObsGroup(o, expected)) {
            return;
          }
        }
      }
      Assert.fail("Cannot find an obs group matching " + expected);
    }

  }

  public class ObsValue {
   
    public Integer conceptId; // required
   
    public Object value; // can be null
   
    public ObsValue(Integer cId, Object val) {
      conceptId = cId;
      value = val;
    }
   
    @Override
        public String toString() {
      return conceptId + "->" + value;
    }
   
    public boolean matches(Obs obs) {
     
      if (!obs.getConcept().getConceptId().equals(conceptId)) {
        return false;
      }
            String valueAsString = null;
            if(value instanceof Date){
                valueAsString = formatObsValueDate((Date)value);
            }else{
                valueAsString = TestUtil.valueAsStringHelper(value);
            }
      return OpenmrsUtil.nullSafeEquals(valueAsString, obs.getValueAsString(Context.getLocale()));
    }
  }
}
TOP

Related Classes of org.openmrs.module.htmlformentry.RegressionTestHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.