Skip to content

Conversation

@marki1an
Copy link
Collaborator

@marki1an marki1an commented Oct 9, 2025

🔧 Type of changes

  • new bid adapter
  • bid adapter update
  • new feature
  • new analytics adapter
  • new module
  • module update
  • bugfix
  • documentation
  • configuration
  • dependency update
  • tech debt (test coverage, refactorings, etc.)

✨ What's the context?

What's the context for the changes?

🧠 Rationale behind the change

Why did you choose to make these changes? Were there any trade-offs you had to consider?

🔎 New Bid Adapter Checklist

  • verify email contact works
  • NO fully dynamic hostnames
  • geographic host parameters are NOT required
  • direct use of HTTP is prohibited - implement an existing Bidder interface that will do all the job
  • if the ORTB is just forwarded to the endpoint, use the generic adapter - define the new adapter as the alias of the generic adapter
  • cover an adapter configuration with an integration test

🧪 Test plan

How do you know the changes are safe to ship to production?

🏎 Quality check

  • Are your changes following our code style guidelines?
  • Are there any breaking changes in your code?
  • Does your test coverage exceed 90%?
  • Are there any erroneous console logs, debuggers or leftover code in your changes?

@marki1an marki1an self-assigned this Oct 9, 2025
@marki1an marki1an added the tests Functional or other tests label Oct 9, 2025
Comment on lines 232 to 237
def responseStatusCode = response.statusCode
if (responseStatusCode != OK_200.code()) {
def responseBody = response.body.asString()
log.error(responseBody)
throw new PrebidServerException(responseStatusCode, responseBody, getHeaders(response))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicate of checkResponseStatusCode method

}

void setInvalidPostResponse() {
mockServerClient.when(request().withPath(endpoint), Times.unlimited(), TimeToLive.unlimited(), -10)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no method is specified, it won’t be limited to POST

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think an error response might not have a body?

Copy link
Collaborator Author

@marki1an marki1an Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PBC returns with an error, forward that error to the client with the same HTTP code received from PBC.

"cache.host" : CACHE_HOST]
private static final Map<String, String> VALID_INTERNAL_CACHE = ["cache.internal.scheme": "http",
"cache.internal.host" : "$networkServiceContainer.hostAndPort".toString(),
"cache.internal.path" : "/cache"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"cache.internal.path" : CACHE_ENDPOINT]


def "PBS should return 200 status code when get vtrack request contain uuid"() {
given: "Random uuid"
def uuid = UUID.randomUUID().toString()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use the UUID only once, so maybe no need for a variable

prebidCache.setResponse(responseBody)

when: "PBS processes get vtrack request"
def response = defaultPbsService.sendGetVtrackRequest(["uuid": uuid, cacheHost: cacheHost])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why cacheHost and not ch? On PBC:

    private static final int UNKNOWN_SIZE_VALUE = 1;
    ServiceType type;
    static final String ID_KEY = "uuid";
    static final String CACHE_HOST_KEY = "ch";
    private static final String UUID_DUPLICATION = "UUID duplication.";

}
}

void setResponse(String responseBody) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use as example TransferValue from PBC get request


static final TransferValue getTransferValue(){
return new TransferValue().tap {
adm = "<script type=\\\"text/javascript\\\">\\n rubicon_cb = Math.random(); rubicon_rurl = document.referrer; if(top.location==document.location){rubicon_rurl = document.location;} rubicon_rurl = escape(rubicon_rurl);\\n window.rubicon_ad = \\\"4073548\\\" + \\\".\\\" + \\\"js\\\";\\n window.rubicon_creative = \\\"4458534\\\" + \\\".\\\" + \\\"js\\\";\\n </script>\\n<div style=\\\"width: 0; height: 0; overflow: hidden;\\\"><img border=\\\"0\\\" width=\\\"1\\\" height=\\\"1\\\" src=\\\"http://beacon-us-iad2.rubiconproject.com/beacon/d/f5b45196-4d05-4e42-8190-264d993c3515?accountId=1001&siteId=113932&zoneId=535510&e=6A1E40E384DA563BD667C48E6BE5FF2436D13A174DE937CDDAAF548B67FBAEBDC779E539A868F72E270E87E31888912083DA7E4E4D5AF24E782EF9778EE5B34E9F0ADFB8523971184242CC624DE62CD4BB342D372FA82497B63ADB685D502967FCB404AD24048D03AFEA50BAA8A987A017B93F2D2A1C5933B4A7786F3B6CF76724F5207A2458AD77E82A954C1004678A\\\" alt=\\\"\\\" /></div>\\n\\n\\n<a href=\\\"http://optimized-by.rubiconproject.com/t/1001/113932/535510-15.4073548.4458534?url=http%3A%2F%2Frubiconproject.com\\\" target=\\\"_blank\\\"><img src=\\\"https://secure-assets.rubiconproject.com/campaigns/1001/50/59/48/1476242257campaign_file_q06ab2.png\\\" border=\\\"0\\\" alt=\\\"\\\" /></a><div style=\\\"height:0px;width:0px;overflow:hidden\\\"><script>(function(){document.write('<iframe src=\\\"https://tap2-cdn.rubiconproject.com/partner/scripts/rubicon/emily.html?pc=1001/113932&geo=na&co=us\\\" frameborder=\\\"0\\\" marginwidth=\\\"0\\\" marginheight=\\\"0\\\" scrolling=\\\"NO\\\" width=\\\"0\\\" height=\\\"0\\\" style=\\\"height:0px;width:0px\\\"></iframe>');})();</script></div>\\n\",\n"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adm = PBSUtils.randomString

Comment on lines 233 to 236
new VTrackResponse().tap {
statusCode = response.statusCode()
responseBody = decode(response.body.asString(), TransferValue)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to check it in tests, it's already there, so just:
decode(response.body.asString(), VTrackResponse)

import groovy.transform.ToString

@ToString(includeNames = true, ignoreNulls = true)
class VTrackResponse {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls remove

Comment on lines 82 to 89
void setResponse(TransferValue vTrackResponse) {
mockServerClient.when(request().withPath(endpoint), Times.unlimited(), TimeToLive.unlimited(), -10)
.respond { request ->
request.withPath(endpoint)
? response().withStatusCode(OK_200.code()).withBody(encode(vTrackResponse))
: HttpResponse.notFoundResponse()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, and rename to setGetResponse

prebidCache.setResponse(responseBody)

when: "PBS processes get vtrack request"
def response = defaultPbsService.sendGetVtrackRequest(["uuid": uuid, ch: cacheHost])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

["uuid": uuid, "ch": cacheHost]

prebidCache.setResponse(responseBody)

when: "PBS processes get vtrack request"
def response = pbsServiceWithInternalCache.sendGetVtrackRequest(["uuid": uuid, "cacheHost": cacheHost])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

["uuid": uuid, "ch": cacheHost]

Comment on lines 29 to 32
int getVTracGetRequestCount() {
getRequestCount(request().withMethod("GET")
.withPath(CACHE_ENDPOINT))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will give you much more information and allow you to verify parameters (lile getRecordedRequests):

mockServerClient.retrieveRecordedRequests(
        request().withMethod("GET").withPath("/cache"))

def initialValue = getCurrentMetricValue(defaultPbsService, VTRACK_READ_OK_METRIC)

and: "Clean cache mock response"
prebidCache.reset(CACHE_ENDPOINT)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for it, you have cleanup. Same for others

and: "Random uuid"
def uuid = UUID.randomUUID().toString()

and: "Clean up and set up successful response"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in all others:
"Setup PBC response"
it's doesn't clean anything

@osulzhenko osulzhenko merged commit a1591f9 into vtrack-get Oct 22, 2025
1 check passed
@osulzhenko osulzhenko deleted the test/vtrack-endpoint branch October 22, 2025 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Functional or other tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants