View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.http.handler;
18  
19  import static com.xebialabs.restito.builder.stub.StubHttp.whenHttp;
20  import static com.xebialabs.restito.semantics.Action.composite;
21  import static com.xebialabs.restito.semantics.Action.ok;
22  import static com.xebialabs.restito.semantics.Action.status;
23  import static com.xebialabs.restito.semantics.Action.stringContent;
24  import static com.xebialabs.restito.semantics.Condition.not;
25  import static com.xebialabs.restito.semantics.Condition.post;
26  import static com.xebialabs.restito.semantics.Condition.withPostBody;
27  import static com.xebialabs.restito.semantics.Condition.withPostBodyContaining;
28  import static java.lang.String.format;
29  import static org.assertj.core.api.Assertions.assertThat;
30  
31  import org.forgerock.http.HttpApplicationException;
32  import org.forgerock.http.protocol.Request;
33  import org.forgerock.http.protocol.Response;
34  import org.forgerock.http.protocol.Status;
35  import org.forgerock.services.context.RootContext;
36  import org.glassfish.grizzly.http.util.HttpStatus;
37  import org.testng.annotations.AfterTest;
38  import org.testng.annotations.BeforeMethod;
39  import org.testng.annotations.BeforeTest;
40  import org.testng.annotations.Test;
41  
42  import com.xebialabs.restito.server.StubServer;
43  
44  /**
45   * This is the base class to ensure common behaviour between CHF client implementations.
46   */
47  public abstract class HttpClientHandlerTest {
48  
49      /** The HTTP server to query. */
50      protected StubServer server;
51  
52      /**
53       * Setup the HTTP server.
54       */
55      @BeforeTest
56      public void setUp() {
57          // Create mock HTTP server.
58          server = new StubServer().run();
59      }
60  
61      /**
62       * Stop the HTTP server.
63       */
64      @AfterTest
65      public void tearDown() {
66          server.stop();
67      }
68  
69      /**
70       * Reset the HTTP server.
71       */
72      @BeforeMethod
73      public void cleanup() {
74          // Clear mocked invocations between tests
75          // So we can reuse the server instance (less traces) still having isolation
76          if (server != null) {
77              server.clear();
78          }
79      }
80  
81      /**
82       * Ensure that a response is produced.
83       * @throws Exception In case of failure.
84       */
85      @Test
86      public void shouldProduceResponse() throws Exception {
87          whenHttp(server).match(post("/ping"))
88                  .then(composite(ok(), stringContent("Pong")));
89  
90          try (HttpClientHandler handler = buildHttpClientHandler()) {
91              Request request = new Request();
92              request.setMethod("POST");
93              request.setUri(format("http://localhost:%d/ping", server.getPort()));
94              Response response = handler.handle(new RootContext(), request).get();
95              assertThat(response.getStatus()).isEqualTo(Status.OK);
96              assertThat(response.getEntity().getString()).isEqualTo("Pong");
97          }
98      }
99  
100     /**
101      * Ensure that a request with a posted entity can be sent.
102      * @throws Exception In case of failure.
103      */
104     @Test
105     public void shouldSendPostHttpMessageWithEntityContent() throws Exception {
106         whenHttp(server).match(post("/test"),
107                 withPostBodyContaining("Hello"))
108                 .then(status(HttpStatus.OK_200));
109 
110         try (HttpClientHandler handler = buildHttpClientHandler()) {
111             Request request = new Request();
112             request.setMethod("POST");
113             request.setUri(format("http://localhost:%d/test", server.getPort()));
114             request.getEntity().setString("Hello");
115             assertThat(handler.handle(new RootContext(), request).get().getStatus()).isEqualTo(Status.OK);
116         }
117     }
118 
119     /**
120      * Ensure that a request with a posted empty entity can be sent.
121      * @throws Exception In case of failure.
122      */
123     @Test
124     public void shouldSendPostHttpMessageWithEmptyEntity() throws Exception {
125         whenHttp(server).match(post("/test"),
126                 not(withPostBody()))
127                 .then(status(HttpStatus.OK_200));
128 
129         try (HttpClientHandler handler = buildHttpClientHandler()) {
130             Request request = new Request();
131             request.setMethod("POST");
132             request.setUri(format("http://localhost:%d/test", server.getPort()));
133             assertThat(handler.handle(new RootContext(), request).get().getStatus()).isEqualTo(Status.OK);
134         }
135     }
136 
137     /**
138      * Ensure that a response with status BAD_GATEWAY is received when an error occurred.
139      * @throws Exception In case of failure.
140      */
141     @Test
142     public void shouldFailToObtainResponse() throws Exception {
143         // The request is invalid because we did not specify the method.
144         final Request invalidRequest = new Request();
145         invalidRequest.setUri(format("http://localhost:%d/shouldFail", server.getPort()));
146 
147         try (HttpClientHandler handler = buildHttpClientHandler()) {
148             final Response response = handler.handle(new RootContext(), invalidRequest).get();
149 
150             assertThat(response.getStatus()).isEqualTo(Status.BAD_GATEWAY);
151             assertThat(response.getEntity().getString()).isEmpty();
152             assertThat(response.getCause()).isNotNull();
153         }
154     }
155 
156     /**
157      *  Instantiates the expected HttpClientHandler to test.
158      *  @return the expected HttpClientHandler to test.
159      *  @throws HttpApplicationException In case of failure when trying to create it.
160      */
161     protected abstract HttpClientHandler buildHttpClientHandler() throws HttpApplicationException;
162 
163 }