Skip to content

Commit 6a47525

Browse files
committed
tests for manager get_units_for_slot_resp
1 parent 2c45104 commit 6a47525

File tree

5 files changed

+208
-10
lines changed

5 files changed

+208
-10
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

adview-manager/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ rand = "0.8"
3131
[dev-dependencies]
3232
# enable the `test-util` only in dev
3333
adex_primitives = { version = "0.2", path = "../primitives", package = "primitives", features = ["test-util"] }
34+
wiremock = "0.5"
35+
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

adview-manager/serve/src/routes.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub async fn get_index(Extension(state): Extension<Arc<State>>) -> Html<String>
3333

3434
/// `GET /preview/ad`
3535
pub async fn get_preview_ad(Extension(state): Extension<Arc<State>>) -> Html<String> {
36-
// For mocking the `get_market_demand_resp` call
36+
// For mocking the `get_units_for_slot_resp` call
3737
let mock_server = MockServer::start().await;
3838

3939
let market_url = mock_server.uri().parse().unwrap();
@@ -88,7 +88,7 @@ pub async fn get_preview_ad(Extension(state): Extension<Arc<State>>) -> Html<Str
8888
campaigns: vec![],
8989
};
9090

91-
// Mock the `get_market_demand_resp` call
91+
// Mock the `get_units_for_slot_resp` call
9292
let mock_call = Mock::given(method("GET"))
9393
// &depositAsset={}&depositAsset={}
9494
.and(path(format!("units-for-slot/{}", options.market_slot)))
@@ -101,13 +101,13 @@ pub async fn get_preview_ad(Extension(state): Extension<Arc<State>>) -> Html<Str
101101
// .and(query_param("depositAsset[]", "0x6B175474E89094C44Da98b954EedeAC495271d03"))
102102
.respond_with(ResponseTemplate::new(200).set_body_json(units_for_slot_resp))
103103
.expect(1)
104-
.named("get_market_demand_resp");
104+
.named("get_units_for_slot_resp");
105105

106106
// Mounting the mock on the mock server - it's now effective!
107107
mock_call.mount(&mock_server).await;
108108

109109
let demand_resp = manager
110-
.get_market_demand_resp()
110+
.get_units_for_slot_resp()
111111
.await
112112
.expect("Should return Mocked response");
113113

adview-manager/src/manager.rs

Lines changed: 199 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl Manager {
250250

251251
// Test with different units with price
252252
// Test if first campaign is not overwritten
253-
pub async fn get_market_demand_resp(&self) -> Result<Response, Error> {
253+
pub async fn get_units_for_slot_resp(&self) -> Result<Response, Error> {
254254
let deposit_asset = self
255255
.options
256256
.whitelisted_tokens
@@ -268,14 +268,18 @@ impl Manager {
268268
.ok_or(Error::NoValidators)?;
269269

270270
let url = format!(
271-
"{}/units-for-slot/{}?{}",
271+
"{}/v5/units-for-slot/{}?{}",
272272
first_validator.url, self.options.market_slot, deposit_asset
273273
);
274-
let mut first_res: Response = self.client.get(url).send().await?.json().await?;
274+
275+
// Ordering of the campaigns matters so we will just push them to the first result
276+
// We reuse `targeting_input_base`, `accepted_referrers` and `fallback_unit`
277+
let json_res: String = self.client.get(url).send().await?.text().await?;
278+
let mut first_res: Response = serde_json::from_str(&json_res).expect("Should convert");
275279

276280
for validator in self.options.validators.iter().skip(1) {
277281
let url = format!(
278-
"{}/units-for-slot/{}?{}",
282+
"{}/v5/units-for-slot/{}?{}",
279283
validator.url, self.options.market_slot, deposit_asset
280284
);
281285
let new_res: Response = self.client.get(url).send().await?.json().await?;
@@ -290,7 +294,7 @@ impl Manager {
290294
}
291295

292296
pub async fn get_next_ad_unit(&self) -> Result<Option<NextAdUnit>, Error> {
293-
let units_for_slot = self.get_market_demand_resp().await?;
297+
let units_for_slot = self.get_units_for_slot_resp().await?;
294298
let m_campaigns = &units_for_slot.campaigns;
295299
let fallback_unit = units_for_slot.fallback_unit;
296300
let targeting_input = units_for_slot.targeting_input_base;
@@ -435,3 +439,193 @@ impl Manager {
435439
}
436440
}
437441
}
442+
443+
#[cfg(test)]
444+
mod test {
445+
use super::*;
446+
use crate::manager::input::Input;
447+
use adex_primitives::{
448+
sentry::CLICK,
449+
test_util::{
450+
CAMPAIGNS, DUMMY_AD_UNITS, DUMMY_IPFS, DUMMY_VALIDATOR_FOLLOWER,
451+
DUMMY_VALIDATOR_LEADER, IDS, LEADER_2, PUBLISHER,
452+
},
453+
};
454+
use wiremock::{
455+
matchers::{method, path},
456+
Mock, MockServer, ResponseTemplate,
457+
};
458+
459+
#[tokio::test]
460+
async fn test_querying_for_units_for_slot() {
461+
// 1. Set up mock servers for each validator
462+
let server = MockServer::start().await;
463+
let slot = DUMMY_IPFS[0];
464+
let seconds_since_epoch = Utc::now();
465+
466+
let original_input = Input {
467+
ad_view: None,
468+
global: input::Global {
469+
ad_slot_id: DUMMY_IPFS[0],
470+
ad_slot_type: "legacy_250x250".to_string(),
471+
publisher_id: *PUBLISHER,
472+
country: None,
473+
event_type: IMPRESSION,
474+
// we can't know only the timestamp
475+
seconds_since_epoch,
476+
user_agent_os: Some("Linux".to_string()),
477+
user_agent_browser_family: Some("Firefox".to_string()),
478+
},
479+
// no AdUnit should be present
480+
ad_unit_id: None,
481+
// no balances
482+
balances: None,
483+
// no campaign
484+
campaign: None,
485+
ad_slot: Some(input::AdSlot {
486+
categories: vec!["IAB3".into(), "IAB13-7".into(), "IAB5".into()],
487+
hostname: "adex.network".to_string(),
488+
}),
489+
};
490+
491+
let modified_input = Input {
492+
ad_view: None,
493+
global: input::Global {
494+
ad_slot_id: DUMMY_IPFS[1],
495+
ad_slot_type: "legacy_250x250".to_string(),
496+
publisher_id: *PUBLISHER,
497+
country: None,
498+
event_type: CLICK,
499+
// we can't know only the timestamp
500+
seconds_since_epoch,
501+
user_agent_os: Some("Linux".to_string()),
502+
user_agent_browser_family: Some("Firefox".to_string()),
503+
},
504+
// no AdUnit should be present
505+
ad_unit_id: None,
506+
// no balances
507+
balances: None,
508+
// no campaign
509+
campaign: None,
510+
ad_slot: Some(input::AdSlot {
511+
categories: vec!["IAB3".into(), "IAB13-7".into(), "IAB5".into()],
512+
hostname: "adex.network".to_string(),
513+
}),
514+
};
515+
516+
let original_referrers = vec![Url::parse("https://ambire.com").expect("should parse")];
517+
let modified_referrers =
518+
vec![Url::parse("https://www.google.com/adsense/start/").expect("should parse")];
519+
520+
let unit_0 = DUMMY_AD_UNITS[0].clone();
521+
let original_ad_unit = AdUnit {
522+
ipfs: unit_0.ipfs,
523+
media_url: unit_0.media_url,
524+
media_mime: unit_0.media_mime,
525+
target_url: unit_0.target_url,
526+
};
527+
528+
let unit_1 = DUMMY_AD_UNITS[1].clone();
529+
let modified_ad_unit = AdUnit {
530+
ipfs: unit_1.ipfs,
531+
media_url: unit_1.media_url,
532+
media_mime: unit_1.media_mime,
533+
target_url: unit_1.target_url,
534+
};
535+
536+
let campaign_0 = Campaign {
537+
campaign: CAMPAIGNS[0].clone().context,
538+
units_with_price: Vec::new(),
539+
};
540+
541+
let campaign_1 = Campaign {
542+
campaign: CAMPAIGNS[1].clone().context,
543+
units_with_price: Vec::new(),
544+
};
545+
546+
let campaign_2 = Campaign {
547+
campaign: CAMPAIGNS[2].clone().context,
548+
units_with_price: Vec::new(),
549+
};
550+
551+
// Original response
552+
let response_1 = Response {
553+
targeting_input_base: original_input.clone(),
554+
accepted_referrers: original_referrers.clone(),
555+
fallback_unit: Some(original_ad_unit.clone()),
556+
campaigns: vec![campaign_0.clone()],
557+
};
558+
559+
// Different targeting_input_base, fallback_unit, accepted_referrers, 1 new campaign and 1 repeating campaign
560+
let response_2 = Response {
561+
targeting_input_base: modified_input.clone(),
562+
accepted_referrers: modified_referrers.clone(),
563+
fallback_unit: Some(modified_ad_unit.clone()),
564+
campaigns: vec![campaign_0.clone(), campaign_1.clone()],
565+
};
566+
567+
// 1 new campaigns, 2 repeating campaigns
568+
let response_3 = Response {
569+
targeting_input_base: modified_input,
570+
accepted_referrers: modified_referrers,
571+
fallback_unit: Some(modified_ad_unit),
572+
campaigns: vec![campaign_0.clone(), campaign_1.clone(), campaign_2.clone()],
573+
};
574+
575+
Mock::given(method("GET"))
576+
.and(path(format!("1/v5/units-for-slot/{}", slot,)))
577+
.respond_with(ResponseTemplate::new(200).set_body_json(&response_1))
578+
.mount(&server)
579+
.await;
580+
581+
Mock::given(method("GET"))
582+
.and(path(format!("2/v5/units-for-slot/{}", slot,)))
583+
.respond_with(ResponseTemplate::new(200).set_body_json(&response_2))
584+
.mount(&server)
585+
.await;
586+
587+
Mock::given(method("GET"))
588+
.and(path(format!("3/v5/units-for-slot/{}", slot,)))
589+
.respond_with(ResponseTemplate::new(200).set_body_json(&response_3))
590+
.mount(&server)
591+
.await;
592+
593+
// 2. Set up a manager
594+
let market_url = server.uri().parse().unwrap();
595+
let whitelisted_tokens = DEFAULT_TOKENS.clone();
596+
let publisher_addr = "0x0000000000000000626f62627973686d75726461"
597+
.parse()
598+
.unwrap();
599+
let mut validator_1 = DUMMY_VALIDATOR_LEADER.clone();
600+
validator_1.url = format!("{}/1", server.uri());
601+
let mut validator_2 = DUMMY_VALIDATOR_FOLLOWER.clone();
602+
validator_2.url = format!("{}/2", server.uri());
603+
let mut validator_3 = DUMMY_VALIDATOR_LEADER.clone();
604+
validator_3.id = IDS[&LEADER_2];
605+
validator_3.url = format!("{}/3", server.uri());
606+
let options = Options {
607+
market_url,
608+
market_slot: DUMMY_IPFS[0],
609+
publisher_addr,
610+
// All passed tokens must be of the same price and decimals, so that the amounts can be accurately compared
611+
whitelisted_tokens,
612+
size: Some(Size::new(300, 100)),
613+
navigator_language: Some("bg".into()),
614+
disabled_video: false,
615+
disabled_sticky: false,
616+
validators: vec![validator_1, validator_2, validator_3],
617+
};
618+
619+
let manager = Manager::new(options.clone(), Default::default())
620+
.expect("Failed to create AdView Manager");
621+
622+
let res = manager
623+
.get_units_for_slot_resp()
624+
.await
625+
.expect("Should get response");
626+
assert_eq!(res.targeting_input_base.global.ad_slot_id, DUMMY_IPFS[0]);
627+
assert_eq!(res.accepted_referrers, original_referrers);
628+
assert_eq!(res.fallback_unit, Some(original_ad_unit));
629+
assert_eq!(res.campaigns, vec![campaign_0, campaign_1, campaign_2]);
630+
}
631+
}

sentry/src/routes/units_for_slot_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const TEST_AD_SLOT: Lazy<(AdSlot, AdUnit)> = Lazy::new(|| {
8484
});
8585

8686
async fn setup_mocked_platform_dummy_app() -> (MockServer, ApplicationGuard) {
87-
// For mocking the `get_market_demand_resp` call
87+
// For mocking the `get_units_for_slot_resp` call
8888
let mock_server = MockServer::start().await;
8989

9090
let platform_url = mock_server.uri().parse().unwrap();

0 commit comments

Comments
 (0)