// Phase 1 smoke — exercises the foundation against live httpbin.org. // // Per SPEC §4 Phase 1 "Done when": build a Request, send through default // Downloader, parse Response, confirm latest_url follows redirects. // // These tests hit the network — gated on the `online` cfg so CI offline // runs aren't broken. #![cfg(feature = "online-tests")] use std::sync::Arc; use strawcore::downloader::request::Request; use strawcore::downloader::ReqwestDownloader; use strawcore::exceptions::NetworkError; use strawcore::localization::{ContentCountry, Localization}; use strawcore::{Downloader, NewPipe}; #[test] fn get_through_default_downloader() { let dl = ReqwestDownloader::new().expect("build downloader"); let resp = dl.get("https://httpbin.org/get").expect("transport"); assert_eq!(resp.response_code(), 200); assert!(resp.response_body().contains("\"url\"")); } #[test] fn latest_url_follows_redirects() { let dl = ReqwestDownloader::new().expect("build downloader"); let resp = dl .get("https://httpbin.org/redirect/3") .expect("transport"); assert_eq!(resp.response_code(), 200); assert!( resp.latest_url().ends_with("/get"), "latest_url should land at /get after 3 redirects, got {}", resp.latest_url() ); } #[test] fn non_2xx_returns_ok_not_err() { let dl = ReqwestDownloader::new().expect("build downloader"); let resp = dl.get("https://httpbin.org/status/404").expect("transport"); assert_eq!(resp.response_code(), 404); } #[test] fn http_429_surfaces_as_recaptcha_err() { let dl = ReqwestDownloader::new().expect("build downloader"); let err = dl.get("https://httpbin.org/status/429").expect_err("429 must be NetworkError"); match err { NetworkError::Recaptcha { url } => assert!(url.contains("/status/429")), other => panic!("expected Recaptcha, got {other:?}"), } } #[test] fn localization_header_attached_when_enabled() { let dl = ReqwestDownloader::new().expect("build downloader"); let req = Request::get("https://httpbin.org/headers") .localization(Some(Localization::new("en", Some("GB".into())))) .build(); let resp = dl.execute(req).expect("transport"); assert_eq!(resp.response_code(), 200); assert!( resp.response_body().to_ascii_lowercase().contains("accept-language"), "Accept-Language should be echoed by httpbin" ); assert!(resp.response_body().contains("en-GB")); } #[test] fn header_keys_lowercased_in_response() { let dl = ReqwestDownloader::new().expect("build downloader"); let resp = dl.get("https://httpbin.org/get").expect("transport"); for (k, _) in resp.response_headers() { assert_eq!(k, &k.to_ascii_lowercase(), "header key {k} not lowercased"); } } #[test] fn newpipe_singleton_wires_downloader() { let dl = Arc::new(ReqwestDownloader::new().expect("build downloader")); NewPipe::init_full( dl.clone(), Localization::default(), ContentCountry::default(), ); let from_global = NewPipe::downloader().expect("downloader registered"); let resp = from_global.get("https://httpbin.org/get").expect("transport"); assert_eq!(resp.response_code(), 200); assert_eq!(NewPipe::preferred_localization().localization_code(), "en-GB"); }