### Question:
RetryAfterHeaderInterval implements RetryInterval { @Override public long getInterval(final RetryContext retryContext) { return retryContext.getResponse() .map(response -> response.headers() .stream() .filter(header -> RETRY_AFTER_HEADER.equalsIgnoreCase(header.name()) && header.values() != null && !header.values().isEmpty()) .map(header -> { String headerValue = header.values().iterator().next(); return determineInterval(headerValue); }) .filter(Objects::nonNull) .findFirst() .orElse(fallback.getInterval(retryContext))) .orElseGet(() -> this.fallback.getInterval(retryContext)); } RetryAfterHeaderInterval(RetryInterval fallback); @Override long getInterval(final RetryContext retryContext);  }### Answer:
@Test void shouldReturnDelay_withRetryHeader_inSeconds() { Response response = mock(Response.class); when(response.headers()).thenReturn( Collections.singletonList( new HttpHeader("Retry-After", Collections.singletonList("120")))); RetryContext context = new RetryContext(1, null, response); long result = this.interval.getInterval(context); assertThat(result).isEqualTo(TimeUnit.SECONDS.toMillis(120)); }
@Test void shouldReturnDelay_withRetryHeader_inHttpDate() { String retryDate = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(120)); Response response = mock(Response.class); when(response.headers()).thenReturn( Collections.singletonList( new HttpHeader("Retry-After", Collections.singletonList(retryDate)))); RetryContext context = new RetryContext(1, null, response); long result = this.interval.getInterval(context); assertThat(result).isCloseTo( TimeUnit.SECONDS.toMillis(120), Percentage.withPercentage(1)); }
@Test void shouldReturnDelay_fromDefault_withoutHeader() { Response response = mock(Response.class); RetryContext context = new RetryContext(1, null, response); long result = this.interval.getInterval(context); assertThat(result).isEqualTo(1000L); verify(fallback, times(1)).getInterval(any(RetryContext.class)); }
@Test void shouldReturnDelay_fromDefault_ifHeaderHasNoValue () { Response response = mock(Response.class); when(response.headers()).thenReturn( Collections.singletonList( new HttpHeader("Retry-After", Collections.emptyList()))); RetryContext context = new RetryContext(1, null, response); long result = this.interval.getInterval(context); assertThat(result).isEqualTo(1000L); verify(fallback, times(1)).getInterval(any(RetryContext.class)); }
@Test void shouldReturnDelay_fromDefault_onParsingDateError() { Response response = mock(Response.class); when(response.headers()).thenReturn( Collections.singletonList( new HttpHeader("Retry-After", Collections.singletonList("Not A Date")))); RetryContext context = new RetryContext(1, null, response); long result = this.interval.getInterval(context); assertThat(result).isEqualTo(1000L); verify(fallback, times(1)).getInterval(any(RetryContext.class)); }