1
2
3
4
5 package com.jcabi.dynamo;
6
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.Iterator;
13 import java.util.Map;
14 import java.util.NoSuchElementException;
15 import java.util.UUID;
16 import org.hamcrest.MatcherAssert;
17 import org.hamcrest.Matchers;
18 import org.junit.jupiter.api.Assertions;
19 import org.junit.jupiter.api.Test;
20 import org.mockito.Mockito;
21 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
22 import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
23
24
25
26
27
28 @SuppressWarnings("unchecked")
29 final class AwsIteratorTest {
30
31 @Test
32 void hasNextOnFreshIterator() throws IOException {
33 final Credentials credentials = Mockito.mock(Credentials.class);
34 final Dosage first = Mockito.mock(Dosage.class);
35 Mockito.doReturn(
36 Collections.singletonList(
37 new Attributes().with("attribute-1", "value-1")
38 )
39 ).when(first).items();
40 Mockito.doReturn(true).when(first).hasNext();
41 final Valve valve = Mockito.mock(Valve.class);
42 Mockito.doReturn(first)
43 .when(valve)
44 .fetch(
45 Mockito.eq(credentials), Mockito.anyString(),
46 Mockito.any(Map.class), Mockito.any(Collection.class)
47 );
48 final String table = "table-1";
49 MatcherAssert.assertThat(
50 "should has next",
51 new AwsIterator(
52 credentials,
53 new AwsFrame(
54 credentials,
55 new AwsTable(
56 credentials,
57 Mockito.mock(Region.class),
58 table
59 ),
60 table
61 ),
62 table, new Conditions(),
63 new ArrayList<>(0), valve
64 ).hasNext(),
65 Matchers.is(true)
66 );
67 }
68
69 @Test
70 void returnsFirstItemValue() throws IOException {
71 final Credentials credentials = Mockito.mock(Credentials.class);
72 final String attr = "attribute-1";
73 final String value = "value-1";
74 final Dosage first = Mockito.mock(Dosage.class);
75 Mockito.doReturn(
76 Collections.singletonList(new Attributes().with(attr, value))
77 ).when(first).items();
78 Mockito.doReturn(true).when(first).hasNext();
79 final Valve valve = Mockito.mock(Valve.class);
80 Mockito.doReturn(first)
81 .when(valve)
82 .fetch(
83 Mockito.eq(credentials), Mockito.anyString(),
84 Mockito.any(Map.class), Mockito.any(Collection.class)
85 );
86 final String table = "table-1";
87 MatcherAssert.assertThat(
88 "should equal to 'value-1'",
89 new AwsIterator(
90 credentials,
91 new AwsFrame(
92 credentials,
93 new AwsTable(
94 credentials,
95 Mockito.mock(Region.class),
96 table
97 ),
98 table
99 ),
100 table, new Conditions(),
101 new ArrayList<>(0), valve
102 ).next().get(attr).s(),
103 Matchers.equalTo(value)
104 );
105 }
106
107 @Test
108 void hasNextAfterFirstDosageConsumed() throws IOException {
109 final Credentials credentials = Mockito.mock(Credentials.class);
110 final String attr = "attribute-1";
111 final String value = "value-1";
112 final Dosage first = Mockito.mock(Dosage.class);
113 Mockito.doReturn(
114 Collections.singletonList(new Attributes().with(attr, value))
115 ).when(first).items();
116 Mockito.doReturn(true).when(first).hasNext();
117 final Dosage second = Mockito.mock(Dosage.class);
118 Mockito.doReturn(second).when(first).next();
119 Mockito.doReturn(
120 Collections.singletonList(new Attributes().with(attr, value))
121 ).when(second).items();
122 Mockito.doReturn(false).when(second).hasNext();
123 final Valve valve = Mockito.mock(Valve.class);
124 Mockito.doReturn(first)
125 .when(valve)
126 .fetch(
127 Mockito.eq(credentials), Mockito.anyString(),
128 Mockito.any(Map.class), Mockito.any(Collection.class)
129 );
130 final String table = "table-1";
131 final Iterator<Item> iterator = new AwsIterator(
132 credentials,
133 new AwsFrame(
134 credentials,
135 new AwsTable(
136 credentials,
137 Mockito.mock(Region.class),
138 table
139 ),
140 table
141 ),
142 table, new Conditions(),
143 new ArrayList<>(0), valve
144 );
145 iterator.next();
146 MatcherAssert.assertThat(
147 "should has next",
148 iterator.hasNext(),
149 Matchers.is(true)
150 );
151 }
152
153 @Test
154 void hasNoNextAfterAllConsumed() throws IOException {
155 final Credentials credentials = Mockito.mock(Credentials.class);
156 final String attr = "attribute-1";
157 final String value = "value-1";
158 final Dosage first = Mockito.mock(Dosage.class);
159 Mockito.doReturn(
160 Collections.singletonList(new Attributes().with(attr, value))
161 ).when(first).items();
162 Mockito.doReturn(true).when(first).hasNext();
163 final Dosage second = Mockito.mock(Dosage.class);
164 Mockito.doReturn(second).when(first).next();
165 Mockito.doReturn(
166 Collections.singletonList(new Attributes().with(attr, value))
167 ).when(second).items();
168 Mockito.doReturn(true).when(second).hasNext();
169 final Dosage last = Mockito.mock(Dosage.class);
170 Mockito.doReturn(last).when(second).next();
171 Mockito.doReturn(new ArrayList<Attributes>(0)).when(last).items();
172 final Valve valve = Mockito.mock(Valve.class);
173 Mockito.doReturn(first)
174 .when(valve)
175 .fetch(
176 Mockito.eq(credentials), Mockito.anyString(),
177 Mockito.any(Map.class), Mockito.any(Collection.class)
178 );
179 final String table = "table-1";
180 final Iterator<Item> iterator = new AwsIterator(
181 credentials,
182 new AwsFrame(
183 credentials,
184 new AwsTable(
185 credentials,
186 Mockito.mock(Region.class),
187 table
188 ),
189 table
190 ),
191 table, new Conditions(),
192 new ArrayList<>(0), valve
193 );
194 iterator.next();
195 iterator.next();
196 MatcherAssert.assertThat(
197 "should not has next",
198 iterator.hasNext(),
199 Matchers.is(false)
200 );
201 }
202
203 @Test
204 void throwsOnEmptyIterator() throws Exception {
205 final Credentials creds = Mockito.mock(Credentials.class);
206 final Dosage dosage = Mockito.mock(Dosage.class);
207 Mockito.doReturn(Collections.emptyList()).when(dosage).items();
208 final Valve vlv = Mockito.mock(Valve.class);
209 Mockito.doReturn(dosage)
210 .when(vlv)
211 .fetch(
212 Mockito.eq(creds), Mockito.anyString(),
213 Mockito.any(Map.class), Mockito.any(Collection.class)
214 );
215 final String table = "table-2";
216 Assertions.assertThrows(
217 NoSuchElementException.class,
218 new AwsIterator(
219 creds,
220 new AwsFrame(
221 creds,
222 new AwsTable(
223 creds,
224 Mockito.mock(Region.class),
225 table
226 ),
227 table
228 ),
229 table, new Conditions(),
230 new ArrayList<>(0), vlv
231 )::next
232 );
233 }
234
235 @Test
236 void iteratesMultipleItemsInSingleDosage() throws IOException {
237 final Credentials creds = Mockito.mock(Credentials.class);
238 final String attr = UUID.randomUUID().toString();
239 final Dosage dosage = Mockito.mock(Dosage.class);
240 Mockito.doReturn(
241 Arrays.asList(
242 new Attributes().with(attr, "première"),
243 new Attributes().with(attr, "deuxième")
244 )
245 ).when(dosage).items();
246 Mockito.doReturn(false).when(dosage).hasNext();
247 final Valve valve = Mockito.mock(Valve.class);
248 Mockito.doReturn(dosage)
249 .when(valve)
250 .fetch(
251 Mockito.eq(creds), Mockito.anyString(),
252 Mockito.any(Map.class), Mockito.any(Collection.class)
253 );
254 final String table = UUID.randomUUID().toString();
255 final Iterator<Item> iter = new AwsIterator(
256 creds,
257 new AwsFrame(
258 creds,
259 new AwsTable(
260 creds,
261 Mockito.mock(Region.class),
262 table
263 ),
264 table
265 ),
266 table, new Conditions(),
267 new ArrayList<>(0), valve
268 );
269 iter.next();
270 MatcherAssert.assertThat(
271 "did not find second item in single dosage",
272 iter.hasNext(),
273 Matchers.is(true)
274 );
275 }
276
277 @Test
278 void throwsOnRemoveBeforeIteration() {
279 final String table = UUID.randomUUID().toString();
280 final Credentials creds = Mockito.mock(Credentials.class);
281 Assertions.assertThrows(
282 IllegalStateException.class,
283 new AwsIterator(
284 creds,
285 new AwsFrame(
286 creds,
287 new AwsTable(
288 creds,
289 Mockito.mock(Region.class),
290 table
291 ),
292 table
293 ),
294 table, new Conditions(),
295 new ArrayList<>(0), Mockito.mock(Valve.class)
296 )::remove
297 );
298 }
299
300 @Test
301 void removesCurrentItem() throws IOException {
302 final DynamoDbClient aws = Mockito.mock(DynamoDbClient.class);
303 final Credentials creds = Mockito.mock(Credentials.class);
304 Mockito.doReturn(aws).when(creds).aws();
305 final String attr = UUID.randomUUID().toString();
306 final Dosage dosage = Mockito.mock(Dosage.class);
307 Mockito.doReturn(
308 Collections.singletonList(
309 new Attributes().with(attr, "ünïcödé")
310 )
311 ).when(dosage).items();
312 Mockito.doReturn(false).when(dosage).hasNext();
313 final Valve valve = Mockito.mock(Valve.class);
314 Mockito.doReturn(dosage)
315 .when(valve)
316 .fetch(
317 Mockito.eq(creds), Mockito.anyString(),
318 Mockito.any(Map.class), Mockito.any(Collection.class)
319 );
320 final String table = UUID.randomUUID().toString();
321 final Iterator<Item> iter = new AwsIterator(
322 creds,
323 new AwsFrame(
324 creds,
325 new AwsTable(
326 creds,
327 Mockito.mock(Region.class),
328 table
329 ),
330 table
331 ),
332 table, new Conditions(),
333 Collections.singletonList(attr), valve
334 );
335 iter.next();
336 iter.remove();
337 Mockito.verify(aws).deleteItem(
338 Mockito.any(DeleteItemRequest.class)
339 );
340 }
341
342 }