Skip to content

Commit 3b18df4

Browse files
authored
Added unit tests
1 parent 9aae2be commit 3b18df4

File tree

7 files changed

+954
-5
lines changed

7 files changed

+954
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828

2929
## [Unreleased]
3030

31+
### Added
32+
- Added basic unit tests
33+
3134
### Changed
3235
- Upgrade to rust 1.87.0
3336
- Upgrade to fastly-cli 11.3.0

Cargo.lock

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

crates/common/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ serde_json = "1.0.91"
2424
sha2 = "0.10.6"
2525
tokio = { version = "1.43", features = ["sync", "macros", "io-util", "rt", "time"] }
2626
url = "2.4.1"
27+
28+
[dev-dependencies]
29+
temp-env = "0.3.6"

crates/common/src/gdpr.rs

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,274 @@ pub fn handle_data_subject_request(_settings: &Settings, req: Request) -> Result
124124
}
125125
}
126126
}
127+
128+
#[cfg(test)]
129+
mod tests {
130+
use super::*;
131+
use fastly::{Body, Request};
132+
133+
fn create_test_settings() -> Settings {
134+
Settings {
135+
ad_server: crate::settings::AdServer {
136+
ad_partner_url: "https://test.com".to_string(),
137+
sync_url: "https://sync.test.com".to_string(),
138+
},
139+
prebid: crate::settings::Prebid {
140+
server_url: "https://prebid.test.com".to_string(),
141+
},
142+
synthetic: crate::settings::Synthetic {
143+
counter_store: "test-counter".to_string(),
144+
opid_store: "test-opid".to_string(),
145+
secret_key: "test-secret".to_string(),
146+
template: "{{test}}".to_string(),
147+
},
148+
}
149+
}
150+
151+
#[test]
152+
fn test_gdpr_consent_default() {
153+
let consent = GdprConsent::default();
154+
assert!(!consent.analytics);
155+
assert!(!consent.advertising);
156+
assert!(!consent.functional);
157+
assert_eq!(consent.version, "1.0");
158+
assert!(consent.timestamp > 0);
159+
}
160+
161+
#[test]
162+
fn test_user_data_default() {
163+
let data = UserData::default();
164+
assert_eq!(data.visit_count, 0);
165+
assert!(data.last_visit > 0);
166+
assert!(data.ad_interactions.is_empty());
167+
assert!(data.consent_history.is_empty());
168+
}
169+
170+
#[test]
171+
fn test_gdpr_consent_serialization() {
172+
let consent = GdprConsent {
173+
analytics: true,
174+
advertising: false,
175+
functional: true,
176+
timestamp: 1234567890,
177+
version: "2.0".to_string(),
178+
};
179+
180+
let json = serde_json::to_string(&consent).unwrap();
181+
assert!(json.contains("\"analytics\":true"));
182+
assert!(json.contains("\"advertising\":false"));
183+
assert!(json.contains("\"functional\":true"));
184+
assert!(json.contains("\"timestamp\":1234567890"));
185+
assert!(json.contains("\"version\":\"2.0\""));
186+
187+
let deserialized: GdprConsent = serde_json::from_str(&json).unwrap();
188+
assert_eq!(deserialized.analytics, consent.analytics);
189+
assert_eq!(deserialized.advertising, consent.advertising);
190+
assert_eq!(deserialized.functional, consent.functional);
191+
assert_eq!(deserialized.timestamp, consent.timestamp);
192+
assert_eq!(deserialized.version, consent.version);
193+
}
194+
195+
#[test]
196+
fn test_create_consent_cookie() {
197+
let consent = GdprConsent {
198+
analytics: true,
199+
advertising: true,
200+
functional: true,
201+
timestamp: 1234567890,
202+
version: "1.0".to_string(),
203+
};
204+
205+
let cookie = create_consent_cookie(&consent);
206+
assert!(cookie.starts_with("gdpr_consent="));
207+
assert!(cookie.contains("Domain=.auburndao.com"));
208+
assert!(cookie.contains("Path=/"));
209+
assert!(cookie.contains("Secure"));
210+
assert!(cookie.contains("SameSite=Lax"));
211+
assert!(cookie.contains("Max-Age=31536000"));
212+
}
213+
214+
#[test]
215+
fn test_get_consent_from_request_no_cookie() {
216+
let req = Request::get("https://example.com");
217+
let consent = get_consent_from_request(&req);
218+
assert!(consent.is_none());
219+
}
220+
221+
#[test]
222+
fn test_get_consent_from_request_with_valid_cookie() {
223+
let mut req = Request::get("https://example.com");
224+
let consent_data = GdprConsent {
225+
analytics: true,
226+
advertising: false,
227+
functional: true,
228+
timestamp: 1234567890,
229+
version: "1.0".to_string(),
230+
};
231+
let cookie_value = format!(
232+
"gdpr_consent={}",
233+
serde_json::to_string(&consent_data).unwrap()
234+
);
235+
req.set_header(header::COOKIE, cookie_value);
236+
237+
let consent = get_consent_from_request(&req);
238+
assert!(consent.is_some());
239+
let consent = consent.unwrap();
240+
assert!(consent.analytics);
241+
assert!(!consent.advertising);
242+
assert!(consent.functional);
243+
}
244+
245+
#[test]
246+
fn test_get_consent_from_request_with_invalid_cookie() {
247+
let mut req = Request::get("https://example.com");
248+
req.set_header(header::COOKIE, "gdpr_consent=invalid-json");
249+
250+
let consent = get_consent_from_request(&req);
251+
assert!(consent.is_none());
252+
}
253+
254+
#[test]
255+
fn test_handle_consent_request_get() {
256+
let settings = create_test_settings();
257+
let req = Request::get("https://example.com/gdpr/consent");
258+
259+
let response = handle_consent_request(&settings, req).unwrap();
260+
assert_eq!(response.get_status(), StatusCode::OK);
261+
assert_eq!(
262+
response.get_header_str(header::CONTENT_TYPE),
263+
Some("application/json")
264+
);
265+
266+
let body = response.into_body_str();
267+
let consent: GdprConsent = serde_json::from_str(&body).unwrap();
268+
assert!(!consent.analytics); // Default values
269+
assert!(!consent.advertising);
270+
assert!(!consent.functional);
271+
}
272+
273+
#[test]
274+
fn test_handle_consent_request_post() {
275+
let settings = create_test_settings();
276+
let consent_data = GdprConsent {
277+
analytics: true,
278+
advertising: true,
279+
functional: false,
280+
timestamp: 1234567890,
281+
version: "1.0".to_string(),
282+
};
283+
284+
let mut req = Request::post("https://example.com/gdpr/consent");
285+
req.set_body(Body::from(serde_json::to_string(&consent_data).unwrap()));
286+
287+
let response = handle_consent_request(&settings, req).unwrap();
288+
assert_eq!(response.get_status(), StatusCode::OK);
289+
assert_eq!(
290+
response.get_header_str(header::CONTENT_TYPE),
291+
Some("application/json")
292+
);
293+
294+
// Check Set-Cookie header
295+
let set_cookie = response.get_header_str(header::SET_COOKIE);
296+
assert!(set_cookie.is_some());
297+
assert!(set_cookie.unwrap().contains("gdpr_consent="));
298+
assert!(set_cookie.unwrap().contains("Domain=.auburndao.com"));
299+
300+
// Check response body
301+
let body = response.into_body_str();
302+
let returned_consent: GdprConsent = serde_json::from_str(&body).unwrap();
303+
assert!(returned_consent.analytics);
304+
assert!(returned_consent.advertising);
305+
assert!(!returned_consent.functional);
306+
}
307+
308+
#[test]
309+
fn test_handle_consent_request_invalid_method() {
310+
let settings = create_test_settings();
311+
let req = Request::put("https://example.com/gdpr/consent");
312+
313+
let response = handle_consent_request(&settings, req).unwrap();
314+
assert_eq!(response.get_status(), StatusCode::METHOD_NOT_ALLOWED);
315+
assert_eq!(response.into_body_str(), "Method not allowed");
316+
}
317+
318+
#[test]
319+
fn test_handle_data_subject_request_get_with_id() {
320+
let settings = create_test_settings();
321+
let mut req = Request::get("https://example.com/gdpr/data");
322+
req.set_header("X-Subject-ID", "test-subject-123");
323+
324+
let response = handle_data_subject_request(&settings, req).unwrap();
325+
assert_eq!(response.get_status(), StatusCode::OK);
326+
assert_eq!(
327+
response.get_header_str(header::CONTENT_TYPE),
328+
Some("application/json")
329+
);
330+
331+
let body = response.into_body_str();
332+
let data: HashMap<String, UserData> = serde_json::from_str(&body).unwrap();
333+
assert!(data.contains_key("test-subject-123"));
334+
assert_eq!(data["test-subject-123"].visit_count, 0); // Default value
335+
}
336+
337+
#[test]
338+
fn test_handle_data_subject_request_get_without_id() {
339+
let settings = create_test_settings();
340+
let req = Request::get("https://example.com/gdpr/data");
341+
342+
let response = handle_data_subject_request(&settings, req).unwrap();
343+
assert_eq!(response.get_status(), StatusCode::BAD_REQUEST);
344+
assert_eq!(response.into_body_str(), "Missing subject ID");
345+
}
346+
347+
#[test]
348+
fn test_handle_data_subject_request_delete_with_id() {
349+
let settings = create_test_settings();
350+
let mut req = Request::delete("https://example.com/gdpr/data");
351+
req.set_header("X-Subject-ID", "test-subject-123");
352+
353+
let response = handle_data_subject_request(&settings, req).unwrap();
354+
assert_eq!(response.get_status(), StatusCode::OK);
355+
assert_eq!(response.into_body_str(), "Data deletion request processed");
356+
}
357+
358+
#[test]
359+
fn test_handle_data_subject_request_delete_without_id() {
360+
let settings = create_test_settings();
361+
let req = Request::delete("https://example.com/gdpr/data");
362+
363+
let response = handle_data_subject_request(&settings, req).unwrap();
364+
assert_eq!(response.get_status(), StatusCode::BAD_REQUEST);
365+
assert_eq!(response.into_body_str(), "Missing subject ID");
366+
}
367+
368+
#[test]
369+
fn test_handle_data_subject_request_invalid_method() {
370+
let settings = create_test_settings();
371+
let req = Request::post("https://example.com/gdpr/data");
372+
373+
let response = handle_data_subject_request(&settings, req).unwrap();
374+
assert_eq!(response.get_status(), StatusCode::METHOD_NOT_ALLOWED);
375+
assert_eq!(response.into_body_str(), "Method not allowed");
376+
}
377+
378+
#[test]
379+
fn test_user_data_serialization() {
380+
let user_data = UserData {
381+
visit_count: 5,
382+
last_visit: 1234567890,
383+
ad_interactions: vec!["click1".to_string(), "view2".to_string()],
384+
consent_history: vec![GdprConsent::default()],
385+
};
386+
387+
let json = serde_json::to_string(&user_data).unwrap();
388+
assert!(json.contains("\"visit_count\":5"));
389+
assert!(json.contains("\"last_visit\":1234567890"));
390+
assert!(json.contains("\"ad_interactions\":[\"click1\",\"view2\"]"));
391+
392+
let deserialized: UserData = serde_json::from_str(&json).unwrap();
393+
assert_eq!(deserialized.visit_count, user_data.visit_count);
394+
assert_eq!(deserialized.last_visit, user_data.last_visit);
395+
assert_eq!(deserialized.ad_interactions.len(), 2);
396+
}
397+
}

0 commit comments

Comments
 (0)