Coverage Report - com.jcabi.http.request.FakeRequest
 
Classes in this File Line Coverage Branch Coverage Complexity
FakeRequest
77%
24/31
32%
11/34
1.105
FakeRequest$1
100%
2/2
N/A
1.105
 
 1  
 /**
 2  
  * Copyright (c) 2011-2017, 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.request;
 31  
 
 32  
 import com.jcabi.aspects.Immutable;
 33  
 import com.jcabi.aspects.Loggable;
 34  
 import com.jcabi.http.ImmutableHeader;
 35  
 import com.jcabi.http.Request;
 36  
 import com.jcabi.http.RequestBody;
 37  
 import com.jcabi.http.RequestURI;
 38  
 import com.jcabi.http.Response;
 39  
 import com.jcabi.http.Wire;
 40  
 import com.jcabi.immutable.Array;
 41  
 import java.io.IOException;
 42  
 import java.io.InputStream;
 43  
 import java.net.HttpURLConnection;
 44  
 import java.nio.charset.Charset;
 45  
 import java.util.Collection;
 46  
 import java.util.Collections;
 47  
 import java.util.Map;
 48  
 import lombok.EqualsAndHashCode;
 49  
 
 50  
 /**
 51  
  * Implementation of {@link Request} that always returns the same
 52  
  * response, specified in the constructor.
 53  
  *
 54  
  * <p>The class is immutable and thread-safe.
 55  
  *
 56  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 57  
  * @version $Id: a1c230f99e9149c56391d0946e47f456b62fb741 $
 58  
  * @since 0.9
 59  
  * @checkstyle ClassDataAbstractionCoupling (500 lines)
 60  
  */
 61  
 @Immutable
 62  1
 @EqualsAndHashCode(of = { "base", "code", "phrase", "hdrs", "content" })
 63  
 @Loggable(Loggable.DEBUG)
 64  
 @SuppressWarnings("PMD.TooManyMethods")
 65  124
 public final class FakeRequest implements Request {
 66  
 
 67  
     /**
 68  
      * An empty immutable {@code byte} array.
 69  
      */
 70  1
     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 71  
 
 72  
     /**
 73  
      * The Charset to use.
 74  
      */
 75  1
     private static final Charset CHARSET = Charset.forName("UTF-8");
 76  
 
 77  
     /**
 78  
      * Base request.
 79  
      * @checkstyle ParameterNumber (15 lines)
 80  
      */
 81  
     private final transient Request base;
 82  
 
 83  
     /**
 84  
      * Status code.
 85  
      */
 86  
     private final transient int code;
 87  
 
 88  
     /**
 89  
      * Reason phrase.
 90  
      */
 91  
     private final transient String phrase;
 92  
 
 93  
     /**
 94  
      * Headers.
 95  
      */
 96  
     private final transient Array<Map.Entry<String, String>> hdrs;
 97  
 
 98  
     /**
 99  
      * Content received.
 100  
      */
 101  
     @Immutable.Array
 102  
     private final transient byte[] content;
 103  
 
 104  
     /**
 105  
      * Public ctor.
 106  
      */
 107  
     public FakeRequest() {
 108  37
         this(
 109  
             HttpURLConnection.HTTP_OK,
 110  
             "OK",
 111  
             Collections.<Map.Entry<String, String>>emptyList(),
 112  
             FakeRequest.EMPTY_BYTE_ARRAY
 113  
         );
 114  37
     }
 115  
 
 116  
     /**
 117  
      * Public ctor.
 118  
      * @param status HTTP status code to return
 119  
      * @param reason HTTP reason
 120  
      * @param headers HTTP headers
 121  
      * @param body HTTP body
 122  
      * @checkstyle ParameterNumber (10 lines)
 123  
      */
 124  
     public FakeRequest(final int status, final String reason,
 125  
         final Collection<Map.Entry<String, String>> headers,
 126  75
         final byte[] body) {
 127  75
         this.code = status;
 128  75
         this.phrase = reason;
 129  75
         this.hdrs = new Array<>(headers);
 130  75
         this.content = body.clone();
 131  75
         this.base = new BaseRequest(
 132  75
             new Wire() {
 133  
                 @Override
 134  
                 // @checkstyle ParameterNumber (6 lines)
 135  
                 public Response send(final Request req, final String home,
 136  
                     final String method,
 137  
                     final Collection<Map.Entry<String, String>> headers,
 138  
                     final InputStream text,
 139  
                     final int connect,
 140  
                     final int read) {
 141  31
                     return new DefaultResponse(
 142  
                         req,
 143  
                         FakeRequest.this.code,
 144  
                         FakeRequest.this.phrase,
 145  
                         FakeRequest.this.hdrs,
 146  
                         FakeRequest.this.content
 147  
                     );
 148  
                 }
 149  
             },
 150  
             "http://localhost:12345/see-FakeRequest-class"
 151  
         );
 152  75
     }
 153  
 
 154  
     @Override
 155  
     public String toString() {
 156  0
         return this.base.toString();
 157  
     }
 158  
 
 159  
     @Override
 160  
     public RequestURI uri() {
 161  6
         return this.base.uri();
 162  
     }
 163  
 
 164  
     @Override
 165  
     public Request header(final String name, final Object value) {
 166  2
         return this.base.header(name, value);
 167  
     }
 168  
 
 169  
     @Override
 170  
     public Request reset(final String name) {
 171  0
         return this.base.reset(name);
 172  
     }
 173  
 
 174  
     @Override
 175  
     public RequestBody body() {
 176  1
         return this.base.body();
 177  
     }
 178  
 
 179  
     @Override
 180  
     public RequestBody multipartBody() {
 181  0
         return this.base.multipartBody();
 182  
     }
 183  
 
 184  
     @Override
 185  
     public Request method(final String method) {
 186  0
         return this.base.method(method);
 187  
     }
 188  
 
 189  
     @Override
 190  
     public Request timeout(final int connect, final int read) {
 191  0
         return this.base.timeout(connect, read);
 192  
     }
 193  
 
 194  
     @Override
 195  
     public Response fetch() throws IOException {
 196  25
         return this.base.fetch();
 197  
     }
 198  
 
 199  
     @Override
 200  
     public Response fetch(final InputStream stream) throws IOException {
 201  1
         if (this.content.length > 0) {
 202  1
             throw new IllegalStateException(
 203  
                 "Request Body is not empty, use fetch() instead"
 204  
             );
 205  
         }
 206  0
         return this.base.fetch(stream);
 207  
     }
 208  
 
 209  
     @Override
 210  
     public <T extends Wire> Request through(final Class<T> type,
 211  
         final Object... args) {
 212  0
         return this.base.through(type, args);
 213  
     }
 214  
 
 215  
     /**
 216  
      * Make a similar request, with the provided status code.
 217  
      * @param status The code
 218  
      * @return New request
 219  
      */
 220  
     public FakeRequest withStatus(final int status) {
 221  4
         return new FakeRequest(
 222  
             status,
 223  
             this.phrase,
 224  
             this.hdrs,
 225  
             this.content
 226  
         );
 227  
     }
 228  
 
 229  
     /**
 230  
      * Make a similar request, with the provided reason line.
 231  
      * @param reason Reason line
 232  
      * @return New request
 233  
      */
 234  
     public FakeRequest withReason(final String reason) {
 235  2
         return new FakeRequest(
 236  
             this.code,
 237  
             reason,
 238  
             this.hdrs,
 239  
             this.content
 240  
         );
 241  
     }
 242  
 
 243  
     /**
 244  
      * Make a similar request, with the provided HTTP header.
 245  
      * @param name Name of the header
 246  
      * @param value Value of it
 247  
      * @return New request
 248  
      */
 249  
     public FakeRequest withHeader(final String name, final String value) {
 250  7
         return new FakeRequest(
 251  
             this.code,
 252  
             this.phrase,
 253  
             this.hdrs.with(new ImmutableHeader(name, value)),
 254  
             this.content
 255  
         );
 256  
     }
 257  
 
 258  
     /**
 259  
      * Make a similar request, with the provided body.
 260  
      * @param text Body
 261  
      * @return New request
 262  
      */
 263  
     public FakeRequest withBody(final String text) {
 264  24
         return this.withBody(text.getBytes(FakeRequest.CHARSET));
 265  
     }
 266  
 
 267  
     /**
 268  
      * Make a similar request, with the provided body.
 269  
      * @param body Body
 270  
      * @return New request
 271  
      */
 272  
     public FakeRequest withBody(final byte[] body) {
 273  25
         return new FakeRequest(
 274  
             this.code,
 275  
             this.phrase,
 276  
             this.hdrs,
 277  
             body
 278  
         );
 279  
     }
 280  
 
 281  
 }