Skip to content

Commit c9263e2

Browse files
committed
Add units
1 parent 4db1d94 commit c9263e2

3 files changed

Lines changed: 387 additions & 20 deletions

File tree

src/main/java/org/prebid/server/settings/helper/DatabaseProfilesResultMapper.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.vertx.sqlclient.Row;
66
import io.vertx.sqlclient.RowIterator;
77
import io.vertx.sqlclient.RowSet;
8+
import org.apache.commons.lang3.StringUtils;
89
import org.prebid.server.exception.PreBidException;
910
import org.prebid.server.json.ObjectMapperProvider;
1011
import org.prebid.server.log.Logger;
@@ -73,17 +74,17 @@ public static StoredDataResult<Profile> map(RowSet<Row> rowSet,
7374

7475
final String fetchedAccountId = Objects.toString(row.getValue(0), null);
7576
final String id = Objects.toString(row.getValue(1), null);
76-
final String profileBodyAsString = Objects.toString(row.getValue(2), null);
77-
final String mergePrecedenceAsString = Objects.toString(row.getValue(3), null);
78-
final String typeAsString = Objects.toString(row.getValue(4), null);
77+
final String profileBodyAsString = Objects.toString(row.getValue(2), StringUtils.EMPTY);
78+
final String mergePrecedenceAsString = Objects.toString(row.getValue(3), StringUtils.EMPTY);
79+
final String typeAsString = Objects.toString(row.getValue(4), StringUtils.EMPTY);
7980

8081
final JsonNode profileBody;
8182
final Profile.MergePrecedence mergePrecedence;
8283
final Profile.Type type;
8384
try {
8485
profileBody = ObjectMapperProvider.mapper().readTree(profileBodyAsString);
85-
mergePrecedence = Profile.MergePrecedence.valueOf(mergePrecedenceAsString);
86-
type = Profile.Type.valueOf(typeAsString);
86+
mergePrecedence = Profile.MergePrecedence.valueOf(mergePrecedenceAsString.toUpperCase());
87+
type = Profile.Type.valueOf(typeAsString.toUpperCase());
8788
} catch (IllegalArgumentException | JsonProcessingException e) {
8889
logger.error("Profile with id={} has invalid value: ''{}'' and will be ignored.",
8990
e, id, typeAsString);
Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
package org.prebid.server.settings.helper;
2+
3+
import io.vertx.sqlclient.Row;
4+
import io.vertx.sqlclient.RowIterator;
5+
import io.vertx.sqlclient.RowSet;
6+
import lombok.Value;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import org.mockito.Mock;
10+
import org.mockito.junit.jupiter.MockitoExtension;
11+
import org.prebid.server.VertxTest;
12+
import org.prebid.server.settings.model.Profile;
13+
import org.prebid.server.settings.model.StoredDataResult;
14+
15+
import java.util.Arrays;
16+
import java.util.Iterator;
17+
18+
import static java.util.Collections.emptySet;
19+
import static java.util.Collections.singleton;
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
import static org.assertj.core.api.Assertions.entry;
22+
import static org.mockito.ArgumentMatchers.anyInt;
23+
import static org.mockito.BDDMockito.given;
24+
import static org.mockito.Mockito.mock;
25+
import static org.mockito.Mockito.withSettings;
26+
import static org.mockito.quality.Strictness.LENIENT;
27+
28+
@ExtendWith(MockitoExtension.class)
29+
public class DatabaseProfilesResultMapperTest extends VertxTest {
30+
31+
@Mock
32+
private RowSet<Row> rowSet;
33+
34+
@Test
35+
public void mapShouldReturnEmptyProfilesWithErrorWhenResultSetHasEmptyResult() {
36+
// given
37+
givenRowSet();
38+
39+
// when
40+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(rowSet, null, emptySet(), emptySet());
41+
42+
// then
43+
assertThat(result.getStoredIdToRequest()).isEmpty();
44+
assertThat(result.getStoredIdToImp()).isEmpty();
45+
assertThat(result.getErrors())
46+
.containsExactly("No profiles were found");
47+
}
48+
49+
@Test
50+
public void mapShouldReturnEmptyProfilesWithErrorWhenResultSetHasEmptyResultForGivenIds() {
51+
// given
52+
givenRowSet();
53+
54+
// when
55+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
56+
rowSet,
57+
null,
58+
singleton("reqId"),
59+
singleton("impId"));
60+
61+
// then
62+
assertThat(result.getStoredIdToRequest()).isEmpty();
63+
assertThat(result.getStoredIdToImp()).isEmpty();
64+
assertThat(result.getErrors())
65+
.containsExactly("No request profiles for ids [reqId] and imp profiles for ids [impId] were found");
66+
}
67+
68+
@Test
69+
public void mapShouldReturnEmptyProfilesWithErrorWhenResultSetHasLessColumns() {
70+
// given
71+
givenRowSet(givenRow("accountId", "id1", "data", "request"));
72+
73+
// when
74+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
75+
rowSet,
76+
"accountId",
77+
singleton("reqId"),
78+
emptySet());
79+
80+
// then
81+
assertThat(result.getStoredIdToRequest()).isEmpty();
82+
assertThat(result.getStoredIdToImp()).isEmpty();
83+
assertThat(result.getErrors())
84+
.containsExactly("Error occurred while mapping profiles: some columns are missing");
85+
}
86+
87+
@Test
88+
public void mapShouldReturnEmptyProfilesWithErrorWhenResultSetHasUnexpectedColumnType() {
89+
// given
90+
givenRowSet(givenRow("accountId", "id1", "{}", 123, "request"));
91+
92+
// when
93+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
94+
rowSet,
95+
"accountId",
96+
singleton("reqId"),
97+
emptySet());
98+
99+
// then
100+
assertThat(result.getStoredIdToRequest()).isEmpty();
101+
assertThat(result.getStoredIdToImp()).isEmpty();
102+
assertThat(result.getErrors())
103+
.containsExactly("No profile found for id: reqId");
104+
}
105+
106+
@Test
107+
public void mapShouldSkipProfileWithInvalidBody() {
108+
// given
109+
givenRowSet(
110+
givenRow("accountId", "id1", "{}", "request", "request"),
111+
givenRow("accountId", "id1", "invalid", "request", "request"));
112+
113+
// when
114+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
115+
rowSet,
116+
"accountId",
117+
singleton("id1"),
118+
emptySet());
119+
120+
// then
121+
assertThat(result.getStoredIdToRequest())
122+
.containsExactly(entry("id1", Profile.of(
123+
Profile.Type.REQUEST,
124+
Profile.MergePrecedence.REQUEST,
125+
mapper.createObjectNode())));
126+
assertThat(result.getStoredIdToImp()).isEmpty();
127+
assertThat(result.getErrors()).isEmpty();
128+
}
129+
130+
@Test
131+
public void mapShouldSkipProfileWithInvalidMergePrecedence() {
132+
// given
133+
givenRowSet(
134+
givenRow("accountId", "id1", "{}", "request", "request"),
135+
givenRow("accountId", "id1", "{}", "invalid", "request"));
136+
137+
// when
138+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
139+
rowSet,
140+
"accountId",
141+
singleton("id1"),
142+
emptySet());
143+
144+
// then
145+
assertThat(result.getStoredIdToRequest())
146+
.containsExactly(entry("id1", Profile.of(
147+
Profile.Type.REQUEST,
148+
Profile.MergePrecedence.REQUEST,
149+
mapper.createObjectNode())));
150+
assertThat(result.getStoredIdToImp()).isEmpty();
151+
assertThat(result.getErrors()).isEmpty();
152+
}
153+
154+
@Test
155+
public void mapShouldSkipProfileWithInvalidType() {
156+
// given
157+
givenRowSet(
158+
givenRow("accountId", "id1", "{}", "request", "request"),
159+
givenRow("accountId", "id1", "{}", "request", "invalid"));
160+
161+
// when
162+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
163+
rowSet,
164+
"accountId",
165+
singleton("id1"),
166+
emptySet());
167+
168+
// then
169+
assertThat(result.getStoredIdToRequest())
170+
.containsExactly(entry("id1", Profile.of(
171+
Profile.Type.REQUEST,
172+
Profile.MergePrecedence.REQUEST,
173+
mapper.createObjectNode())));
174+
assertThat(result.getStoredIdToImp()).isEmpty();
175+
assertThat(result.getErrors()).isEmpty();
176+
}
177+
178+
@Test
179+
public void mapShouldReturnProfileWithErrorForMissingId() {
180+
// given
181+
givenRowSet(givenRow("accountId", "id1", "{}", "request", "request"));
182+
183+
// when
184+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
185+
rowSet,
186+
"accountId",
187+
singleton("id1"),
188+
singleton("id2"));
189+
190+
// then
191+
assertThat(result.getStoredIdToRequest())
192+
.containsExactly(entry("id1", Profile.of(
193+
Profile.Type.REQUEST,
194+
Profile.MergePrecedence.REQUEST,
195+
mapper.createObjectNode())));
196+
assertThat(result.getStoredIdToImp()).isEmpty();
197+
assertThat(result.getErrors())
198+
.containsExactly("No profile found for id: id2");
199+
}
200+
201+
@Test
202+
public void mapShouldReturnEmptyProfileWithErrorsForMissingIdsIfAccountDiffers() {
203+
// given
204+
givenRowSet(
205+
givenRow("accountId", "id1", "{}", "request", "request"),
206+
givenRow("accountId", "id2", "{}", "request", "imp"));
207+
208+
// when
209+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
210+
rowSet,
211+
"otherAccountId",
212+
singleton("id1"),
213+
singleton("id2"));
214+
215+
// then
216+
assertThat(result.getStoredIdToRequest()).isEmpty();
217+
assertThat(result.getStoredIdToImp()).isEmpty();
218+
assertThat(result.getErrors())
219+
.containsExactlyInAnyOrder(
220+
"No profile found for id: id1 for account: otherAccountId",
221+
"No profile found for id: id2 for account: otherAccountId");
222+
}
223+
224+
@Test
225+
public void mapShouldReturnEmptyProfileWithErrorIfMultipleStoredItemsFoundButNoAccountIdIsDefined() {
226+
// given
227+
givenRowSet(
228+
givenRow("accountId1", "id1", "{}", "request", "request"),
229+
givenRow("accountId2", "id1", "{}", "request", "request"));
230+
231+
// when
232+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
233+
rowSet,
234+
null,
235+
singleton("id1"),
236+
emptySet());
237+
238+
// then
239+
assertThat(result.getStoredIdToRequest()).isEmpty();
240+
assertThat(result.getStoredIdToImp()).isEmpty();
241+
assertThat(result.getErrors())
242+
.containsExactly("Multiple profiles found for id: id1 but no account was specified");
243+
}
244+
245+
@Test
246+
public void mapShouldReturnEmptyProfileWithErrorIfMultipleStoredItemsFoundButNoAccountIdIsDiffers() {
247+
// given
248+
givenRowSet(
249+
givenRow("accountId1", "id1", "{}", "request", "request"),
250+
givenRow("accountId2", "id1", "{}", "request", "request"),
251+
givenRow("accountId1", "id2", "{}", "request", "imp"),
252+
givenRow("accountId2", "id2", "{}", "request", "imp"));
253+
254+
// when
255+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
256+
rowSet,
257+
"otherAccountId",
258+
singleton("id1"),
259+
singleton("id2"));
260+
261+
// then
262+
assertThat(result.getStoredIdToRequest()).isEmpty();
263+
assertThat(result.getStoredIdToImp()).isEmpty();
264+
assertThat(result.getErrors())
265+
.containsExactlyInAnyOrder(
266+
"No profile found among multiple id: id1 for account: otherAccountId",
267+
"No profile found among multiple id: id2 for account: otherAccountId");
268+
}
269+
270+
@Test
271+
public void mapShouldReturnExpectedProfileForGivenAccount() {
272+
// given
273+
givenRowSet(
274+
givenRow("accountId", "id1", "{}", "request", "request"),
275+
givenRow("otherAccountId", "id1", "{}", "request", "request"),
276+
givenRow("accountId", "id2", "{}", "profile", "imp"),
277+
givenRow("otherAccountId", "id2", "{}", "request", "imp"));
278+
279+
// when
280+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(
281+
rowSet,
282+
"accountId",
283+
singleton("id1"),
284+
singleton("id2"));
285+
286+
// then
287+
assertThat(result.getStoredIdToRequest())
288+
.containsExactly(entry("id1", Profile.of(
289+
Profile.Type.REQUEST,
290+
Profile.MergePrecedence.REQUEST,
291+
mapper.createObjectNode())));
292+
assertThat(result.getStoredIdToImp())
293+
.containsExactly(entry("id2", Profile.of(
294+
Profile.Type.IMP,
295+
Profile.MergePrecedence.PROFILE,
296+
mapper.createObjectNode())));
297+
assertThat(result.getErrors()).isEmpty();
298+
}
299+
300+
@Test
301+
public void mapWithoutParamsShouldReturnEmptyProfileWithErrorWhenResultSetHasEmptyResult() {
302+
// given
303+
givenRowSet();
304+
305+
// when
306+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(rowSet);
307+
308+
// then
309+
assertThat(result.getStoredIdToRequest()).isEmpty();
310+
assertThat(result.getStoredIdToImp()).isEmpty();
311+
assertThat(result.getErrors())
312+
.containsExactly("No profiles were found");
313+
}
314+
315+
@Test
316+
public void mapWithoutParamsShouldReturnExpectedProfile() {
317+
// given
318+
givenRowSet(
319+
givenRow("accountId", "id1", "{}", "request", "request"),
320+
givenRow("accountId", "id2", "{}", "profile", "imp"));
321+
322+
// when
323+
final StoredDataResult<Profile> result = DatabaseProfilesResultMapper.map(rowSet);
324+
325+
// then
326+
assertThat(result.getStoredIdToRequest())
327+
.containsExactly(entry("id1", Profile.of(
328+
Profile.Type.REQUEST,
329+
Profile.MergePrecedence.REQUEST,
330+
mapper.createObjectNode())));
331+
assertThat(result.getStoredIdToImp())
332+
.containsExactly(entry("id2", Profile.of(
333+
Profile.Type.IMP,
334+
Profile.MergePrecedence.PROFILE,
335+
mapper.createObjectNode())));
336+
assertThat(result.getErrors()).isEmpty();
337+
}
338+
339+
private void givenRowSet(Row... rows) {
340+
given(rowSet.iterator()).willReturn(CustomRowIterator.of(Arrays.asList(rows).iterator()));
341+
}
342+
343+
private Row givenRow(Object... values) {
344+
final Row row = mock(Row.class, withSettings().strictness(LENIENT));
345+
given(row.getValue(anyInt())).willAnswer(invocation -> values[(Integer) invocation.getArgument(0)]);
346+
given(row.size()).willReturn(values.length);
347+
return row;
348+
}
349+
350+
@Value(staticConstructor = "of")
351+
private static class CustomRowIterator implements RowIterator<Row> {
352+
353+
Iterator<Row> delegate;
354+
355+
@Override
356+
public boolean hasNext() {
357+
return delegate.hasNext();
358+
}
359+
360+
@Override
361+
public Row next() {
362+
return delegate.next();
363+
}
364+
}
365+
}

0 commit comments

Comments
 (0)