public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
   if (delegate != null) {
     T body = delegate.extractData(response);
     return new ResponseEntity<T>(body, response.getHeaders(), response.getStatusCode());
   } else {
     return new ResponseEntity<T>(response.getHeaders(), response.getStatusCode());
   }
 }
  @Test
  public void informational() throws IOException {
    HttpMessageConverter<?> converter = mock(HttpMessageConverter.class);
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.CONTINUE);

    Object result = extractor.extractData(response);

    assertNull(result);
  }
  public void testNotModified() throws IOException {
    HttpMessageConverter<?> converter = mock(HttpMessageConverter.class);
    extractor =
        new HttpMessageConverterExtractor<String>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.NOT_MODIFIED);

    Object result = extractor.extractData(response);

    assertNull(result);
  }
  @Test
  public void zeroContentLength() throws IOException {
    HttpMessageConverter<?> converter = mock(HttpMessageConverter.class);
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentLength(0);
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);

    Object result = extractor.extractData(response);

    assertNull(result);
  }
  @Test
  @SuppressWarnings("unchecked")
  public void emptyMessageBody() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    HttpHeaders responseHeaders = new HttpHeaders();
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(response.getBody()).willReturn(new ByteArrayInputStream("".getBytes()));

    Object result = extractor.extractData(response);
    assertNull(result);
  }
  @Test
  @SuppressWarnings("unchecked")
  public void cannotRead() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(response.getBody()).willReturn(new ByteArrayInputStream("Foobar".getBytes()));
    given(converter.canRead(String.class, contentType)).willReturn(false);
    exception.expect(RestClientException.class);

    extractor.extractData(response);
  }
  @Test
  @SuppressWarnings("unchecked")
  public void normal() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    String expected = "Foo";
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(response.getBody()).willReturn(new ByteArrayInputStream(expected.getBytes()));
    given(converter.canRead(String.class, contentType)).willReturn(true);
    given(converter.read(eq(String.class), any(HttpInputMessage.class))).willReturn(expected);

    Object result = extractor.extractData(response);

    assertEquals(expected, result);
  }
  @SuppressWarnings("unchecked")
  public void testNormal() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(converter);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    String expected = "Foo";
    extractor = new HttpMessageConverterExtractor<String>(String.class, converters);
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(converter.canRead(String.class, contentType)).willReturn(true);
    given(converter.read(String.class, response)).willReturn(expected);

    Object result = extractor.extractData(response);

    assertEquals(expected, result);
  }
  @Test // SPR-13592
  @SuppressWarnings("unchecked")
  public void converterThrowsIOException() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    extractor = new HttpMessageConverterExtractor<>(String.class, createConverterList(converter));
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(response.getBody()).willReturn(new ByteArrayInputStream("Foobar".getBytes()));
    given(converter.canRead(String.class, contentType)).willThrow(IOException.class);
    exception.expect(RestClientException.class);
    exception.expectMessage(
        "Error while extracting response for type "
            + "[class java.lang.String] and content type [text/plain]");
    exception.expectCause(Matchers.instanceOf(IOException.class));

    extractor.extractData(response);
  }
  @SuppressWarnings("unchecked")
  public void testCannotRead() throws IOException {
    HttpMessageConverter<String> converter = mock(HttpMessageConverter.class);
    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(converter);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    extractor = new HttpMessageConverterExtractor<String>(String.class, converters);
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(converter.canRead(String.class, contentType)).willReturn(false);

    try {
      extractor.extractData(response);
      fail("RestClientException expected");
    } catch (RestClientException expected) {
      // expected
    }
  }
  @SuppressWarnings("unchecked")
  public void testGenerics() throws IOException {
    GenericHttpMessageConverter<String> converter = mock(GenericHttpMessageConverter.class);
    List<HttpMessageConverter<?>> converters = createConverterList(converter);
    HttpHeaders responseHeaders = new HttpHeaders();
    MediaType contentType = MediaType.TEXT_PLAIN;
    responseHeaders.setContentType(contentType);
    String expected = "Foo";
    ParameterizedTypeReference<List<String>> reference =
        new ParameterizedTypeReference<List<String>>() {};
    Type type = reference.getType();
    extractor = new HttpMessageConverterExtractor<List<String>>(type, converters);
    given(response.getStatusCode()).willReturn(HttpStatus.OK);
    given(response.getHeaders()).willReturn(responseHeaders);
    given(converter.canRead(type, null, contentType)).willReturn(true);
    given(converter.read(type, null, response)).willReturn(expected);

    Object result = extractor.extractData(response);

    assertEquals(expected, result);
  }