View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.client.cache;
28  
29  import static org.junit.Assert.assertEquals;
30  import static org.junit.Assert.assertFalse;
31  import static org.junit.Assert.assertNotNull;
32  import static org.junit.Assert.assertNull;
33  import static org.junit.Assert.assertSame;
34  import static org.junit.Assert.assertTrue;
35  import static org.junit.Assert.fail;
36  import static org.mockito.Mockito.mock;
37  
38  import java.util.Date;
39  import java.util.HashMap;
40  import java.util.Map;
41  
42  import org.apache.http.Header;
43  import org.apache.http.HttpStatus;
44  import org.apache.http.HttpVersion;
45  import org.apache.http.StatusLine;
46  import org.apache.http.client.utils.DateUtils;
47  import org.apache.http.message.BasicHeader;
48  import org.apache.http.message.BasicStatusLine;
49  import org.junit.Before;
50  import org.junit.Test;
51  
52  public class TestHttpCacheEntry {
53  
54      private Date now;
55      private Date elevenSecondsAgo;
56      private Date nineSecondsAgo;
57      private Resource mockResource;
58      private StatusLine statusLine;
59      private HttpCacheEntry entry;
60  
61      @Before
62      public void setUp() {
63          now = new Date();
64          elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
65          nineSecondsAgo = new Date(now.getTime() - 9 * 1000L);
66          statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1,
67                  HttpStatus.SC_OK, "OK");
68          mockResource = mock(Resource.class);
69      }
70  
71      private HttpCacheEntry makeEntry(final Header[] headers) {
72          return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo,
73                  statusLine, headers, mockResource, HeaderConstants.GET_METHOD);
74      }
75  
76      @Test
77      public void testGetHeadersReturnsCorrectHeaders() {
78          final Header[] headers = { new BasicHeader("foo", "fooValue"),
79                  new BasicHeader("bar", "barValue1"),
80                  new BasicHeader("bar", "barValue2")
81          };
82          entry = makeEntry(headers);
83          assertEquals(2, entry.getHeaders("bar").length);
84      }
85  
86      @Test
87      public void testGetFirstHeaderReturnsCorrectHeader() {
88          final Header[] headers = { new BasicHeader("foo", "fooValue"),
89                  new BasicHeader("bar", "barValue1"),
90                  new BasicHeader("bar", "barValue2")
91          };
92          entry = makeEntry(headers);
93          assertEquals("barValue1", entry.getFirstHeader("bar").getValue());
94      }
95  
96      @Test
97      public void testGetHeadersReturnsEmptyArrayIfNoneMatch() {
98          final Header[] headers = { new BasicHeader("foo", "fooValue"),
99                  new BasicHeader("bar", "barValue1"),
100                 new BasicHeader("bar", "barValue2")
101         };
102         entry = makeEntry(headers);
103         assertEquals(0, entry.getHeaders("baz").length);
104     }
105 
106     @Test
107     public void testGetFirstHeaderReturnsNullIfNoneMatch() {
108         final Header[] headers = { new BasicHeader("foo", "fooValue"),
109                 new BasicHeader("bar", "barValue1"),
110                 new BasicHeader("bar", "barValue2")
111         };
112         entry = makeEntry(headers);
113         assertEquals(null, entry.getFirstHeader("quux"));
114     }
115 
116     @Test
117     public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() {
118         final Header[] headers = new Header[0];
119         entry = makeEntry(headers);
120         assertFalse(entry.hasVariants());
121     }
122 
123     @Test
124     public void testCacheEntryWithOneVaryHeaderHasVariants() {
125         final Header[] headers = { new BasicHeader("Vary", "User-Agent") };
126         entry = makeEntry(headers);
127         assertTrue(entry.hasVariants());
128     }
129 
130     @Test
131     public void testCacheEntryWithMultipleVaryHeadersHasVariants() {
132         final Header[] headers = { new BasicHeader("Vary", "User-Agent"),
133                 new BasicHeader("Vary", "Accept-Encoding")
134         };
135         entry = makeEntry(headers);
136         assertTrue(entry.hasVariants());
137     }
138 
139     @Test
140     public void testCacheEntryWithVaryStarHasVariants(){
141         final Header[] headers = { new BasicHeader("Vary", "*") };
142         entry = makeEntry(headers);
143         assertTrue(entry.hasVariants());
144     }
145 
146     @SuppressWarnings("unused")
147     @Test
148     public void mustProvideRequestDate() {
149         try {
150             new HttpCacheEntry(null, new Date(), statusLine,
151                     new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
152             fail("Should have thrown exception");
153         } catch (final IllegalArgumentException expected) {
154         }
155     }
156 
157     @SuppressWarnings("unused")
158     @Test
159     public void mustProvideResponseDate() {
160         try {
161             new HttpCacheEntry(new Date(), null, statusLine,
162                     new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
163             fail("Should have thrown exception");
164         } catch (final IllegalArgumentException expected) {
165         }
166     }
167 
168     @SuppressWarnings("unused")
169     @Test
170     public void mustProvideStatusLine() {
171         try {
172             new HttpCacheEntry(new Date(), new Date(), null,
173                     new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
174             fail("Should have thrown exception");
175         } catch (final IllegalArgumentException expected) {
176         }
177     }
178 
179     @SuppressWarnings("unused")
180     @Test
181     public void mustProvideResponseHeaders() {
182         try {
183             new HttpCacheEntry(new Date(), new Date(), statusLine,
184                     null, mockResource, HeaderConstants.GET_METHOD);
185             fail("Should have thrown exception");
186         } catch (final IllegalArgumentException expected) {
187         }
188     }
189 
190     @Test
191     public void canRetrieveOriginalStatusLine() {
192         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
193                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
194         assertSame(statusLine, entry.getStatusLine());
195     }
196 
197     @Test
198     public void protocolVersionComesFromOriginalStatusLine() {
199         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
200                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
201         assertSame(statusLine.getProtocolVersion(),
202                 entry.getProtocolVersion());
203     }
204 
205     @Test
206     public void reasonPhraseComesFromOriginalStatusLine() {
207         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
208                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
209         assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase());
210     }
211 
212     @Test
213     public void statusCodeComesFromOriginalStatusLine() {
214         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
215                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
216         assertEquals(statusLine.getStatusCode(), entry.getStatusCode());
217     }
218 
219     @Test
220     public void canGetOriginalRequestDate() {
221         final Date requestDate = new Date();
222         entry = new HttpCacheEntry(requestDate, new Date(), statusLine,
223                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
224         assertSame(requestDate, entry.getRequestDate());
225     }
226 
227     @Test
228     public void canGetOriginalResponseDate() {
229         final Date responseDate = new Date();
230         entry = new HttpCacheEntry(new Date(), responseDate, statusLine,
231                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
232         assertSame(responseDate, entry.getResponseDate());
233     }
234 
235     @Test
236     public void canGetOriginalResource() {
237         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
238                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
239         assertSame(mockResource, entry.getResource());
240     }
241 
242     @Test
243     public void canGetOriginalHeaders() {
244         final Header[] headers = {
245                 new BasicHeader("Server", "MockServer/1.0"),
246                 new BasicHeader("Date", DateUtils.formatDate(now))
247         };
248         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
249                 headers, mockResource, HeaderConstants.GET_METHOD);
250         final Header[] result = entry.getAllHeaders();
251         assertEquals(headers.length, result.length);
252         for(int i=0; i<headers.length; i++) {
253             assertEquals(headers[i], result[i]);
254         }
255     }
256 
257     @SuppressWarnings("unused")
258     @Test
259     public void canConstructWithoutVariants() {
260         new HttpCacheEntry(new Date(), new Date(), statusLine,
261                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
262     }
263 
264     @SuppressWarnings("unused")
265     @Test
266     public void canProvideVariantMap() {
267         new HttpCacheEntry(new Date(), new Date(), statusLine,
268                 new Header[]{}, mockResource,
269                 new HashMap<String,String>(), HeaderConstants.GET_METHOD);
270     }
271 
272     @Test
273     public void canRetrieveOriginalVariantMap() {
274         final Map<String,String> variantMap = new HashMap<String,String>();
275         variantMap.put("A","B");
276         variantMap.put("C","D");
277         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
278                 new Header[]{}, mockResource,
279                 variantMap, HeaderConstants.GET_METHOD);
280         final Map<String,String> result = entry.getVariantMap();
281         assertEquals(2, result.size());
282         assertEquals("B", result.get("A"));
283         assertEquals("D", result.get("C"));
284     }
285 
286     @Test
287     public void retrievedVariantMapIsNotModifiable() {
288         final Map<String,String> variantMap = new HashMap<String,String>();
289         variantMap.put("A","B");
290         variantMap.put("C","D");
291         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
292                 new Header[]{}, mockResource,
293                 variantMap, HeaderConstants.GET_METHOD);
294         final Map<String,String> result = entry.getVariantMap();
295         try {
296             result.remove("A");
297             fail("Should have thrown exception");
298         } catch (final UnsupportedOperationException expected) {
299         }
300         try {
301             result.put("E","F");
302             fail("Should have thrown exception");
303         } catch (final UnsupportedOperationException expected) {
304         }
305     }
306 
307     @Test
308     public void canConvertToString() {
309         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
310                 new Header[]{}, mockResource, HeaderConstants.GET_METHOD);
311         assertNotNull(entry.toString());
312         assertFalse("".equals(entry.toString()));
313     }
314 
315     @Test
316     public void testMissingDateHeaderIsIgnored() {
317         final Header[] headers = new Header[] {};
318         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
319                                    headers, mockResource, HeaderConstants.GET_METHOD);
320         assertNull(entry.getDate());
321     }
322 
323     @Test
324     public void testMalformedDateHeaderIsIgnored() {
325         final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
326         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
327                                    headers, mockResource, HeaderConstants.GET_METHOD);
328         assertNull(entry.getDate());
329     }
330 
331     @Test
332     public void testValidDateHeaderIsParsed() {
333         final long nowMs = System.currentTimeMillis();
334         // round down to nearest second to make comparison easier
335         final Date date = new Date(nowMs - (nowMs % 1000L));
336         final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(date)) };
337         entry = new HttpCacheEntry(new Date(), new Date(), statusLine,
338                                    headers, mockResource, HeaderConstants.GET_METHOD);
339         final Date dateHeaderValue = entry.getDate();
340         assertNotNull(dateHeaderValue);
341         assertEquals(date.getTime(), dateHeaderValue.getTime());
342     }
343 
344     @Test
345     public void testGetMethodReturnsCorrectRequestMethod() {
346         final Header[] headers = { new BasicHeader("foo", "fooValue"),
347                 new BasicHeader("bar", "barValue1"),
348                 new BasicHeader("bar", "barValue2")
349         };
350         entry = makeEntry(headers);
351         assertEquals(HeaderConstants.GET_METHOD, entry.getRequestMethod());
352     }
353 }