Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
93e6573
added initila Pixfuture adapter files and codesd
pixfuture-media Dec 5, 2024
458fad1
Miodified vendors timewait
pixfuture-media Dec 5, 2024
d67a079
Adding test file
pixfuture-media Dec 9, 2024
a9fe81b
Added prams_test.go
pixfuture-media Dec 9, 2024
606b185
Changing pix endpoint to srv-adapter.pixfuture.com
pixfuture-media Dec 9, 2024
061b818
Made changes in test.go
pixfuture-media Dec 10, 2024
d0bc2e1
Addede changes to pixfuture_test.go
pixfuture-media Dec 10, 2024
eec17ff
Merge branch 'prebid:master' into master
pixfuture-media Dec 13, 2024
cb8e3a7
update coverage.out
pixfuture-media Dec 13, 2024
bba6eed
added doc
pixfuture-media Dec 13, 2024
22df0f8
fixing bags
pixfuture-media Dec 18, 2024
3f33089
Merge branch 'prebid:master' into master
pixfuture-media Dec 19, 2024
a22b19e
Fixed naming convention issue for Pixfuture adapter to align with bes…
pixfuture-media Dec 19, 2024
993f157
Merge branch 'master' of github.com:pixfuture-media/prebid-server
pixfuture-media Dec 19, 2024
284c847
Merge branch 'prebid:master' into master
pixfuture-media Jan 13, 2025
9e470a0
Made changes regarding github-actions
pixfuture-media Jan 13, 2025
3b4ca26
Made changes regarding github-actions
pixfuture-media Jan 13, 2025
1df8f71
Made changes regarding go test
pixfuture-media Jan 15, 2025
6a59158
Merge branch 'prebid:master' into master
pixfuture-media Jan 17, 2025
2ba1a64
Made changes regarding go test
pixfuture-media Jan 17, 2025
ea7d94e
Update adapters/pixfuture/pixfuture.go
pixfuture-media Jan 30, 2025
8dac147
Update adapters/pixfuture/pixfuture.go
pixfuture-media Jan 30, 2025
078c276
Update adapters/pixfuture/pixfuture.go
pixfuture-media Jan 30, 2025
0b62c21
Update adapters/pixfuture/pixfuture.go
pixfuture-media Jan 30, 2025
7bdabf4
Made changes in Pixfuture.go
pixfuture-media Jan 30, 2025
3f219c9
Made changes regarding GitHub reviews
pixfuture-media Jan 31, 2025
bb9b65d
Made changes regarding GitHub reviews
pixfuture-media Jan 31, 2025
7a3352f
Made changes regarding GitHub reviews
pixfuture-media Jan 31, 2025
3f13c25
Made changes regarding GitHub reviews
pixfuture-media Jan 31, 2025
a407b22
Made changes regarding GitHub reviews
pixfuture-media Jan 31, 2025
3457b8c
Made changes regarding GitHub reviews
pixfuture-media Feb 3, 2025
f1b859c
Merge branch 'prebid:master' into master
pixfuture-media Feb 4, 2025
025a574
Made changes regarding GitHub reviews
pixfuture-media Feb 14, 2025
eece8b6
Made changes regarding GitHub reviews
Feb 20, 2025
33fbff5
Made changes regarding GitHub reviews
pixfuture-media Feb 24, 2025
1912ebd
Merge branch 'prebid:master' into master
pixfuture-media Mar 11, 2025
81c11fb
Merge branch 'prebid:master' into master
pixfuture-media Mar 14, 2025
817bebf
Made changes regarding GitHub reviews
pixfuture-media Mar 14, 2025
2f15c50
Made changes regarding GitHub reviews
pixfuture-media Mar 17, 2025
c5b5f20
Update adapters/pixfuture/pixfuture.go
pixfuture-media Mar 17, 2025
be83555
Made changes regarding GitHub reviews
pixfuture-media Mar 17, 2025
f8fddb7
Made changes regarding GitHub reviews
pixfuture-media Mar 17, 2025
1aa2761
Made changes regarding GitHub reviews
pixfuture-media Mar 17, 2025
90328f3
Merge branch 'prebid:master' into master
pixfuture-media Mar 24, 2025
3a1d57b
Merge branch 'prebid:master' into master
pixfuture-media Mar 26, 2025
14278ca
Made changes regarding GitHub reviews
pixfuture-media Apr 2, 2025
7a44e1c
Merge branch 'prebid:master' into master
pixfuture-media Apr 3, 2025
d78a147
Merge branch 'prebid:master' into master
pixfuture-media Apr 10, 2025
3beb6bc
Made changes regarding GitHub reviews
pixfuture-media Apr 10, 2025
27148f5
Merge branch 'prebid:master' into master
pixfuture-media Apr 16, 2025
fd9504e
Made changes regarding GitHub reviews
pixfuture-media Apr 17, 2025
a3e6d9a
Made changes regarding GitHub reviews
pixfuture-media Apr 21, 2025
aa3b6b2
Made changes regarding GitHub reviews
pixfuture-media Apr 23, 2025
d3c660b
Merge branch 'prebid:master' into master
pixfuture-media Apr 24, 2025
edbb31c
Made changes regarding GitHub reviews
pixfuture-media Apr 24, 2025
0600cda
Merge branch 'prebid:master' into master
pixfuture-media Jun 23, 2025
986bcf7
Merge branch 'prebid:master' into master
pixfuture-media Jul 21, 2025
89fb585
Made changes regarding GitHub reviews
pixfuture-media Jul 21, 2025
77157f2
Made changes regarding GitHub reviews
pixfuture-media Jul 21, 2025
9cf8565
Merge branch 'prebid:master' into master
pixfuture-media Jul 25, 2025
c21c807
Made changes regarding GitHub reviews
pixfuture-media Jul 25, 2025
0b1b509
Merge branch 'prebid:master' into master
pixfuture-media Jul 29, 2025
e8b0591
Merge branch 'prebid:master' into master
pixfuture-media Jul 30, 2025
461d626
Merge branch 'prebid:master' into master
pixfuture-media Jul 31, 2025
351b275
Merge branch 'prebid:master' into master
pixfuture-media Aug 4, 2025
2b9a50f
Merge branch 'prebid:master' into master
pixfuture-media Aug 18, 2025
d5dd656
Update code based on feedback received from Prebid team
pixfuture-media Nov 14, 2025
5d3bef4
Fix validation issues and clean code
pixfuture-media Nov 17, 2025
c1f03ba
Merge branch 'prebid:master' into master
pixfuture-media Feb 11, 2026
0a39bde
Enhance bid response processing and error handling
pixfuture-media Feb 13, 2026
857c4c1
Add GPP and GPP SID to userSync URL
pixfuture-media Feb 13, 2026
89ae5f6
Remove BidderPixfuture from bidders list
pixfuture-media Feb 13, 2026
bac0bf5
Add BidderPixfuture to the list of bidders
pixfuture-media Feb 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions adapters/pixfuture/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package pixfuture

import (
"encoding/json"
"testing"

"github.com/prebid/prebid-server/v3/openrtb_ext"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestValidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
require.NoError(t, err, "Failed to fetch the json schema.")

tests := []struct {
name string
json string
}{
{
name: "Minimum length satisfied",
json: `{"pix_id": "123"}`,
},
{
name: "Longer valid string",
json: `{"pix_id": "abcdef"}`,
},
}

for _, tt := range tests {
tt := tt // capture range variable
Copy link
Contributor

@scr-oath scr-oath Jul 25, 2025

Choose a reason for hiding this comment

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

nitpick (non-blocking): This hasn't been needed for several versions of go now

Why tt := tt is no longer necessary in Go

The line:

tt := tt // capture range variable

was historically required in Go when using range variables inside subtests or goroutines, to "capture" the loop variable at each iteration. This prevented bugs due to all closures sharing the same variable in older Go versions.

Change in Go 1.22:

As of Go 1.22, this is no longer necessary. The Go release notes state:

"The iteration variables of for loops are now per-iteration copies, eliminating a common source of bugs when using closures or goroutines inside loops."
Go 1.22 Release Notes – Iteration Variables

Summary:
If your project requires Go 1.22 or later, you can safely remove tt := tt from range-based subtests and goroutines.
See the official Go 1.22 release notes for more details.

Copy link
Author

Choose a reason for hiding this comment

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

Got it—so it’s not absolutely required to change the code, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nope - I approved with this as an observation (as in "see something; say something" 😄 )

https://conventionalcomments.org/

Describes the (non-blocking) decoration

Copy link
Author

Choose a reason for hiding this comment

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

Thank you, dear Sheridan!

Copy link
Author

Choose a reason for hiding this comment

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

Hi Sheridan,
After applying all the recent changes, the function call to "func (a *adapter) MakeRequests(request *openrtb2.BidRequest..." in "pixfuture.go" stopped being called.
Could you help identify what might be causing this issue?

t.Run(tt.name, func(t *testing.T) {
assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderPixfuture, json.RawMessage(tt.json)), "Schema rejected valid params: %s", tt.json)
})
}
}

func TestInvalidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
require.NoError(t, err, "Failed to fetch the json schema.")

tests := []struct {
name string
json string
}{
{
name: "Wrong type (integer)",
json: `{"pix_id": 123}`,
},
{
name: "Too short (minLength: 3)",
json: `{"pix_id": "ab"}`,
},
{
name: "Missing required pix_id",
json: `{}`,
},
{
name: "Empty string (violates minLength)",
json: `{"pix_id": ""}`,
},
}

for _, tt := range tests {
tt := tt // capture range variable
t.Run(tt.name, func(t *testing.T) {
err := validator.Validate(openrtb_ext.BidderPixfuture, json.RawMessage(tt.json))
assert.Errorf(t, err, "Schema allowed invalid params: %s", tt.json)
})
}
}
175 changes: 175 additions & 0 deletions adapters/pixfuture/pixfuture.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// Package pixfuture implements the Pixfuture adapter for Prebid Server.
// It provides functionality to handle bid requests and responses according to Pixfuture's specifications
package pixfuture

import (
"fmt"
"net/http"

"github.com/prebid/openrtb/v20/openrtb2"
"github.com/prebid/prebid-server/v3/adapters"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/errortypes"
"github.com/prebid/prebid-server/v3/openrtb_ext"
"github.com/prebid/prebid-server/v3/util/iterutil"
"github.com/prebid/prebid-server/v3/util/jsonutil"
)

type adapter struct {
endpoint string
}

func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
return &adapter{
endpoint: config.Endpoint,
}, nil
}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {

var errs []error
var adapterRequests []*adapters.RequestData
headers := http.Header{}
headers.Set("Content-Type", "application/json")
headers.Set("Accept", "application/json")

for imp := range iterutil.SlicePointerValues(request.Imp) {

var bidderExt adapters.ExtImpBidder
var pixfutureExt openrtb_ext.ImpExtPixfuture

if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil {
errs = append(errs, err)
continue
}
if err := jsonutil.Unmarshal(bidderExt.Bidder, &pixfutureExt); err != nil {
errs = append(errs, err)
continue
}
if pixfutureExt.PixID == "" {
errs = append(errs, &errortypes.BadInput{Message: "Missing required parameter pix_id"})
continue
}

requestCopy := *request
requestCopy.Imp = []openrtb2.Imp{*imp} // slice notation with dereferencing

reqJSON, err := jsonutil.Marshal(requestCopy)
if err != nil {
errs = append(errs, err)
continue
}

adapterRequests = append(adapterRequests, &adapters.RequestData{
Method: http.MethodPost,
Uri: a.endpoint,
Body: reqJSON,
Headers: headers,
ImpIDs: []string{imp.ID},
})
}

if len(adapterRequests) == 0 && len(errs) > 0 {
return nil, errs
}
Comment on lines +72 to +74
Copy link
Collaborator

Choose a reason for hiding this comment

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

Delete this conditional block as this case is handled in the return statement such that if there are no adapterRequests, nil will be returned along with any errors.

return adapterRequests, errs
}

func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if adapters.IsResponseStatusCodeNoContent(response) {
return nil, nil
}

if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil {
return nil, []error{err}
}

var bidResp openrtb2.BidResponse
// Step 1: Check if body is empty to avoid unnecessary unmarshal overhead
if len(response.Body) == 0 {
return nil, nil // Or return a specific error if Pixfuture always expects a body
}

// Step 2: The Unmarshal call (Lines 88-92)
if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Invalid response format: %s", err.Error()),
}}
}

// Pre-calculate total number of bids
expectedBids := 0
for i := range bidResp.SeatBid {
expectedBids += len(bidResp.SeatBid[i].Bid)
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(expectedBids)
bidResponse.Currency = bidResp.Cur

var errs []error
for i := range bidResp.SeatBid {
// Use index j to avoid copying the large openrtb2.Bid struct
for j := range bidResp.SeatBid[i].Bid {
bid := &bidResp.SeatBid[i].Bid[j]

bidType, err := getMediaTypeForBid(bid)
if err != nil {
errs = append(errs, &errortypes.BadServerResponse{
Message: "Failed to parse impression \"" + bid.ImpID + "\" mediatype",
})
continue
}

bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: bid,
BidType: bidType,
})
}
}

if len(bidResponse.Bids) == 0 {
return nil, errs
}

return bidResponse, errs
}

func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) {
// First try standard MType field (OpenRTB 2.6)
switch bid.MType {
case openrtb2.MarkupBanner:
return openrtb_ext.BidTypeBanner, nil
case openrtb2.MarkupVideo:
return openrtb_ext.BidTypeVideo, nil
case openrtb2.MarkupNative:
return openrtb_ext.BidTypeNative, nil
}

// Fallback to custom extension
var ext struct {
Prebid struct {
Type string `json:"type"`
} `json:"prebid"`
}
Comment on lines +149 to +153
Copy link
Contributor

Choose a reason for hiding this comment

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

This can use the ext definition in openrtb_ext

Comment on lines +149 to +153
Copy link
Collaborator

Choose a reason for hiding this comment

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

As mentioned here, you should replace this with the defintion in openrtb_ext so your whole function looks like this:

func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
	var ext openrtb_ext.ExtBid
	if err := jsonutil.Unmarshal(bid.Ext, &ext); err != nil {
		return "", err
	}

	switch ext.Prebid.Type {
	case "banner":
		return openrtb_ext.BidTypeBanner, nil
	case "video":
		return openrtb_ext.BidTypeVideo, nil
	case "native":
		return openrtb_ext.BidTypeNative, nil
	default:
		return "", &errortypes.BadServerResponse{Message: "Unknown bid type: " + string(ext.Prebid.Type)}
	}
}


if len(bid.Ext) > 0 {
if err := jsonutil.Unmarshal(bid.Ext, &ext); err != nil {
return "", &errortypes.BadServerResponse{
Message: fmt.Sprintf("Failed to parse bid ext for impression %s: %v", bid.ImpID, err),
}
}
}

switch ext.Prebid.Type {

Choose a reason for hiding this comment

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

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeBanner. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the MType field in the response to accurately determine the media type for the impression.

Choose a reason for hiding this comment

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

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeNative. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the MType field in the response to accurately determine the media type for the impression.

Choose a reason for hiding this comment

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

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeVideo. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the MType field in the response to accurately determine the media type for the impression.

case "banner":
return openrtb_ext.BidTypeBanner, nil
case "video":
return openrtb_ext.BidTypeVideo, nil
case "native":
return openrtb_ext.BidTypeNative, nil
default:
return "", &errortypes.BadServerResponse{
Message: fmt.Sprintf("Unknown bid type for impression %s", bid.ImpID),
}
}
}
19 changes: 19 additions & 0 deletions adapters/pixfuture/pixfuture_test.go
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unit tests are considered nice to haves. The JSON test framework is required to achieve code coverage wherever possible. Please see the developer docs Test Your Adapter section on how to test your adapter.

Copy link
Author

Choose a reason for hiding this comment

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

Test JSONs have been reviewed and edited.

Copy link
Author

Choose a reason for hiding this comment

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

Test stuff has been reviewed and recreated

Copy link
Collaborator

Choose a reason for hiding this comment

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

None of your JSON tests are being executed because you're not calling RunJSONBidderTest as described in the Test Your Adapter section of the developer docs. Please add a TestJsonSamples test as described in the docs.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package pixfuture

import (
"testing"

"github.com/prebid/prebid-server/v3/adapters/adapterstest"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/openrtb_ext"
"github.com/stretchr/testify/require"
)

func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderPixfuture, config.Adapter{
Endpoint: "http://any.url",
}, config.Server{})
require.NoError(t, buildErr, "Builder returned unexpected error")

adapterstest.RunJSONBidderTest(t, "pixfuturetest", bidder)
}
111 changes: 111 additions & 0 deletions adapters/pixfuture/pixfuturetest/exemplary/banner-site.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"mockBidRequest": {
"id": "test-request-id",
"site": {
"page": "test.com",
"publisher": {
"id": "123456789"
}
},
"imp": [
{
"id": "imp1",
"banner": {
"w": 300,
"h": 250
},
"ext": {
"bidder": {
"pix_id": "55463"
}
}
}
]
},
"httpCalls": [
{
"expectedRequest": {
"uri": "http://any.url",
"headers": {
"Content-Type": [
"application/json"
],
"Accept": [
"application/json"
]
},
"body": {
"id": "test-request-id",
"site": {
"page": "test.com",
"publisher": {
"id": "123456789"
}
},
"imp": [
{
"id": "imp1",
"banner": {
"w": 300,
"h": 250
},
"ext": {
"bidder": {
"pix_id": "55463"
}
}
}
]
},
"impIDs": [
"imp1"
]
},
"mockResponse": {
"status": 200,
"body": {
"id": "test-response-id",
"cur": "USD",
"seatbid": [
{
"bid": [
{
"id": "bid1",
"impid": "imp1",
"price": 1.23,
"adm": "<div>Banner Ad</div>",
"ext": {
"prebid": {
"type": "banner"
}
}
}
]
}
]
}
}
}
],
"expectedBidResponses": [
{
"bids": [
{
"bid": {
"id": "bid1",
"impid": "imp1",
"price": 1.23,
"adm": "<div>Banner Ad</div>",
"ext": {
"prebid": {
"type": "banner"
}
}
},
"type": "banner"
}
],
"currency": "USD"
}
]
}
Loading
Loading