lastfm_edit/
vcr_test_utils.rs1use crate::vcr_form_data::{encode_form_data, parse_form_data};
2use http_client_vcr::{Filter, FilterChain, SerializableRequest, SerializableResponse};
3
4#[derive(Debug)]
8pub struct LastFmPasswordOnlyFilter;
9
10impl Filter for LastFmPasswordOnlyFilter {
11 fn filter_request(&self, request: &mut SerializableRequest) {
12 if let Some(body) = &mut request.body {
14 if body.contains('=') && (body.contains('&') || !body.contains(' ')) {
15 let mut params = parse_form_data(body);
16
17 if params.contains_key("password") {
19 params.insert("password".to_string(), "test_password".to_string());
20 *body = encode_form_data(¶ms);
21 }
22 }
23 }
24
25 if let Some(cookie_values) = request.headers.get_mut("cookie") {
27 for cookie_header in cookie_values.iter_mut() {
28 *cookie_header = self.filter_session_cookies(cookie_header);
29 }
30 }
31 }
32
33 fn filter_response(&self, response: &mut SerializableResponse) {
34 if let Some(set_cookie_values) = response.headers.get_mut("set-cookie") {
36 for set_cookie_header in set_cookie_values.iter_mut() {
37 if set_cookie_header.contains("sessionid=") {
38 *set_cookie_header = self.filter_set_cookie_session(set_cookie_header);
39 }
40 }
41 }
42 }
43}
44
45impl LastFmPasswordOnlyFilter {
46 fn filter_session_cookies(&self, cookie_header: &str) -> String {
48 let mut filtered_cookies = Vec::new();
49
50 for cookie in cookie_header.split(';') {
51 let cookie = cookie.trim();
52 if cookie.starts_with("sessionid=") {
53 filtered_cookies.push("sessionid=test_session_id");
55 } else {
56 filtered_cookies.push(cookie);
57 }
58 }
59
60 filtered_cookies.join("; ")
61 }
62
63 fn filter_set_cookie_session(&self, set_cookie_header: &str) -> String {
65 if set_cookie_header.starts_with("sessionid=") {
66 if let Some(semicolon_pos) = set_cookie_header.find(';') {
68 let attributes = &set_cookie_header[semicolon_pos..];
69 format!("sessionid=test_session_id{attributes}")
70 } else {
71 "sessionid=test_session_id".to_string()
72 }
73 } else {
74 set_cookie_header.to_string()
75 }
76 }
77}
78
79pub const TEST_API_KEY: &str = "TEST_API_KEY";
81
82#[derive(Debug)]
84pub struct LastFmApiKeyFilter;
85
86impl Filter for LastFmApiKeyFilter {
87 fn filter_request(&self, request: &mut SerializableRequest) {
88 if let Some(real_key) = std::env::var("LASTFM_EDIT_API_KEY")
89 .ok()
90 .filter(|k| !k.is_empty())
91 {
92 request.url = request.url.replace(&real_key, TEST_API_KEY);
93 }
94 }
95
96 fn filter_response(&self, _response: &mut SerializableResponse) {}
97}
98
99pub fn create_lastfm_test_filter_chain() -> Result<FilterChain, regex::Error> {
105 let filter_chain = FilterChain::new()
106 .add_filter(Box::new(LastFmPasswordOnlyFilter))
107 .add_filter(Box::new(LastFmApiKeyFilter));
108 Ok(filter_chain)
109}