001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.mock;
014
015import java.util.*;
016import java.util.concurrent.*;
017
018import org.apache.juneau.rest.*;
019import org.apache.juneau.utils.*;
020
021/**
022 * Creates a mocked interface against a REST resource class.
023 *
024 * <div class='warn'>
025 *    <b>Deprecated</b> - Use <c>org.apache.juneau.restmock2</c>
026 * </div>
027 *
028 * <p>
029 * Allows you to test your REST resource classes without a running servlet container.
030 *
031 * <h5 class='figure'>Example:</h5>
032 * <p class='bcode w800'>
033 *  <jk>public class</jk> MockTest {
034 *
035 *    <jc>// Our REST resource to test.</jc>
036 *    <ja>@Rest</ja>(serializers=JsonSerializer.Simple.<jk>class</jk>, parsers=JsonParser.<jk>class</jk>)
037 *    <jk>public static class</jk> MyRest {
038 *
039 *       <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/String"</js>)
040 *       <jk>public</jk> String echo(<ja>@Body</ja> String b) {
041 *          <jk>return</jk> b;
042 *       }
043 *    }
044 *
045 *  <ja>@Test</ja>
046 *  <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
047 *    MockRest
048 *       .<jsm>create</jsm>(MyRest.<jk>class</jk>)
049 *       .put(<js>"/String"</js>, <js>"'foo'"</js>)
050 *       .execute()
051 *       .assertStatus(200)
052 *       .assertBody(<js>"'foo'"</js>);
053 *  }
054 * </p>
055 */
056@Deprecated
057public class MockRest implements MockHttpConnection {
058   private static Map<Class<?>,RestContext> CONTEXTS = new ConcurrentHashMap<>();
059
060   private final RestContext rc;
061
062   private MockRest(Class<?> c, boolean debug) throws Exception {
063      if (! CONTEXTS.containsKey(c)) {
064         Object r = c.newInstance();
065         RestContext rc = RestContext.create(r).logger(debug ? BasicRestLogger.class : NoOpRestLogger.class).build();
066         if (r instanceof RestServlet) {
067            ((RestServlet)r).setContext(rc);
068         } else {
069            rc.postInit();
070         }
071         rc.postInitChildFirst();
072         CONTEXTS.put(c, rc);
073      }
074      rc = CONTEXTS.get(c);
075   }
076
077   /**
078    * Create a new mock REST interface
079    *
080    * @param c The REST class.
081    * @return A new mock interface.
082    * @throws RuntimeException
083    *    For testing conveniences, this method wraps all exceptions in a RuntimeException so that you can easily define mocks as reusable fields.
084    */
085   public static MockRest create(Class<?> c) throws RuntimeException {
086      return create(c, false);
087   }
088
089   /**
090    * Create a new mock REST interface
091    *
092    * @param c The REST class.
093    * @param debug
094    *    If <jk>true</jk>, the REST interface will use the {@link BasicRestLogger} for logging.
095    *    <br>Otherwise, uses {@link NoOpRestLogger}.
096    * @return A new mock interface.
097    * @throws RuntimeException
098    *    For testing conveniences, this method wraps all exceptions in a RuntimeException so that you can easily define mocks as reusable fields.
099    */
100   public static MockRest create(Class<?> c, boolean debug) throws RuntimeException {
101      try {
102         return new MockRest(c, debug);
103      } catch (Exception e) {
104         throw new RuntimeException(e);
105      }
106   }
107
108   /**
109    * Performs a REST request against the REST interface.
110    *
111    * @param method The HTTP method
112    * @param path The URI path.
113    * @param body The body of the request.
114    * @return A new servlet request.
115    * @throws Exception Error occurred.
116    */
117   @Override /* MockHttpConnection */
118   public MockServletRequest request(String method, String path, Object body) throws Exception {
119      return MockServletRequest.create(method, path).body(body).restContext(rc);
120   }
121
122   /**
123    * Performs a REST request against the REST interface.
124    *
125    * @param method The HTTP method
126    * @param path The URI path.
127    * @return A new servlet request.
128    * @throws Exception Error occurred.
129    */
130   public MockServletRequest request(String method, String path) throws Exception {
131      return request(method, path, null);
132   }
133
134   /**
135    * Perform a GET request.
136    *
137    * @param path The URI path.
138    * @return A new servlet request.
139    * @throws Exception Error occurred.
140    */
141   public MockServletRequest get(String path) throws Exception {
142      return request("GET", path, null);
143   }
144
145   /**
146    * Perform a PUT request.
147    *
148    * @param path The URI path.
149    * @param body The body of the request.
150    * @return A new servlet request.
151    * @throws Exception Error occurred.
152    */
153   public MockServletRequest put(String path, Object body) throws Exception {
154      return request("PUT", path, body);
155   }
156
157   /**
158    * Perform a POST request.
159    *
160    * @param path The URI path.
161    * @param body The body of the request.
162    * @return A new servlet request.
163    * @throws Exception Error occurred.
164    */
165   public MockServletRequest post(String path, Object body) throws Exception {
166      return request("POST", path, body);
167   }
168
169   /**
170    * Perform a DELETE request.
171    *
172    * @param path The URI path.
173    * @return A new servlet request.
174    * @throws Exception Error occurred.
175    */
176   public MockServletRequest delete(String path) throws Exception {
177      return request("DELETE", path, null);
178   }
179
180   /**
181    * Perform an OPTIONS request.
182    *
183    * @param path The URI path.
184    * @return A new servlet request.
185    * @throws Exception Error occurred.
186    */
187   public MockServletRequest options(String path) throws Exception {
188      return request("OPTIONS", path, null);
189   }
190}