1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.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.hc.client5.http.utils.DateUtils;
43 import org.apache.hc.core5.http.Header;
44 import org.apache.hc.core5.http.HttpStatus;
45 import org.apache.hc.core5.http.message.BasicHeader;
46 import org.junit.Before;
47 import org.junit.Test;
48
49 public class TestHttpCacheEntry {
50
51 private Date now;
52 private Date elevenSecondsAgo;
53 private Date nineSecondsAgo;
54 private Resource mockResource;
55 private HttpCacheEntry entry;
56
57 @Before
58 public void setUp() {
59 now = new Date();
60 elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
61 nineSecondsAgo = new Date(now.getTime() - 9 * 1000L);
62 mockResource = mock(Resource.class);
63 }
64
65 private HttpCacheEntry makeEntry(final Header[] headers) {
66 return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, HttpStatus.SC_OK, headers, mockResource);
67 }
68
69 @Test
70 public void testGetHeadersReturnsCorrectHeaders() {
71 final Header[] headers = { new BasicHeader("foo", "fooValue"),
72 new BasicHeader("bar", "barValue1"),
73 new BasicHeader("bar", "barValue2")
74 };
75 entry = makeEntry(headers);
76 assertEquals(2, entry.getHeaders("bar").length);
77 }
78
79 @Test
80 public void testGetFirstHeaderReturnsCorrectHeader() {
81 final Header[] headers = { new BasicHeader("foo", "fooValue"),
82 new BasicHeader("bar", "barValue1"),
83 new BasicHeader("bar", "barValue2")
84 };
85 entry = makeEntry(headers);
86 assertEquals("barValue1", entry.getFirstHeader("bar").getValue());
87 }
88
89 @Test
90 public void testGetHeadersReturnsEmptyArrayIfNoneMatch() {
91 final Header[] headers = { new BasicHeader("foo", "fooValue"),
92 new BasicHeader("bar", "barValue1"),
93 new BasicHeader("bar", "barValue2")
94 };
95 entry = makeEntry(headers);
96 assertEquals(0, entry.getHeaders("baz").length);
97 }
98
99 @Test
100 public void testGetFirstHeaderReturnsNullIfNoneMatch() {
101 final Header[] headers = { new BasicHeader("foo", "fooValue"),
102 new BasicHeader("bar", "barValue1"),
103 new BasicHeader("bar", "barValue2")
104 };
105 entry = makeEntry(headers);
106 assertEquals(null, entry.getFirstHeader("quux"));
107 }
108
109 @Test
110 public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() {
111 final Header[] headers = new Header[0];
112 entry = makeEntry(headers);
113 assertFalse(entry.hasVariants());
114 }
115
116 @Test
117 public void testCacheEntryWithOneVaryHeaderHasVariants() {
118 final Header[] headers = { new BasicHeader("Vary", "User-Agent") };
119 entry = makeEntry(headers);
120 assertTrue(entry.hasVariants());
121 }
122
123 @Test
124 public void testCacheEntryWithMultipleVaryHeadersHasVariants() {
125 final Header[] headers = { new BasicHeader("Vary", "User-Agent"),
126 new BasicHeader("Vary", "Accept-Encoding")
127 };
128 entry = makeEntry(headers);
129 assertTrue(entry.hasVariants());
130 }
131
132 @Test
133 public void testCacheEntryWithVaryStarHasVariants(){
134 final Header[] headers = { new BasicHeader("Vary", "*") };
135 entry = makeEntry(headers);
136 assertTrue(entry.hasVariants());
137 }
138
139 @SuppressWarnings("unused")
140 @Test
141 public void mustProvideRequestDate() {
142 try {
143 new HttpCacheEntry(null, new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource);
144 fail("Should have thrown exception");
145 } catch (final NullPointerException expected) {
146 }
147 }
148
149 @SuppressWarnings("unused")
150 @Test
151 public void mustProvideResponseDate() {
152 try {
153 new HttpCacheEntry(new Date(), null, HttpStatus.SC_OK, new Header[]{}, mockResource);
154 fail("Should have thrown exception");
155 } catch (final NullPointerException expected) {
156 }
157 }
158
159 @SuppressWarnings("unused")
160 @Test
161 public void mustProvideResponseHeaders() {
162 try {
163 new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, null, mockResource);
164 fail("Should have thrown exception");
165 } catch (final NullPointerException expected) {
166 }
167 }
168
169 @Test
170 public void statusCodeComesFromOriginalStatusLine() {
171 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource);
172 assertEquals(HttpStatus.SC_OK, entry.getStatus());
173 }
174
175 @Test
176 public void canGetOriginalRequestDate() {
177 final Date requestDate = new Date();
178 entry = new HttpCacheEntry(requestDate, new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource);
179 assertSame(requestDate, entry.getRequestDate());
180 }
181
182 @Test
183 public void canGetOriginalResponseDate() {
184 final Date responseDate = new Date();
185 entry = new HttpCacheEntry(new Date(), responseDate, HttpStatus.SC_OK, new Header[]{}, mockResource);
186 assertSame(responseDate, entry.getResponseDate());
187 }
188
189 @Test
190 public void canGetOriginalResource() {
191 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource);
192 assertSame(mockResource, entry.getResource());
193 }
194
195 @Test
196 public void canGetOriginalHeaders() {
197 final Header[] headers = {
198 new BasicHeader("Server", "MockServer/1.0"),
199 new BasicHeader("Date", DateUtils.formatDate(now))
200 };
201 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, headers, mockResource);
202 final Header[] result = entry.getHeaders();
203 assertEquals(headers.length, result.length);
204 for(int i=0; i<headers.length; i++) {
205 assertEquals(headers[i], result[i]);
206 }
207 }
208
209 @SuppressWarnings("unused")
210 @Test
211 public void canConstructWithoutVariants() {
212 new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource);
213 }
214
215 @SuppressWarnings("unused")
216 @Test
217 public void canProvideVariantMap() {
218 new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
219 new Header[]{}, mockResource,
220 new HashMap<String,String>());
221 }
222
223 @Test
224 public void canRetrieveOriginalVariantMap() {
225 final Map<String,String> variantMap = new HashMap<>();
226 variantMap.put("A","B");
227 variantMap.put("C","D");
228 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
229 new Header[]{}, mockResource,
230 variantMap);
231 final Map<String,String> result = entry.getVariantMap();
232 assertEquals(2, result.size());
233 assertEquals("B", result.get("A"));
234 assertEquals("D", result.get("C"));
235 }
236
237 @Test
238 public void retrievedVariantMapIsNotModifiable() {
239 final Map<String,String> variantMap = new HashMap<>();
240 variantMap.put("A","B");
241 variantMap.put("C","D");
242 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
243 new Header[]{}, mockResource,
244 variantMap);
245 final Map<String,String> result = entry.getVariantMap();
246 try {
247 result.remove("A");
248 fail("Should have thrown exception");
249 } catch (final UnsupportedOperationException expected) {
250 }
251 try {
252 result.put("E","F");
253 fail("Should have thrown exception");
254 } catch (final UnsupportedOperationException expected) {
255 }
256 }
257
258 @Test
259 public void canConvertToString() {
260 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
261 new Header[]{}, mockResource);
262 assertNotNull(entry.toString());
263 assertFalse("".equals(entry.toString()));
264 }
265
266 @Test
267 public void testMissingDateHeaderIsIgnored() {
268 final Header[] headers = new Header[] {};
269 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
270 headers, mockResource);
271 assertNull(entry.getDate());
272 }
273
274 @Test
275 public void testMalformedDateHeaderIsIgnored() {
276 final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
277 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
278 headers, mockResource);
279 assertNull(entry.getDate());
280 }
281
282 @Test
283 public void testValidDateHeaderIsParsed() {
284 final long nowMs = System.currentTimeMillis();
285
286 final Date date = new Date(nowMs - (nowMs % 1000L));
287 final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(date)) };
288 entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
289 headers, mockResource);
290 final Date dateHeaderValue = entry.getDate();
291 assertNotNull(dateHeaderValue);
292 assertEquals(date.getTime(), dateHeaderValue.getTime());
293 }
294
295 @Test
296 public void testGetMethodReturnsCorrectRequestMethod() {
297 final Header[] headers = { new BasicHeader("foo", "fooValue"),
298 new BasicHeader("bar", "barValue1"),
299 new BasicHeader("bar", "barValue2")
300 };
301 entry = makeEntry(headers);
302 assertEquals(HeaderConstants.GET_METHOD, entry.getRequestMethod());
303 }
304 }