

package gov.va.med.repositories.fpds.interceptor;


import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

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

import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;

import org.apache.cxf.feature.transform.XSLTOutInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.junit.BeforeClass;
import org.junit.Test;


public class RoutingXsltOutInterceptorTest
{

    private static RoutingXsltOutInterceptor interceptor = null;


    @BeforeClass
    public static void setUpBeforeClass( )
        throws Exception
    {
        interceptor = new RoutingXsltOutInterceptor();

    }


    //@Test
    public void testHandleMessageBasicJson( )
    {
        
        Message message = mock( Message.class );
        Message inMessage = mock( Message.class );
        Exchange exchange = mock( Exchange.class );
        List contentList = mock(List.class);
        UriInfo uriInfo = mock(UriInfo.class);
        MultivaluedMap queryParams = mock(MultivaluedMap.class);
        Map<String, XSLTOutInterceptor> outInterceptors = mock(Map.class);
        XSLTOutInterceptor jsonInterceptor = mock(XSLTOutInterceptor.class);
        
        when(message.getExchange()).thenReturn( exchange );
        when(exchange.getInMessage()).thenReturn( inMessage );
        when(inMessage.getContent( List.class )).thenReturn( contentList );
        when(contentList.get( -1 )).thenReturn(uriInfo);
        when(uriInfo.getQueryParameters()).thenReturn( queryParams );
        when(queryParams.getFirst( "_type" )).thenReturn( "json" );
        when(outInterceptors.get( null )).thenReturn( jsonInterceptor );
        jsonInterceptor.handleFault( message );

        interceptor.setOutInterceptorsInternal( outInterceptors );
        interceptor.handleMessage( message );
        
        verify(jsonInterceptor, times(1)).handleMessage( message );
    }
    
    //@Test
    public void testHandleMessageNoTypeSpecifiedJson( )
    {
        
        Message message = mock( Message.class );
        Message inMessage = mock( Message.class );
        Exchange exchange = mock( Exchange.class );
        List contentList = mock(List.class);
        UriInfo uriInfo = mock(UriInfo.class);
        MultivaluedMap queryParams = mock(MultivaluedMap.class);
        Map<String, XSLTOutInterceptor> outInterceptors = mock(Map.class);
        XSLTOutInterceptor jsonInterceptor = mock(XSLTOutInterceptor.class);
        
        when(message.getExchange()).thenReturn( exchange );
        when(exchange.getInMessage()).thenReturn( inMessage );
        when(inMessage.getContent( List.class )).thenReturn( contentList );
        when(contentList.get( -1 )).thenReturn(uriInfo);
        when(uriInfo.getQueryParameters()).thenReturn( queryParams );
        when(queryParams.getFirst( "_type" )).thenReturn( null );
        when(outInterceptors.get( null )).thenReturn( jsonInterceptor );
        jsonInterceptor.handleFault( message );

        interceptor.setOutInterceptorsInternal( outInterceptors );
        interceptor.handleMessage( message );
        
        verify(jsonInterceptor, times(1)).handleMessage( message );
    }
    
    //@Test
    public void testHandleMessageBasicXml( )
    {
        
        Message message = mock( Message.class );
        Message inMessage = mock( Message.class );
        Exchange exchange = mock( Exchange.class );
        List contentList = mock(List.class);
        UriInfo uriInfo = mock(UriInfo.class);
        MultivaluedMap queryParams = mock(MultivaluedMap.class);
        Map<String, XSLTOutInterceptor> outInterceptors = mock(Map.class);
        XSLTOutInterceptor jsonInterceptor = mock(XSLTOutInterceptor.class);
        
        when(message.getExchange()).thenReturn( exchange );
        when(exchange.getInMessage()).thenReturn( inMessage );
        when(inMessage.getContent( List.class )).thenReturn( contentList );
        when(contentList.get( -1 )).thenReturn(uriInfo);
        when(uriInfo.getQueryParameters()).thenReturn( queryParams );
        when(queryParams.getFirst( "_type" )).thenReturn( "xml" );
        
        interceptor.setOutInterceptorsInternal( outInterceptors );
        interceptor.handleMessage( message );
        
        verify(jsonInterceptor, times(0)).handleMessage( message );
    }
    
    //@Test
    public void testHandleMessageBasicFault( )
    {
        
        Message message = mock( Message.class );
        Message inMessage = mock( Message.class );
        Exchange exchange = mock( Exchange.class );
        List contentList = mock(List.class);
        UriInfo uriInfo = mock(UriInfo.class);
        MultivaluedMap queryParams = mock(MultivaluedMap.class);
        Map<String, XSLTOutInterceptor> outInterceptors = mock(Map.class);
        XSLTOutInterceptor jsonInterceptor = mock(XSLTOutInterceptor.class);
        
        when(message.getExchange()).thenReturn( exchange );
        when(exchange.getInMessage()).thenReturn( inMessage );
        when(inMessage.getContent( List.class )).thenReturn( contentList );
        when(contentList.get( -1 )).thenThrow( ClassCastException.class );
        
        
        interceptor.setOutInterceptorsInternal( outInterceptors );
        interceptor.handleMessage( message );
    }


    //@Test
    public void testSetOutInterceptors( )
    {
        Map<String, String> interceptorConfig = new HashMap<String, String>();
        interceptorConfig.put( "json", "templates/response/GenericObservationRead1-json.xsl" );

        interceptor.setOutInterceptors( interceptorConfig );
    }


    //@Test
    public void testSetMultipleOutInterceptors( )
    {
        Map<String, String> interceptorConfig = new HashMap<String, String>();
        interceptorConfig.put( "json1", "templates/response/GenericObservationRead1-json.xsl" );
        interceptorConfig.put( "json2", "templates/response/GenericObservationRead1-json.xsl" );
        interceptorConfig.put( "json3", "templates/response/GenericObservationRead1-json.xsl" );

        interceptor.setOutInterceptors( interceptorConfig );
    }


    //@Test( expected = IllegalArgumentException.class )
    public void testSetOutInterceptorsBadXsltPath( )
    {
        Map<String, String> interceptorConfig = new HashMap<String, String>();
        interceptorConfig.put( "json", "templates/BAD/GenericObservationRead1-json.xsl" );

        interceptor.setOutInterceptors( interceptorConfig );
    }

}
