1
2
3
4
5 package com.jcabi.dynamo;
6
7 import com.jcabi.immutable.ArrayMap;
8 import java.util.Collections;
9 import java.util.Random;
10 import java.util.UUID;
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 software.amazon.awssdk.services.dynamodb.model.AttributeValue;
16 import software.amazon.awssdk.services.dynamodb.model.ExpectedAttributeValue;
17
18
19
20
21
22 @SuppressWarnings("PMD.TooManyMethods")
23 final class AttributesTest {
24
25 @Test
26 void worksAsMapWithCorrectKeySetSize() {
27 MatcherAssert.assertThat(
28 "should has size 1",
29 new Attributes().with(
30 "id",
31 AttributeValue.builder().s("some text value").build()
32 ).keySet(),
33 Matchers.hasSize(1)
34 );
35 }
36
37 @Test
38 void worksAsMapWithCorrectEntry() {
39 final String attr = "id";
40 final AttributeValue value = AttributeValue.builder().s("some text value").build();
41 MatcherAssert.assertThat(
42 "should has some entry",
43 new Attributes().with(attr, value),
44 Matchers.hasEntry(attr, value)
45 );
46 }
47
48 @Test
49 void worksAsMapFromExistingMap() {
50 final String attr = "id";
51 final AttributeValue value = AttributeValue.builder().s("some text value").build();
52 MatcherAssert.assertThat(
53 "should has some text value",
54 new Attributes(new Attributes().with(attr, value)),
55 Matchers.hasEntry(attr, value)
56 );
57 }
58
59 @Test
60 void buildsExpectedKeys() {
61 final String attr = "attr-13";
62 final String value = "some value \u20ac";
63 MatcherAssert.assertThat(
64 "should has 'some value \u20ac'",
65 new Attributes().with(attr, value).asKeys(),
66 Matchers.hasEntry(
67 attr,
68 ExpectedAttributeValue.builder().value(
69 AttributeValue.builder().s(value).build()
70 ).build()
71 )
72 );
73 }
74
75 @Test
76 void filtersOutUnnecessaryKeys() {
77 MatcherAssert.assertThat(
78 "should be empty match",
79 new Attributes()
80 .with("first", "test-1")
81 .with("second", "test-2")
82 .only(Collections.singletonList("never"))
83 .keySet(),
84 Matchers.empty()
85 );
86 }
87
88 @Test
89 void caseSensitiveWithDifferentCase() {
90 MatcherAssert.assertThat(
91 "should has size 2",
92 new Attributes().with(
93 new ArrayMap<String, AttributeValue>()
94 .with("Gamma", AttributeValue.builder().s("").build())
95 .with("gAMma", AttributeValue.builder().s("").build())
96 ).keySet(),
97 Matchers.hasSize(2)
98 );
99 }
100
101 @Test
102 void caseSensitivePreservesKeys() {
103 final String first = "Alpha";
104 final String second = "AlPha";
105 MatcherAssert.assertThat(
106 "should has keys 'Alpha', 'AlPha'",
107 new Attributes()
108 .with(first, "val-1")
109 .with(second, "val-2"),
110 Matchers.allOf(
111 Matchers.hasKey(first),
112 Matchers.hasKey(second)
113 )
114 );
115 }
116
117 @Test
118 void caseSensitiveFiltersCorrectly() {
119 final String third = "Beta";
120 MatcherAssert.assertThat(
121 "should has key 'Beta'",
122 new Attributes()
123 .with(third, "some text to use")
124 .only(Collections.singletonList(third)),
125 Matchers.hasKey(third)
126 );
127 }
128
129 @Test
130 void buildsWithLongValue() {
131 final String attr = UUID.randomUUID().toString();
132 final long number = new Random().nextLong();
133 MatcherAssert.assertThat(
134 "did not store long value as numeric attribute",
135 new Attributes().with(attr, number).get(attr).n(),
136 Matchers.equalTo(String.valueOf(number))
137 );
138 }
139
140 @Test
141 void buildsWithIntegerValue() {
142 final String attr = UUID.randomUUID().toString();
143 final int number = new Random().nextInt();
144 MatcherAssert.assertThat(
145 "did not store integer value as numeric attribute",
146 new Attributes().with(attr, number).get(attr).n(),
147 Matchers.equalTo(String.valueOf(number))
148 );
149 }
150
151 @Test
152 void rejectsDirectPut() {
153 Assertions.assertThrows(
154 UnsupportedOperationException.class,
155 () -> new Attributes().put(
156 UUID.randomUUID().toString(),
157 AttributeValue.builder().s("ü").build()
158 )
159 );
160 }
161
162 @Test
163 void rejectsDirectRemove() {
164 Assertions.assertThrows(
165 UnsupportedOperationException.class,
166 () -> new Attributes().remove(UUID.randomUUID().toString())
167 );
168 }
169
170 @Test
171 void rejectsDirectClear() {
172 Assertions.assertThrows(
173 UnsupportedOperationException.class,
174 () -> new Attributes().clear()
175 );
176 }
177
178 @Test
179 void rejectsDirectPutAll() {
180 Assertions.assertThrows(
181 UnsupportedOperationException.class,
182 () -> new Attributes().putAll(
183 Collections.singletonMap(
184 UUID.randomUUID().toString(),
185 AttributeValue.builder().s("ö").build()
186 )
187 )
188 );
189 }
190
191 @Test
192 void retainsOnlyMatchingKeys() {
193 final String kept = UUID.randomUUID().toString();
194 MatcherAssert.assertThat(
195 "did not retain the matching key",
196 new Attributes()
197 .with(kept, "ütf-vàl")
198 .with(UUID.randomUUID().toString(), "öther")
199 .only(Collections.singletonList(kept)),
200 Matchers.hasKey(kept)
201 );
202 }
203
204 @Test
205 void mergesWithMapOfAttributes() {
206 MatcherAssert.assertThat(
207 "did not merge all map entries",
208 new Attributes().with(
209 new ArrayMap<String, AttributeValue>()
210 .with(
211 UUID.randomUUID().toString(),
212 AttributeValue.builder().s("ä").build()
213 )
214 .with(
215 UUID.randomUUID().toString(),
216 AttributeValue.builder().s("ö").build()
217 )
218 ).keySet(),
219 Matchers.hasSize(2)
220 );
221 }
222
223 @Test
224 void convertsMultipleAttributesToExpectedKeys() {
225 MatcherAssert.assertThat(
226 "did not convert all attributes to expected keys",
227 new Attributes()
228 .with(UUID.randomUUID().toString(), "vàl-1")
229 .with(UUID.randomUUID().toString(), "vàl-2")
230 .asKeys().keySet(),
231 Matchers.hasSize(2)
232 );
233 }
234
235 }