View Javadoc
1   /*
2    * Copyright (c) 2011-2022, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.http.wire;
31  
32  import com.google.common.cache.CacheBuilder;
33  import com.google.common.cache.CacheLoader;
34  import com.google.common.cache.LoadingCache;
35  import com.jcabi.http.Request;
36  import com.jcabi.http.Response;
37  import com.jcabi.http.mock.MkAnswer;
38  import com.jcabi.http.mock.MkContainer;
39  import com.jcabi.http.mock.MkGrizzlyContainer;
40  import com.jcabi.http.request.JdkRequest;
41  import com.jcabi.http.response.RestResponse;
42  import java.net.HttpURLConnection;
43  import java.util.concurrent.Callable;
44  import org.hamcrest.MatcherAssert;
45  import org.hamcrest.Matchers;
46  import org.junit.jupiter.api.Test;
47  
48  /**
49   * Test case for {@link CachingWire}.
50   * @since 1.0
51   */
52  final class CachingWireTest {
53  
54      /**
55       * CachingWire can cache GET requests.
56       * @throws Exception If something goes wrong inside
57       */
58      @Test
59      void cachesGetRequest() throws Exception {
60          final MkContainer container = new MkGrizzlyContainer().next(
61              new MkAnswer.Simple("")
62          ).start();
63          final Request req = new JdkRequest(container.home())
64              .through(CachingWire.class);
65          for (int idx = 0; idx < 10; ++idx) {
66              req.fetch().as(RestResponse.class)
67                  .assertStatus(HttpURLConnection.HTTP_OK);
68          }
69          container.stop();
70          MatcherAssert.assertThat(container.queries(), Matchers.equalTo(1));
71      }
72  
73      /**
74       * CachingWire can ignore PUT requests.
75       * @throws Exception If something goes wrong inside
76       */
77      @Test
78      void ignoresPutRequest() throws Exception {
79          final MkContainer container = new MkGrizzlyContainer()
80              .next(new MkAnswer.Simple(""))
81              .next(new MkAnswer.Simple(""))
82              .start();
83          final Request req = new JdkRequest(container.home())
84              .through(CachingWire.class).method(Request.PUT);
85          for (int idx = 0; idx < 2; ++idx) {
86              req.fetch().as(RestResponse.class)
87                  .assertStatus(HttpURLConnection.HTTP_OK);
88          }
89          container.stop();
90          MatcherAssert.assertThat(container.queries(), Matchers.equalTo(2));
91      }
92  
93      /**
94       * CachingWire can flush on regular expression match.
95       * @throws Exception If something goes wrong inside
96       */
97      @Test
98      void flushesOnRegularExpressionMatch() throws Exception {
99          final MkContainer container = new MkGrizzlyContainer()
100             .next(new MkAnswer.Simple("first response"))
101             .next(new MkAnswer.Simple("second response"))
102             .next(new MkAnswer.Simple("third response"))
103             .start();
104         final Request req = new JdkRequest(container.home())
105             .through(CachingWire.class, "POST /flush\\?a=1");
106         req.fetch()
107             .as(RestResponse.class)
108             .assertBody(Matchers.containsString("first"));
109         req.fetch()
110             .as(RestResponse.class)
111             .assertBody(Matchers.containsString("first re"));
112         req.method(Request.POST).uri().path("flush")
113             .queryParam("a", "1").back().fetch();
114         req.fetch()
115             .as(RestResponse.class)
116             .assertBody(Matchers.containsString("third"));
117         container.stop();
118         MatcherAssert.assertThat(
119             container.queries(),
120             Matchers.equalTo(3)
121         );
122     }
123 
124     /**
125      * CachingWire can use custom cache.
126      * @throws Exception If something goes wrong inside
127      */
128     @Test
129     void cachesGetRequestWithCustomCache() throws Exception {
130         final MkContainer container = new MkGrizzlyContainer().next(
131             new MkAnswer.Simple("")
132         ).next(
133             new MkAnswer.Simple(HttpURLConnection.HTTP_BAD_GATEWAY)
134         ).start();
135         final LoadingCache<Callable<Response>, Response> cache =
136             CacheBuilder
137                 .newBuilder()
138                 .build(
139                     new CacheLoader<Callable<Response>, Response>() {
140                         @Override
141                         public Response load(final Callable<Response> query)
142                             throws Exception {
143                             return query.call();
144                         }
145                     }
146                 );
147         final Request req = new JdkRequest(container.home())
148             .through(CachingWire.class, cache);
149         for (int idx = 0; idx < 10; ++idx) {
150             req.fetch().as(RestResponse.class)
151                 .assertStatus(HttpURLConnection.HTTP_OK);
152         }
153         container.stop();
154         MatcherAssert.assertThat(container.queries(), Matchers.equalTo(1));
155     }
156 
157 }