package uk.ac.ic.wlgitbridge.bridge.resource;

import com.ning.http.client.HttpResponseHeaders;
import org.junit.Test;
import uk.ac.ic.wlgitbridge.bridge.db.noop.NoopDbStore;
import uk.ac.ic.wlgitbridge.bridge.util.CastUtil;
import uk.ac.ic.wlgitbridge.git.exception.SizeLimitExceededException;
import uk.ac.ic.wlgitbridge.io.http.ning.NingHttpClientFacade;
import uk.ac.ic.wlgitbridge.io.http.ning.NingHttpHeaders;
import uk.ac.ic.wlgitbridge.util.FunctionT;

import java.io.IOException;
import java.util.HashMap;
import java.util.Optional;
import java.util.concurrent.ExecutionException;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class UrlResourceCacheTest {

    private static String PROJ = "proj";

    private static String URL = "http://localhost/file.jpg";

    private static String NEW_PATH = "file1.jpg";

    private final NingHttpClientFacade http = mock(NingHttpClientFacade.class);

    private final UrlResourceCache cache
            = new UrlResourceCache(new NoopDbStore(), http);

    private static HttpResponseHeaders withContentLength(long cl) {
        return NingHttpHeaders
                .builder()
                .addHeader("Content-Length", String.valueOf(cl))
                .build();
    }

    private void respondWithContentLength(long cl) throws ExecutionException {
        when(http.get(any(), any())).thenAnswer(invoc -> {
            Object[] args = invoc.getArguments();
            //noinspection unchecked
            ((FunctionT<
                    HttpResponseHeaders, Boolean, SizeLimitExceededException
            >) args[1]).apply(withContentLength(cl));
            return new byte[CastUtil.assumeInt(cl)];
        });
    }

    private void getWithMaxLength(long max)
            throws IOException, SizeLimitExceededException {
        cache.get(
                PROJ, URL, NEW_PATH,
                new HashMap<>(), new HashMap<>(),
                Optional.of(max)
        );
    }

    @Test
    public void getDoesNotThrowWhenContentLengthLT() throws Exception {
        respondWithContentLength(1);
        getWithMaxLength(2);
    }

    @Test
    public void getDoesNotThrowWhenContentLengthEQ() throws Exception {
        respondWithContentLength(2);
        getWithMaxLength(2);
    }

    @Test (expected = SizeLimitExceededException.class)
    public void getThrowsSizeLimitExceededWhenContentLengthGT()
            throws Exception {
        respondWithContentLength(3);
        getWithMaxLength(2);
    }

    @Test
    public void getWithEmptyContentIsValid() throws Exception {
        respondWithContentLength(0);
        getWithMaxLength(0);
    }

}

@@ -1354,17 +1354,42 @@
 (long cl
-)
+, long actual)%0A           
  throws 
@@ -1758,17 +1758,21 @@
 sumeInt(
-c
+actua
 l)%5D;%0A   
@@ -1779,32 +1779,160 @@
      %7D);%0A    %7D%0A%0A
+    private void respondWithContentLength(long cl) throws ExecutionException %7B%0A        respondWithContentLength(cl, cl);%0A    %7D%0A%0A
     private void
@@ -1949,20 +1949,30 @@
 xLength(
-l
+Optional%3CL
 ong
+%3E
  max)%0A  
@@ -2085,32 +2085,16 @@
 EW_PATH,
-%0A               
  new Has
@@ -2119,33 +2119,160 @@
 Map%3C%3E(),
+ max);
 %0A    
+%7D%0A%0A
     
-        
+private void getWithMaxLength(long max)%0A            throws IOException, SizeLimitExceededException %7B%0A        getWithMaxLength(
 Optional
@@ -2279,25 +2279,163 @@
 .of(max)
+);
 %0A    
+%7D%0A%0A
     
+private void getWithoutLimit()%0A            throws IOException, SizeLimitExceededException %7B%0A        getWithMaxLength(Optional.empty()
 );%0A    %7D
@@ -3117,10 +3117,175 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void getWithoutLimitDoesNotThrow() throws Exception %7B%0A        respondWithContentLength(Integer.MAX_VALUE, 0);%0A        getWithoutLimit();%0A    %7D%0A%0A
 %7D%0A

Add test