Skip to content

Commit 1e55870

Browse files
author
MananRPatel
committed
Yahoo Ads: preserve non-promoted regs.ext values during 2.6 promotion
Make stripPromotedFromExt remove a regs.ext key only when its value was actually promoted to top-level (resolved value non-null). A malformed, non-promotable value (e.g. a non-textual gpp) is now left untouched in regs.ext instead of being dropped when a sibling field triggers the rebuild. Add a test covering the mixed case (valid coppa promoted, malformed gpp kept in ext) and trim redundant comments.
1 parent 75b65c6 commit 1e55870

2 files changed

Lines changed: 34 additions & 23 deletions

File tree

src/main/java/org/prebid/server/bidder/yahooads/YahooAdsBidder.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ private static Banner modifyBanner(Banner banner) {
162162
.build();
163163
}
164164

165+
// Promote legacy 2.5 regs.ext gpp/gpp_sid/coppa to their 2.6 top-level slots.
165166
private static Regs modifyRegs(Regs regs) {
166167
final ExtRegs originalExt = regs.getExt();
167168
if (originalExt == null
@@ -186,7 +187,7 @@ private static Regs modifyRegs(Regs regs) {
186187
.gpp(resolvedGpp)
187188
.gppSid(resolvedGppSid)
188189
.coppa(resolvedCoppa)
189-
.ext(stripPromotedFromExt(originalExt))
190+
.ext(stripPromotedFromExt(originalExt, resolvedGpp, resolvedGppSid, resolvedCoppa))
190191
.build();
191192
}
192193

@@ -223,16 +224,22 @@ private static Integer resolveCoppa(Regs regs, ExtRegs ext) {
223224
return node != null && node.isIntegralNumber() ? node.asInt() : null;
224225
}
225226

226-
private static ExtRegs stripPromotedFromExt(ExtRegs original) {
227+
// Drop a key from ext only if it was promoted; keep gpc/dsa, unknown, and non-promoted values.
228+
private static ExtRegs stripPromotedFromExt(ExtRegs original,
229+
String resolvedGpp,
230+
List<Integer> resolvedGppSid,
231+
Integer resolvedCoppa) {
227232
final ExtRegs stripped = ExtRegs.of(
228233
original.getGdpr(),
229234
original.getUsPrivacy(),
230235
original.getGpc(),
231236
original.getDsa());
232237
original.getProperties().forEach((key, value) -> {
233-
if (!GPP_PROPERTY.equals(key)
234-
&& !GPP_SID_PROPERTY.equals(key)
235-
&& !COPPA_PROPERTY.equals(key)) {
238+
final boolean promoted =
239+
(GPP_PROPERTY.equals(key) && resolvedGpp != null)
240+
|| (GPP_SID_PROPERTY.equals(key) && !CollectionUtils.isEmpty(resolvedGppSid))
241+
|| (COPPA_PROPERTY.equals(key) && resolvedCoppa != null);
242+
if (!promoted) {
236243
stripped.addProperty(key, value);
237244
}
238245
});

src/test/java/org/prebid/server/bidder/yahooads/YahooAdsBidderTest.java

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,6 @@ public void makeBidsShouldSkipNotSupportedImpAndReturnVideoBidWhenVideoPresent()
393393

394394
@Test
395395
public void makeHttpRequestsShouldPreserveTopLevel26RegsAndExtTypedFields() {
396-
// 2.6-shape publisher: all regulatory signals at top-level + typed ext fields.
397-
// Bidder should pass them through untouched.
398396
final ExtRegsDsa dsa = ExtRegsDsa.of(2, 2, 3, emptyList());
399397
final BidRequest bidRequest = givenBidRequest(identity(),
400398
requestBuilder -> requestBuilder.regs(Regs.builder()
@@ -412,22 +410,18 @@ public void makeHttpRequestsShouldPreserveTopLevel26RegsAndExtTypedFields() {
412410
// then
413411
assertThat(result.getErrors()).isEmpty();
414412
final Regs regs = result.getValue().getFirst().getPayload().getRegs();
415-
// 2.6 top-level fields preserved
416413
assertThat(regs.getGdpr()).isEqualTo(1);
417414
assertThat(regs.getUsPrivacy()).isEqualTo("1YNN");
418415
assertThat(regs.getGpp()).isEqualTo("gppconsent");
419416
assertThat(regs.getGppSid()).containsExactly(6);
420417
assertThat(regs.getCoppa()).isEqualTo(1);
421-
// Typed ext fields preserved (gpc, dsa have no top-level slot in 2.6)
422418
assertThat(regs.getExt()).isNotNull();
423419
assertThat(regs.getExt().getGpc()).isEqualTo("1");
424420
assertThat(regs.getExt().getDsa()).isEqualTo(dsa);
425421
}
426422

427423
@Test
428424
public void makeHttpRequestsShouldPromoteLegacyExtGppGppSidAndCoppaToTopLevel() {
429-
// 2.5-shape publisher: gpp/gpp_sid/coppa carried as ext properties.
430-
// Bidder should promote them to 2.6 top-level slots and strip from ext.
431425
final BidRequest bidRequest = givenBidRequest(identity(),
432426
requestBuilder -> requestBuilder.regs(Regs.builder()
433427
.ext(ExtRegs.of(null, null, null, null))
@@ -445,17 +439,14 @@ public void makeHttpRequestsShouldPromoteLegacyExtGppGppSidAndCoppaToTopLevel()
445439
// then
446440
assertThat(result.getErrors()).isEmpty();
447441
final Regs regs = result.getValue().getFirst().getPayload().getRegs();
448-
// promoted to top-level
449442
assertThat(regs.getGpp()).isEqualTo("legacy_gpp_value");
450443
assertThat(regs.getGppSid()).containsExactly(6, 8);
451444
assertThat(regs.getCoppa()).isEqualTo(1);
452-
// stripped from ext (ext was empty after stripping, so it becomes null)
453445
assertThat(regs.getExt()).isNull();
454446
}
455447

456448
@Test
457449
public void makeHttpRequestsShouldPromoteOnlyGppFromExtAndStripIt() {
458-
// Only gpp lives in ext; gpp_sid and coppa remain unset everywhere.
459450
final BidRequest bidRequest = givenBidRequest(identity(),
460451
requestBuilder -> requestBuilder.regs(Regs.builder()
461452
.ext(ExtRegs.of(null, null, null, null))
@@ -476,7 +467,6 @@ public void makeHttpRequestsShouldPromoteOnlyGppFromExtAndStripIt() {
476467

477468
@Test
478469
public void makeHttpRequestsShouldPreserveTopLevelGdprWhilePromotingGppFromExt() {
479-
// Mixed-shape publisher: 2.6 gdpr top-level + legacy 2.5 gpp in ext.
480470
final BidRequest bidRequest = givenBidRequest(identity(),
481471
requestBuilder -> requestBuilder.regs(Regs.builder()
482472
.gdpr(1)
@@ -497,9 +487,6 @@ public void makeHttpRequestsShouldPreserveTopLevelGdprWhilePromotingGppFromExt()
497487

498488
@Test
499489
public void makeHttpRequestsShouldKeepGpcAndUnrelatedExtPropertyAfterPromotion() {
500-
// Publisher sent gpp in ext + typed gpc + an unrelated ext property.
501-
// After promoting gpp: gpc must stay in typed ext, the unrelated property must
502-
// also survive, and ext must NOT be nulled.
503490
final BidRequest bidRequest = givenBidRequest(identity(),
504491
requestBuilder -> requestBuilder.regs(Regs.builder()
505492
.ext(ExtRegs.of(null, null, "1", null))
@@ -514,7 +501,6 @@ public void makeHttpRequestsShouldKeepGpcAndUnrelatedExtPropertyAfterPromotion()
514501
assertThat(result.getErrors()).isEmpty();
515502
final Regs regs = result.getValue().getFirst().getPayload().getRegs();
516503
assertThat(regs.getGpp()).isEqualTo("with_gpc");
517-
// ext survives: gpc kept, unrelated property kept, gpp stripped
518504
assertThat(regs.getExt()).isNotNull();
519505
assertThat(regs.getExt().getGpc()).isEqualTo("1");
520506
assertThat(regs.getExt().getProperty("gpp")).isNull();
@@ -523,8 +509,6 @@ public void makeHttpRequestsShouldKeepGpcAndUnrelatedExtPropertyAfterPromotion()
523509

524510
@Test
525511
public void makeHttpRequestsShouldNotPromoteWhenExtPropertyHasWrongType() {
526-
// Defensive type guards: gpp as integer (not text), gpp_sid as text (not array),
527-
// coppa as text (not integer). None should promote; regs should be unchanged.
528512
final BidRequest bidRequest = givenBidRequest(identity(),
529513
requestBuilder -> requestBuilder.regs(Regs.builder()
530514
.ext(ExtRegs.of(null, null, null, null))
@@ -542,16 +526,36 @@ public void makeHttpRequestsShouldNotPromoteWhenExtPropertyHasWrongType() {
542526
assertThat(regs.getGpp()).isNull();
543527
assertThat(regs.getGppSid()).isNull();
544528
assertThat(regs.getCoppa()).isNull();
545-
// ext is preserved with the malformed properties untouched
546529
assertThat(regs.getExt()).isNotNull();
547530
assertThat(regs.getExt().getProperty("gpp").asInt()).isEqualTo(99);
548531
assertThat(regs.getExt().getProperty("gpp_sid").asText()).isEqualTo("not_array");
549532
assertThat(regs.getExt().getProperty("coppa").asText()).isEqualTo("not_int");
550533
}
551534

535+
@Test
536+
public void makeHttpRequestsShouldLeaveMalformedExtValueInExtWhenSiblingFieldIsPromoted() {
537+
final BidRequest bidRequest = givenBidRequest(identity(),
538+
requestBuilder -> requestBuilder.regs(Regs.builder()
539+
.ext(ExtRegs.of(null, null, null, null))
540+
.build()).device(Device.builder().ua("UA").build()));
541+
bidRequest.getRegs().getExt().addProperty("coppa", IntNode.valueOf(1));
542+
bidRequest.getRegs().getExt().addProperty("gpp", IntNode.valueOf(99));
543+
544+
// when
545+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
546+
547+
// then
548+
assertThat(result.getErrors()).isEmpty();
549+
final Regs regs = result.getValue().getFirst().getPayload().getRegs();
550+
assertThat(regs.getCoppa()).isEqualTo(1);
551+
assertThat(regs.getGpp()).isNull();
552+
assertThat(regs.getExt()).isNotNull();
553+
assertThat(regs.getExt().getProperty("coppa")).isNull();
554+
assertThat(regs.getExt().getProperty("gpp").asInt()).isEqualTo(99);
555+
}
556+
552557
@Test
553558
public void makeHttpRequestsShouldShortCircuitWhenRegsHasNoExt() {
554-
// regs is set but ext is null — modifyRegs should return regs unchanged.
555559
final BidRequest bidRequest = givenBidRequest(identity(),
556560
requestBuilder -> requestBuilder.regs(Regs.builder()
557561
.gdpr(0)

0 commit comments

Comments
 (0)