From b92935c0d19cff2beca651ff52723b8d5cbb5e4f Mon Sep 17 00:00:00 2001 From: floxis-admin Date: Mon, 5 Oct 2026 20:02:06 +0300 Subject: [PATCH 1/3] Floxis: add adapex alias Adapex is a white-label partner of the Floxis exchange. The alias bids to hb.adapex.io and syncs through sync.adapex.io. Requests are now grouped by resolved URL so an endpoint without a host macro sends one request per seat regardless of region or partner params. --- .../server/bidder/floxis/FloxisBidder.java | 20 +++--- src/main/resources/bidder-config/floxis.yaml | 12 ++++ .../bidder/floxis/FloxisBidderTest.java | 43 ++++++++++++ .../java/org/prebid/server/it/AdapexTest.java | 34 ++++++++++ .../adapex/test-adapex-bid-request.json | 66 +++++++++++++++++++ .../adapex/test-adapex-bid-response.json | 23 +++++++ .../adapex/test-auction-adapex-request.json | 35 ++++++++++ .../adapex/test-auction-adapex-response.json | 44 +++++++++++++ .../server/it/test-application.properties | 2 + 9 files changed, 269 insertions(+), 10 deletions(-) create mode 100644 src/test/java/org/prebid/server/it/AdapexTest.java create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-request.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-response.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-request.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-response.json diff --git a/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java b/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java index 7e51b073b12..b12b5fb4ff3 100644 --- a/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java +++ b/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java @@ -55,7 +55,7 @@ public FloxisBidder(String endpointUrl, JacksonMapper mapper) { @Override public Result>> makeHttpRequests(BidRequest request) { final List errors = new ArrayList<>(); - final Map> impsByHost = new LinkedHashMap<>(); + final Map> impsByTarget = new LinkedHashMap<>(); for (Imp imp : request.getImp()) { final ExtImpFloxis impExt; @@ -66,15 +66,15 @@ public Result>> makeHttpRequests(BidRequest request continue; } - impsByHost.computeIfAbsent( - new HostId(impExt.getSeat(), resolveBidHost(impExt)), key -> new ArrayList<>()) - .add(imp); + // Keyed on the resolved URL: an alias endpoint without {Host} must not split imps per region/partner. + final RequestTarget target = new RequestTarget(impExt.getSeat(), resolveUrl(impExt)); + impsByTarget.computeIfAbsent(target, key -> new ArrayList<>()).add(imp); } - final List> httpRequests = impsByHost.entrySet().stream() + final List> httpRequests = impsByTarget.entrySet().stream() .map(entry -> BidderUtil.defaultRequest( request.toBuilder().imp(entry.getValue()).build(), - resolveUrl(entry.getKey()), + entry.getKey().url(), mapper)) .toList(); @@ -99,10 +99,10 @@ private ExtImpFloxis parseImpExt(Imp imp) { return ExtImpFloxis.of(impExt.getSeat(), region, partner); } - private String resolveUrl(HostId hostId) { + private String resolveUrl(ExtImpFloxis impExt) { return endpointUrl - .replaceMacro(HOST_MACRO, hostId.host()) - .replaceMacro(SEAT_MACRO, hostId.seat()) + .replaceMacro(HOST_MACRO, resolveBidHost(impExt)) + .replaceMacro(SEAT_MACRO, impExt.getSeat()) .expand(); } @@ -202,6 +202,6 @@ private static int countFormats(Imp imp) { return formats; } - private record HostId(String seat, String host) { + private record RequestTarget(String seat, String url) { } } diff --git a/src/main/resources/bidder-config/floxis.yaml b/src/main/resources/bidder-config/floxis.yaml index a2f058c5e14..a78060961a4 100644 --- a/src/main/resources/bidder-config/floxis.yaml +++ b/src/main/resources/bidder-config/floxis.yaml @@ -4,6 +4,18 @@ adapters: endpoint-compression: gzip ortb-version: "2.6" modifying-vast-xml-allowed: false + aliases: + adapex: + enabled: false + endpoint: https://hb.adapex.io/pbs?seat={SeatId} + meta-info: + vendor-id: 1609 + usersync: + enabled: true + cookie-family-name: adapex + redirect: + url: "https://sync.adapex.io/sync?gdpr={gdpr}&gdpr_consent={gdpr_consent}&gpp={gpp}&gpp_sid={gpp_sid}&us_privacy={us_privacy}&dest={redirect_url}" + uid-macro: "${USER_ID}" meta-info: maintainer-email: prebid@floxis.tech app-media-types: diff --git a/src/test/java/org/prebid/server/bidder/floxis/FloxisBidderTest.java b/src/test/java/org/prebid/server/bidder/floxis/FloxisBidderTest.java index f94d035289f..879b1661b24 100644 --- a/src/test/java/org/prebid/server/bidder/floxis/FloxisBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/floxis/FloxisBidderTest.java @@ -171,6 +171,49 @@ public void makeHttpRequestsShouldLeaveEndpointUnchangedWhenItDeclaresNoMacros() .containsExactly("http://localhost:8090/floxis-exchange"); } + @Test + public void makeHttpRequestsShouldIgnoreRegionAndPartnerWhenAliasEndpointDeclaresNoHostMacro() { + // given + final FloxisBidder bidder = new FloxisBidder("https://hb.adapex.io/pbs?seat={SeatId}", jacksonMapper); + final BidRequest bidRequest = givenBidRequest(imp -> imp.ext(givenImpExt("abc", "eu", "acme"))); + + // when + final Result>> result = bidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getUri) + .containsExactly("https://hb.adapex.io/pbs?seat=abc"); + } + + @Test + public void makeHttpRequestsShouldRouteOnceWhenImpsDifferOnlyInRegionAndPartnerOnAliasEndpoint() { + // given + final FloxisBidder bidder = new FloxisBidder("https://hb.adapex.io/pbs?seat={SeatId}", jacksonMapper); + final BidRequest bidRequest = BidRequest.builder() + .id("req-1") + .imp(asList( + givenImp(imp -> imp.id("imp-1").ext(givenImpExt("seat-a", "eu"))), + givenImp(imp -> imp.id("imp-2").ext(givenImpExt("seat-a", "apac", "acme"))), + givenImp(imp -> imp.id("imp-3").ext(givenImpExt("seat-b", "eu"))))) + .site(Site.builder().id("271").build()) + .build(); + + // when + final Result>> result = bidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(2) + .extracting(HttpRequest::getUri, request -> request.getPayload().getImp().stream() + .map(Imp::getId) + .toList()) + .containsExactly( + tuple("https://hb.adapex.io/pbs?seat=seat-a", asList("imp-1", "imp-2")), + tuple("https://hb.adapex.io/pbs?seat=seat-b", singletonList("imp-3"))); + } + @Test public void makeHttpRequestsShouldRouteOnceAndForwardAllImpsWhenSeatAndRegionMatch() { // given diff --git a/src/test/java/org/prebid/server/it/AdapexTest.java b/src/test/java/org/prebid/server/it/AdapexTest.java new file mode 100644 index 00000000000..05d082a6c2a --- /dev/null +++ b/src/test/java/org/prebid/server/it/AdapexTest.java @@ -0,0 +1,34 @@ +package org.prebid.server.it; + +import io.restassured.response.Response; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.prebid.server.model.Endpoint; + +import java.io.IOException; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static java.util.Collections.singletonList; + +public class AdapexTest extends IntegrationTest { + + @Test + public void openrtb2AuctionShouldRespondWithBidsFromAdapex() throws IOException, JSONException { + // given + WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/adapex-exchange")) + .withQueryParam("seat", equalTo("pub-seat-1")) + .withRequestBody(equalToJson(jsonFrom("openrtb2/adapex/test-adapex-bid-request.json"))) + .willReturn(aResponse().withBody(jsonFrom("openrtb2/adapex/test-adapex-bid-response.json")))); + + // when + final Response response = responseFor("openrtb2/adapex/test-auction-adapex-request.json", + Endpoint.openrtb2_auction); + + // then + assertJsonEquals("openrtb2/adapex/test-auction-adapex-response.json", response, singletonList("adapex")); + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-request.json new file mode 100644 index 00000000000..909c72773d0 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-request.json @@ -0,0 +1,66 @@ +{ + "id": "request_id", + "imp": [ + { + "id": "imp_id", + "secure": 1, + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "tid": "${json-unit.any-string}", + "bidder": { + "seat": "pub-seat-1" + } + } + } + ], + "source": { + "tid": "${json-unit.any-string}", + "schain": { + "complete": 1, + "ver": "1.0", + "nodes": [ + { + "asi": "adapex.io", + "sid": "pub-seat-1", + "hp": 1 + } + ] + } + }, + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": "${json-unit.any-number}", + "cur": [ + "USD" + ], + "regs": { + "gdpr": 0 + }, + "ext": { + "prebid": { + "server": { + "externalurl": "http://localhost:8080", + "gvlid": 1, + "datacenter": "local", + "http_method": "POST", + "endpoint": "/openrtb2/auction" + } + } + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-response.json new file mode 100644 index 00000000000..7c65e4bd1a4 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-adapex-bid-response.json @@ -0,0 +1,23 @@ +{ + "id": "request_id", + "cur": "USD", + "seatbid": [ + { + "seat": "adapex", + "bid": [ + { + "id": "bid_id", + "impid": "imp_id", + "price": 3.33, + "adid": "adid001", + "crid": "crid001", + "cid": "cid001", + "adm": "adm001", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-request.json b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-request.json new file mode 100644 index 00000000000..59bbdf3f678 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-request.json @@ -0,0 +1,35 @@ +{ + "id": "request_id", + "imp": [ + { + "id": "imp_id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "adapex": { + "seat": "pub-seat-1" + } + } + } + ], + "source": { + "schain": { + "complete": 1, + "ver": "1.0", + "nodes": [ + { + "asi": "adapex.io", + "sid": "pub-seat-1", + "hp": 1 + } + ] + } + }, + "regs": { + "ext": { + "gdpr": 0 + } + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-response.json new file mode 100644 index 00000000000..fa15ff0cca9 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/adapex/test-auction-adapex-response.json @@ -0,0 +1,44 @@ +{ + "id": "request_id", + "seatbid": [ + { + "bid": [ + { + "id": "bid_id", + "impid": "imp_id", + "price": 3.33, + "adm": "adm001", + "adid": "adid001", + "cid": "cid001", + "crid": "crid001", + "w": 300, + "h": 250, + "exp": 300, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner", + "meta": { + "adaptercode": "adapex" + } + }, + "origbidcpm": 3.33, + "origbidcur": "USD" + } + } + ], + "seat": "adapex", + "group": 0 + } + ], + "cur": "USD", + "ext": { + "responsetimemillis": { + "adapex": "{{ adapex.response_time_ms }}" + }, + "prebid": { + "auctiontimestamp": 0 + }, + "tmaxrequest": 5000 + } +} 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 cc1a749d4ba..3b7cd9a782c 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -271,6 +271,8 @@ adapters.flipp.enabled=true adapters.flipp.endpoint=http://localhost:8090/flipp-exchange adapters.floxis.enabled=true adapters.floxis.endpoint=http://localhost:8090/floxis-exchange +adapters.floxis.aliases.adapex.enabled=true +adapters.floxis.aliases.adapex.endpoint=http://localhost:8090/adapex-exchange?seat={SeatId} adapters.audiencenetwork.enabled=true adapters.audiencenetwork.endpoint=http://localhost:8090/audienceNetwork-exchange adapters.audiencenetwork.timeout-notification-url-template=http://localhost:8090/audienceNetwork-timeout From 5464b56c9abb04b27888ec30f3263ec010147aa3 Mon Sep 17 00:00:00 2001 From: floxis-admin Date: Fri, 9 Oct 2026 11:23:08 +0300 Subject: [PATCH 2/3] Adapex: verify alias configuration and usersync privacy --- .../bidder/FloxisConfigurationTest.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java diff --git a/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java b/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java new file mode 100644 index 00000000000..b3efc892e9d --- /dev/null +++ b/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java @@ -0,0 +1,114 @@ +package org.prebid.server.spring.config.bidder; + +import com.iab.openrtb.request.BidRequest; +import com.iab.openrtb.request.Imp; +import org.junit.jupiter.api.Test; +import org.prebid.server.VertxTest; +import org.prebid.server.auction.versionconverter.OrtbVersion; +import org.prebid.server.bidder.Bidder; +import org.prebid.server.bidder.BidderDeps; +import org.prebid.server.bidder.BidderInstanceDeps; +import org.prebid.server.bidder.UsersyncInfoFactory; +import org.prebid.server.bidder.UsersyncMethodType; +import org.prebid.server.bidder.model.HttpRequest; +import org.prebid.server.json.JacksonMapper; +import org.prebid.server.privacy.ccpa.Ccpa; +import org.prebid.server.privacy.model.Privacy; +import org.prebid.server.proto.openrtb.ext.ExtPrebid; +import org.prebid.server.proto.openrtb.ext.request.floxis.ExtImpFloxis; +import org.prebid.server.proto.response.UsersyncInfo; +import org.prebid.server.spring.config.BiddersConfiguration; +import org.prebid.server.spring.config.SpringConfiguration; +import org.prebid.server.spring.config.bidder.model.CompressionType; +import org.prebid.server.spring.env.YamlPropertySourceFactory; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.io.ClassPathResource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FloxisConfigurationTest extends VertxTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ConfigurationPropertiesAutoConfiguration.class)) + .withUserConfiguration(FloxisConfiguration.class, BiddersConfiguration.class, SpringConfiguration.class) + .withBean(JacksonMapper.class, () -> jacksonMapper) + .withInitializer(context -> context.getEnvironment().getPropertySources().addLast( + new PropertiesPropertySource("application", + YamlPropertySourceFactory.readPropertiesFromYamlResource( + new ClassPathResource("application.yaml"))))); + + @Test + public void adapexShouldBeDisabledByDefaultAndInheritFloxisCapabilities() { + contextRunner.run(context -> { + final BidderDeps deps = context.getBean(BidderDeps.class); + final BidderInstanceDeps adapex = instance(deps, "adapex"); + final BidderInstanceDeps floxis = instance(deps, "floxis"); + + assertThat(adapex.getBidderInfo().isEnabled()).isFalse(); + assertThat(adapex.getBidderInfo().getAliasOf()).isEqualTo("floxis"); + assertThat(adapex.getBidderInfo().getCapabilities()).isEqualTo(floxis.getBidderInfo().getCapabilities()); + assertThat(adapex.getBidderInfo().getGdpr().getVendorId()).isEqualTo(1609); + assertThat(adapex.getBidderInfo().getOrtbVersion()).isEqualTo(OrtbVersion.ORTB_2_6); + assertThat(adapex.getBidderInfo().getCompressionType()).isEqualTo(CompressionType.GZIP); + assertThat(adapex.getBidderInfo().isCcpaEnforced()).isTrue(); + }); + } + + @Test + @SuppressWarnings("unchecked") + public void enabledAdapexShouldUseOwnEndpointWhenFloxisIsDisabled() { + contextRunner.withPropertyValues("adapters.floxis.aliases.adapex.enabled=true").run(context -> { + final BidderDeps deps = context.getBean(BidderDeps.class); + final Bidder bidder = (Bidder) instance(deps, "adapex").getBidder(); + final BidRequest request = BidRequest.builder() + .imp(List.of(Imp.builder() + .id("imp-1") + .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpFloxis.of("a b&c", "eu", "acme")))) + .build())) + .build(); + + assertThat(instance(deps, "floxis").getBidderInfo().isEnabled()).isFalse(); + assertThat(bidder.makeHttpRequests(request).getValue()) + .extracting(HttpRequest::getUri) + .containsExactly("https://hb.adapex.io/pbs?seat=a%20b%26c"); + }); + } + + @Test + public void adapexUsersyncShouldUseOwnCookieFamilyAndForwardPrivacyToOwnHostAndCallback() { + contextRunner.run(context -> { + final BidderInstanceDeps adapex = instance(context.getBean(BidderDeps.class), "adapex"); + final Privacy privacy = Privacy.builder() + .gdpr("1") + .consentString("consent") + .ccpa(Ccpa.of("1YNN")) + .gpp("gpp") + .gppSid(List.of(2, 6)) + .build(); + + final UsersyncInfo usersync = new UsersyncInfoFactory("https://pbs.example") + .build("adapex", null, adapex.getUsersyncer().getRedirect(), privacy); + + assertThat(adapex.getUsersyncer().getCookieFamilyName()).isEqualTo("adapex"); + assertThat(adapex.getUsersyncer().isEnabled()).isTrue(); + assertThat(usersync.getType()).isEqualTo(UsersyncMethodType.REDIRECT); + assertThat(usersync.getUrl()).isEqualTo("https://sync.adapex.io/sync?gdpr=1&gdpr_consent=consent" + + "&gpp=gpp&gpp_sid=2%2C6&us_privacy=1YNN" + + "&dest=https%3A%2F%2Fpbs.example%2Fsetuid%3Fbidder%3Dadapex%26gdpr%3D1" + + "%26gdpr_consent%3Dconsent%26us_privacy%3D1YNN%26gpp%3Dgpp%26gpp_sid%3D2%252C6" + + "%26f%3Di%26uid%3D%24%7BUSER_ID%7D"); + }); + } + + private static BidderInstanceDeps instance(BidderDeps deps, String name) { + return deps.getInstances().stream() + .filter(instance -> instance.getName().equals(name)) + .findFirst() + .orElseThrow(); + } +} From fd825d1a8dca9fb59de76fd85542868f428b33be Mon Sep 17 00:00:00 2001 From: floxis-admin Date: Sat, 24 Oct 2026 00:20:45 +0300 Subject: [PATCH 3/3] Adapex: address review feedback Group imps by resolved URL only, drop the configuration tests and the seat macro from the integration test endpoint. --- .../server/bidder/floxis/FloxisBidder.java | 13 +- .../java/org/prebid/server/it/AdapexTest.java | 2 - .../bidder/FloxisConfigurationTest.java | 114 ------------------ .../server/it/test-application.properties | 2 +- 4 files changed, 5 insertions(+), 126 deletions(-) delete mode 100644 src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java diff --git a/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java b/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java index b12b5fb4ff3..e90d244338f 100644 --- a/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java +++ b/src/main/java/org/prebid/server/bidder/floxis/FloxisBidder.java @@ -55,7 +55,7 @@ public FloxisBidder(String endpointUrl, JacksonMapper mapper) { @Override public Result>> makeHttpRequests(BidRequest request) { final List errors = new ArrayList<>(); - final Map> impsByTarget = new LinkedHashMap<>(); + final Map> impsByUrl = new LinkedHashMap<>(); for (Imp imp : request.getImp()) { final ExtImpFloxis impExt; @@ -66,15 +66,13 @@ public Result>> makeHttpRequests(BidRequest request continue; } - // Keyed on the resolved URL: an alias endpoint without {Host} must not split imps per region/partner. - final RequestTarget target = new RequestTarget(impExt.getSeat(), resolveUrl(impExt)); - impsByTarget.computeIfAbsent(target, key -> new ArrayList<>()).add(imp); + impsByUrl.computeIfAbsent(resolveUrl(impExt), key -> new ArrayList<>()).add(imp); } - final List> httpRequests = impsByTarget.entrySet().stream() + final List> httpRequests = impsByUrl.entrySet().stream() .map(entry -> BidderUtil.defaultRequest( request.toBuilder().imp(entry.getValue()).build(), - entry.getKey().url(), + entry.getKey(), mapper)) .toList(); @@ -201,7 +199,4 @@ private static int countFormats(Imp imp) { } return formats; } - - private record RequestTarget(String seat, String url) { - } } diff --git a/src/test/java/org/prebid/server/it/AdapexTest.java b/src/test/java/org/prebid/server/it/AdapexTest.java index 05d082a6c2a..fe66a4be058 100644 --- a/src/test/java/org/prebid/server/it/AdapexTest.java +++ b/src/test/java/org/prebid/server/it/AdapexTest.java @@ -8,7 +8,6 @@ import java.io.IOException; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; @@ -20,7 +19,6 @@ public class AdapexTest extends IntegrationTest { public void openrtb2AuctionShouldRespondWithBidsFromAdapex() throws IOException, JSONException { // given WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/adapex-exchange")) - .withQueryParam("seat", equalTo("pub-seat-1")) .withRequestBody(equalToJson(jsonFrom("openrtb2/adapex/test-adapex-bid-request.json"))) .willReturn(aResponse().withBody(jsonFrom("openrtb2/adapex/test-adapex-bid-response.json")))); diff --git a/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java b/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java deleted file mode 100644 index b3efc892e9d..00000000000 --- a/src/test/java/org/prebid/server/spring/config/bidder/FloxisConfigurationTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.prebid.server.spring.config.bidder; - -import com.iab.openrtb.request.BidRequest; -import com.iab.openrtb.request.Imp; -import org.junit.jupiter.api.Test; -import org.prebid.server.VertxTest; -import org.prebid.server.auction.versionconverter.OrtbVersion; -import org.prebid.server.bidder.Bidder; -import org.prebid.server.bidder.BidderDeps; -import org.prebid.server.bidder.BidderInstanceDeps; -import org.prebid.server.bidder.UsersyncInfoFactory; -import org.prebid.server.bidder.UsersyncMethodType; -import org.prebid.server.bidder.model.HttpRequest; -import org.prebid.server.json.JacksonMapper; -import org.prebid.server.privacy.ccpa.Ccpa; -import org.prebid.server.privacy.model.Privacy; -import org.prebid.server.proto.openrtb.ext.ExtPrebid; -import org.prebid.server.proto.openrtb.ext.request.floxis.ExtImpFloxis; -import org.prebid.server.proto.response.UsersyncInfo; -import org.prebid.server.spring.config.BiddersConfiguration; -import org.prebid.server.spring.config.SpringConfiguration; -import org.prebid.server.spring.config.bidder.model.CompressionType; -import org.prebid.server.spring.env.YamlPropertySourceFactory; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.core.env.PropertiesPropertySource; -import org.springframework.core.io.ClassPathResource; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class FloxisConfigurationTest extends VertxTest { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ConfigurationPropertiesAutoConfiguration.class)) - .withUserConfiguration(FloxisConfiguration.class, BiddersConfiguration.class, SpringConfiguration.class) - .withBean(JacksonMapper.class, () -> jacksonMapper) - .withInitializer(context -> context.getEnvironment().getPropertySources().addLast( - new PropertiesPropertySource("application", - YamlPropertySourceFactory.readPropertiesFromYamlResource( - new ClassPathResource("application.yaml"))))); - - @Test - public void adapexShouldBeDisabledByDefaultAndInheritFloxisCapabilities() { - contextRunner.run(context -> { - final BidderDeps deps = context.getBean(BidderDeps.class); - final BidderInstanceDeps adapex = instance(deps, "adapex"); - final BidderInstanceDeps floxis = instance(deps, "floxis"); - - assertThat(adapex.getBidderInfo().isEnabled()).isFalse(); - assertThat(adapex.getBidderInfo().getAliasOf()).isEqualTo("floxis"); - assertThat(adapex.getBidderInfo().getCapabilities()).isEqualTo(floxis.getBidderInfo().getCapabilities()); - assertThat(adapex.getBidderInfo().getGdpr().getVendorId()).isEqualTo(1609); - assertThat(adapex.getBidderInfo().getOrtbVersion()).isEqualTo(OrtbVersion.ORTB_2_6); - assertThat(adapex.getBidderInfo().getCompressionType()).isEqualTo(CompressionType.GZIP); - assertThat(adapex.getBidderInfo().isCcpaEnforced()).isTrue(); - }); - } - - @Test - @SuppressWarnings("unchecked") - public void enabledAdapexShouldUseOwnEndpointWhenFloxisIsDisabled() { - contextRunner.withPropertyValues("adapters.floxis.aliases.adapex.enabled=true").run(context -> { - final BidderDeps deps = context.getBean(BidderDeps.class); - final Bidder bidder = (Bidder) instance(deps, "adapex").getBidder(); - final BidRequest request = BidRequest.builder() - .imp(List.of(Imp.builder() - .id("imp-1") - .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpFloxis.of("a b&c", "eu", "acme")))) - .build())) - .build(); - - assertThat(instance(deps, "floxis").getBidderInfo().isEnabled()).isFalse(); - assertThat(bidder.makeHttpRequests(request).getValue()) - .extracting(HttpRequest::getUri) - .containsExactly("https://hb.adapex.io/pbs?seat=a%20b%26c"); - }); - } - - @Test - public void adapexUsersyncShouldUseOwnCookieFamilyAndForwardPrivacyToOwnHostAndCallback() { - contextRunner.run(context -> { - final BidderInstanceDeps adapex = instance(context.getBean(BidderDeps.class), "adapex"); - final Privacy privacy = Privacy.builder() - .gdpr("1") - .consentString("consent") - .ccpa(Ccpa.of("1YNN")) - .gpp("gpp") - .gppSid(List.of(2, 6)) - .build(); - - final UsersyncInfo usersync = new UsersyncInfoFactory("https://pbs.example") - .build("adapex", null, adapex.getUsersyncer().getRedirect(), privacy); - - assertThat(adapex.getUsersyncer().getCookieFamilyName()).isEqualTo("adapex"); - assertThat(adapex.getUsersyncer().isEnabled()).isTrue(); - assertThat(usersync.getType()).isEqualTo(UsersyncMethodType.REDIRECT); - assertThat(usersync.getUrl()).isEqualTo("https://sync.adapex.io/sync?gdpr=1&gdpr_consent=consent" - + "&gpp=gpp&gpp_sid=2%2C6&us_privacy=1YNN" - + "&dest=https%3A%2F%2Fpbs.example%2Fsetuid%3Fbidder%3Dadapex%26gdpr%3D1" - + "%26gdpr_consent%3Dconsent%26us_privacy%3D1YNN%26gpp%3Dgpp%26gpp_sid%3D2%252C6" - + "%26f%3Di%26uid%3D%24%7BUSER_ID%7D"); - }); - } - - private static BidderInstanceDeps instance(BidderDeps deps, String name) { - return deps.getInstances().stream() - .filter(instance -> instance.getName().equals(name)) - .findFirst() - .orElseThrow(); - } -} 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 3b7cd9a782c..01456426dd0 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -272,7 +272,7 @@ adapters.flipp.endpoint=http://localhost:8090/flipp-exchange adapters.floxis.enabled=true adapters.floxis.endpoint=http://localhost:8090/floxis-exchange adapters.floxis.aliases.adapex.enabled=true -adapters.floxis.aliases.adapex.endpoint=http://localhost:8090/adapex-exchange?seat={SeatId} +adapters.floxis.aliases.adapex.endpoint=http://localhost:8090/adapex-exchange adapters.audiencenetwork.enabled=true adapters.audiencenetwork.endpoint=http://localhost:8090/audienceNetwork-exchange adapters.audiencenetwork.timeout-notification-url-template=http://localhost:8090/audienceNetwork-timeout