blob: e5708e69648192f45f08d98f62892938976c6d8a [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
// * with the License. You may obtain a copy of the License at *
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 *
// * *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation2;
import static org.apache.juneau.http.HttpMethodName.*;
import static org.apache.juneau.rest.testutils.TestUtils.*;
import static org.junit.Assert.*;
import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.dto.swagger.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.marshall.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock2.*;
import org.apache.juneau.rest.testutils.*;
import org.junit.*;
import org.junit.runners.*;
/**
* Tests related to @Path annotation.
*/
@SuppressWarnings({})
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PathAnnotationTest {
//=================================================================================================================
// Basic tests
//=================================================================================================================
@Rest
public static class A {
@RestMethod(name=GET, path="/")
public void noPath(RestResponse res) {
res.setOutput(GET);
}
@RestMethod(name=GET, path="/a")
public String simplePath() {
return "GET /a";
}
@RestMethod(name=GET, path="/a/{foo}")
public String simplePathOneVar(RestResponse res, @Path("foo") String foo) {
return "GET /a " + foo;
}
@RestMethod(name=GET, path="/a/{foo}/{bar}")
public String simplePathTwoVars(RestResponse res, @Path("foo") String foo, @Path("bar") String bar) {
return "GET /a " + foo + "," + bar;
}
@RestMethod(name=GET, path="/a/{foo}/{bar}/*")
public String simplePathWithRemainder(@Path("foo") String foo, @Path("bar") int bar, @Path("/*") String remainder) {
return "GET /a "+foo+","+bar+",r="+remainder;
}
}
static MockRest a = MockRest.build(A.class, null);
@Test
public void a00_nonExistentPath() throws Exception {
a.get("/bad?noTrace=true").execute().assertStatus(404);
}
@Test
public void a01_noPath() throws Exception {
a.get(null).execute().assertBody("GET");
a.get().execute().assertBody("GET");
}
@Test
public void a02_simplePath() throws Exception {
a.get("/a").execute().assertBody("GET /a");
}
@Test
public void a03_simplePathOneVar() throws Exception {
a.get("/a/foo").execute().assertBody("GET /a foo");
}
@Test
public void a04_simplePathTwoVars() throws Exception {
a.get("/a/foo/bar").execute().assertBody("GET /a foo,bar");
}
@Test
public void a05_simplePathWithRemainder() throws Exception {
a.get("/a/foo/123/baz").execute().assertBody("GET /a foo,123,r=baz");
}
@Test
public void a06_urlEncodedPathPart() throws Exception {
// URL-encoded part should not get decoded before finding method to invoke.
// This should match /get1/{foo} and not /get1/{foo}/{bar}
// NOTE: When testing on Tomcat, must specify the following system property:
// -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
a.get("/a/x%2Fy").execute().assertBody("GET /a x/y");
a.get("/a/x%2Fy/x%2Fy").execute().assertBody("GET /a x/y,x/y");
}
//=================================================================================================================
// Primitives
//=================================================================================================================
@Rest
public static class B {
@RestMethod(name=GET, path="/int/{x}/foo")
public String b01(@Path(name="x") int x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/short/{x}/foo")
public String b02(@Path(name="x") short x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/long/{x}/foo")
public String b03(@Path(name="x") long x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/char/{x}/foo")
public String b04(@Path(name="x") char x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/float/{x}/foo")
public String b05(@Path(name="x") float x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/double/{x}/foo")
public String b06(@Path(name="x") double x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/byte/{x}/foo")
public String b07(@Path(name="x") byte x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/boolean/{x}/foo")
public String b08(@Path(name="x") boolean x) {
return String.valueOf(x);
}
}
static MockRest b = MockRest.build(B.class, null);
@Test
public void b01_int() throws Exception {
b.get("/int/123/foo").execute().assertBody("123");
b.get("/int/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b02_short() throws Exception {
b.get("/short/123/foo").execute().assertBody("123");
b.get("/short/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b03_long() throws Exception {
b.get("/long/123/foo").execute().assertBody("123");
b.get("/long/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b04_char() throws Exception {
b.get("/char/c/foo").execute().assertBody("c");
b.get("/char/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b05_float() throws Exception {
b.get("/float/1.23/foo").execute().assertBody("1.23");
b.get("/float/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b06_double() throws Exception {
b.get("/double/1.23/foo").execute().assertBody("1.23");
b.get("/double/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b07_byte() throws Exception {
b.get("/byte/123/foo").execute().assertBody("123");
b.get("/byte/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void b08_boolean() throws Exception {
b.get("/boolean/true/foo").execute().assertBody("true");
b.get("/boolean/bad/foo?noTrace=true").execute().assertStatus(400);
}
//=================================================================================================================
// Primitive objects
//=================================================================================================================
@Rest
public static class C {
@RestMethod(name=GET, path="/Integer/{x}/foo")
public String c01(@Path(name="x") Integer x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Short/{x}/foo")
public String c02(@Path(name="x") Short x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Long/{x}/foo")
public String c03(@Path(name="x") Long x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Character/{x}/foo")
public String c04(@Path(name="x") Character x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Float/{x}/foo")
public String c05(@Path(name="x") Float x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Double/{x}/foo")
public String c06(@Path(name="x") Double x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Byte/{x}/foo")
public String c07(@Path(name="x") Byte x) {
return String.valueOf(x);
}
@RestMethod(name=GET, path="/Boolean/{x}/foo")
public String c08(@Path(name="x") Boolean x) {
return String.valueOf(x);
}
}
static MockRest c = MockRest.build(C.class, null);
@Test
public void c01_Integer() throws Exception {
c.get("/Integer/123/foo").execute().assertBody("123");
c.get("/Integer/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c02_Short() throws Exception {
c.get("/Short/123/foo").execute().assertBody("123");
c.get("/Short/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c03_Long() throws Exception {
c.get("/Long/123/foo").execute().assertBody("123");
c.get("/Long/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c04_Char() throws Exception {
c.get("/Character/c/foo").execute().assertBody("c");
c.get("/Character/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c05_Float() throws Exception {
c.get("/Float/1.23/foo").execute().assertBody("1.23");
c.get("/Float/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c06_Double() throws Exception {
c.get("/Double/1.23/foo").execute().assertBody("1.23");
c.get("/Double/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c07_Byte() throws Exception {
c.get("/Byte/123/foo").execute().assertBody("123");
c.get("/Byte/bad/foo?noTrace=true").execute().assertStatus(400);
}
@Test
public void c08_Boolean() throws Exception {
c.get("/Boolean/true/foo").execute().assertBody("true");
c.get("/Boolean/bad/foo?noTrace=true").execute().assertStatus(400);
}
//=================================================================================================================
// POJOs convertible from strings
//=================================================================================================================
@Rest
public static class D {
// Object with forString(String) method
@RestMethod(name=GET, path="/uuid/{uuid}")
public UUID uuid(RestResponse res, @Path(name="uuid") UUID uuid) {
return uuid;
}
}
static MockRest d = MockRest.build(D.class, null);
@Test
public void d01_uuid() throws Exception {
UUID uuid = UUID.randomUUID();
d.get("/uuid/" + uuid).execute().assertBody(uuid.toString());
}
//=================================================================================================================
// @Path annotation without name.
//=================================================================================================================
@Rest
public static class E {
@RestMethod(name=GET, path="/x/{foo}/{bar}")
public Object normal1(@Path String foo, @Path String bar) {
return new ObjectMap().append("m","normal1").append("foo", foo).append("bar", bar);
}
@RestMethod(name=GET, path="/x/{foo}/x/{bar}/x")
public Object normal2(@Path String foo, @Path String bar) {
return new ObjectMap().append("m","normal2").append("foo", foo).append("bar", bar);
}
@RestMethod(name=GET, path="/y/{0}/{1}")
public Object numbers1(@Path String foo, @Path String bar) {
return new ObjectMap().append("m","numbers1").append("0", foo).append("1", bar);
}
@RestMethod(name=GET, path="/y/{0}/y/{1}/y")
public Object numbers2(@Path String foo, @Path String bar) {
return new ObjectMap().append("m","numbers2").append("0", foo).append("1", bar);
}
@RestMethod(name=GET, path="/z/{1}/z/{0}/z")
public Object numbers3(@Path String foo, @Path String bar) {
return new ObjectMap().append("m","numbers3").append("0", foo).append("1", bar);
}
}
static MockRest e = MockRest.build(E.class, null);
@Test
public void e01_normal1() throws Exception {
e.get("/x/x1/x2").execute().assertBody("{m:'normal1',foo:'x1',bar:'x2'}");
}
@Test
public void e02_normal2() throws Exception {
e.get("/x/x1/x/x2/x").execute().assertBody("{m:'normal2',foo:'x1',bar:'x2'}");
}
@Test
public void e03_numbers1() throws Exception {
e.get("/y/y1/y2").execute().assertBody("{m:'numbers1','0':'y1','1':'y2'}");
}
@Test
public void e04_numbers2() throws Exception {
e.get("/y/y1/y/y2/y").execute().assertBody("{m:'numbers2','0':'y1','1':'y2'}");
}
@Test
public void e05_numbers3() throws Exception {
e.get("/z/z1/z/z2/z").execute().assertBody("{m:'numbers3','0':'z2','1':'z1'}");
}
//=================================================================================================================
// Path variables on class.
//=================================================================================================================
@Rest(path="/f/{a}/{b}")
public static class F {
@RestMethod(name=GET, path="/")
public String noPath(RequestPath path) {
return format("noPath: {0}", path);
}
@RestMethod(name=GET, path="/*")
public String noPath2(RequestPath path) {
return format("noPath2: {0}", path);
}
@RestMethod(name=GET, path="/a")
public String noVars(RequestPath path) {
return format("noVars: {0}", path);
}
@RestMethod(name=GET, path="/b/{c}/{d}")
public String twoVars(RequestPath path) {
return format("twoVars: {0}", path);
}
@RestMethod(name=GET, path="/c/{a}/{b}")
public String twoVarsOverlapping(RequestPath path) {
return format("twoVarsOverlapping: {0}", path);
}
@RestMethod(name=GET, path="/d/{c}/{d}/*")
public String withRemainder(RequestPath path) {
return format("withRemainder: {0}", path);
}
private String format(String msg, Object...args) {
return SimpleJson.DEFAULT.format(msg, args);
}
}
static MockRest f = MockRest.create(F.class).servletPath("/f").build();
@Test
public void f01a_noPath() throws Exception {
f.get("/f/x1/x2").execute().assertBody("noPath: {a:'x1',b:'x2'}");
}
@Test
public void f01b_incompletePath() throws Exception {
f.get("/f/x1").execute().assertStatus(404);
f.get("/f").execute().assertStatus(404);
}
@Test
public void f01c_noPath_blanks() throws Exception {
f.get("/f//").execute().assertStatus(404);
f.get("/f/x/").execute().assertStatus(404);
f.get("/f//x").execute().assertStatus(404);
}
@Test
public void f02a_noPath2() throws Exception {
f.get("/f/x1/x2/foo").execute().assertBody("noPath2: {'/*':'foo','/**':'foo',a:'x1',b:'x2'}");
}
@Test
public void f02b_noPath2_blanks() throws Exception {
f.get("/f///foo").execute().assertStatus(404);
f.get("/f/x1//foo").execute().assertStatus(404);
f.get("/f//x2/foo").execute().assertStatus(404);
}
@Test
public void f03a_noVars() throws Exception {
f.get("/f/x1/x2/a").execute().assertBody("noVars: {a:'x1',b:'x2'}");
}
@Test
public void f03b_noVars_blanks() throws Exception {
f.get("/f///a").execute().assertStatus(404);
f.get("/f/x1//a").execute().assertStatus(404);
f.get("/f//x2/a").execute().assertStatus(404);
}
@Test
public void f04a_twoVars() throws Exception {
f.get("/f/x1/x2/b/x3/x4").execute().assertBody("twoVars: {a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void f04b_twoVars_blanks() throws Exception {
f.get("/f//x2/b/x3/x4").execute().assertStatus(404);
f.get("/f/x1//b/x3/x4").execute().assertStatus(404);
f.get("/f/x1/x2/b//x4").execute().assertStatus(200);
f.get("/f/x1/x2/b/x3/").execute().assertStatus(200);
f.get("/f///b//").execute().assertStatus(404);
}
@Test
public void f05_twoVarsOverlapping() throws Exception {
f.get("/f/x1/x2/c/x3/x4").execute().assertBody("twoVarsOverlapping: {a:'x3',b:'x4'}");
}
@Test
public void f06a_withRemainder() throws Exception {
f.get("/f/x1/x2/d/x3/x4").execute().assertBody("withRemainder: {a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void f06b_withRemainder_lank() throws Exception {
f.get("/f/x1/x2/d/x3/x4/").execute().assertBody("withRemainder: {'/*':'','/**':'',a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void f06c_withRemainderWithStuff() throws Exception {
f.get("/f/x1/x2/d/x3/x4/foo/bar").execute().assertBody("withRemainder: {'/*':'foo/bar','/**':'foo/bar',a:'x1',b:'x2',c:'x3',d:'x4'}");
}
//=================================================================================================================
// Path variables on child class.
//=================================================================================================================
@Rest(children={F.class})
public static class G {}
static MockRest g = MockRest.create(G.class).build();
@Test
public void g01a_noPath() throws Exception {
g.get("/f/x1/x2").execute().assertBody("noPath: {a:'x1',b:'x2'}");
}
@Test
public void g01b_incompletePath() throws Exception {
g.get("/f/x1").execute().assertStatus(404);
g.get("/f").execute().assertStatus(404);
}
@Test
public void g01c_noPath_blanks() throws Exception {
g.get("/f//").execute().assertStatus(404);
g.get("/f/x1/").execute().assertStatus(404);
g.get("/f//x2").execute().assertStatus(404);
}
@Test
public void g02a_noVars() throws Exception {
g.get("/f/x1/x2/a").execute().assertBody("noVars: {a:'x1',b:'x2'}");
}
@Test
public void g02b_noVars_blanks() throws Exception {
g.get("/f///a").execute().assertStatus(404);
g.get("/f/x1//a").execute().assertStatus(404);
g.get("/f//x2/a").execute().assertStatus(404);
}
@Test
public void g03a_twoVars() throws Exception {
g.get("/f/x1/x2/b/x3/x4").execute().assertBody("twoVars: {a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void g03b_twoVars_blanks() throws Exception {
g.get("/f//x2/b/x3/x4").execute().assertStatus(404);
g.get("/f/x1//b/x3/x4").execute().assertStatus(404);
g.get("/f/x1/x2/b//x4").execute().assertStatus(200);
g.get("/f/x1/x2/b/x3/").execute().assertStatus(200);
g.get("/f///b//").execute().assertStatus(404);
}
@Test
public void g04_twoVarsOverlapping() throws Exception {
g.get("/f/x1/x2/c/x3/x4").execute().assertBody("twoVarsOverlapping: {a:'x3',b:'x4'}");
}
@Test
public void g05a_withRemainder() throws Exception {
g.get("/f/x1/x2/d/x3/x4").execute().assertBody("withRemainder: {a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void g05b_withRemainderBlank() throws Exception {
g.get("/f/x1/x2/d/x3/x4/").execute().assertBody("withRemainder: {'/*':'','/**':'',a:'x1',b:'x2',c:'x3',d:'x4'}");
}
@Test
public void g05c_withRemainderWithStuff() throws Exception {
g.get("/f/x1/x2/d/x3/x4/foo/bar").execute().assertBody("withRemainder: {'/*':'foo/bar','/**':'foo/bar',a:'x1',b:'x2',c:'x3',d:'x4'}");
}
//=================================================================================================================
// Path variables on parent and child class.
//=================================================================================================================
@Rest(path="/h/{ha}/{hb}", children={F.class})
public static class H {}
static MockRest h = MockRest.create(H.class).servletPath("/h").build();
@Test
public void h01a_noPath() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2").execute().assertBody("noPath: {a:'x1',b:'x2',ha:'ha1',hb:'hb1'}");
}
@Test
public void h01b_incompletePath() throws Exception {
// These are 405 instead of 404 because when children don't match, we try to find a matching Java method.
h.get("/h/ha1/hb1/f/x1").execute().assertStatus(404);
h.get("/h/ha1/hb1/f").execute().assertStatus(404);
h.get("/h/ha1/hb1").execute().assertStatus(404);
h.get("/h/ha1").execute().assertStatus(404);
h.get("/h").execute().assertStatus(404);
}
@Test
public void h01c_noPath_blanks() throws Exception {
h.get("/h//hb1/f/x1/x2").execute().assertStatus(404);
h.get("/h/ha1//f/x1/x2").execute().assertStatus(404);
h.get("/h/ha1/hb1/f//x2").execute().assertStatus(404);
h.get("/h/ha1/hb1/f/x1/").execute().assertStatus(404);
h.get("/h///f//").execute().assertStatus(404);
}
@Test
public void h02a_noPath2() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/foo").execute().assertBody("noPath2: {'/*':'foo','/**':'foo',a:'x1',b:'x2',ha:'ha1',hb:'hb1'}");
}
@Test
public void h02b_noPath2_blanks() throws Exception {
h.get("/h//hb1/f/x1/x2/foo").execute().assertStatus(404);
h.get("/h/ha1//f/x1/x2/foo").execute().assertStatus(404);
h.get("/h/ha1/hb1/f//x2/foo").execute().assertStatus(404);
h.get("/h/ha1/hb1/f/x1//foo").execute().assertStatus(404);
h.get("/h///f///foo").execute().assertStatus(404);
}
@Test
public void h03a_noVars() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/a").execute().assertBody("noVars: {a:'x1',b:'x2',ha:'ha1',hb:'hb1'}");
}
@Test
public void h03b_noVars_blanks() throws Exception {
h.get("/h//hb1/f/x1/x2/a").execute().assertStatus(404);
h.get("/h/ha1//f/x1/x2/a").execute().assertStatus(404);
h.get("/h/ha1/hb1/f//x2/a").execute().assertStatus(404);
h.get("/h/ha1/hb1/f/x1//a").execute().assertStatus(404);
h.get("/h///f///a").execute().assertStatus(404);
}
@Test
public void h04_twoVars() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/b/x3/x4").execute().assertBody("twoVars: {a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1'}");
}
@Test
public void h05_twoVarsOverlapping() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/c/x3/x4").execute().assertBody("twoVarsOverlapping: {a:'x3',b:'x4',ha:'ha1',hb:'hb1'}");
}
@Test
public void h06a_withRemainder() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/d/x3/x4").execute().assertBody("withRemainder: {a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1'}");
}
@Test
public void h06b_withRemainderBlank() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/d/x3/x4/").execute().assertBody("withRemainder: {'/*':'','/**':'',a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1'}");
}
@Test
public void h06c_withRemainderWithStuff() throws Exception {
h.get("/h/ha1/hb1/f/x1/x2/d/x3/x4/foo/bar").execute().assertBody("withRemainder: {'/*':'foo/bar','/**':'foo/bar',a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1'}");
}
//=================================================================================================================
// Path variables on parents and child class.
//=================================================================================================================
@Rest(path="/i/{ia}/{ib}", children={H.class})
public static class I {}
static MockRest i = MockRest.create(I.class).servletPath("/i").build();
@Test
public void i01a_noPath() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2").execute().assertBody("noPath: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i01b_incompletePath() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1/hb1/f").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1/hb1").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1").execute().assertStatus(404);
i.get("/i/ia1/ib1/h").execute().assertStatus(404);
i.get("/i/ia1/ib1").execute().assertStatus(404);
i.get("/i/ia1").execute().assertStatus(404);
i.get("/i").execute().assertStatus(404);
}
@Test
public void i01c_noPath_blanks() throws Exception {
i.get("/i//ib1/h/ha1/hb1/f/x1/x2").execute().assertStatus(404);
i.get("/i/ia1//h/ha1/hb1/f/x1/x2").execute().assertStatus(404);
i.get("/i/ia1/ib1/h//hb1/f/x1/x2").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1//f/x1/x2").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1/hb1/f//x2").execute().assertStatus(404);
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/").execute().assertStatus(404);
i.get("/i///h///f//").execute().assertStatus(404);
}
@Test
public void i02_noPath2() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/foo").execute().assertBody("noPath2: {'/*':'foo','/**':'foo',a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i03_noVars() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/a").execute().assertBody("noVars: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i04_twoVars() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/b/x3/x4").execute().assertBody("twoVars: {a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i05_twoVarsOverlapping() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/c/x3/x4").execute().assertBody("twoVarsOverlapping: {a:'x3',b:'x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i06a_withRemainder() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/d/x3/x4").execute().assertBody("withRemainder: {a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i06b_withRemainderBlank() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/d/x3/x4/").execute().assertBody("withRemainder: {'/*':'','/**':'',a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
@Test
public void i06c_withRemainderWithStuff() throws Exception {
i.get("/i/ia1/ib1/h/ha1/hb1/f/x1/x2/d/x3/x4/foo/bar").execute().assertBody("withRemainder: {'/*':'foo/bar','/**':'foo/bar',a:'x1',b:'x2',c:'x3',d:'x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
}
//=================================================================================================================
// Optional path parameter.
//=================================================================================================================
@Rest(serializers=SimpleJsonSerializer.class)
public static class J {
@RestMethod(name=GET,path="/a/{f1}")
public Object a(@Path("f1") Optional<Integer> f1) throws Exception {
assertNotNull(f1);
return f1;
}
@RestMethod(name=GET,path="/b/{f1}")
public Object b(@Path("f1") Optional<ABean> f1) throws Exception {
assertNotNull(f1);
return f1;
}
@RestMethod(name=GET,path="/c/{f1}")
public Object c(@Path("f1") Optional<List<ABean>> f1) throws Exception {
assertNotNull(f1);
return f1;
}
@RestMethod(name=GET,path="/d/{f1}")
public Object d(@Path("f1") List<Optional<ABean>> f1) throws Exception {
return f1;
}
}
static MockRest j = MockRest.create(J.class).json().build();
@Test
public void j01_optionalParam_integer() throws Exception {
j.get("/a/123").execute().assertStatus(200).assertBody("123");
}
@Test
public void j02_optionalParam_bean() throws Exception {
j.get("/b/(a=1,b=foo)").execute().assertStatus(200).assertBody("{a:1,b:'foo'}");
}
@Test
public void j03_optionalParam_listOfBeans() throws Exception {
j.get("/c/@((a=1,b=foo))").execute().assertStatus(200).assertBody("[{a:1,b:'foo'}]");
}
@Test
public void j04_optionalParam_listOfOptionals() throws Exception {
j.get("/d/@((a=1,b=foo))").execute().assertStatus(200).assertBody("[{a:1,b:'foo'}]");
}
//=================================================================================================================
// @Path on POJO
//=================================================================================================================
//-----------------------------------------------------------------------------------------------------------------
// Basic tests
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class SA {
@Path(
name="P",
description={"a","b"},
type="string",
_enum="a,b",
example="a"
)
public static class SA01 {
public SA01(String x) {}
@Override
public String toString() {
return "sa01";
}
}
@RestMethod(name=GET,path="/basic/{P}")
public void sa01(SA01 f) {}
@Path(
name="P",
api={
"description:'a\nb',",
"type:'string',",
"enum:['a','b'],",
"x-example:'a'"
}
)
public static class SA02 {
public SA02(String x) {}
@Override
public String toString() {
return "sa02";
}
}
@RestMethod(name=GET,path="/api/{P}")
public void sa02(SA02 f) {}
@Path(
name="P",
api={
"description:'b\nc',",
"type:'string',",
"enum:['b','c'],",
"x-example:'b'"
},
description={"a","b"},
type="string",
_enum="a,b",
example="a"
)
public static class SA03 {
public SA03(String x) {}
@Override
public String toString() {
return "sa03";
}
}
@RestMethod(name=GET,path="/mixed/{P}")
public void sa03(SA03 f) {}
@Path("P")
public static class SA04 {
@Override
public String toString() {
return "sa04";
}
}
@RestMethod(name=GET,path="/value/{P}")
public void sa04(SA04 f) {}
@Path(name="P", _enum={" ['a','b'] "})
public static class SA19 {
@Override
public String toString() {
return "sa19";
}
}
@RestMethod(name=GET,path="/enum/{P}")
public void sa19(SA19 f) {}
}
static Swagger sa = getSwagger(SA.class);
@Test
public void sa01_Path_onPojo_basic() throws Exception {
ParameterInfo x = sa.getParameterInfo("/basic/{P}","get","path","P");
assertEquals("P", x.getName());
assertEquals("a\nb", x.getDescription());
assertEquals("string", x.getType());
assertObjectEquals("['a','b']", x.getEnum());
assertEquals("a", x.getExample());
assertObjectEquals("{'in':'path',name:'P',type:'string',description:'a\\nb',required:true,'enum':['a','b'],'x-example':'a','x-examples':{example:'/basic/a'}}", x);
}
@Test
public void sa02_Path_onPojo_api() throws Exception {
ParameterInfo x = sa.getParameterInfo("/api/{P}","get","path","P");
assertEquals("P", x.getName());
assertEquals("a\nb", x.getDescription());
assertEquals("string", x.getType());
assertObjectEquals("['a','b']", x.getEnum());
assertEquals("a", x.getExample());
assertObjectEquals("{'in':'path',name:'P',type:'string',description:'a\\nb',required:true,'enum':['a','b'],'x-example':'a','x-examples':{example:'/api/a'}}", x);
}
@Test
public void sa03_Path_onPojo_mixed() throws Exception {
ParameterInfo x = sa.getParameterInfo("/mixed/{P}","get","path","P");
assertEquals("P", x.getName());
assertEquals("a\nb", x.getDescription());
assertEquals("string", x.getType());
assertObjectEquals("['a','b']", x.getEnum());
assertEquals("a", x.getExample());
assertObjectEquals("{'in':'path',name:'P',type:'string',description:'a\\nb',required:true,'enum':['a','b'],'x-example':'a','x-examples':{example:'/mixed/a'}}", x);
}
@Test
public void sa04_Path_onPojo_value() throws Exception {
ParameterInfo x = sa.getParameterInfo("/value/{P}","get","path","P");
assertEquals("P", x.getName());
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true}", x);
}
@Test
public void sa05_Path_onPojo_enum() throws Exception {
ParameterInfo x = sa.getParameterInfo("/enum/{P}","get","path","P");
assertObjectEquals("['a','b']", x.getEnum());
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true,'enum':['a','b']}", x);
}
//-----------------------------------------------------------------------------------------------------------------
// Schema
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class SB {
@Path(name="P")
public static class SB01 {}
@RestMethod(name=GET,path="/schemaValue/{P}")
public void sb01(SB01 f) {}
@Path("P")
public static class SB02 {
public String f1;
}
@RestMethod(name=GET,path="/autoDetectBean/{P}")
public void sb02(SB02 b) {}
@Path("P")
public static class SB03 extends LinkedList<String> {
private static final long serialVersionUID = 1L;
}
@RestMethod(name=GET,path="/autoDetectList/{P}")
public void sb03(SB03 b) {}
@Path("P")
public static class SB04 {}
@RestMethod(name=GET,path="/autoDetectStringObject/{P}")
public void sb04(SB04 b) {}
}
static Swagger sb = getSwagger(SB.class);
@Test
public void sb01_Path_onPojo_schemaValue() throws Exception {
ParameterInfo x = sb.getParameterInfo("/schemaValue/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true}", x);
}
@Test
public void sb02_Path_onPojo_autoDetectBean() throws Exception {
ParameterInfo x = sb.getParameterInfo("/autoDetectBean/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'object',required:true,schema:{properties:{f1:{type:'string'}}}}", x);
}
@Test
public void sb03_Path_onPojo_autoDetectList() throws Exception {
ParameterInfo x = sb.getParameterInfo("/autoDetectList/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'array',required:true,items:{type:'string'}}", x);
}
@Test
public void sb04_Path_onPojo_autoDetectStringObject() throws Exception {
ParameterInfo x = sb.getParameterInfo("/autoDetectStringObject/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true}", x);
}
//-----------------------------------------------------------------------------------------------------------------
// Examples
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class SC {
@Path(name="P", example={" {f1:'a'} "})
public static class SC01 {
public String f1;
}
@RestMethod(name=GET,path="/example/{P}")
public void sc01(SC01 f) {}
}
static Swagger sc = getSwagger(SC.class);
@Test
public void sc01_Path_onPojo_example() throws Exception {
ParameterInfo x = sc.getParameterInfo("/example/{P}","get","path","P");
assertEquals("{f1:'a'}", x.getExample());
}
//=================================================================================================================
// @Path on parameter
//=================================================================================================================
//-----------------------------------------------------------------------------------------------------------------
// Basic tests
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class TA {
@RestMethod(name=GET,path="/basic/{P}")
public void ta01(@Path(
name="P",
description="a",
type="string"
) String h) {}
@RestMethod(name=GET,path="/api/{P}")
public void ta02(@Path(
name="P",
api={
"description:'a',",
"type:'string'"
}
) String h) {}
@RestMethod(name=GET,path="/mixed/{P}")
public void ta03(@Path(
name="P",
api={
"description:'b',",
"type:'string'"
},
description="a",
type="string"
) String h) {}
@RestMethod(name=GET,path="/value/{P}")
public void ta04(@Path("P") String h) {}
@RestMethod(name=GET,path="/enum/{P}")
public void ta05(@Path(name="P", _enum={" ['a','b'] "}) String h) {}
}
static Swagger ta = getSwagger(TA.class);
@Test
public void ta01_Path_onParameter_basic() throws Exception {
ParameterInfo x = ta.getParameterInfo("/basic/{P}","get","path","P");
assertEquals("a", x.getDescription());
assertEquals("string", x.getType());
}
@Test
public void ta02_Path_onParameter_api() throws Exception {
ParameterInfo x = ta.getParameterInfo("/api/{P}","get","path","P");
assertEquals("a", x.getDescription());
assertEquals("string", x.getType());
}
@Test
public void ta03_Path_onParameter_mixed() throws Exception {
ParameterInfo x = ta.getParameterInfo("/mixed/{P}","get","path","P");
assertEquals("a", x.getDescription());
assertEquals("string", x.getType());
}
@Test
public void ta04_Path_onParameter_value() throws Exception {
ParameterInfo x = ta.getParameterInfo("/value/{P}","get","path","P");
assertEquals("P", x.getName());
}
@Test
public void ta05_Path_onParameter_enum() throws Exception {
ParameterInfo x = ta.getParameterInfo("/enum/{P}","get","path","P");
assertObjectEquals("['a','b']", x.getEnum());
}
//-----------------------------------------------------------------------------------------------------------------
// Schema
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class TB {
@RestMethod(name=GET,path="/schemaValue/{P}")
public void tb01(@Path(name="P") String h) {}
public static class TB02 {
public String f1;
}
@RestMethod(name=GET,path="/autoDetectBean/{P}")
public void tb02(@Path("P") TB02 b) {}
public static class TB03 extends LinkedList<String> {
private static final long serialVersionUID = 1L;
}
@RestMethod(name=GET,path="/autoDetectList/{P}")
public void tb03(@Path("P") TB03 b) {}
public static class TB04 {}
@RestMethod(name=GET,path="/autoDetectStringObject/{P}")
public void tb04(@Path("P") TB04 b) {}
@RestMethod(name=GET,path="/autoDetectInteger/{P}")
public void tb05(@Path("P") Integer b) {}
@RestMethod(name=GET,path="/autoDetectBoolean/{P}")
public void tb06(@Path("P") Boolean b) {}
}
static Swagger tb = getSwagger(TB.class);
@Test
public void tb01_Path_onParameter_schemaValue() throws Exception {
ParameterInfo x = tb.getParameterInfo("/schemaValue/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true}", x);
}
@Test
public void tb02_Path_onParameter_autoDetectBean() throws Exception {
ParameterInfo x = tb.getParameterInfo("/autoDetectBean/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'object',required:true,schema:{properties:{f1:{type:'string'}}}}", x);
}
@Test
public void tb03_Path_onParameter_autoDetectList() throws Exception {
ParameterInfo x = tb.getParameterInfo("/autoDetectList/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'array',required:true,items:{type:'string'}}", x);
}
@Test
public void tb04_Path_onParameter_autoDetectStringObject() throws Exception {
ParameterInfo x = tb.getParameterInfo("/autoDetectStringObject/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'string',required:true}", x);
}
@Test
public void tb05_Path_onParameter_autoDetectInteger() throws Exception {
ParameterInfo x = tb.getParameterInfo("/autoDetectInteger/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'integer',required:true,format:'int32'}", x);
}
@Test
public void tb06_Path_onParameter_autoDetectBoolean() throws Exception {
ParameterInfo x = tb.getParameterInfo("/autoDetectBoolean/{P}","get","path","P");
assertObjectEquals("{'in':'path',name:'P',type:'boolean',required:true}", x);
}
//-----------------------------------------------------------------------------------------------------------------
// Examples
//-----------------------------------------------------------------------------------------------------------------
@Rest
public static class TC {
@RestMethod(name=GET,path="/example/{P}")
public void ta21(@Path(name="P", example="{f1:'b'}") String h) {}
}
static Swagger tc = getSwagger(TC.class);
@Test
public void tc01_Path_onParameter_example2() throws Exception {
ParameterInfo x = tc.getParameterInfo("/example/{P}","get","path","P");
assertEquals("{f1:'b'}", x.getExample());
}
}