

package gov.va.med.cds.filter;


import static org.junit.Assert.assertTrue;

import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xml.sax.SAXException;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;


@RunWith( SuiteAwareRunner.class )
public class FilterValidationTest
{

    private static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
    private static final String XML_GOOD_FILTER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><filter:filter vhimVersion=\"Test_Vhim_X_00\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><filterId>testFilterId</filterId><patients><resolvedIdentifiers><identity>testId-1</identity><assigningAuthority>AA1</assigningAuthority><assigningFacility>DNS   -605</assigningFacility></resolvedIdentifiers></patients><entryPointFilter queryName=\"intoleranceQuery\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><startDate>2006-01-01</startDate><endDate>2006-12-31</endDate><recordIdentifiers><identity>100</identity></recordIdentifiers><xpathQuery><xpath>TestXpath</xpath><parameter name=\"parameter1\"><value>TestValue1</value></parameter><parameter name=\"parameter2\"><value>TestValue2</value></parameter></xpathQuery></entryPointFilter><entryPointFilter queryName=\"IC-statusHistory\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><recordIdentifiers><identity>200</identity></recordIdentifiers><xpathQuery><xpath>intoleranceConditions[status='Status']</xpath></xpathQuery></entryPointFilter><correlationFilter queryName=\"combinedQuery\"><xpathQuery><xpath>TestCorrelationXpath</xpath><parameter name=\"parameter3\"><value>TestValue3</value></parameter></xpathQuery></correlationFilter></filter:filter>";
    private static final String XML_BAD_FILTER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><filter:filter vhimVersion=\"Test_Vhim_X_00\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><!-- <filterId>testFilterId</filterId> --><patients><resolvedIdentifiers><identity>testId-1</identity><assigningAuthority>AA1</assigningAuthority><assigningFacility>DNS   -605</assigningFacility></resolvedIdentifiers></patients><entryPointFilter queryName=\"intoleranceQuery\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><startDate>2006-01-01</startDate><endDate>2006-12-31</endDate><recordIdentifiers><identity>100</identity></recordIdentifiers><xpathQuery><xpath>TestXpath</xpath><parameter name=\"parameter1\"><value>TestValue1</value></parameter><parameter name=\"parameter2\"><value>TestValue2</value></parameter></xpathQuery></entryPointFilter><entryPointFilter queryName=\"IC-statusHistory\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><recordIdentifiers><identity>200</identity></recordIdentifiers><xpathQuery><xpath>intoleranceConditions[status='Status']</xpath></xpathQuery></entryPointFilter><correlationFilter queryName=\"combinedQuery\"><xpathQuery><xpath>TestCorrelationXpath</xpath><parameter name=\"parameter3\"><value>TestValue3</value></parameter></xpathQuery></correlationFilter></filter:filter>";
    private static final String XML_BAD_FILTER_CLIENTNAME = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><filter:filter vhimVersion=\"Test_Vhim_X_00\" xmlns:filter=\"Filter\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><filterId>testFilterId</filterId><clientName>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</clientName><patients><resolvedIdentifiers><identity>testId-1</identity><assigningAuthority>AA1</assigningAuthority><assigningFacility>DNS   -605</assigningFacility></resolvedIdentifiers></patients><entryPointFilter queryName=\"intoleranceQuery\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><startDate>2006-01-01</startDate><endDate>2006-12-31</endDate><recordIdentifiers><identity>100</identity></recordIdentifiers><xpathQuery><xpath>TestXpath</xpath><parameter name=\"parameter1\"><value>TestValue1</value></parameter><parameter name=\"parameter2\"><value>TestValue2</value></parameter></xpathQuery></entryPointFilter><entryPointFilter queryName=\"IC-statusHistory\"><domainEntryPoint>IntoleranceCondition</domainEntryPoint><recordIdentifiers><identity>200</identity></recordIdentifiers><xpathQuery><xpath>intoleranceConditions[status='Status']</xpath></xpathQuery></entryPointFilter><correlationFilter queryName=\"combinedQuery\"><xpathQuery><xpath>TestCorrelationXpath</xpath><parameter name=\"parameter3\"><value>TestValue3</value></parameter></xpathQuery></correlationFilter></filter:filter>";
    private static final String CDS_FILTER_XSD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:vhimversion=\"Vhimversion\" xmlns:filter=\"Filter\" targetNamespace=\"Filter\"><!--imports for all non target name spaces--><!-- global definition --><xs:element name=\"filter\" type=\"filter:Filter\"/><!--type definitions--><xs:complexType name=\"Filter\"><xs:sequence><xs:element name=\"filterId\" type=\"filter:FilterId\"/><xs:element name=\"clientName\" minOccurs=\"0\"><xs:simpleType><xs:restriction base=\"xs:string\"><xs:maxLength value=\"100\"/></xs:restriction></xs:simpleType></xs:element><xs:element name=\"patients\" type=\"filter:patient\" maxOccurs=\"unbounded\"/><xs:element name=\"entryPointFilter\" type=\"filter:EntryFilter\" maxOccurs=\"unbounded\"/><xs:element name=\"correlationFilter\" type=\"filter:CorrelationFilter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/><xs:element name=\"aggregationFilter\" type=\"filter:CorrelationFilter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/></xs:sequence><xs:attribute name=\"vhimVersion\" type=\"xs:string\" use=\"required\"/></xs:complexType><xs:complexType name=\"patient\"><xs:choice><xs:element name=\"resolvedIdentifiers\" type=\"filter:PersonIdentifier\" maxOccurs=\"unbounded\"/><xs:sequence><xs:element name=\"NationalId\" type=\"xs:string\"/><xs:element name=\"excludeIdentifiers\" type=\"filter:PersonIdentifier\" minOccurs=\"0\" maxOccurs=\"unbounded\"/></xs:sequence></xs:choice></xs:complexType><xs:complexType name=\"PersonIdentifier\"><xs:sequence><xs:element name=\"identity\" type=\"xs:string\"/><xs:element name=\"assigningAuthority\" type=\"xs:string\"/><xs:element name=\"assigningFacility\" type=\"xs:string\"/></xs:sequence></xs:complexType><xs:complexType name=\"EntityIdentifier\"><xs:sequence><xs:element name=\"identity\" type=\"xs:string\" minOccurs=\"0\"/><xs:element name=\"namespaceId\" type=\"xs:string\" default=\"VHA\" minOccurs=\"0\"/><xs:element name=\"universalId\" type=\"xs:string\" minOccurs=\"0\"/><xs:element name=\"universalIdType\" type=\"xs:string\" minOccurs=\"0\"/></xs:sequence></xs:complexType><xs:complexType name=\"EntryFilter\"><xs:sequence><xs:element name=\"domainEntryPoint\" type=\"xs:string\"/><xs:element name=\"startDate\" type=\"filter:DateParameter\" minOccurs=\"0\"/><xs:element name=\"endDate\" type=\"filter:DateParameter\" minOccurs=\"0\"/><xs:element name=\"recordIdentifiers\" type=\"filter:EntityIdentifier\" minOccurs=\"0\" maxOccurs=\"unbounded\"/><xs:element name=\"xpathQuery\" type=\"filter:XpathQuery\" minOccurs=\"0\"/></xs:sequence><xs:attribute name=\"queryName\" type=\"xs:ID\" use=\"required\"/></xs:complexType><xs:complexType name=\"CorrelationFilter\"><xs:sequence><xs:element name=\"xpathQuery\" type=\"filter:XpathQuery\"/></xs:sequence><xs:attribute name=\"queryName\" use=\"required\"/></xs:complexType><xs:complexType name=\"XpathQuery\"><xs:sequence><xs:element name=\"xpath\" type=\"filter:XPath\"/><xs:element name=\"parameter\" type=\"filter:Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/></xs:sequence></xs:complexType><xs:simpleType name=\"DateParameter\"><xs:restriction base=\"xs:date\"/></xs:simpleType><xs:complexType name=\"Parameter\"><xs:all><xs:element name=\"value\"><xs:simpleType><xs:restriction base=\"xs:string\"/></xs:simpleType></xs:element></xs:all><xs:attribute name=\"name\" use=\"required\"/><xs:attribute name=\"type\"/></xs:complexType><xs:simpleType name=\"XPath\"><xs:restriction base=\"xs:string\"/></xs:simpleType><xs:simpleType name=\"FilterId\"><xs:restriction base=\"xs:string\"/></xs:simpleType></xs:schema>";
    
   
    private static Schema schema = null;
    private InputStream xmlResource = null;
    private Source schemaSource = null;
    private static InputStream filterSchemaSource = null;


    @Test
    @Suite( groups = { "checkintest" } )
    public void testGoodFilter( )
        throws Exception
    {
        xmlResource = new ByteArrayInputStream( XML_GOOD_FILTER.getBytes() );
        schemaSource = new StreamSource( xmlResource );

        // Validates the specified input
        schema.newValidator().validate( schemaSource );
        assertTrue( true );
    }


    @Test( expected = SAXException.class )
    @Suite( groups = { "checkintest" } )
    public void testBadFilter( )
        throws Exception
    {
        xmlResource = new ByteArrayInputStream( XML_BAD_FILTER.getBytes() );
        schemaSource = new StreamSource( xmlResource );

        // if validation fails, Validator throws SAXException
        schema.newValidator().validate( schemaSource );
    }
    
    
    @Test( expected = SAXException.class )
    @Suite( groups = { "checkintest" } )
    public void testBadFilterClientName( )
        throws Exception
    {
        xmlResource = new ByteArrayInputStream( XML_BAD_FILTER_CLIENTNAME.getBytes() );
        schemaSource = new StreamSource( xmlResource );

        // if validation fails, Validator throws SAXException
        schema.newValidator().validate( schemaSource );
    }


    @BeforeClass
    @Suite( groups = { "checkintest" } )
    public static void beforeFilterValidationTestClassSetUp( )
        throws Exception
    {
        // Obtain schema object
        SchemaFactory schemaFactory = SchemaFactory.newInstance( W3C_XML_SCHEMA_NS_URI );
        filterSchemaSource = new ByteArrayInputStream( CDS_FILTER_XSD.getBytes() );
        StreamSource ss = new StreamSource( filterSchemaSource );
        schema = schemaFactory.newSchema( ss );
    }


    @AfterClass
    @Suite( groups = { "checkintest" } )
    public static void afterFilterValidationTestClassTearDown( )
        throws Exception
    {
        filterSchemaSource = null;
        schema = null;
    }
}
