package org.jooby.internal.jetty;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import java.io.IOException;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
import org.jooby.servlet.ServletServletRequest;
import org.jooby.servlet.ServletServletResponse;
import org.jooby.spi.HttpHandler;
import org.jooby.spi.NativeWebSocket;
import org.jooby.test.MockUnit;
import org.jooby.test.MockUnit.Block;
import org.junit.Test;
public class JettyHandlerTest {
private Block wsStopTimeout = unit -> {
WebSocketServerFactory ws = unit.get(WebSocketServerFactory.class);
ws.setStopTimeout(30000L);
};
@Test
public void handleShouldSetMultipartConfig() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("Multipart/Form-Data");
request.setAttribute(eq(Request.__MULTIPART_CONFIG_ELEMENT),
isA(MultipartConfigElement.class));
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(isA(ServletServletRequest.class),
isA(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
@Test
public void handleShouldIgnoreMultipartConfig() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(isA(ServletServletRequest.class),
isA(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
@Test
public void handleWsUpgrade() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class, NativeWebSocket.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
HttpServletResponse rsp = unit.get(HttpServletResponse.class);
NativeWebSocket ws = unit.get(NativeWebSocket.class);
WebSocketServerFactory factory = unit.get(WebSocketServerFactory.class);
expect(factory.isUpgradeRequest(req, rsp)).andReturn(true);
expect(factory.acceptWebSocket(req, rsp)).andReturn(true);
expect(req.getAttribute(JettyWebSocket.class.getName())).andReturn(ws);
req.removeAttribute(JettyWebSocket.class.getName());
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(unit.capture(ServletServletRequest.class),
unit.capture(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
}, unit -> {
ServletServletRequest req = unit.captured(ServletServletRequest.class).get(0);
req.upgrade(NativeWebSocket.class);
});
}
@Test(expected = UnsupportedOperationException.class)
public void handleThrowUnsupportedOperationExceptionWhenWsIsMissing() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class, NativeWebSocket.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
HttpServletResponse rsp = unit.get(HttpServletResponse.class);
WebSocketServerFactory factory = unit.get(WebSocketServerFactory.class);
expect(factory.isUpgradeRequest(req, rsp)).andReturn(true);
expect(factory.acceptWebSocket(req, rsp)).andReturn(true);
expect(req.getAttribute(JettyWebSocket.class.getName())).andReturn(null);
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(unit.capture(ServletServletRequest.class),
unit.capture(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
}, unit -> {
ServletServletRequest req = unit.captured(ServletServletRequest.class).get(0);
req.upgrade(NativeWebSocket.class);
});
}
@Test(expected = UnsupportedOperationException.class)
public void handleThrowUnsupportedOperationExceptionOnNoWebSocketRequest() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class, NativeWebSocket.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
HttpServletResponse rsp = unit.get(HttpServletResponse.class);
WebSocketServerFactory factory = unit.get(WebSocketServerFactory.class);
expect(factory.isUpgradeRequest(req, rsp)).andReturn(false);
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(unit.capture(ServletServletRequest.class),
unit.capture(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
}, unit -> {
ServletServletRequest req = unit.captured(ServletServletRequest.class).get(0);
req.upgrade(NativeWebSocket.class);
});
}
@Test(expected = UnsupportedOperationException.class)
public void handleThrowUnsupportedOperationExceptionOnHankshakeRejection() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class, NativeWebSocket.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
HttpServletResponse rsp = unit.get(HttpServletResponse.class);
WebSocketServerFactory factory = unit.get(WebSocketServerFactory.class);
expect(factory.isUpgradeRequest(req, rsp)).andReturn(true);
expect(factory.acceptWebSocket(req, rsp)).andReturn(false);
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(unit.capture(ServletServletRequest.class),
unit.capture(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
}, unit -> {
ServletServletRequest req = unit.captured(ServletServletRequest.class).get(0);
req.upgrade(NativeWebSocket.class);
});
}
@Test(expected = UnsupportedOperationException.class)
public void handleThrowUnsupportedOperationExceptionOnWrongType() throws Exception {
new MockUnit(Request.class, HttpHandler.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class, NativeWebSocket.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
dispatcher.handle(unit.capture(ServletServletRequest.class),
unit.capture(ServletServletResponse.class));
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(unit.get(HttpHandler.class), unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
}, unit -> {
ServletServletRequest req = unit.captured(ServletServletRequest.class).get(0);
req.upgrade(JettyHandlerTest.class);
});
}
@Test(expected = ServletException.class)
public void handleShouldReThrowServletException() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new ServletException("intentional err");
};
new MockUnit(Request.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(false);
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(dispatcher, unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
@Test(expected = IOException.class)
public void handleShouldReThrowIOException() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new IOException("intentional err");
};
new MockUnit(Request.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(false);
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(dispatcher, unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
@Test(expected = IllegalArgumentException.class)
public void handleShouldReThrowIllegalArgumentException() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new IllegalArgumentException("intentional err");
};
new MockUnit(Request.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(false);
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(dispatcher, unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
@Test(expected = IllegalStateException.class)
public void handleShouldReThrowIllegalStateException() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new Exception("intentional err");
};
new MockUnit(Request.class, WebSocketServerFactory.class,
HttpServletRequest.class, HttpServletResponse.class)
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(true);
expect(request.getContentType()).andReturn("application/json");
})
.expect(unit -> {
HttpServletRequest request = unit.get(HttpServletRequest.class);
expect(request.getPathInfo()).andReturn("/");
expect(request.getContextPath()).andReturn("");
})
.expect(unit -> {
Request request = unit.get(Request.class);
request.setHandled(false);
})
.expect(wsStopTimeout)
.run(unit -> {
new JettyHandler(dispatcher, unit.get(WebSocketServerFactory.class),
"target", -1)
.handle("/", unit.get(Request.class),
unit.get(HttpServletRequest.class),
unit.get(HttpServletResponse.class));
});
}
}