code: /*******************************************************************************
   * Copyright 2018 572682
   * 
   * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
   * License for the specific language governing permissions and limitations under
   * the License.
   ******************************************************************************/
  package us.dot.its.jpo.ode.wrapper;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.fail;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.net.URI;
  import java.net.UnknownHostException;
  import java.util.Collections;
  import java.util.Locale;
  import java.util.Map;
  
  import javax.net.ssl.SSLContext;
  import javax.ws.rs.core.Response;
  
  import org.apache.http.Header;
  import org.apache.http.HeaderIterator;
  import org.apache.http.HttpEntity;
  import org.apache.http.HttpStatus;
  import org.apache.http.ProtocolVersion;
  import org.apache.http.StatusLine;
  import org.apache.http.client.methods.CloseableHttpResponse;
  import org.apache.http.client.methods.HttpUriRequest;
  import org.apache.http.client.methods.RequestBuilder;
  import org.apache.http.entity.BasicHttpEntity;
  import org.apache.http.impl.client.CloseableHttpClient;
  import org.apache.http.message.BasicStatusLine;
  import org.apache.http.params.HttpParams;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  
  import mockit.Expectations;
  import mockit.Mocked;
  //import mockit.integration.junit4.JMockit;
  import us.dot.its.jpo.ode.wrapper.HttpClientFactory.HttpClient;
  import us.dot.its.jpo.ode.wrapper.HttpClientFactory.HttpException;
  import us.dot.its.jpo.ode.wrapper.HttpClientFactory.HttpResponse;
  
  @SuppressWarnings("deprecation")
  //@RunWith(JMockit.class)
  public class HttpClientTest {
  
     @Mocked
     SSLContext sslContext;
     
     @Mocked
     CloseableHttpClient closeableHttpClient;
  
     @Test @Ignore
     public void testGet() throws Exception {
        { // BEGIN Happy Path
           URI uri = new URI("http://ip:port/path");
           final String headerKey = "headerKey";
           final String headerValue = "headerValue";
           String paramKey = "paramKey";
           String paramValue = "paramValue";
           String entityContent = "entityContent";
           
           final MockCloseableHttpResponse closeableresponse = new MockCloseableHttpResponse();
           closeableresponse.setStatusLine(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 
                 HttpStatus.SC_OK, "SUCCESS"));
           BasicHttpEntity entity = new BasicHttpEntity();
           entity.setContent(new ByteArrayInputStream(entityContent.getBytes()));
           closeableresponse.setEntity(entity);
           final HttpUriRequest request = RequestBuilder
                 .get(uri)
                 .addHeader(headerKey, headerValue)
                 .addParameter(paramKey, paramValue)
                 .build();
           
           new Expectations() {{
              // Note: withAny returns the request,, that's why object instance
              ///      is passed rather than a type.
              closeableHttpClient.execute(withAny(request)); result = closeableresponse;
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           HttpResponse response = client.get(uri.toString(), 
                 Collections.singletonMap(headerKey, headerValue), 
                 Collections.singletonMap(paramKey, paramValue));
           
           assertEquals(entityContent, response.getBody());
           assertEquals(Response.Status.OK, response.getStatusCode());
           
           closeableresponse.close();
  
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            assertEquals(request.toString(), captured.toString());
  //            
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(1, capturedHeaders.length);
  //            assertEquals(headerKey, capturedHeaders[0].getName());
  //            assertEquals(headerValue, capturedHeaders[0].getValue());
  //         }};
        }// END Happy Path
  
        { // BEGIN simulating a bad request
           final MockCloseableHttpResponse closeableresponse = new MockCloseableHttpResponse();
           closeableresponse.setStatusLine(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 
                 HttpStatus.SC_BAD_REQUEST, "FAILURE"));
           BasicHttpEntity entity = new BasicHttpEntity();
           entity.setContent(new ByteArrayInputStream("".getBytes()));
           closeableresponse.setEntity(entity);
           final HttpUriRequest request = RequestBuilder.get().build();
           
           new Expectations() {{
              closeableHttpClient.execute(withAny(request)); result = closeableresponse;
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           HttpResponse response = client.get(null, null, null);
           
           assertEquals("", response.getBody());
           assertEquals(Response.Status.BAD_REQUEST, response.getStatusCode());
           
           closeableresponse.close();
           
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            
  //            assertEquals(request.toString(), captured.toString());
  //
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(0, capturedHeaders.length);
  //         }};
        }// END simulating a bad request
  
        { // BEGIN execute throws exception
           final HttpUriRequest request = RequestBuilder.get().build();
           
           new Expectations() {{
              closeableHttpClient.execute(withAny(request)); result = new IOException();
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           try {
              client.get(null, null, null);
              fail("Exception was aexpected.");
           } catch (HttpException e) {
              
           } catch (Exception e) {
              fail("Unexpected Exception." + e);
           }
           
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            
  //            assertEquals(request.toString(), captured.toString());
  //
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(0, capturedHeaders.length);
  //         }};
        }// END execute throws exception
     }
  
     @Test @Ignore
     public void testPost() throws Exception {
        { // BEGIN Happy Path
           URI uri = new URI("http://ip:port/path");
           final String headerKey = "headerKey";
           final String headerValue = "headerValue";
           String paramKey = "paramKey";
           String paramValue = "paramValue";
           String entityContent = "entityContent";
           
           final MockCloseableHttpResponse closeableresponse = new MockCloseableHttpResponse();
           closeableresponse.setStatusLine(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 
                 HttpStatus.SC_OK, "SUCCESS"));
           BasicHttpEntity entity = new BasicHttpEntity();
           entity.setContent(new ByteArrayInputStream(entityContent.getBytes()));
           closeableresponse.setEntity(entity);
           
           final HttpUriRequest request = RequestBuilder.post(uri)
                 .addHeader(headerKey, headerValue)
                 .addParameter(paramKey, paramValue)
                 .setEntity(entity)
                 .build();
           
           new Expectations() {{
              // Note: withAny returns the request,, that's why object instance
              ///      is passed rather than a type.
              closeableHttpClient.execute(withAny(request)); result = closeableresponse;
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           HttpResponse response = client.post(uri.toString(), 
                 Collections.singletonMap(headerKey, headerValue), 
                 Collections.singletonMap(paramKey, paramValue),
                 entityContent);
           
           assertEquals(entityContent, response.getBody());
           assertEquals(Response.Status.OK, response.getStatusCode());
           
           closeableresponse.close();
  
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            assertEquals(request.toString(), captured.toString());
  //            
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(1, capturedHeaders.length);
  //            assertEquals(headerKey, capturedHeaders[0].getName());
  //            assertEquals(headerValue, capturedHeaders[0].getValue());
  //         }};
        }// END Happy Path
  
        { // BEGIN simulating a bad request
           final MockCloseableHttpResponse closeableresponse = new MockCloseableHttpResponse();
           closeableresponse.setStatusLine(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 
                 HttpStatus.SC_BAD_REQUEST, "FAILURE"));
           BasicHttpEntity entity = new BasicHttpEntity();
           entity.setContent(new ByteArrayInputStream("".getBytes()));
           closeableresponse.setEntity(entity);
           final HttpUriRequest request = RequestBuilder.post().build();
           
           new Expectations() {{
              closeableHttpClient.execute(withAny(request)); result = closeableresponse;
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           HttpResponse response = client.post(null, null, null, null);
           
           assertEquals("", response.getBody());
           assertEquals(Response.Status.BAD_REQUEST, response.getStatusCode());
           
           closeableresponse.close();
           
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            
  //            assertEquals(request.toString(), captured.toString());
  //
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(0, capturedHeaders.length);
  //         }};
        }// END simulating a bad request
  
        { // BEGIN execute throws exception
           final HttpUriRequest request = RequestBuilder.post().build();
           
           new Expectations() {{
              closeableHttpClient.execute(withAny(request)); result = new IOException();
           }};
  
           HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
  
           try {
              client.post(null, null, null, null);
              fail("Exception was aexpected.");
           } catch (HttpException e) {
              
           } catch (Exception e) {
              fail("Unexpected Exception." + e);
           }
           
  //         new Verifications() {{
  //            HttpUriRequest captured;
  //            closeableHttpClient.execute(captured = withCapture());
  //            
  //            assertEquals(request.toString(), captured.toString());
  //
  //            Header[] capturedHeaders = captured.getAllHeaders();
  //            assertEquals(0, capturedHeaders.length);
  //         }};
        }// END execute throws exception
     }
  
     @Test
     public void testGetCookies() throws HttpException {
        HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
        Map<String, String> cookies = client.getCookies();
        
        // Not much can be tested here.
        assertEquals(0, cookies.size());
     }
  
     @Test
     public void testClose() throws Exception {
        HttpClient client = HttpClientFactory.build(sslContext).createHttpClient();
        
        // Not much can be tested here. If no exception is thrown, test is PASSed
        client.close();
     }
  
     class MockCloseableHttpResponse implements CloseableHttpResponse {
        private StatusLine statusLine;
        private HttpEntity entity;
  
        
        @Override
        public StatusLine getStatusLine() {
           return statusLine;
        }
  
        @Override
        public void setStatusLine(StatusLine statusLine) {
           this.statusLine = statusLine;
        }
  
        @Override
        public HttpEntity getEntity() {
           return entity;
        }
  
        @Override
        public void setEntity(HttpEntity entity) {
           this.entity = entity;
        }
  
        @Override
        public void setStatusLine(ProtocolVersion ver, int code) {
        }
  
        @Override
        public void setStatusLine(ProtocolVersion ver, int code, String reason) {
        }
  
        @Override
        public void setStatusCode(int code) throws IllegalStateException {
        }
  
        @Override
        public void setReasonPhrase(String reason) throws IllegalStateException {
        }
  
        @Override
        public Locale getLocale() {
           return null;
        }
  
        @Override
        public void setLocale(Locale loc) {
        }
  
        @Override
        public ProtocolVersion getProtocolVersion() {
           return null;
        }
  
        @Override
        public boolean containsHeader(String name) {
           return false;
        }
  
        @Override
        public Header[] getHeaders(String name) {
           return null;
        }
  
        @Override
        public Header getFirstHeader(String name) {
           return null;
        }
  
        @Override
        public Header getLastHeader(String name) {
           return null;
        }
  
        @Override
        public Header[] getAllHeaders() {
           return null;
        }
  
        @Override
        public void addHeader(Header header) {
        }
  
        @Override
        public void addHeader(String name, String value) {
        }
  
        @Override
        public void setHeader(Header header) {
        }
  
        @Override
        public void setHeader(String name, String value) {
        }
  
        @Override
        public void setHeaders(Header[] headers) {
        }
  
        @Override
        public void removeHeader(Header header) {
        }
  
        @Override
        public void removeHeaders(String name) {
        }
  
        @Override
        public HeaderIterator headerIterator() {
           return null;
        }
  
        @Override
        public HeaderIterator headerIterator(String name) {
           return null;
        }
  
        @Override
        public HttpParams getParams() {
           return null;
        }
  
        @Override
        public void setParams(HttpParams params) {
        }
  
        @Override
        public void close() throws IOException {
        }
        
     }
  }
  