1
2
3
4
5 package com.jcabi.dynamo;
6
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.Map;
11 import org.hamcrest.MatcherAssert;
12 import org.hamcrest.Matchers;
13 import org.junit.jupiter.api.Assertions;
14 import org.junit.jupiter.api.Test;
15 import org.mockito.Mockito;
16 import software.amazon.awssdk.core.exception.SdkClientException;
17 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
18 import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
19 import software.amazon.awssdk.services.dynamodb.model.ConsumedCapacity;
20 import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
21 import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
22
23
24
25
26
27 @SuppressWarnings("PMD.TooManyMethods")
28 final class QueryValveTest {
29
30 @Test
31 @SuppressWarnings("unchecked")
32 void fetchesDataWithNoNext() throws Exception {
33 final Credentials credentials = Mockito.mock(Credentials.class);
34 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
35 Mockito.doReturn(aws).when(credentials).aws();
36 Mockito.doReturn(
37 QueryResponse.builder()
38 .items(
39 Collections.singletonList(Collections.emptyMap())
40 )
41 .consumedCapacity(
42 ConsumedCapacity.builder().capacityUnits(1.0d).build()
43 )
44 .build()
45 ).when(aws).query(Mockito.any(QueryRequest.class));
46 MatcherAssert.assertThat(
47 "should be false",
48 new QueryValve().fetch(
49 credentials, "table",
50 new Conditions(), new ArrayList<>(0)
51 ).hasNext(),
52 Matchers.is(false)
53 );
54 }
55
56 @Test
57 @SuppressWarnings("unchecked")
58 void fetchesDataWithItems() throws Exception {
59 final Credentials credentials = Mockito.mock(Credentials.class);
60 final Map<String, AttributeValue> item = Collections.emptyMap();
61 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
62 Mockito.doReturn(aws).when(credentials).aws();
63 Mockito.doReturn(
64 QueryResponse.builder()
65 .items(
66 Collections.singletonList(item)
67 )
68 .consumedCapacity(
69 ConsumedCapacity.builder().capacityUnits(1.0d).build()
70 )
71 .build()
72 ).when(aws).query(Mockito.any(QueryRequest.class));
73 MatcherAssert.assertThat(
74 "should has item",
75 new QueryValve().fetch(
76 credentials, "table",
77 new Conditions(), new ArrayList<>(0)
78 ).items(),
79 Matchers.hasItem(item)
80 );
81 }
82
83 @Test
84 void countsItemsViaQuery() throws Exception {
85 final Credentials credentials = Mockito.mock(Credentials.class);
86 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
87 Mockito.doReturn(aws).when(credentials).aws();
88 final int expected = 7;
89 Mockito.doReturn(
90 QueryResponse.builder()
91 .count(expected)
92 .consumedCapacity(
93 ConsumedCapacity.builder().capacityUnits(1.0d).build()
94 )
95 .build()
96 ).when(aws).query(Mockito.any(QueryRequest.class));
97 MatcherAssert.assertThat(
98 "should not return wrong count",
99 new QueryValve().count(
100 credentials, "c\u00f6unt-tbl", new Conditions()
101 ),
102 Matchers.equalTo(expected)
103 );
104 }
105
106 @Test
107 void wrapsExceptionOnFetch() {
108 Assertions.assertThrows(
109 IOException.class,
110 () -> {
111 final Credentials creds =
112 Mockito.mock(Credentials.class);
113 final DynamoDbClient aws =
114 Mockito.mock(DynamoDbClient.class);
115 Mockito.doReturn(aws).when(creds).aws();
116 Mockito.doThrow(SdkClientException.create("f\u00e4iled"))
117 .when(aws).query(Mockito.any(QueryRequest.class));
118 new QueryValve().fetch(
119 creds, "f\u00e4il-tbl",
120 new Conditions(), new ArrayList<>(0)
121 );
122 }
123 );
124 }
125
126 @Test
127 void wrapsExceptionOnCount() {
128 Assertions.assertThrows(
129 IOException.class,
130 () -> {
131 final Credentials creds =
132 Mockito.mock(Credentials.class);
133 final DynamoDbClient aws =
134 Mockito.mock(DynamoDbClient.class);
135 Mockito.doReturn(aws).when(creds).aws();
136 Mockito.doThrow(SdkClientException.create("f\u00e4iled"))
137 .when(aws).query(Mockito.any(QueryRequest.class));
138 new QueryValve().count(
139 creds, "c\u00f6unt-err", new Conditions()
140 );
141 }
142 );
143 }
144
145 @Test
146 @SuppressWarnings("unchecked")
147 void reportsNextWhenMorePages() throws Exception {
148 final Credentials credentials = Mockito.mock(Credentials.class);
149 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
150 Mockito.doReturn(aws).when(credentials).aws();
151 Mockito.doReturn(
152 QueryResponse.builder()
153 .items(
154 Collections.singletonList(
155 Collections.singletonMap(
156 "h\u00e4sh",
157 AttributeValue.builder()
158 .s("v\u00e4l").build()
159 )
160 )
161 )
162 .lastEvaluatedKey(
163 Collections.singletonMap(
164 "h\u00e4sh",
165 AttributeValue.builder()
166 .s("l\u00e4st").build()
167 )
168 )
169 .consumedCapacity(
170 ConsumedCapacity.builder().capacityUnits(1.0d).build()
171 )
172 .build()
173 ).when(aws).query(Mockito.any(QueryRequest.class));
174 MatcherAssert.assertThat(
175 "should not report no next when there is next",
176 new QueryValve().fetch(
177 credentials, "p\u00e4ge-tbl",
178 new Conditions(), new ArrayList<>(0)
179 ).hasNext(),
180 Matchers.is(true)
181 );
182 }
183
184 @Test
185 @SuppressWarnings("unchecked")
186 void fetchesNextPage() throws Exception {
187 final Credentials credentials = Mockito.mock(Credentials.class);
188 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
189 Mockito.doReturn(aws).when(credentials).aws();
190 final Map<String, AttributeValue> item = Collections.singletonMap(
191 "s\u00f6rt",
192 AttributeValue.builder().s("v\u00e4l2").build()
193 );
194 Mockito.doReturn(
195 QueryResponse.builder()
196 .items(
197 Collections.singletonList(
198 Collections.singletonMap(
199 "s\u00f6rt",
200 AttributeValue.builder()
201 .s("v\u00e4l1").build()
202 )
203 )
204 )
205 .lastEvaluatedKey(
206 Collections.singletonMap(
207 "s\u00f6rt",
208 AttributeValue.builder()
209 .s("l\u00e4st").build()
210 )
211 )
212 .consumedCapacity(
213 ConsumedCapacity.builder().capacityUnits(1.0d).build()
214 )
215 .build()
216 ).doReturn(
217 QueryResponse.builder()
218 .items(Collections.singletonList(item))
219 .consumedCapacity(
220 ConsumedCapacity.builder().capacityUnits(1.0d).build()
221 )
222 .build()
223 ).when(aws).query(Mockito.any(QueryRequest.class));
224 MatcherAssert.assertThat(
225 "should not return wrong items on next page",
226 new QueryValve().fetch(
227 credentials, "n\u00e9xt-tbl",
228 new Conditions(), new ArrayList<>(0)
229 ).next().items(),
230 Matchers.hasItem(item)
231 );
232 }
233
234 @Test
235 @SuppressWarnings("unchecked")
236 void throwsOnNextWithoutMorePages() {
237 Assertions.assertThrows(
238 IllegalStateException.class,
239 () -> {
240 final Credentials creds =
241 Mockito.mock(Credentials.class);
242 final DynamoDbClient aws =
243 Mockito.mock(DynamoDbClient.class);
244 Mockito.doReturn(aws).when(creds).aws();
245 Mockito.doReturn(
246 QueryResponse.builder()
247 .items(
248 Collections.singletonList(
249 Collections.emptyMap()
250 )
251 )
252 .consumedCapacity(
253 ConsumedCapacity.builder()
254 .capacityUnits(1.0d).build()
255 )
256 .build()
257 ).when(aws).query(Mockito.any(QueryRequest.class));
258 new QueryValve().fetch(
259 creds, "n\u00f6-next-tbl",
260 new Conditions(), new ArrayList<>(0)
261 ).next();
262 }
263 );
264 }
265
266 @Test
267 @SuppressWarnings("unchecked")
268 void fetchesWithIndexName() throws Exception {
269 final Credentials credentials = Mockito.mock(Credentials.class);
270 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
271 Mockito.doReturn(aws).when(credentials).aws();
272 Mockito.doReturn(
273 QueryResponse.builder()
274 .items(
275 Collections.singletonList(Collections.emptyMap())
276 )
277 .consumedCapacity(
278 ConsumedCapacity.builder().capacityUnits(1.0d).build()
279 )
280 .build()
281 ).when(aws).query(Mockito.any(QueryRequest.class));
282 MatcherAssert.assertThat(
283 "should not fail fetching with index name",
284 new QueryValve()
285 .withIndexName("\u00efndex")
286 .fetch(
287 credentials, "t\u00e4ble",
288 new Conditions(), new ArrayList<>(0)
289 ).items(),
290 Matchers.hasSize(1)
291 );
292 }
293
294 @Test
295 @SuppressWarnings("unchecked")
296 void fetchesWithConsistentRead() throws Exception {
297 final Credentials creds = Mockito.mock(Credentials.class);
298 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
299 Mockito.doReturn(aws).when(creds).aws();
300 Mockito.doReturn(
301 QueryResponse.builder()
302 .items(
303 Collections.singletonList(Collections.emptyMap())
304 )
305 .consumedCapacity(
306 ConsumedCapacity.builder()
307 .capacityUnits(1.0d).build()
308 )
309 .build()
310 ).when(aws).query(Mockito.any(QueryRequest.class));
311 MatcherAssert.assertThat(
312 "did not fetch with consistent read disabled",
313 new QueryValve()
314 .withConsistentRead(false)
315 .fetch(
316 creds, "c\u00f6nsist-tbl",
317 new Conditions(), new ArrayList<>(0)
318 ).items(),
319 Matchers.hasSize(1)
320 );
321 }
322
323 @Test
324 @SuppressWarnings("unchecked")
325 void fetchesWithCustomLimit() throws Exception {
326 final Credentials creds = Mockito.mock(Credentials.class);
327 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
328 Mockito.doReturn(aws).when(creds).aws();
329 Mockito.doReturn(
330 QueryResponse.builder()
331 .items(
332 Collections.singletonList(Collections.emptyMap())
333 )
334 .consumedCapacity(
335 ConsumedCapacity.builder()
336 .capacityUnits(1.0d).build()
337 )
338 .build()
339 ).when(aws).query(Mockito.any(QueryRequest.class));
340 MatcherAssert.assertThat(
341 "did not fetch with custom limit",
342 new QueryValve()
343 .withLimit(5)
344 .fetch(
345 creds, "l\u00efmit-tbl",
346 new Conditions(), new ArrayList<>(0)
347 ).items(),
348 Matchers.hasSize(1)
349 );
350 }
351
352 @Test
353 @SuppressWarnings("unchecked")
354 void fetchesWithAttributeToGet() throws Exception {
355 final Credentials creds = Mockito.mock(Credentials.class);
356 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
357 Mockito.doReturn(aws).when(creds).aws();
358 Mockito.doReturn(
359 QueryResponse.builder()
360 .items(
361 Collections.singletonList(Collections.emptyMap())
362 )
363 .consumedCapacity(
364 ConsumedCapacity.builder()
365 .capacityUnits(1.0d).build()
366 )
367 .build()
368 ).when(aws).query(Mockito.any(QueryRequest.class));
369 MatcherAssert.assertThat(
370 "did not fetch with attribute to get",
371 new QueryValve()
372 .withAttributeToGet("\u00e4ttr")
373 .fetch(
374 creds, "\u00e4ttr-tbl",
375 new Conditions(), new ArrayList<>(0)
376 ).items(),
377 Matchers.hasSize(1)
378 );
379 }
380
381 }