package org.jooby.internal.handlers;
import static org.easymock.EasyMock.expect;
import java.util.Optional;
import java.util.Set;
import org.jooby.MediaType;
import org.jooby.Mutant;
import org.jooby.Request;
import org.jooby.Response;
import org.jooby.Route;
import org.jooby.Route.Chain;
import org.jooby.Route.Definition;
import org.jooby.Status;
import org.jooby.test.MockUnit;
import org.jooby.test.MockUnit.Block;
import org.junit.Test;
import com.google.common.collect.Sets;
public class OptionsHandlerTest {
private Block path = unit -> {
Request req = unit.get(Request.class);
expect(req.path()).andReturn("/");
};
private Block next = unit -> {
Chain chain = unit.get(Route.Chain.class);
chain.next(unit.get(Request.class), unit.get(Response.class));
};
@Test
public void handle() throws Exception {
new MockUnit(Request.class, Response.class, Route.Chain.class, Route.Definition.class)
.expect(next)
.expect(allow(false))
.expect(path)
.expect(method("GET"))
.expect(matches("POST", false))
.expect(matches("PUT", false))
.expect(matches("DELETE", false))
.expect(matches("PATCH", false))
.expect(matches("HEAD", false))
.expect(matches("CONNECT", false))
.expect(matches("OPTIONS", false))
.expect(matches("TRACE", false))
.expect(unit -> {
Response rsp = unit.get(Response.class);
expect(rsp.header("Allow", "")).andReturn(rsp);
expect(rsp.length(0)).andReturn(rsp);
expect(rsp.status(Status.OK)).andReturn(rsp);
})
.run(unit -> {
Set<Definition> routes = Sets.newHashSet(unit.get(Route.Definition.class));
new OptionsHandler(routes)
.handle(unit.get(Request.class), unit.get(Response.class),
unit.get(Route.Chain.class));
});
}
@Test
public void handleSome() throws Exception {
new MockUnit(Request.class, Response.class, Route.Chain.class, Route.Definition.class)
.expect(next)
.expect(allow(false))
.expect(path)
.expect(method("GET"))
.expect(matches("POST", true))
.expect(routeMethod("POST"))
.expect(matches("PUT", false))
.expect(matches("DELETE", false))
.expect(matches("PATCH", true))
.expect(routeMethod("PATCH"))
.expect(matches("HEAD", false))
.expect(matches("CONNECT", false))
.expect(matches("OPTIONS", false))
.expect(matches("TRACE", false))
.expect(unit -> {
Response rsp = unit.get(Response.class);
expect(rsp.header("Allow", "POST, PATCH")).andReturn(rsp);
expect(rsp.length(0)).andReturn(rsp);
expect(rsp.status(Status.OK)).andReturn(rsp);
})
.run(unit -> {
Set<Definition> routes = Sets.newHashSet(unit.get(Route.Definition.class));
new OptionsHandler(routes)
.handle(unit.get(Request.class), unit.get(Response.class),
unit.get(Route.Chain.class));
});
}
@Test
public void handleNone() throws Exception {
new MockUnit(Request.class, Response.class, Route.Chain.class, Route.Definition.class)
.expect(next)
.expect(allow(true))
.run(unit -> {
Set<Definition> routes = Sets.newHashSet(unit.get(Route.Definition.class));
new OptionsHandler(routes)
.handle(unit.get(Request.class), unit.get(Response.class),
unit.get(Route.Chain.class));
});
}
private Block matches(final String method, final boolean matches) {
return unit -> {
Route route = unit.mock(Route.class);
Optional<Route> ifRoute = matches ? Optional.of(route) : Optional.empty();
Definition def = unit.get(Route.Definition.class);
expect(def.matches(method, "/", MediaType.all, MediaType.ALL)).andReturn(ifRoute);
};
}
private Block method(final String method) {
return unit -> {
Request req = unit.get(Request.class);
expect(req.method()).andReturn(method);
};
}
private Block routeMethod(final String method) {
return unit -> {
Route.Definition req = unit.get(Route.Definition.class);
expect(req.method()).andReturn(method);
};
}
private Block allow(final boolean set) {
return unit -> {
Mutant mutant = unit.mock(Mutant.class);
expect(mutant.isSet()).andReturn(set);
Response rsp = unit.get(Response.class);
expect(rsp.header("Allow")).andReturn(mutant);
};
}
}