

package gov.va.med.cds.integration.vhim400;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import gov.va.med.cds.integration.AbstractEndToEndTest;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.request.TemplateRequestProcessor;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.vhim400.builders.FilterBuilder;
import gov.va.med.cds.testharness.xml.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;


@RunWith( SuiteAwareSpringRunner.class )
@ContextConfiguration( locations = { "classpath:gov/va/med/cds/config/nonWeblogicFailingVistADataSourcesContext.xml" } )
public class EndToEndReadLabTest
    extends
        AbstractEndToEndTest
{
    private static final String PATIENT_IDENTITY_1 = "1";
    private static final String PATIENT_IDENTITY_2 = "2";
    private static final String ASSIGNING_FACILITY_VISTA_578 = "578";
    private static final String ASSIGNING_FACILITY_VISTA_503 = "503";
    private static final String ASSIGNING_FACILITY_VISTA_504 = "504";
    private static final String ASSIGNING_FACILITY_VISTA_580 = "580";
    private static final String ASSIGNING_AUTHORITY_VISTA = "USVHA";

    private static final String ASSIGNING_AUTHORITY_ELEMENT_NAME = "assigningAuthority";
    private static final String ASSIGNING_FACILITY_ELEMENT_NAME = "assigningFacility";
    private static final String PATIENT_IDENTITY_ELEMENT_NAME = "identity";

    private static final String QUERY_TIMOUT_SECONDS_MIN = "0";

    private static final String XPATH_DOMAINENTRYPOINT = "//labTestPromise";
    private static final String XPATH_DOMAINENTRYPOINT_40011 = "//labTestPromises";

    protected static final String XPATH_PATIENT_40011 = "//clinicaldata:ClinicalData/patient";/// "//patients/patient"; (normal value)     clinicaldata:ClinicalData/patient (true xpath)
    protected static final String XPATH_RESOLVED_IDENTIFIERS_40011 = "//clinicaldata:ClinicalData/patient/requestedResolvedIdentifiers"; // "//requestedResolvedIdentifiers/requestedResolvedIdentifier"; (normal value)  clinicaldata:ClinicalData/patient/requestedResolvedIdentifiers (true xpath)
    private static final String XPATH_REQUESTEDEXCLUDEDINDETIFIERS = "//requestedExcludedIdentifiers/requestedExcludedIdentifier/assigningFacility";
    private static final String XPATH_REQUESTEDEXCLUDEDINDETIFIERS_40011 = "//requestedExcludedIdentifiers/assigningFacility";

    private TemplateRequestProcessor templateRequestProcessor;


    @Before
    @Suite( groups = { "checkintest" } )
    public void beforeEndToEndReadLabTestClassSetUp( )
        throws Exception
    {
        templateRequestProcessor = ( TemplateRequestProcessor )getRequestProcessor();
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testLabChemHemRead1_Dates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID, true, 5 );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testLabChemHemRead1_NoDates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID, false, 54 );
    }


    //@Test
    @Suite( groups = "checkintest" )
    public void testMHVLabRead40011_Dates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID, true, 4 );
    }


    //@Test
    @Suite( groups = "checkintest" )
    public void testMHVLabRead40011_NoDates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID, false, 6 );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabReadWithNullComments()
        throws Exception
    {
    	String readTemplateId = TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;
        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, "18" };

        String[][] patientIdentifiers = { vistaPatient578 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, 11, "/clinicaldata:ClinicalData/patient/labTestPromises/labCommentEvents/comments" );

        vistaPatient578[2] = "14";
        patientIdentifiers[0] = vistaPatient578;
        resolvedPatients = getResolvedPatients( patientIdentifiers );

        readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, 9, "/clinicaldata:ClinicalData/patient/labTestPromises/labTests/chemistryResults/labCommentEvents/comments" );
    }    
    
    
    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabChemHemRead1_Dates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID, true, "1998-06-01", "1998-12-31", 4 );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabChemHemRead1_NoDates( )
        throws Exception
    {
        testLabRead( TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID, false, 6 );
    }


    protected void testLabRead( String readTemplateId, boolean includeDates, int numExpectedElements )
        throws Exception
    {
        testLabRead( readTemplateId, includeDates, null, null, numExpectedElements );
    }


    protected void testLabRead( String readTemplateId, boolean includeDates, String startDate, String endDate, int numExpectedElements )
        throws Exception
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;
        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] hdrPatient = { "USVHA", "605", "test_sourceid_500" };

        String[][] patientIdentifiers = {hdrPatient };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );
        if ( includeDates )
        {
            entryPointFilterMap.put( FilterBuilder.START_DATE_KEY, ( startDate != null ) ? startDate : "1998-01-01" );
            entryPointFilterMap.put( FilterBuilder.END_DATE_KEY, ( endDate != null ) ? endDate : "2008-06-23" );
        }

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, numExpectedElements, null );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testLabChemHemRead_NoDates( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, PATIENT_IDENTITY_1 };
        String[] vistaPatient580 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_580, PATIENT_IDENTITY_2 };

        String[][] patientIdentifiers = { vistaPatient578, vistaPatient580 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        readAndAssertDomainData( readTemplateId, filterId, requestId, entryPointFilterMaps, resolvedPatients, 54, null );
    }


   // @SuppressWarnings( "unchecked" )
    //@Test
    //@Suite( groups = { "checkintest" } )
    public void testMHVLabRead40011WithExcludeIdentifiers( )
        throws Exception
    {
        String nationalId = "1237567890V123456";
        String readTemplateId = TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> excludeIdentifiers = getExcludeIdentifiers( ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578 );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithNationalIdAndExcludeIdentifiers( filterId, entryPointFilterMaps, nationalId,
                        excludeIdentifiers, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false );

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, readTemplateId );

        Element requestedExcludeIdentifiers = ( Element )clinicalDataDocument.selectSingleNode( XPATH_REQUESTEDEXCLUDEDINDETIFIERS_40011 );
        assertTrue( requestedExcludeIdentifiers.getText().contains( ASSIGNING_FACILITY_VISTA_578 ) );

        List<Element> labTestPromises = clinicalDataDocument.selectNodes( XPATH_DOMAINENTRYPOINT_40011 );
        assertTrue( labTestPromises.size() == 6 );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabRead40011_SingleSiteFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID;
        testSingleSiteFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_DISPLAYMSG );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabChemHemRead1_SingleSiteFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID;
        testSingleSiteFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_WARNING_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_FATALERROR_DISPLAYMSG );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testLabChemHemRead1_SingleSiteFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID;
        testSingleSiteFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_WARNING_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_FATALERROR_DISPLAYMSG );
    }


    @SuppressWarnings( "unchecked" )
    private void testSingleSiteFailure( String readTemplateId, String xpathWarningDisplayMessage, String xpathErrorDisplayMessage )
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, PATIENT_IDENTITY_1 };
        String[] vistaPatient503 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_503, PATIENT_IDENTITY_1 };

        String[][] patientIdentifiers = { vistaPatient578, vistaPatient503 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false );

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, readTemplateId );

        List<Element> warnings = clinicalDataDocument.selectNodes( xpathWarningDisplayMessage );
        Assert.assertEquals( 1, warnings.size() );

        List<Element> errors = clinicalDataDocument.selectNodes( xpathErrorDisplayMessage );
        Assert.assertEquals( 0, errors.size() );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabRead40011_AllSitesFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID;
        testAllSitesFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_DISPLAYMSG );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabChemHemRead1_AllSitesFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID;
        testAllSitesFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_WARNING_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_FATALERROR_DISPLAYMSG );
    }


    //@Test
    @Suite( groups = { "checkintest" } )
    public void testLabChemHemRead1_AllSitesFailure( )
        throws Exception
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID;
        testAllSitesFailure( readTemplateId, XPATH_ERRORSECTION_WARNINGS_WARNING_DISPLAYMSG, XPATH_ERRORSECTION_FATALERRORS_FATALERROR_DISPLAYMSG );
    }


    @SuppressWarnings( "unchecked" )
    private void testAllSitesFailure( String readTemplateId, String xpathWarningDisplayMessage, String xpathErrorDisplayMessage )
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient504 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_504, PATIENT_IDENTITY_1 };
        String[] vistaPatient503 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_503, PATIENT_IDENTITY_1 };

        String[][] patientIdentifiers = { vistaPatient504, vistaPatient503 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false );

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, readTemplateId );

        List<Element> warnings = clinicalDataDocument.selectNodes( xpathWarningDisplayMessage );
        Assert.assertEquals( 0, warnings.size() );

        List<Element> errors = clinicalDataDocument.selectNodes( xpathErrorDisplayMessage );
        Assert.assertEquals( 1, errors.size() );
    }


    //@Test
    @Suite( groups = { "timeouttest" } )
    public void testMHVLabRead40011WithTimeout( )
        throws Exception
    {
        testLabTimeout( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID );
    }


    //@Test
    @Suite( groups = { "timeouttest" } )
    public void testMHVLabChemHemRead1WithTimeout( )
        throws Exception
    {
        testLabTimeout( TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID );
    }


    //@Test
    @Suite( groups = { "timeouttest" } )
    public void testLabChemHemRead1WithTimeout( )
        throws Exception
    {
        testLabTimeout( TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID );
    }


    @SuppressWarnings( "unchecked" )
    protected void testLabTimeout( String readTemplateId )
        throws Exception
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;
        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, PATIENT_IDENTITY_1 };

        String[][] patientIdentifiers = { vistaPatient578 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );
        entryPointFilterMap.put( FilterBuilder.QUERY_TIMEOUT_SECONDS, QUERY_TIMOUT_SECONDS_MIN );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( true ); ///was false

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, readTemplateId );

        String xPathDisplayMessage = XPATH_ERRORSECTION_FATALERRORS_FATALERROR_DISPLAYMSG;
        if ( readTemplateId.equals( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID ) )
            xPathDisplayMessage = XPATH_ERRORSECTION_FATALERRORS_DISPLAYMSG;

        // Check for possible timeout error
        List<Element> errors = clinicalDataDocument.selectNodes( xPathDisplayMessage );
        assertEquals( 1, errors.size() );
        assertTrue( errors.get( 0 ).getText().contains( READ_REQUEST_TIMEOUT_ERROR_MSG ) );
    }


    @SuppressWarnings( "unchecked" )
    //@Test
    @Suite( groups = { "checkintest" } )
    public void testMHVLabChemHemRead1WithExcludeIdentifiers( )
        throws Exception
    {
        String nationalId = "1234567890V123456";
        String readTemplateId = TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> excludeIdentifiers = getExcludeIdentifiers( ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578 );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithNationalIdAndExcludeIdentifiers( filterId, entryPointFilterMaps, nationalId,
                        excludeIdentifiers, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false );

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, readTemplateId );

        Element requestedExcludeIdentifiers = ( Element )clinicalDataDocument.selectSingleNode( XPATH_REQUESTEDEXCLUDEDINDETIFIERS );
        assertTrue( requestedExcludeIdentifiers.getText().contains( ASSIGNING_FACILITY_VISTA_578 ) );

        List<Element> labTestPromises = clinicalDataDocument.selectNodes( XPATH_DOMAINENTRYPOINT );
        assertTrue( labTestPromises.size() == 7 );
    }



    //@Test
    //@Suite( groups = { "smoketest" } )
    public void testLabChemHemRead_NoDates_MARTSQA( )
        throws Exception
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "613", "201622" };//3 // Env 1
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "613", "2" };//62 // Env 1
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "613", "201475" };//3
        String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "613", "7207005" };//3
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "613", "201235" };//7 //Env 2
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "657", "33903" };16

        String[][] patientIdentifiers = { vistaPatient };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        //readAndAssertDomainData( TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null);
        readAndAssertDomainData( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null );
        readAndAssertDomainData( TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null );
    }


    //@Test
    //@Suite( groups = { "smoketest" } )
    public void testLabChemHemRead_NoDates_DNS   ( )
        throws Exception
    {
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;

        String requestId = TemplateIdHelper.getUniqueIdentifier();

        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "992", "7206589" };// SQA Env 1 - 4
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "992", "7206616" };// SQA Env 1 - 1
        //String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "992", "7206550" };// SQA Env 1 - 3
        String[] vistaPatient = { ASSIGNING_AUTHORITY_VISTA, "992", "7207005" };// SQA Env 1 - 3

        String[][] patientIdentifiers = { vistaPatient };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        //readAndAssertDomainData( TemplateIdHelper.MHV_LAB_CHEM_HEM_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null );
        readAndAssertDomainData( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null );
        readAndAssertDomainData( TemplateIdHelper.LAB_CHEM_HEM_READ_TEMPLATE_ID, filterId, requestId, entryPointFilterMaps, resolvedPatients, 3, null );
    }


    @SuppressWarnings( "unchecked" )
    private Document readAndAssertDomainData( String templateId, String filterId, String requestId, List<Map<String, String>> entryPointFilterMaps,
                    List<Map<String, String>> resolvedPatients, int numExpectedElements, String xPath )
        throws Exception
    {
        String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false );
        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( templateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        Assert.assertXmlValidation( clinicalDataXml, templateId );

        String xpathPatient = XPATH_PATIENT;
        String xpathResolvedIdentifiers = XPATH_RESOLVED_IDENTIFIERS;
        String xPathDomainEntryPoint = XPATH_DOMAINENTRYPOINT;

        if ( templateId.equals( TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID ) )
        {
            xpathPatient = XPATH_PATIENT_40011;
            xpathResolvedIdentifiers = XPATH_RESOLVED_IDENTIFIERS_40011;
            xPathDomainEntryPoint = XPATH_DOMAINENTRYPOINT_40011;
        }

        List<Element> errorSections = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION );
        assertTrue( errorSections.size() == 0 );

        // Check for domain entry point elements
        List<Element> domainElements = clinicalDataDocument.selectNodes( xpathPatient );
        assertTrue( domainElements.size() > 0 );

        // Assert that the resolved identifier assigning facility values from the filter are in the result document
        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( xpathResolvedIdentifiers );
        assertTrue( resultsResolvedIdentifiersList.size() == resolvedPatients.size() );
        for ( Element resultsResolvedIdentifiers : resultsResolvedIdentifiersList )
        {
            String resultsAssigningAuthority = resultsResolvedIdentifiers.element( ASSIGNING_AUTHORITY_ELEMENT_NAME ).getText();
            String resultsAssigningFacility = resultsResolvedIdentifiers.element( ASSIGNING_FACILITY_ELEMENT_NAME ).getText();
            String resultsPatientIdentity = resultsResolvedIdentifiers.element( PATIENT_IDENTITY_ELEMENT_NAME ).getText();

            Map<String, String> assigningAuthorityFacilityAndPatientIdentityMap = null;
            for ( Map<String, String> resolvedPatientMap : resolvedPatients )
            {
                String mapAssigningAuthority = resolvedPatientMap.get( FilterBuilder.ASSIGNING_AUTHORITY_KEY );
                String mapAssigningFacility = resolvedPatientMap.get( FilterBuilder.ASSIGNING_FACILITY );
                String mapIdentity = resolvedPatientMap.get( FilterBuilder.IDENTITY );
                if ( mapAssigningAuthority != null && mapAssigningAuthority.equalsIgnoreCase( resultsAssigningAuthority )
                                && mapAssigningFacility != null && mapAssigningFacility.equalsIgnoreCase( resultsAssigningFacility )
                                && mapIdentity != null && mapIdentity.equalsIgnoreCase( resultsPatientIdentity ) )
                {
                    assigningAuthorityFacilityAndPatientIdentityMap = resolvedPatientMap;
                    break;
                }
            }

            assertNotNull( assigningAuthorityFacilityAndPatientIdentityMap );
            String mapPatientIdentity = assigningAuthorityFacilityAndPatientIdentityMap.get( FilterBuilder.IDENTITY );
            assertNotNull( mapPatientIdentity );
            assertTrue( mapPatientIdentity.equals( resultsPatientIdentity ) );
        }

        List<Element> vsoeElements = clinicalDataDocument.selectNodes( xPathDomainEntryPoint );
        assertTrue( vsoeElements.size() == numExpectedElements );
        
        if ( null != xPath) 
        {
            List<Element> xpathElements = clinicalDataDocument.selectNodes( xPath );
            assertTrue( xpathElements.size() > 0 );
        }

        return clinicalDataDocument;
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testNonExistentTemplateResponse( )
    {
        String readTemplateId = "UnknownExampleTemplateName";
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;
        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, PATIENT_IDENTITY_1 };
        String[] vistaPatient503 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_503, PATIENT_IDENTITY_1 };

        String[][] patientIdentifiers = { vistaPatient578, vistaPatient503 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients,
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false ); /// was false

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        String assertMessage = "A non-existing templateId ('"
                        + readTemplateId
                        + "') was sent to the system.  The system should have returned a message containing the text: 'CANNOT_LOAD_TEMPLATE_METADATA'";
        assertTrue( assertMessage, clinicalDataXml.contains( "CANNOT_LOAD_TEMPLATE_METADATA" ) );

    }


    @SuppressWarnings( "unused" )
   //@Test
   //@Suite( groups = { "checkintest" } )
    public void testInvalidICNResponse( )
    {
        String readTemplateId = TemplateIdHelper.MHV_LAB_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.LAB_SINGLE_PATIENT_ALL_DATA_FILTER;
        String requestId = TemplateIdHelper.getUniqueIdentifier();

        String[] vistaPatient578 = { ASSIGNING_AUTHORITY_VISTA, ASSIGNING_FACILITY_VISTA_578, "79437494792478585" };

        String[][] patientIdentifiers = { vistaPatient578 };

        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterMap = new HashMap<String, String>();
        entryPointFilterMap.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "LabTestPromise" );
        entryPointFilterMap.put( FilterBuilder.QUERY_NAME_KEY, "testQueryName" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterMap );

        String filterXml = FilterBuilder.buildFilterWithNationalId( filterId, entryPointFilterMaps, "7943749479247",
                        DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        //String filterXml = FilterBuilder.buildFilterWithResolvedIdentfiers( filterId, entryPointFilterMaps, resolvedPatients, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) );

        templateRequestProcessor.setValidateReadResponseXML( false ); /// was false

        Document clinicalDataDocument = templateRequestProcessor.readClinicalData( readTemplateId, filterXml, filterId, requestId );
        assertNotNull( clinicalDataDocument );

        String clinicalDataXml = clinicalDataDocument.asXML();
        //TODO need to Spring inject this test with IDM STUB populated with identifiers - now it throws a null pointer
        //assertTrue( clinicalDataXml.contains( "NO_PATIENT_IDS_RESOLVED" ) );

    }

}
