diff --git a/adapters/adform/adform.go b/adapters/adform/adform.go index 5881f4ab86e..d7e5dedac22 100644 --- a/adapters/adform/adform.go +++ b/adapters/adform/adform.go @@ -79,6 +79,7 @@ type adformBid struct { Height uint64 `json:"height,omitempty"` DealId string `json:"deal_id,omitempty"` CreativeId string `json:"win_crid,omitempty"` + VastContent string `json:"vast_content,omitempty"` } const priceTypeGross = "gross" @@ -241,7 +242,8 @@ func toPBSBidSlice(adformBids []*adformBid, r *adformRequest) pbs.PBSBidSlice { bids := make(pbs.PBSBidSlice, 0) for i, bid := range adformBids { - if bid.Banner == "" || bid.ResponseType != "banner" { + adm, bidType := getAdAndType(bid) + if adm == "" { continue } pbsBid := pbs.PBSBid{ @@ -249,12 +251,12 @@ func toPBSBidSlice(adformBids []*adformBid, r *adformRequest) pbs.PBSBidSlice { AdUnitCode: r.adUnits[i].adUnitCode, BidderCode: r.bidderCode, Price: bid.Price, - Adm: bid.Banner, + Adm: adm, Width: bid.Width, Height: bid.Height, DealId: bid.DealId, Creative_id: bid.CreativeId, - CreativeMediaType: string(openrtb_ext.BidTypeBanner), + CreativeMediaType: string(bidType), } bids = append(bids, &pbsBid) @@ -632,21 +634,23 @@ func toOpenRtbBidResponse(adformBids []*adformBid, r *openrtb.BidRequest) *adapt } for i, bid := range adformBids { - if bid.Banner == "" || bid.ResponseType != "banner" { + adm, bidType := getAdAndType(bid) + if adm == "" { continue } + openRtbBid := openrtb.Bid{ ID: r.Imp[i].ID, ImpID: r.Imp[i].ID, Price: bid.Price, - AdM: bid.Banner, + AdM: adm, W: bid.Width, H: bid.Height, DealID: bid.DealId, CrID: bid.CreativeId, } - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: openrtb_ext.BidTypeBanner}) + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: bidType}) currency = bid.Currency } @@ -654,3 +658,12 @@ func toOpenRtbBidResponse(adformBids []*adformBid, r *openrtb.BidRequest) *adapt return bidResponse } + +func getAdAndType(bid *adformBid) (string, openrtb_ext.BidType) { + if bid.ResponseType == "banner" { + return bid.Banner, openrtb_ext.BidTypeBanner + } else if bid.ResponseType == "vast_content" { + return bid.VastContent, openrtb_ext.BidTypeVideo + } + return "", "" +} diff --git a/adapters/adform/adform_test.go b/adapters/adform/adform_test.go index f227776207d..0bfb95b6369 100644 --- a/adapters/adform/adform_test.go +++ b/adapters/adform/adform_test.go @@ -107,6 +107,16 @@ func createAdformServerResponse(testData aBidInfo) ([]byte, error) { DealId: testData.tags[2].dealId, CreativeId: testData.tags[2].creativeId, }, + { + ResponseType: "vast_content", + VastContent: testData.tags[3].content, + Price: testData.tags[3].price, + Currency: "EUR", + Width: testData.width, + Height: testData.height, + DealId: testData.tags[3].dealId, + CreativeId: testData.tags[3].creativeId, + }, } adformServerResponse, err := json.Marshal(bids) return adformServerResponse, err @@ -123,10 +133,21 @@ func TestAdformBasicResponse(t *testing.T) { if err != nil { t.Fatalf("Should not have gotten adapter error: %v", err) } - if len(bids) != 2 { - t.Fatalf("Received %d bids instead of 2", len(bids)) + if len(bids) != 3 { + t.Fatalf("Received %d bids instead of 3", len(bids)) + } + expectedTypes := []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeVideo, } - for _, bid := range bids { + + for i, bid := range bids { + + if bid.CreativeMediaType != string(expectedTypes[i]) { + t.Errorf("Expected a %s bid. Got: %s", expectedTypes[i], bid.CreativeMediaType) + } + matched := false for _, tag := range adformTestData.tags { if bid.AdUnitCode == tag.code { @@ -224,7 +245,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest { func preparePrebidRequestBody(requestData aBidInfo, t *testing.T) *bytes.Buffer { prebidRequest := pbs.PBSRequest{ - AdUnits: make([]pbs.AdUnit, 3), + AdUnits: make([]pbs.AdUnit, 4), Device: &openrtb.Device{ UA: requestData.deviceUA, IP: requestData.deviceIP, @@ -326,6 +347,7 @@ func createTestData(secure bool) aBidInfo { {mid: 32344, keyValues: "color:red,age:30-40", keyWords: "red,blue", cdims: "300x300,400x200", priceType: "gross", code: "code1", price: 1.23, content: "banner-content1", dealId: "dealId1", creativeId: "creativeId1"}, {mid: 32345, priceType: "net", code: "code2", minp: 23.1, cdims: "300x200"}, // no bid for ad unit {mid: 32346, code: "code3", price: 1.24, content: "banner-content2", dealId: "dealId2", url: "https://adform.com?a=b"}, + {mid: 32347, code: "code4", content: "vast-xml"}, }, secure: secure, currency: "EUR", @@ -379,6 +401,11 @@ func createOpenRtbRequest(testData *aBidInfo) *openrtb.BidRequest { func TestOpenRTBStandardResponse(t *testing.T) { testData := createTestData(true) request := createOpenRtbRequest(&testData) + expectedTypes := []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeVideo, + } responseBody, err := createAdformServerResponse(testData) if err != nil { @@ -390,16 +417,17 @@ func TestOpenRTBStandardResponse(t *testing.T) { bidder := new(AdformAdapter) bidResponse, errs := bidder.MakeBids(request, nil, httpResponse) - if len(bidResponse.Bids) != 2 { - t.Fatalf("Expected 2 bids. Got %d", len(bidResponse.Bids)) + if len(bidResponse.Bids) != 3 { + t.Fatalf("Expected 3 bids. Got %d", len(bidResponse.Bids)) } if len(errs) != 0 { t.Errorf("Expected 0 errors. Got %d", len(errs)) } - for _, typeBid := range bidResponse.Bids { - if typeBid.BidType != openrtb_ext.BidTypeBanner { - t.Errorf("Expected a banner bid. Got: %s", bidResponse.Bids[0].BidType) + for i, typeBid := range bidResponse.Bids { + + if typeBid.BidType != expectedTypes[i] { + t.Errorf("Expected a %s bid. Got: %s", expectedTypes[i], typeBid.BidType) } bid := typeBid.Bid matched := false @@ -561,10 +589,10 @@ func assertAdformServerRequest(testData aBidInfo, r *http.Request, isOpenRtb boo var midsWithCurrency = "" var queryString = "" if isOpenRtb { - midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9RVVSJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9RVVSJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9RVVS" + midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9RVVSJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9RVVSJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9RVVS&bWlkPTMyMzQ3JnJjdXI9RVVS" queryString = "CC=1&adid=6D92078A-8246-4BA4-AE5B-76104861E7DC&eids=eyJ0ZXN0LmNvbSI6eyJvdGhlcl91c2VyX2lkIjpbMF0sInNvbWVfdXNlcl9pZCI6WzFdfSwidGVzdDIub3JnIjp7Im90aGVyX3VzZXJfaWQiOlsyXX19&fd=1&gdpr=1&gdpr_consent=abc&ip=111.111.111.111&pt=gross&rp=4&stid=transaction-id&url=https%3A%2F%2Fadform.com%3Fa%3Db&" + midsWithCurrency } else { - midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9VVNEJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9VVNEJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9VVNE" // no way to pass currency in legacy adapter + midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9VVNEJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9VVNEJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9VVNE&bWlkPTMyMzQ3JnJjdXI9VVNE" // no way to pass currency in legacy adapter queryString = "CC=1&adid=6D92078A-8246-4BA4-AE5B-76104861E7DC&fd=1&gdpr=1&gdpr_consent=abc&ip=111.111.111.111&pt=gross&rp=4&stid=transaction-id&" + midsWithCurrency } @@ -646,7 +674,7 @@ func TestPriceTypeUrlParameterCreation(t *testing.T) { // Asserts that toOpenRtbBidResponse() creates a *adapters.BidderResponse with // the currency of the last valid []*adformBid element and the expected number of bids func TestToOpenRtbBidResponse(t *testing.T) { - expectedBids := 3 + expectedBids := 4 lastCurrency, anotherCurrency, emptyCurrency := "EUR", "USD", "" request := &openrtb.BidRequest{ @@ -672,6 +700,11 @@ func TestToOpenRtbBidResponse(t *testing.T) { Ext: json.RawMessage(`{"bidder1": { "mid": "32344" }}`), Banner: &openrtb.Banner{}, }, + { + ID: "video-imp-no4", + Ext: json.RawMessage(`{"bidder1": { "mid": "32345" }}`), + Banner: &openrtb.Banner{}, + }, }, Device: &openrtb.Device{UA: "ua", IP: "ip"}, User: &openrtb.User{BuyerUID: "buyerUID"}, @@ -703,6 +736,16 @@ func TestToOpenRtbBidResponse(t *testing.T) { ResponseType: "banner", Banner: "banner-content4", Price: 1.25, + Currency: emptyCurrency, + Width: 300, + Height: 200, + DealId: "dealId4", + CreativeId: "creativeId4", + }, + { + ResponseType: "vast_content", + VastContent: "vast-content", + Price: 1.25, Currency: lastCurrency, Width: 300, Height: 200, diff --git a/adapters/adform/adformtest/exemplary/multiformat-impression.json b/adapters/adform/adformtest/exemplary/multiformat-impression.json new file mode 100644 index 00000000000..efd4aca63e2 --- /dev/null +++ b/adapters/adform/adformtest/exemplary/multiformat-impression.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "banner-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "mid": 12345 + } + } + }, + { + "id": "video-imp-id", + "video": { + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "mid": 54321 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTEyMzQ1JnJjdXI9VVNE&bWlkPTU0MzIxJnJjdXI9VVNE" + }, + "mockResponse": { + "status": 200, + "body": [ + { + "response": "banner", + "banner": "", + "win_bid": 0.5, + "win_cur": "USD", + "width": 300, + "height": 250, + "deal_id": null, + "win_crid": "20078830" + }, + { + "response": "vast_content", + "vast_content": "", + "win_bid": 0.7, + "win_cur": "USD", + "width": 640, + "height": 480, + "deal_id": "DID-123-22", + "win_crid": "20078831" + } + ] + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "banner-imp-id", + "impid": "banner-imp-id", + "price": 0.5, + "adm": "", + "crid": "20078830", + "w": 300, + "h": 250 + }, + "type": "banner" + }, + { + "bid": { + "id": "video-imp-id", + "impid": "video-imp-id", + "price": 0.7, + "adm": "", + "crid": "20078831", + "dealid": "DID-123-22", + "w": 640, + "h": 480 + }, + "type": "video" + } + ] + } + ] + } diff --git a/adapters/adform/adformtest/exemplary/single-banner-impression.json b/adapters/adform/adformtest/exemplary/single-banner-impression.json new file mode 100644 index 00000000000..fd7f3cde526 --- /dev/null +++ b/adapters/adform/adformtest/exemplary/single-banner-impression.json @@ -0,0 +1,64 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "mid": 12345 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTEyMzQ1JnJjdXI9VVNE" + }, + "mockResponse": { + "status": 200, + "body": [ + { + "response": "banner", + "banner": "", + "win_bid": 0.5, + "win_cur": "USD", + "width": 300, + "height": 250, + "deal_id": null, + "win_crid": "20078830" + } + ] + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "", + "crid": "20078830", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adform/adformtest/exemplary/single-video-impression.json b/adapters/adform/adformtest/exemplary/single-video-impression.json new file mode 100644 index 00000000000..e22977e6523 --- /dev/null +++ b/adapters/adform/adformtest/exemplary/single-video-impression.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 640, + "h": 480 + }, + "ext": { + "bidder": { + "mid": 54321 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTU0MzIxJnJjdXI9VVNE" + }, + "mockResponse": { + "status": 200, + "body": [ + { + "response": "vast_content", + "vast_content": "", + "win_bid": 0.5, + "win_cur": "USD", + "width": 640, + "height": 480, + "deal_id": null, + "win_crid": "20078830" + } + ] + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "", + "crid": "20078830", + "w": 640, + "h": 480 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/adform/adformtest/params/race/video.json b/adapters/adform/adformtest/params/race/video.json new file mode 100644 index 00000000000..51f8f1b94d2 --- /dev/null +++ b/adapters/adform/adformtest/params/race/video.json @@ -0,0 +1,3 @@ +{ + "mid": "858300" +} diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml index 8aafd9f6815..4dce10b9af8 100644 --- a/static/bidder-info/adform.yaml +++ b/static/bidder-info/adform.yaml @@ -4,6 +4,8 @@ capabilities: app: mediaTypes: - banner + - video site: mediaTypes: - banner + - video