From 91412bd67fbc86d2963569de0bfa44ece0fcab4a Mon Sep 17 00:00:00 2001 From: antonbabak Date: Tue, 29 Jul 2025 10:31:13 +0200 Subject: [PATCH] MinuteMedia Adapter: Add test endpoint --- .../bidder/minutemedia/MinuteMediaBidder.java | 23 +++++++------- .../bidder/MinuteMediaConfiguration.java | 24 +++++++++++--- .../resources/bidder-config/minutemedia.yaml | 1 + .../minutemedia/MinuteMediaBidderTest.java | 31 +++++++++++++++++-- .../server/it/test-application.properties | 1 + 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidder.java b/src/main/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidder.java index 544e4df12d8..e1ade2c251a 100644 --- a/src/main/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidder.java +++ b/src/main/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidder.java @@ -37,10 +37,12 @@ public class MinuteMediaBidder implements Bidder { public static final String PUBLISHER_ID_MACRO = "{{PublisherId}}"; private final String endpointUrl; + private final String testEndpointUrl; private final JacksonMapper mapper; - public MinuteMediaBidder(String endpointUrl, JacksonMapper mapper) { + public MinuteMediaBidder(String endpointUrl, String testEndpointUrl, JacksonMapper mapper) { this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); + this.testEndpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(testEndpointUrl)); this.mapper = Objects.requireNonNull(mapper); } @@ -49,15 +51,15 @@ public Result>> makeHttpRequests(BidRequest bidRequ final String orgId; try { - orgId = extractFirstImpOrdId(bidRequest.getImp()); + orgId = extractFirstImpOrgId(bidRequest.getImp()); } catch (PreBidException e) { return Result.withError(BidderError.badInput(e.getMessage())); } - return Result.withValue(BidderUtil.defaultRequest(bidRequest, resolveEndpoint(endpointUrl, orgId), mapper)); + return Result.withValue(BidderUtil.defaultRequest(bidRequest, makeUrl(orgId, bidRequest.getTest()), mapper)); } - private String extractFirstImpOrdId(List imps) { + private String extractFirstImpOrgId(List imps) { return imps.stream() .findFirst() .map(this::parseImpExt) @@ -76,8 +78,9 @@ private ExtImpMinuteMedia parseImpExt(Imp imp) { } } - private String resolveEndpoint(String endpointUrl, String orgId) { - return endpointUrl.replace(PUBLISHER_ID_MACRO, HttpUtil.encodeUrl(orgId)); + private String makeUrl(String orgId, Integer test) { + final String url = Objects.equals(test, 1) ? testEndpointUrl : endpointUrl; + return url.replace(PUBLISHER_ID_MACRO, HttpUtil.encodeUrl(orgId)); } @Override @@ -120,15 +123,11 @@ private static BidderBid makeBidderBid(Bid bid, String currency, List BidType.banner; case 2 -> BidType.video; - default -> throw new PreBidException( - "Unsupported bid mediaType: %s for impression: %s".formatted(bid.getMtype(), bid.getImpid())); + case null, default -> throw new PreBidException( + "Unsupported bid mediaType: %s for impression: %s".formatted(markupType, bid.getImpid())); }; } } diff --git a/src/main/java/org/prebid/server/spring/config/bidder/MinuteMediaConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/MinuteMediaConfiguration.java index 3b01a2f482a..fd32784ea58 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/MinuteMediaConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/MinuteMediaConfiguration.java @@ -1,5 +1,8 @@ package org.prebid.server.spring.config.bidder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.prebid.server.bidder.BidderDeps; import org.prebid.server.bidder.minutemedia.MinuteMediaBidder; import org.prebid.server.json.JacksonMapper; @@ -23,19 +26,30 @@ public class MinuteMediaConfiguration { @Bean("minutemediaConfigurationProperties") @ConfigurationProperties("adapters.minutemedia") - BidderConfigurationProperties configurationProperties() { - return new BidderConfigurationProperties(); + MinuteMediaConfigurationProperties configurationProperties() { + return new MinuteMediaConfigurationProperties(); } @Bean - BidderDeps minutemediaBidderDeps(BidderConfigurationProperties minutemediaConfigurationProperties, + BidderDeps minutemediaBidderDeps(MinuteMediaConfigurationProperties minutemediaConfigurationProperties, @NotBlank @Value("${external-url}") String externalUrl, JacksonMapper mapper) { - return BidderDepsAssembler.forBidder(BIDDER_NAME) + return BidderDepsAssembler.forBidder(BIDDER_NAME) .withConfig(minutemediaConfigurationProperties) .usersyncerCreator(UsersyncerCreator.create(externalUrl)) - .bidderCreator(config -> new MinuteMediaBidder(config.getEndpoint(), mapper)) + .bidderCreator(config -> new MinuteMediaBidder( + config.getEndpoint(), + config.getTestEndpoint(), + mapper)) .assemble(); } + + @Data + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + private static class MinuteMediaConfigurationProperties extends BidderConfigurationProperties { + + private String testEndpoint; + } } diff --git a/src/main/resources/bidder-config/minutemedia.yaml b/src/main/resources/bidder-config/minutemedia.yaml index 5271b51be67..096f7776ded 100644 --- a/src/main/resources/bidder-config/minutemedia.yaml +++ b/src/main/resources/bidder-config/minutemedia.yaml @@ -1,6 +1,7 @@ adapters: minutemedia: endpoint: https://pbs.minutemedia-prebid.com/pbs-mm?publisher_id={{PublisherId}} + test-endpoint: https://pbs.minutemedia-prebid.com/pbs-test?publisher_id={{PublisherId}} modifying-vast-xml-allowed: true meta-info: maintainer-email: hb@minutemedia.com diff --git a/src/test/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidderTest.java b/src/test/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidderTest.java index 02d22021d6f..a9df3c14105 100644 --- a/src/test/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/minutemedia/MinuteMediaBidderTest.java @@ -33,13 +33,20 @@ public class MinuteMediaBidderTest extends VertxTest { private static final String ENDPOINT_URL = "https://randomurl.com/exchange?publisherId={{PublisherId}}"; + private static final String TEST_ENDPOINT_URL = "https://test.com/exchange?publisherId={{PublisherId}}"; - private final MinuteMediaBidder target = new MinuteMediaBidder(ENDPOINT_URL, jacksonMapper); + private final MinuteMediaBidder target = new MinuteMediaBidder(ENDPOINT_URL, TEST_ENDPOINT_URL, jacksonMapper); @Test public void creationShouldFailOnInvalidEndpointUrl() { assertThatIllegalArgumentException() - .isThrownBy(() -> new MinuteMediaBidder("invalid_url", jacksonMapper)); + .isThrownBy(() -> new MinuteMediaBidder("invalid_url", TEST_ENDPOINT_URL, jacksonMapper)); + } + + @Test + public void creationShouldFailOnInvalidTestEndpointUrl() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new MinuteMediaBidder(ENDPOINT_URL, "invalid_url", jacksonMapper)); } @Test @@ -76,6 +83,26 @@ public void makeHttpRequestsShouldResolveEndpointUrlUsingFirstImp() { assertThat(result.getErrors()).isEmpty(); } + @Test + public void makeHttpRequestsShouldResolveTestEndpointUrlWhenTestIsOne() { + // given + final BidRequest bidRequest = givenBidRequest( + impBuilder -> impBuilder.ext(givenImpExt("123")), + impBuilder -> impBuilder.ext(givenImpExt("456"))) + .toBuilder() + .test(1) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly("https://test.com/exchange?publisherId=123"); + assertThat(result.getErrors()).isEmpty(); + } + @Test public void makeHttpRequestsShouldReturnErrorOnAbsentImpExtBidderOrg() { // given diff --git a/src/test/resources/org/prebid/server/it/test-application.properties b/src/test/resources/org/prebid/server/it/test-application.properties index 01ff79b8691..d974cb4cda1 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -373,6 +373,7 @@ adapters.mgidX.enabled=true adapters.mgidX.endpoint=http://localhost:8090/mgidx-exchange adapters.minutemedia.enabled=true adapters.minutemedia.endpoint=http://localhost:8090/minutemedia-exchange?publisherId={{PublisherId}} +adapters.minutemedia.test-endpoint=http://localhost:8090/minutemedia-exchange?publisherId={{PublisherId}} adapters.missena.enabled=true adapters.missena.endpoint=http://localhost:8090/missena-exchange adapters.mobfoxpb.enabled=true