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.collections.*;
21  import org.apache.juneau.http.annotation.*;
22  import org.apache.juneau.rest.*;
23  import org.apache.juneau.rest.mock.*;
24  import org.apache.juneau.utest.utils.*;
25  import org.junit.jupiter.api.*;
26  
27  class Restx_Parsers_Test extends TestBase {
28  
29  	//------------------------------------------------------------------------------------------------------------------
30  	// Setup
31  	//------------------------------------------------------------------------------------------------------------------
32  
33  	public static class PA extends FakeReaderParser {
34  		public PA(FakeReaderParser.Builder b) {
35  			super(b.consumes("text/a").function((session,in,type)->"text/a - " + in));
36  		}
37  	}
38  
39  	public static class PB extends FakeReaderParser {
40  		public PB(FakeReaderParser.Builder b) {
41  			super(b.consumes("text/b").function((session,in,type)->"text/b - " + in));
42  		}
43  	}
44  
45  	public static class PC extends FakeReaderParser {
46  		public PC(FakeReaderParser.Builder b) {
47  			super(b.consumes("text/c").function((session,in,type)->"text/c - " + in));
48  		}
49  	}
50  
51  	public static class PD extends FakeReaderParser {
52  		public PD(FakeReaderParser.Builder b) {
53  			super(b.consumes("text/d").function((session,in,type)->"text/d - " + in));
54  		}
55  	}
56  
57  	//------------------------------------------------------------------------------------------------------------------
58  	// Basic tests
59  	//------------------------------------------------------------------------------------------------------------------
60  
61  	@Rest(parsers=PA.class)
62  	public static class A {
63  		@RestPut
64  		public String a(@Content String in) {
65  			return in;
66  		}
67  		@RestPut(parsers=PB.class)
68  		public String b(@Content String in) {
69  			return in;
70  		}
71  		@RestPut(parsers={Inherit.class, PB.class,PC.class})
72  		public String c(@Content String in) {
73  			return in;
74  		}
75  		@RestPut(parsers={Inherit.class, PD.class})
76  		public String d(@Content String in) {
77  			return in;
78  		}
79  		@RestPut
80  		public String e(@Content String in) {
81  			return in;
82  		}
83  	}
84  
85  	@Test void a01_basic() throws Exception {
86  		var a = MockRestClient.buildLax(A.class);
87  
88  		a.put("/a", "test1")
89  			.contentType("text/a")
90  			.run()
91  			.assertContent("text/a - test1");
92  		a.put("/a?noTrace=true", "test1")
93  			.contentType("text/b")
94  			.run()
95  			.assertStatus(415)
96  			.assertContent().isContains(
97  				"Unsupported media-type in request header 'Content-Type': 'text/b'",
98  				"Supported media-types: ['text/a"
99  			);
100 
101 		a.put("/b", "test2")
102 			.contentType("text/b")
103 			.run()
104 			.assertContent("text/b - test2");
105 		a.put("/b?noTrace=true", "test2")
106 			.contentType("text/a")
107 			.run()
108 			.assertStatus(415)
109 			.assertContent().isContains(
110 				"Unsupported media-type in request header 'Content-Type': 'text/a'",
111 				"Supported media-types: ['text/b']"
112 			);
113 
114 		a.put("/c", "test3")
115 			.contentType("text/a")
116 			.run()
117 			.assertContent("text/a - test3");
118 		a.put("/c", "test3")
119 			.contentType("text/b")
120 			.run()
121 			.assertContent("text/b - test3");
122 
123 		a.put("/d", "test4")
124 			.contentType("text/a")
125 			.run()
126 			.assertContent("text/a - test4");
127 		a.put("/d", "test4")
128 			.contentType("text/d")
129 			.run()
130 			.assertContent("text/d - test4");
131 
132 		a.put("/e?noTrace=true", "test1")
133 			.contentType("text/bad")
134 			.run()
135 			.assertStatus(415)
136 			.assertContent().isContains(
137 				"Unsupported media-type in request header 'Content-Type': 'text/bad'",
138 				"Supported media-types: ['text/a"
139 			);
140 	}
141 
142 	//------------------------------------------------------------------------------------------------------------------
143 	// Test parser inheritance.
144 	//------------------------------------------------------------------------------------------------------------------
145 
146 	public static class P1 extends FakeReaderParser{ public P1(FakeReaderParser.Builder b) {super(b.consumes("text/p1"));} }
147 	public static class P2 extends FakeReaderParser{ public P2(FakeReaderParser.Builder b) {super(b.consumes("text/p2"));} }
148 	public static class P3 extends FakeReaderParser{ public P3(FakeReaderParser.Builder b) {super(b.consumes("text/p3"));} }
149 	public static class P4 extends FakeReaderParser{ public P4(FakeReaderParser.Builder b) {super(b.consumes("text/p4"));} }
150 	public static class P5 extends FakeReaderParser{ public P5(FakeReaderParser.Builder b) {super(b.consumes("text/p5"));} }
151 
152 	@Rest(parsers={P1.class,P2.class})
153 	public static class B {}
154 
155 	@Rest(parsers={P3.class,P4.class})
156 	public static class B1 extends B {}
157 
158 	@Rest
159 	public static class B2 extends B1 {
160 		@RestOp
161 		public JsonList a(RestRequest req) {
162 			// Should show ['text/p3','text/p4','text/p1','text/p2']
163 			return JsonList.of(req.getOpContext().getSupportedContentTypes());
164 		}
165 		@RestOp(parsers=P5.class)
166 		public JsonList b(RestRequest req) {
167 			// Should show ['text/p5']
168 			return JsonList.of(req.getOpContext().getSupportedContentTypes());
169 		}
170 		@RestOp(parsers={P5.class,Inherit.class})
171 		public JsonList c(RestRequest req) {
172 			// Should show ['text/p5','text/p3','text/p4','text/p1','text/p2']
173 			return JsonList.of(req.getOpContext().getSupportedContentTypes());
174 		}
175 	}
176 
177 	@Test void b01_inheritence() throws Exception {
178 		var b = MockRestClient.build(B2.class);
179 		b.get("/a").run().assertContent("['text/p3','text/p4','text/p1','text/p2']");
180 		b.get("/b").run().assertContent("['text/p5']");
181 		b.get("/c").run().assertContent("['text/p5','text/p3','text/p4','text/p1','text/p2']");
182 	}
183 
184 }