1010import org .mockito .junit .jupiter .MockitoExtension ;
1111import org .prebid .server .VertxTest ;
1212import org .prebid .server .metric .Metrics ;
13+ import org .prebid .server .privacy .gdpr .vendorlist .proto .Feature ;
14+ import org .prebid .server .privacy .gdpr .vendorlist .proto .PurposeCode ;
15+ import org .prebid .server .privacy .gdpr .vendorlist .proto .SpecialFeature ;
16+ import org .prebid .server .privacy .gdpr .vendorlist .proto .SpecialPurpose ;
1317import org .prebid .server .privacy .gdpr .vendorlist .proto .Vendor ;
1418import org .prebid .server .privacy .gdpr .vendorlist .proto .VendorList ;
1519import org .prebid .server .vertx .httpclient .HttpClient ;
1822import java .time .Clock ;
1923import java .time .Instant ;
2024import java .time .ZoneOffset ;
25+ import java .util .Arrays ;
2126import java .util .Date ;
22- import java .util .HashMap ;
23- import java .util .Map ;
27+ import java .util .EnumSet ;
28+ import java .util .function .Function ;
29+ import java .util .stream .Collectors ;
2430
25- import static java .util .Collections .emptyMap ;
2631import static org .assertj .core .api .Assertions .assertThat ;
2732import static org .mockito .ArgumentMatchers .anyLong ;
2833import static org .mockito .ArgumentMatchers .anyString ;
2934import static org .mockito .BDDMockito .given ;
3035import static org .mockito .Mockito .never ;
3136import static org .mockito .Mockito .verify ;
37+ import static org .prebid .server .privacy .gdpr .vendorlist .proto .PurposeCode .ONE ;
38+ import static org .prebid .server .privacy .gdpr .vendorlist .proto .PurposeCode .TWO ;
3239
3340@ ExtendWith (MockitoExtension .class )
3441public class LiveVendorListServiceTest extends VertxTest {
@@ -68,7 +75,8 @@ public void isDeletedShouldReturnFalseWhenFetchNeverSucceeded() {
6875 @ Test
6976 public void isDeletedShouldReturnTrueWhenVendorIsDeletedInLiveVendorList () throws JsonProcessingException {
7077 // given
71- final String responseBody = givenLiveGvlJson (Map .of (42 , "2024-01-01T00:00:00Z" ));
78+ final Vendor vendor = givenVendor (42 , "2024-01-01T00:00:00Z" );
79+ final String responseBody = mapper .writeValueAsString (givenVendorList (vendor ));
7280 given (httpClient .get (anyString (), anyLong ()))
7381 .willReturn (Future .succeededFuture (HttpClientResponse .of (200 , null , responseBody )));
7482
@@ -83,11 +91,11 @@ public void isDeletedShouldReturnTrueWhenVendorIsDeletedInLiveVendorList() throw
8391 @ Test
8492 public void extractDeletedVendorIdsShouldReturnOnlyVendorsWithPastDeletedDate () {
8593 // given
86- final VendorList vendorList = givenVendorList (Map . of (
87- 1 , givenVendor (1 , "2024-01-01T00:00:00Z" ),
88- 2 , givenVendor (2 , null ),
89- 3 , givenVendor (3 , "2025-01-01T00:00:00Z" ),
90- 4 , givenVendor (4 , "2024-06-01T12:00:00Z" ) ));
94+ final VendorList vendorList = givenVendorList (
95+ givenVendor (1 , "2024-01-01T00:00:00Z" ),
96+ givenVendor (2 , null ),
97+ givenVendor (3 , "2025-01-01T00:00:00Z" ),
98+ givenVendor (4 , "2024-06-01T12:00:00Z" ));
9199
92100 // when
93101 final var deletedIds = target .extractDeletedVendorIds (vendorList );
@@ -99,7 +107,9 @@ public void extractDeletedVendorIdsShouldReturnOnlyVendorsWithPastDeletedDate()
99107 @ Test
100108 public void refreshShouldUpdateDeletedVendorIdsAndIncrementOkMetric () throws JsonProcessingException {
101109 // given
102- givenHttpClientReturnsResponse (200 , givenLiveGvlJson (Map .of (1 , "2024-01-01T00:00:00Z" )));
110+ final Vendor vendor = givenVendor (1 , "2024-01-01T00:00:00Z" );
111+ final String responseBody = mapper .writeValueAsString (givenVendorList (vendor ));
112+ givenHttpClientReturnsResponse (200 , responseBody );
103113
104114 // when
105115 target .refresh ();
@@ -113,12 +123,14 @@ public void refreshShouldUpdateDeletedVendorIdsAndIncrementOkMetric() throws Jso
113123 @ Test
114124 public void refreshShouldReplaceDeletedVendorIdsOnSubsequentSuccessfulFetch () throws JsonProcessingException {
115125 // given
126+ final Vendor vendor = givenVendor (1 , "2024-01-01T00:00:00Z" );
127+ final String responseBody = mapper .writeValueAsString (givenVendorList (vendor ));
128+ final Vendor vendor2 = givenVendor (2 , "2024-02-01T00:00:00Z" );
129+ final String responseBody2 = mapper .writeValueAsString (givenVendorList (vendor2 ));
116130 given (httpClient .get (anyString (), anyLong ()))
117131 .willReturn (
118- Future .succeededFuture (HttpClientResponse .of (
119- 200 , null , givenLiveGvlJson (Map .of (1 , "2024-01-01T00:00:00Z" )))),
120- Future .succeededFuture (HttpClientResponse .of (
121- 200 , null , givenLiveGvlJson (Map .of (2 , "2024-02-01T00:00:00Z" )))));
132+ Future .succeededFuture (HttpClientResponse .of (200 , null , responseBody )),
133+ Future .succeededFuture (HttpClientResponse .of (200 , null , responseBody2 )));
122134
123135 // when
124136 target .refresh ();
@@ -171,26 +183,29 @@ public void refreshShouldIncrementErrorMetricOnInvalidJson() {
171183 }
172184
173185 @ Test
174- public void refreshShouldIncrementErrorMetricWhenNoDeletedVendorsInResponse () throws JsonProcessingException {
186+ public void refreshShouldIncrementErrorMetricOnInvalidVendorList () throws JsonProcessingException {
175187 // given
176- givenHttpClientReturnsResponse (200 , givenLiveGvlJson (emptyMap ()));
188+ final Vendor vendor = givenVendor (42 , "2024-01-01T00:00:00Z" )
189+ .toBuilder ().features (null ).build ();
190+ final String responseBody = mapper .writeValueAsString (givenVendorList (vendor ));
191+ givenHttpClientReturnsResponse (200 , responseBody );
177192
178193 // when
179194 target .refresh ();
180195
181196 // then
182197 assertThat (target .isDeleted (1 )).isFalse ();
183198 verify (metrics ).updatePrivacyTcfVendorListLatestErrorMetric ();
184- verify (metrics , never ()).updatePrivacyTcfVendorListLatestOkMetric ();
185199 }
186200
187201 @ Test
188202 public void refreshShouldKeepLastGoodSetOnFailureAfterSuccessfulFetch () throws JsonProcessingException {
189203 // given
204+ final Vendor vendor = givenVendor (1 , "2024-01-01T00:00:00Z" );
205+ final String responseBody = mapper .writeValueAsString (givenVendorList (vendor ));
190206 given (httpClient .get (anyString (), anyLong ()))
191207 .willReturn (
192- Future .succeededFuture (HttpClientResponse .of (
193- 200 , null , givenLiveGvlJson (Map .of (1 , "2024-01-01T00:00:00Z" )))),
208+ Future .succeededFuture (HttpClientResponse .of (200 , null , responseBody )),
194209 Future .failedFuture (new RuntimeException ("connection failed" )));
195210
196211 // when
@@ -208,22 +223,23 @@ private void givenHttpClientReturnsResponse(int statusCode, String response) {
208223 .willReturn (Future .succeededFuture (HttpClientResponse .of (statusCode , null , response )));
209224 }
210225
211- private String givenLiveGvlJson (Map <Integer , String > vendorIdToDeletedDate ) throws JsonProcessingException {
212- final Map <Integer , Object > vendors = new HashMap <>();
213- for (Map .Entry <Integer , String > entry : vendorIdToDeletedDate .entrySet ()) {
214- vendors .put (entry .getKey (), Map .of ("id" , entry .getKey (), "deletedDate" , entry .getValue ()));
215- }
216- return mapper .writeValueAsString (Map .of ("vendors" , vendors ));
217- }
218-
219226 private static Vendor givenVendor (int id , String deletedDate ) {
220227 return Vendor .builder ()
221228 .id (id )
222229 .deletedDate (deletedDate != null ? Instant .parse (deletedDate ) : null )
230+ .purposes (EnumSet .of (ONE ))
231+ .legIntPurposes (EnumSet .of (TWO ))
232+ .flexiblePurposes (EnumSet .noneOf (PurposeCode .class ))
233+ .specialPurposes (EnumSet .noneOf (SpecialPurpose .class ))
234+ .features (EnumSet .noneOf (Feature .class ))
235+ .specialFeatures (EnumSet .noneOf (SpecialFeature .class ))
223236 .build ();
224237 }
225238
226- private static VendorList givenVendorList (Map <Integer , Vendor > vendors ) {
227- return VendorList .of (1 , Date .from (Instant .parse ("2020-08-20T16:05:24Z" )), vendors );
239+ private static VendorList givenVendorList (Vendor ... vendors ) {
240+ return VendorList .of (
241+ 1 ,
242+ Date .from (Instant .parse ("2020-08-20T16:05:24Z" )),
243+ Arrays .stream (vendors ).collect (Collectors .toMap (Vendor ::getId , Function .identity ())));
228244 }
229245}
0 commit comments