Skip to content

Commit bfdc4f7

Browse files
authored
Merge pull request #458 from AmbireTech/analytics-recorder-test-improvements
Additional testing for recorder + DateHour FromSql/ToSql tests
2 parents 577cdcd + 8a0aa63 commit bfdc4f7

File tree

2 files changed

+177
-28
lines changed

2 files changed

+177
-28
lines changed

primitives/src/sentry.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,10 @@ mod postgres {
897897
#[cfg(test)]
898898
mod test {
899899
use super::*;
900-
use crate::util::tests::prep_db::{ADDRESSES, DUMMY_IPFS};
900+
use crate::{
901+
postgres::POSTGRES_POOL,
902+
util::tests::prep_db::{ADDRESSES, DUMMY_IPFS},
903+
};
901904
use serde_json::json;
902905

903906
#[test]
@@ -922,4 +925,39 @@ mod test {
922925
serde_json::to_value(click).expect("should serialize")
923926
);
924927
}
928+
929+
#[tokio::test]
930+
pub async fn datehour_from_to_sql() {
931+
let client = POSTGRES_POOL.get().await.unwrap();
932+
let sql_type = "TIMESTAMPTZ";
933+
934+
let example_datehour = DateHour::<Utc>::from_ymdh(2021, 1, 1, 1);
935+
let expected_datehour =
936+
DateHour::try_from(Utc.ymd(2021, 1, 1).and_hms(1, 0, 0)).expect("Should get DateHour");
937+
assert_eq!(
938+
example_datehour, expected_datehour,
939+
"Example and expected datehour must be the same"
940+
);
941+
942+
// from SQL
943+
let actual_datehour: DateHour<Utc> = client
944+
.query_one(
945+
&*format!("SELECT '{}'::{}", example_datehour.to_datetime(), sql_type),
946+
&[],
947+
)
948+
.await
949+
.unwrap()
950+
.get(0);
951+
952+
assert_eq!(&expected_datehour, &actual_datehour);
953+
954+
// to SQL
955+
let actual_datehour: DateHour<Utc> = client
956+
.query_one(&*format!("SELECT $1::{}", sql_type), &[&example_datehour])
957+
.await
958+
.unwrap()
959+
.get(0);
960+
961+
assert_eq!(&expected_datehour, &actual_datehour);
962+
}
925963
}

sentry/src/analytics.rs

+138-27
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ mod test {
9898
use super::*;
9999
use primitives::{
100100
sentry::Analytics,
101-
util::tests::prep_db::{ADDRESSES, DUMMY_CAMPAIGN},
101+
util::tests::prep_db::{ADDRESSES, DUMMY_CAMPAIGN, DUMMY_IPFS},
102102
UnifiedNum,
103103
};
104104

@@ -117,15 +117,8 @@ mod test {
117117
Ok(event_analytics)
118118
}
119119

120-
#[tokio::test]
121-
async fn test_analytics_recording() {
122-
let database = DATABASE_POOL.get().await.expect("Should get a DB pool");
123-
124-
setup_test_migrations(database.pool.clone())
125-
.await
126-
.expect("Migrations should succeed");
127-
128-
let test_events = vec![
120+
fn get_test_events() -> HashMap<String, (Event, Address, UnifiedNum)> {
121+
vec![
129122
(
130123
"click_empty".into(),
131124
(
@@ -152,11 +145,61 @@ mod test {
152145
UnifiedNum::from_u64(1_000_000),
153146
),
154147
),
148+
(
149+
"click_with_unit_and_slot".into(),
150+
(
151+
Event::Click {
152+
publisher: ADDRESSES["publisher"],
153+
ad_unit: Some(DUMMY_IPFS[0]),
154+
ad_slot: Some(DUMMY_IPFS[1]),
155+
referrer: Some("http://127.0.0.1".into()),
156+
},
157+
ADDRESSES["publisher"],
158+
UnifiedNum::from_u64(1_000_000),
159+
),
160+
),
161+
(
162+
"click_with_different_data".into(),
163+
(
164+
Event::Click {
165+
publisher: ADDRESSES["publisher"],
166+
ad_unit: Some(DUMMY_IPFS[2]),
167+
ad_slot: Some(DUMMY_IPFS[3]),
168+
referrer: Some("http://127.0.0.1".into()),
169+
},
170+
ADDRESSES["publisher"],
171+
UnifiedNum::from_u64(1_000_000),
172+
),
173+
),
174+
(
175+
"impression_with_slot_unit_and_referrer".into(),
176+
(
177+
Event::Impression {
178+
publisher: ADDRESSES["publisher"],
179+
ad_unit: Some(DUMMY_IPFS[0]),
180+
ad_slot: Some(DUMMY_IPFS[1]),
181+
referrer: Some("http://127.0.0.1".into()),
182+
},
183+
ADDRESSES["publisher"],
184+
UnifiedNum::from_u64(1_000_000),
185+
),
186+
),
155187
]
156188
.into_iter()
157-
.collect::<HashMap<String, _>>();
189+
.collect::<HashMap<String, _>>()
190+
}
191+
192+
#[tokio::test]
193+
async fn test_analytics_recording_with_empty_events() {
194+
let test_events = get_test_events();
195+
let database = DATABASE_POOL.get().await.expect("Should get a DB pool");
196+
197+
setup_test_migrations(database.pool.clone())
198+
.await
199+
.expect("Migrations should succeed");
158200

159201
let campaign = DUMMY_CAMPAIGN.clone();
202+
160203
let session = Session {
161204
ip: None,
162205
country: None,
@@ -167,6 +210,7 @@ mod test {
167210
let input_events = vec![
168211
test_events["click_empty"].clone(),
169212
test_events["impression_empty"].clone(),
213+
test_events["impression_empty"].clone(),
170214
];
171215

172216
record(&database.clone(), &campaign, &session, input_events.clone())
@@ -176,6 +220,7 @@ mod test {
176220
let analytics = get_all_analytics(&database.pool)
177221
.await
178222
.expect("should get all analytics");
223+
assert_eq!(analytics.len(), 2);
179224

180225
let click_analytics = analytics
181226
.iter()
@@ -193,35 +238,101 @@ mod test {
193238

194239
assert_eq!(
195240
impression_analytics.payout_amount,
196-
UnifiedNum::from_u64(1_000_000)
241+
UnifiedNum::from_u64(2_000_000)
197242
);
198-
assert_eq!(impression_analytics.payout_count, 1);
243+
assert_eq!(impression_analytics.payout_count, 2);
244+
}
245+
246+
#[tokio::test]
247+
async fn test_recording_with_session() {
248+
let database = DATABASE_POOL.get().await.expect("Should get a DB pool");
249+
250+
setup_test_migrations(database.pool.clone())
251+
.await
252+
.expect("Migrations should succeed");
253+
254+
let test_events = get_test_events();
255+
256+
let campaign = DUMMY_CAMPAIGN.clone();
257+
258+
let session = Session {
259+
ip: Default::default(),
260+
country: Some("Bulgaria".into()),
261+
referrer_header: Some("http://127.0.0.1".into()),
262+
os: Some("Windows".into()),
263+
};
264+
265+
let input_events = vec![
266+
test_events["click_with_unit_and_slot"].clone(),
267+
test_events["click_with_unit_and_slot"].clone(),
268+
test_events["click_with_different_data"].clone(),
269+
test_events["click_with_different_data"].clone(),
270+
test_events["click_with_different_data"].clone(),
271+
test_events["impression_with_slot_unit_and_referrer"].clone(),
272+
test_events["impression_with_slot_unit_and_referrer"].clone(),
273+
test_events["impression_with_slot_unit_and_referrer"].clone(),
274+
test_events["impression_with_slot_unit_and_referrer"].clone(),
275+
];
199276

200-
record(&database.clone(), &campaign, &session, input_events)
277+
record(&database.clone(), &campaign, &session, input_events.clone())
201278
.await
202279
.expect("should record");
203280

204281
let analytics = get_all_analytics(&database.pool)
205282
.await
206-
.expect("should find analytics");
207-
let click_analytics = analytics
208-
.iter()
209-
.find(|a| a.event_type == "CLICK")
210-
.expect("There should be a click event");
211-
let impression_analytics = analytics
283+
.expect("should get all analytics");
284+
assert_eq!(analytics.len(), 3);
285+
286+
assert!(
287+
analytics
288+
.iter()
289+
.all(|a| a.country == Some("Bulgaria".into())),
290+
"all analytics should have the same country as the one in the session"
291+
);
292+
assert!(
293+
analytics
294+
.iter()
295+
.all(|a| a.os_name == OperatingSystem::map_os("Windows")),
296+
"all analytics should have the same os as the one in the session"
297+
);
298+
299+
let with_slot_and_unit: Analytics = analytics
212300
.iter()
213-
.find(|a| a.event_type == "IMPRESSION")
214-
.expect("There should be an impression event");
301+
.find(|a| {
302+
a.ad_unit == Some(DUMMY_IPFS[0])
303+
&& a.ad_slot == Some(DUMMY_IPFS[1])
304+
&& a.event_type == "CLICK".to_string()
305+
})
306+
.expect("entry should exist")
307+
.to_owned();
308+
assert_eq!(with_slot_and_unit.hostname, Some("127.0.0.1".to_string()));
309+
assert_eq!(with_slot_and_unit.payout_count, 2);
215310
assert_eq!(
216-
click_analytics.payout_amount,
311+
with_slot_and_unit.payout_amount,
217312
UnifiedNum::from_u64(2_000_000)
218313
);
219-
assert_eq!(click_analytics.payout_count, 2);
220314

315+
let with_different_slot_and_unit: Analytics = analytics
316+
.iter()
317+
.find(|a| a.ad_unit == Some(DUMMY_IPFS[2]) && a.ad_slot == Some(DUMMY_IPFS[3]))
318+
.expect("entry should exist")
319+
.to_owned();
320+
assert_eq!(with_different_slot_and_unit.payout_count, 3);
221321
assert_eq!(
222-
impression_analytics.payout_amount,
223-
UnifiedNum::from_u64(2_000_000)
322+
with_different_slot_and_unit.payout_amount,
323+
UnifiedNum::from_u64(3_000_000)
224324
);
225-
assert_eq!(impression_analytics.payout_count, 2);
325+
326+
let with_referrer: Analytics = analytics
327+
.iter()
328+
.find(|a| {
329+
a.ad_unit == Some(DUMMY_IPFS[0])
330+
&& a.ad_slot == Some(DUMMY_IPFS[1])
331+
&& a.event_type == "IMPRESSION".to_string()
332+
})
333+
.expect("entry should exist")
334+
.to_owned();
335+
assert_eq!(with_referrer.payout_count, 4);
336+
assert_eq!(with_referrer.payout_amount, UnifiedNum::from_u64(4_000_000));
226337
}
227338
}

0 commit comments

Comments
 (0)