View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.rest.annotation;
18  
19  import org.apache.juneau.*;
20  import org.apache.juneau.rest.*;
21  import org.apache.juneau.rest.mock.*;
22  import org.junit.jupiter.api.*;
23  
24  class Restx_Path_Test extends TestBase {
25  
26  	//------------------------------------------------------------------------------------------------------------------
27  	// Nested children.
28  	//------------------------------------------------------------------------------------------------------------------
29  
30  	@Rest(path="/p0", children={A1.class})
31  	public static class A  {
32  		@RestOp(path="/")
33  		public String a(RestContext c) {
34  			return "A-" + c.getFullPath();
35  		}
36  	}
37  	@Rest(path="/p1", children={A2.class})
38  	public static class A1 {
39  		@RestOp(path="/")
40  		public String a(RestContext c) {
41  			return "A01-" + c.getFullPath();
42  		}
43  	}
44  	public static class A2a  {
45  		@RestOp(path="/")
46  		public String a(RestContext c) {
47  			return "A02a-" + c.getFullPath();
48  		}
49  	}
50  	@Rest(path="/p2")
51  	public static class A2 extends A2a {}
52  
53  	@Test void a01_nestedChildren() throws Exception {
54  		var a = MockRestClient.build(A.class);
55  		// Since we're not running from a servlet container, we access A directly with no path.
56  		// However, the path is still reflected in RestContext.getPath().
57  		a.get("/").run().assertContent("A-p0");
58  		a.get("/p1").run().assertContent("A01-p0/p1");
59  		a.get("/p1/p2").run().assertContent("A02a-p0/p1/p2");
60  	}
61  
62  	//-----------------------------------------------------------------------------------------------------------------
63  	// Overlapping URL patterns
64  	//-----------------------------------------------------------------------------------------------------------------
65  
66  	@Rest
67  	public static class B {
68  		@RestGet(path="/")
69  		public String a() {
70  			return "a";
71  		}
72  		@RestGet(path="/*")
73  		public String b() {
74  			return "b";
75  		}
76  		@RestGet(path="/foo")
77  		public String c() {
78  			return "c";
79  		}
80  		@RestGet(path="/foo/*")
81  		public String d() {
82  			return "d";
83  		}
84  		@RestGet(path="/{id}")
85  		public String e() {
86  			return "e";
87  		}
88  		@RestGet(path="/{id}/*")
89  		public String f() {
90  			return "f";
91  		}
92  		@RestGet(path="/{id}/foo")
93  		public String g() {
94  			return "g";
95  		}
96  		@RestGet(path="/{id}/foo/*")
97  		public String h() {
98  			return "h";
99  		}
100 	}
101 
102 	@Test void b01_overlappingPaths() throws Exception {
103 		var b = MockRestClient.build(B.class);
104 		// [/] = [test5a]
105 		// [/*] = [test5b]   -- Cannot get called.
106 		// [/foo] = [test5c]
107 		// [/foo/*] = [test5d]
108 		// [/{id}] = [test5e]
109 		// [/{id}/*] = [test5f]
110 		// [/{id}/foo] = [test5g]
111 		// [/{id}/foo/*] = [test5h]
112 		b.get("/").run().assertContent("a");
113 		b.get("/foo").run().assertContent("c");
114 		b.get("/foo/x").run().assertContent("d");
115 		b.get("/x").run().assertContent("e");
116 		b.get("/x/x").run().assertContent("f");
117 		b.get("/x/foo").run().assertContent("g");
118 		b.get("/x/foo/x").run().assertContent("h");
119 	}
120 
121 	//-----------------------------------------------------------------------------------------------------------------
122 	// Overridden URL patterns
123 	//-----------------------------------------------------------------------------------------------------------------
124 
125 	@Rest
126 	public static class C1 {
127 		@RestGet(path="/foo")
128 		public String a() {
129 			return "a";
130 		}
131 	}
132 
133 	@Rest
134 	public static class C2 extends C1 {
135 		@RestGet(path="/foo")
136 		public String b() {  // Overrides method on parent.
137 			return "b";
138 		}
139 	}
140 
141 	@Test void c01_pathOverriddenByChild() throws Exception {
142 		var c2 = MockRestClient.build(C2.class);
143 		c2.get("/foo").run().assertContent("b");
144 	}
145 }