package org.infernus.idea.checkstyle.model;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.net.URLConnection;
import java.util.Scanner;
import static java.lang.String.format;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class HTTPURLConfigurationLocationTest {
private HttpServer httpServer;
private int serverPort = -1;
@Before
public void startHttpServer() throws IOException {
httpServer = HttpServer.create(new InetSocketAddress(0), 0);
httpServer.createContext("/", new TestHandler());
httpServer.setExecutor(null);
httpServer.start();
serverPort = httpServer.getAddress().getPort();
}
@After
public void stopHttpServer() {
httpServer.stop(0);
}
@Test
public void aRemoteFileCanBeFetched() throws IOException {
final InputStream stream = aLocationWithPath("/valid").resolveFile();
assertThat(toString(stream), is("A test response"));
}
@Test
public void aRemoteFileCanBeFetchedViaARedirect() throws IOException {
final InputStream stream = aLocationWithPath("/redirect").resolveFile();
assertThat(toString(stream), is("A test response"));
}
@Test(expected = FileNotFoundException.class)
public void aMissingRemoteFileThrowsAFileNotFoundException() throws IOException {
aLocationWithPath("/invalid").resolveFile();
}
@Test(expected = SocketTimeoutException.class)
public void aTimeoutThrowsASocketTimeoutException() throws IOException {
aTimingOutLocation().resolveFile();
}
private String toString(InputStream is) {
Scanner s = new Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
@NotNull
private HTTPURLConfigurationLocation aLocationWithPath(final String path) {
final HTTPURLConfigurationLocation location = new HTTPURLConfigurationLocation();
location.setDescription("aTestLocation");
location.setLocation(format("http://localhost:%s%s", serverPort, path));
return location;
}
@NotNull
private HTTPURLConfigurationLocation aTimingOutLocation() {
final TimingOutHTTPURLConfigurationLocation location = new TimingOutHTTPURLConfigurationLocation();
location.setDescription("aTimingOutTestLocation");
location.setLocation(format("http://localhost:%s%s", serverPort, "/delayed"));
return location;
}
private class TestHandler implements HttpHandler {
@Override
public void handle(HttpExchange exch) throws IOException {
String response;
int status;
switch (exch.getRequestURI().getPath()) {
case "/valid":
response = "A test response";
status = 200;
break;
case "/delayed":
waitFor(100);
response = "A delayed test response";
status = 200;
break;
case "/redirect":
response = "A redirect";
status = 301;
exch.getResponseHeaders().add("Location", format("http://localhost:%s/valid", serverPort));
break;
default:
response = "";
status = 404;
}
exch.sendResponseHeaders(status, response.length());
OutputStream os = exch.getResponseBody();
os.write(response.getBytes());
os.close();
}
private void waitFor(final int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
}
}
}
private class TimingOutHTTPURLConfigurationLocation extends HTTPURLConfigurationLocation {
@NotNull
@Override
URLConnection connectionTo(final String location) throws IOException {
final URLConnection urlConnection = super.connectionTo(location);
urlConnection.setConnectTimeout(1);
urlConnection.setReadTimeout(1);
return urlConnection;
}
}
}