use super::*; #[test] fn source_projection_rejects_unsafe_or_unsupported_playback_contracts() { let sources = serde_json::json!({ "episodeNumber": 1, "config": { "sun": { "player": "native", "proxy": false } }, "tracks": [{ "track": "ssub", "providers": [{ "provider": "sun", "servers": [{ "headers": { "Origin": "https://ultracloud.cc", "Referer": "https://ultracloud.cc/" }, "streams": [{ "url": "https://vault.keeply.top/master.m3u8?token=secret", "format": "hls", "embed": null }] }], "subtitles": [{ "file": "https://vault.keeply.top/english.jpeg", "format": "vtt", "language": "en", "label": "English", "default": true }] }] }] }); let identity = Identity::new("catalog".into(), 1).unwrap(); let source = SourceDocument::from_sources(&sources, identity.clone(), "Episode 1").unwrap(); assert_eq!(Identity::from_key(&identity.key()).unwrap(), identity); assert_ne!( Identity::new("catalog".into(), 2).unwrap().key(), source.identity.key() ); for key in [ "miruro:catalog:01", "miruro:catalog:0", "miruro:catalog:2147483648", "miruro:catalog/:1", ] { assert!(Identity::from_key(key).is_err()); } for (pointer, value) in [ ("/episodeNumber", serde_json::json!(49)), ("/config/sun/proxy", serde_json::json!({"segments": true})), ( "/tracks/0/providers/0/servers/0/streams/0/url", serde_json::json!("file:///secret"), ), ( "/tracks/0/providers/0/servers/0/streams/0/embed", serde_json::json!({"url": "https://embed.example"}), ), ( "/tracks/0/providers/0/servers/0/headers/origin", serde_json::json!("secret"), ), ( "/tracks/0/providers/0/servers/0/headers/Referer", serde_json::json!("secret\r\nX-Injected: true"), ), ] { let mut invalid_sources = sources.clone(); if let Some(field) = invalid_sources.pointer_mut(pointer) { *field = value; } else { invalid_sources["tracks"][0]["providers"][0]["servers"][0]["headers"]["origin"] = value; } let error = SourceDocument::from_sources(&invalid_sources, identity.clone(), "Episode 1") .unwrap_err(); assert!(!error.to_string().contains("secret")); } let mut invalid_source = source; invalid_source .subtitles .push(invalid_source.subtitles[0].clone()); assert!(invalid_source.validate().is_err()); invalid_source.subtitles[1].default = false; invalid_source.subtitles[1].format = "srt".into(); assert!(invalid_source.validate().is_err()); } #[test] fn episodes_resolve_by_promise_id_with_independent_tables_or_fail_explicitly() { let initial = r#"{"type":"data","nodes":[null,{"type":"data","data":[{"detail":1,"episodes":4},{"id":2,"episode_count":3},"series",12,["Promise",5],9]}]}"#; let unrelated = r#"{"type":"chunk","id":4,"data":["unrelated"]}"#; let episode_chunk = r#"{"type":"chunk","id":9,"data":[[1],{"episode_number":2,"absolute_number":3,"title":4,"canon_type":5},1,49,"Locusts",null]}"#; let detail = decode_detail(&format!("{initial}\n{unrelated}\n{episode_chunk}\n")).unwrap(); assert_eq!(detail.media["episode_count"], 12); assert_eq!(detail.episodes[0]["episode_number"], 1); assert_eq!(detail.episodes[0]["absolute_number"], 49); assert_eq!(detail.episodes[0]["title"], "Locusts"); assert!(detail.episodes[0]["canon_type"].is_null()); for chunk in [ "", // The promised episodes never arrive. r#"{"type":"chunk","id":9,"error":["failed"]}"#, r#"{"type":"chunk","id":9,"data":[[999]]}"#, r#"{"type":"chunk","id":9,"data":[[0]]}"#, // Reference cycle. r#"{"type":"chunk","id":9,"data":[["Date","2026-10-12"]]}"#, ] { assert_eq!( decode_detail(&format!("{initial}\n{chunk}")) .err() .unwrap() .kind(), io::ErrorKind::InvalidData ); } assert_eq!( decode_detail(r#"{"type":"redirect","location":"/"}"#) .err() .unwrap() .kind(), io::ErrorKind::NotFound ); }