diff --git a/adapters/amx/amx.go b/adapters/amx/amx.go index 737fac421f0..dc6743a14a9 100644 --- a/adapters/amx/amx.go +++ b/adapters/amx/amx.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" "net/url" - "strings" "github.com/mxmCherry/openrtb/v15/openrtb2" "github.com/prebid/prebid-server/adapters" @@ -14,10 +13,8 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -const vastImpressionFormat = "" -const vastSearchPoint = "" const nbrHeaderName = "x-nbr" -const adapterVersion = "pbs1.1" +const adapterVersion = "pbs1.2" // AMXAdapter is the AMX bid adapter type AMXAdapter struct { @@ -114,8 +111,8 @@ func (adapter *AMXAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt } type amxBidExt struct { - Himp []string `json:"himp,omitempty"` - StartDelay *int `json:"startdelay,omitempty"` + StartDelay *int `json:"startdelay,omitempty"` + CreativeType *int `json:"ct,omitempty"` } // MakeBids will parse the bids from the AMX server @@ -161,11 +158,6 @@ func (adapter *AMXAdapter) MakeBids(request *openrtb2.BidRequest, externalReques Bid: &bid, BidType: bidType, } - if b.BidType == openrtb_ext.BidTypeVideo { - b.Bid.AdM = interpolateImpressions(bid, bidExt) - // remove the NURL so a client/player doesn't fire it twice - b.Bid.NURL = "" - } bidResponse.Bids = append(bidResponse.Bids, b) } @@ -189,25 +181,9 @@ func getMediaTypeForBid(bidExt amxBidExt) openrtb_ext.BidType { return openrtb_ext.BidTypeVideo } - return openrtb_ext.BidTypeBanner -} - -func pixelToImpression(pixel string) string { - return fmt.Sprintf(vastImpressionFormat, pixel) -} - -func interpolateImpressions(bid openrtb2.Bid, ext amxBidExt) string { - var buffer strings.Builder - if bid.NURL != "" { - buffer.WriteString(pixelToImpression(bid.NURL)) - } - - for _, impPixel := range ext.Himp { - if impPixel != "" { - buffer.WriteString(pixelToImpression(impPixel)) - } + if bidExt.CreativeType != nil && *bidExt.CreativeType == 10 { + return openrtb_ext.BidTypeNative } - results := strings.Replace(bid.AdM, vastSearchPoint, vastSearchPoint+buffer.String(), 1) - return results + return openrtb_ext.BidTypeBanner } diff --git a/adapters/amx/amx_test.go b/adapters/amx/amx_test.go index 229889db7cf..f4a40c46d13 100644 --- a/adapters/amx/amx_test.go +++ b/adapters/amx/amx_test.go @@ -3,7 +3,6 @@ package amx import ( "encoding/json" "fmt" - "regexp" "testing" "github.com/mxmCherry/openrtb/v15/openrtb2" @@ -174,42 +173,66 @@ func TestMakeRequestsPublisherId(t *testing.T) { } } -var vastImpressionRXP = regexp.MustCompile(``) +func TestMakeBids(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAMX, config.Adapter{ + Endpoint: amxTestEndpoint}) -func countImpressionPixels(vast string) int { - matches := vastImpressionRXP.FindAllIndex([]byte(vast), -1) - return len(matches) -} + if buildErr != nil { + t.Fatalf("Failed to build bidder: %v", buildErr) + } -func TestVideoImpInsertion(t *testing.T) { - markup := interpolateImpressions(openrtb2.Bid{ - AdM: sampleVastADM, - NURL: "https://example2.com/nurl", - }, amxBidExt{Himp: []string{"https://example.com/pixel.png"}}) - assert.Contains(t, markup, "example2.com/nurl") - assert.Contains(t, markup, "example.com/pixel.png") - assert.Equal(t, 3, countImpressionPixels(markup), "should have 3 Impression pixels") - - // make sure that a blank NURL won't result in a blank impression tag - markup = interpolateImpressions(openrtb2.Bid{ - AdM: sampleVastADM, - NURL: "", - }, amxBidExt{}) - assert.Equal(t, 1, countImpressionPixels(markup), "should have 1 impression pixels") - - // we should also ignore blank ext.Himp pixels - markup = interpolateImpressions(openrtb2.Bid{ - AdM: sampleVastADM, - NURL: "https://example-nurl.com/nurl", - }, amxBidExt{Himp: []string{"", "", ""}}) - assert.Equal(t, 2, countImpressionPixels(markup), "should have 2 impression pixels") -} + type testCase struct { + bidType openrtb_ext.BidType + adm string + extRaw string + valid bool + } + + tests := []testCase{ + {openrtb_ext.BidTypeNative, `{"assets":[]}`, `{"ct":10}`, true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": 1}`, true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": "invalid"}`, false}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{}`, true}, + {openrtb_ext.BidTypeVideo, sampleVastADM, `{"startdelay": 1}`, true}, + {openrtb_ext.BidTypeBanner, sampleVastADM, `{"ct": 1}`, true}, // the server shouldn't do this + } + + for _, test := range tests { + bid := openrtb2.Bid{ + AdM: test.adm, + Price: 1, + Ext: json.RawMessage(test.extRaw), + } + + sb := openrtb2.SeatBid{ + Bid: []openrtb2.Bid{bid}, + } + + resp := openrtb2.BidResponse{ + SeatBid: []openrtb2.SeatBid{sb}, + } + + respJson, jsonErr := json.Marshal(resp) + if jsonErr != nil { + t.Fatalf("Failed to serialize test bid %v: %v", test, jsonErr) + } + + bids, errs := bidder.MakeBids(nil, nil, &adapters.ResponseData{ + StatusCode: 200, + Body: respJson, + }) + + if !test.valid { + assert.Len(t, errs, 1) + continue + } + + if len(errs) > 0 { + t.Fatalf("Failed to make bids: %v", errs) + } + + assert.Len(t, bids.Bids, 1) + assert.Equal(t, test.bidType, bids.Bids[0].BidType) + } -func TestNoDisplayImpInsertion(t *testing.T) { - data := interpolateImpressions(openrtb2.Bid{ - AdM: sampleDisplayADM, - NURL: "https://example2.com/nurl", - }, amxBidExt{Himp: []string{"https://example.com/pixel.png"}}) - assert.NotContains(t, data, "example2.com/nurl") - assert.NotContains(t, data, "example.com/pixel.png") } diff --git a/adapters/amx/amxtest/exemplary/app-simple.json b/adapters/amx/amxtest/exemplary/app-simple.json index c208bff9da4..066eb02d579 100644 --- a/adapters/amx/amxtest/exemplary/app-simple.json +++ b/adapters/amx/amxtest/exemplary/app-simple.json @@ -64,7 +64,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", "body": { "app": { "bundle": "639881495", diff --git a/adapters/amx/amxtest/exemplary/display-multiple.json b/adapters/amx/amxtest/exemplary/display-multiple.json index f885bdb2c5b..eaa5025155d 100644 --- a/adapters/amx/amxtest/exemplary/display-multiple.json +++ b/adapters/amx/amxtest/exemplary/display-multiple.json @@ -98,7 +98,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/exemplary/simple-native.json b/adapters/amx/amxtest/exemplary/simple-native.json new file mode 100644 index 00000000000..a342623382d --- /dev/null +++ b/adapters/amx/amxtest/exemplary/simple-native.json @@ -0,0 +1,96 @@ +{ + "mockBidRequest": { + "id": "req_id", + "imp": [ + { + "id": "imp_id", + "native": { + "request": "{\"native\":{\"ver\":1.1,\"assets\":[]}}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "siteId": "1234" + } + } + } + ] + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "body": { + "id": "req_id", + "imp": [ + { + "id": "imp_id", + "native": { + "request": "{\"native\":{\"ver\":1.1,\"assets\":[]}}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "siteId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "req_id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "example_bid_id", + "impid": "example_imp_id", + "price": 1, + "adid": "12345678", + "adm": "{\"native\":{\"ver\":1.1,\"assets\":[]}}", + "adomain": ["advertiser.com"], + "cid": "1", + "crid": "12345", + "cat": ["IAB1-1"], + "ext": { + "ct": 10 + } + } + ] + } + ], + "bidid": "123456", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "example_bid_id", + "impid": "example_imp_id", + "price": 1, + "adid": "12345678", + "adm": "{\"native\":{\"ver\":1.1,\"assets\":[]}}", + "adomain": ["advertiser.com"], + "cid": "1", + "crid": "12345", + "cat": ["IAB1-1"], + "ext": { + "ct": 10 + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/amx/amxtest/exemplary/video-simple.json b/adapters/amx/amxtest/exemplary/video-simple.json index 678722adf8c..934e8e3151b 100644 --- a/adapters/amx/amxtest/exemplary/video-simple.json +++ b/adapters/amx/amxtest/exemplary/video-simple.json @@ -13,7 +13,7 @@ "imp": [ { "video": { - "api": [1,2], + "api": [1, 2], "boxingallowed": 1, "linearity": 1, "maxduration": 90, @@ -21,7 +21,7 @@ "mimes": ["video/mp4"], "placement": 1, "playbackmethod": [2], - "protocols": [1,2,3,4,5,6,7,8], + "protocols": [1, 2, 3, 4, 5, 6, 7, 8], "skip": 1, "skipafter": 5, "startdelay": 0, @@ -91,130 +91,134 @@ } } }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", - "body": { - "device": { - "dnt": 0, - "h": 1120, - "ip": "98.249.0.0", - "language": "en", - "os": "macos", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", - "w": 1792 - }, - "id": "TL3JS6F43CKNDQFY", - "imp": [ - { - "video": { - "api": [1,2], - "boxingallowed": 1, - "linearity": 1, - "maxduration": 90, - "minduration": 6, - "mimes": ["video/mp4"], - "placement": 1, - "playbackmethod": [2], - "protocols": [1,2,3,4,5,6,7,8], - "skip": 1, - "skipafter": 5, - "startdelay": 0, - "h": 300, - "pos": 1, - "w": 640 - }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "body": { + "device": { + "dnt": 0, + "h": 1120, + "ip": "98.249.0.0", + "language": "en", + "os": "macos", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", + "w": 1792 + }, + "id": "TL3JS6F43CKNDQFY", + "imp": [ + { + "video": { + "api": [1, 2], + "boxingallowed": 1, + "linearity": 1, + "maxduration": 90, + "minduration": 6, + "mimes": ["video/mp4"], + "placement": 1, + "playbackmethod": [2], + "protocols": [1, 2, 3, 4, 5, 6, 7, 8], + "skip": 1, + "skipafter": 5, + "startdelay": 0, + "h": 300, + "pos": 1, + "w": 640 + }, + "ext": { + "bidder": { + "tagId": "cHJlYmlkLm9yZw", + "adUnitId": "tagid-override" + } + }, + "tagid": "tagid-override", + "id": "1", + "secure": 1 + } + ], + "regs": { "ext": { - "bidder": { - "tagId": "cHJlYmlkLm9yZw", - "adUnitId": "tagid-override" - } + "gdpr": 0, + "us_privacy": "1---" + } + }, + "site": { + "domain": "www.example.com", + "ext": { + "amp": 0 }, - "tagid": "tagid-override", - "id": "1", - "secure": 1 - } - ], - "regs": { - "ext": { - "gdpr": 0, - "us_privacy": "1---" - } - }, - "site": { - "domain": "www.example.com", - "ext": { - "amp": 0 + "publisher": { + "id": "cHJlYmlkLm9yZw" + }, + "page": "https://www.example.com/es6/es6_objects.htm", + "ref": "https://www.example.com/es6/es6_objects.htm" }, - "publisher": { - "id": "cHJlYmlkLm9yZw" + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "amxrtb.com", + "hp": 1, + "sid": "1234" + } + ], + "ver": "1.0" + } + } }, - "page": "https://www.example.com/es6/es6_objects.htm", - "ref": "https://www.example.com/es6/es6_objects.htm" - }, - "source": { - "ext": { - "schain": { - "complete": 1, - "nodes": [ + "tmax": 300, + "user": { + "ext": { + "eids": [ { - "asi": "amxrtb.com", - "hp": 1, - "sid": "1234" + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "88de601e-3d98-48e7-81d7-00000000" + } + ] } ], - "ver": "1.0" + "gdpr": 0, + "us_privacy": "1---" } } - }, - "tmax": 300, - "user": { - "ext": { - "eids": [ - { - "source": "amxid", - "uids": [ - { - "atype": 1, - "id": "88de601e-3d98-48e7-81d7-00000000" - } - ] - } - ], - "gdpr": 0, - "us_privacy": "1---" - } } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "WQ5V2DWVTMNXABDD", - "seatbid": [{ - "bid": [{ - "id": "TEST", - "impid": "1", - "price": 10.0, - "adid": "1", - "adm": "00:00:15", - "nurl": "https://example.com/nurl", - "adomain": ["amxrtb.com"], - "iurl": "https://assets.a-mo.net/300x250.v2.png", - "cid": "1", - "crid": "1", - "h": 600, - "w": 300, - "ext": { - "himp": ["https://example.com/imp-tracker/pixel.gif?param=1¶m2=2"], - "startdelay": 0 + }, + "mockResponse": { + "status": 200, + "body": { + "id": "WQ5V2DWVTMNXABDD", + "seatbid": [ + { + "bid": [ + { + "id": "TEST", + "impid": "1", + "price": 10.0, + "adid": "1", + "adm": "00:00:15", + "adomain": ["amxrtb.com"], + "iurl": "https://assets.a-mo.net/300x250.v2.png", + "cid": "1", + "crid": "1", + "h": 600, + "w": 300, + "ext": { + "startdelay": 0 + } + } + ] } - }] - }], - "cur": "USD" + ], + "cur": "USD" + } } } - }], + ], "expectedBidResponses": [ { "currency": "USD", @@ -225,13 +229,12 @@ "impid": "1", "price": 10.0, "adid": "1", - "adm": "00:00:15", + "adm": "00:00:15", "adomain": ["amxrtb.com"], "iurl": "https://assets.a-mo.net/300x250.v2.png", "cid": "1", "crid": "1", "ext": { - "himp": ["https://example.com/imp-tracker/pixel.gif?param=1¶m2=2"], "startdelay": 0 }, "h": 600, @@ -242,4 +245,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/amx/amxtest/exemplary/web-simple.json b/adapters/amx/amxtest/exemplary/web-simple.json index f75bd85acb0..cc0777cb533 100644 --- a/adapters/amx/amxtest/exemplary/web-simple.json +++ b/adapters/amx/amxtest/exemplary/web-simple.json @@ -98,7 +98,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", "body": { "device": { "dnt": 0, diff --git a/adapters/amx/amxtest/supplemental/204-response.json b/adapters/amx/amxtest/supplemental/204-response.json index f51347d34d2..ee56633d186 100644 --- a/adapters/amx/amxtest/supplemental/204-response.json +++ b/adapters/amx/amxtest/supplemental/204-response.json @@ -13,7 +13,7 @@ "imp": [ { "video": { - "api": [1,2], + "api": [1, 2], "h": 300, "pos": 1, "w": 640 @@ -45,65 +45,65 @@ "test": 0, "tmax": 300 }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", - "body": { - "device": { - "dnt": 0, - "h": 1120, - "ip": "98.249.0.0", - "language": "en", - "os": "macos", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", - "w": 1792 - }, - "id": "TL3JS6F43CKNDQFY", - "imp": [ - { - "video": { - "api": [1,2], - "mimes": null, - "h": 300, - "pos": 1, - "w": 640 - }, - "id": "1", - "secure": 1 - } - ], - "site": { - "ext": { - "amp": 0 - } - }, - "source": { - "ext": { - "schain": { - "complete": 1, - "nodes": [ - { - "asi": "amxrtb.com", - "hp": 1, - "sid": "1234" - } - ], - "ver": "1.0" + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "body": { + "device": { + "dnt": 0, + "h": 1120, + "ip": "98.249.0.0", + "language": "en", + "os": "macos", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", + "w": 1792 + }, + "id": "TL3JS6F43CKNDQFY", + "imp": [ + { + "video": { + "api": [1, 2], + "mimes": null, + "h": 300, + "pos": 1, + "w": 640 + }, + "id": "1", + "secure": 1 + } + ], + "site": { + "ext": { + "amp": 0 } - } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "amxrtb.com", + "hp": 1, + "sid": "1234" + } + ], + "ver": "1.0" + } + } + }, + "tmax": 300 + } + }, + "mockResponse": { + "status": 204, + "headers": { + "X-Nbr": ["3b"] }, - "tmax": 300 + "body": {} } - }, - "mockResponse": { - "status": 204, - "headers": { - "X-Nbr": [ - "3b" - ] - }, - "body": {} } - }], + ], "expectedMakeBidsErrors": [] } diff --git a/adapters/amx/amxtest/supplemental/400-response.json b/adapters/amx/amxtest/supplemental/400-response.json index bb20bc94e7c..3ae0d0b33d0 100644 --- a/adapters/amx/amxtest/supplemental/400-response.json +++ b/adapters/amx/amxtest/supplemental/400-response.json @@ -13,7 +13,7 @@ "imp": [ { "video": { - "api": [1,2], + "api": [1, 2], "h": 300, "pos": 1, "w": 640 @@ -45,66 +45,66 @@ "test": 0, "tmax": 300 }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", - "body": { - "device": { - "dnt": 0, - "h": 1120, - "ip": "98.249.0.0", - "language": "en", - "os": "macos", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", - "w": 1792 - }, - "id": "TL3JS6F43CKNDQFY", - "imp": [ - { - "video": { - "api": [1,2], - "mimes": null, - "h": 300, - "pos": 1, - "w": 640 - }, - "id": "1", - "secure": 1 - } - ], - "site": { - "ext": { - "amp": 0 - } - }, - "source": { - "ext": { - "schain": { - "complete": 1, - "nodes": [ - { - "asi": "amxrtb.com", - "hp": 1, - "sid": "1234" - } - ], - "ver": "1.0" + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", + "body": { + "device": { + "dnt": 0, + "h": 1120, + "ip": "98.249.0.0", + "language": "en", + "os": "macos", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", + "w": 1792 + }, + "id": "TL3JS6F43CKNDQFY", + "imp": [ + { + "video": { + "api": [1, 2], + "mimes": null, + "h": 300, + "pos": 1, + "w": 640 + }, + "id": "1", + "secure": 1 + } + ], + "site": { + "ext": { + "amp": 0 } - } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "amxrtb.com", + "hp": 1, + "sid": "1234" + } + ], + "ver": "1.0" + } + } + }, + "tmax": 300 + } + }, + "mockResponse": { + "status": 400, + "headers": { + "X-Nbr": ["3b"] }, - "tmax": 300 + "body": {} } - }, - "mockResponse": { - "status": 400, - "headers": { - "X-Nbr": [ - "3b" - ] - }, - "body": {} } - }], + ], "expectedMakeBidsErrors": [ { "value": "Invalid Request: 400. Error Code: 3b", diff --git a/adapters/amx/amxtest/supplemental/500-response.json b/adapters/amx/amxtest/supplemental/500-response.json index c56a217ce2e..2e37f3ec7dc 100644 --- a/adapters/amx/amxtest/supplemental/500-response.json +++ b/adapters/amx/amxtest/supplemental/500-response.json @@ -47,7 +47,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.1", + "uri": "http://pbs-dev.amxrtb.com/auction/openrtb?v=pbs1.2", "body": { "device": { "dnt": 0, diff --git a/static/bidder-info/amx.yaml b/static/bidder-info/amx.yaml index 43c33c43ce0..ae2942c460b 100644 --- a/static/bidder-info/amx.yaml +++ b/static/bidder-info/amx.yaml @@ -6,10 +6,12 @@ capabilities: mediaTypes: - banner - video + - native app: mediaTypes: - banner - video + - native userSync: redirect: url: "https://prebid.a-mo.net/cchain/0?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}"