use crate::fetched_transcript::FetchedTranscript;
use crate::models::{
FetchedTranscriptSnippet, MicroformatData, MicroformatEmbed, MicroformatThumbnail,
TranslationLanguage, VideoThumbnail,
};
use crate::transcript::Transcript;
use crate::transcript_list::TranscriptList;
use reqwest::Client;
use std::collections::HashMap;
use tokio::test;
fn create_client() -> Client {
Client::builder()
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
.build()
.unwrap()
}
#[allow(dead_code)]
const MOCK_VIDEO_ID: &str = "arj7oStGLkU";
#[allow(dead_code)]
fn create_mock_transcript() -> FetchedTranscript {
FetchedTranscript {
snippets: vec![
FetchedTranscriptSnippet {
text: "Hello, this is a test transcript.".to_string(),
start: 0.0,
duration: 2.5,
},
FetchedTranscriptSnippet {
text: "This is mocked data for CI testing.".to_string(),
start: 2.5,
duration: 3.0,
},
],
video_id: MOCK_VIDEO_ID.to_string(),
language: "English".to_string(),
language_code: "en".to_string(),
is_generated: false,
}
}
#[allow(dead_code)]
fn create_mock_transcript_list() -> TranscriptList {
let _client = create_client();
let translation_languages = vec![
TranslationLanguage {
language: "English".to_string(),
language_code: "en".to_string(),
},
TranslationLanguage {
language: "French".to_string(),
language_code: "fr".to_string(),
},
];
let mut manually_created_transcripts = HashMap::new();
let english_transcript = Transcript::new(
MOCK_VIDEO_ID.to_string(),
"https://mock.youtube.com/transcript/en".to_string(),
"English".to_string(),
"en".to_string(),
false,
translation_languages.clone(),
);
manually_created_transcripts.insert("en".to_string(), english_transcript);
TranscriptList::new(
MOCK_VIDEO_ID.to_string(),
manually_created_transcripts,
HashMap::new(),
translation_languages,
)
}
#[allow(dead_code)]
fn create_mock_microformat_data() -> MicroformatData {
let thumbnails = vec![VideoThumbnail {
url: "https://i.ytimg.com/vi/mock_video_id/maxresdefault.jpg".to_string(),
width: 1280,
height: 720,
}];
let thumbnail = MicroformatThumbnail {
thumbnails: Some(thumbnails),
};
let embed = MicroformatEmbed {
height: Some(720),
iframe_url: Some("https://www.youtube.com/embed/mock_video_id".to_string()),
width: Some(1280),
};
let available_countries = vec![
"US".to_string(),
"GB".to_string(),
"CA".to_string(),
"AU".to_string(),
"DE".to_string(),
"FR".to_string(),
"JP".to_string(),
];
MicroformatData {
available_countries: Some(available_countries),
category: Some("Science & Technology".to_string()),
description: Some("This is a mock video description for testing.".to_string()),
embed: Some(embed),
external_channel_id: Some("UC_mock_channel_id".to_string()),
external_video_id: Some("mock_video_id".to_string()),
has_ypc_metadata: Some(false),
is_family_safe: Some(true),
is_shorts_eligible: Some(false),
is_unlisted: Some(false),
length_seconds: Some("300".to_string()),
like_count: Some("1000".to_string()),
owner_channel_name: Some("Mock Channel".to_string()),
owner_profile_url: Some("https://www.youtube.com/@MockChannel".to_string()),
publish_date: Some("2023-01-01T12:00:00Z".to_string()),
thumbnail: Some(thumbnail),
title: Some("Mock Video Title".to_string()),
upload_date: Some("2023-01-01T12:00:00Z".to_string()),
view_count: Some("10000".to_string()),
}
}
#[test]
async fn test_list_transcripts() {
let transcript_list = create_mock_transcript_list();
assert_eq!(transcript_list.video_id, MOCK_VIDEO_ID);
let mut found_transcripts = false;
for transcript in &transcript_list {
found_transcripts = true;
assert_eq!(transcript.video_id, MOCK_VIDEO_ID);
assert!(!transcript.language_code.is_empty());
assert!(!transcript.language.is_empty());
}
assert!(found_transcripts, "No transcripts found in the list");
}
#[test]
async fn test_find_transcript() {
let transcript_list = create_mock_transcript_list();
let transcript = transcript_list.find_transcript(&["en"]);
assert!(transcript.is_ok(), "Failed to find English transcript");
let transcript = transcript_list.find_transcript(&["non-existent", "en"]);
assert!(
transcript.is_ok(),
"Failed to find transcript with fallback languages"
);
let transcript = transcript_list.find_transcript(&["non-existent"]);
assert!(transcript.is_err(), "Found a non-existent transcript");
}
#[test]
async fn test_fetch_transcript() {
let transcript = create_mock_transcript();
assert_eq!(transcript.video_id, MOCK_VIDEO_ID);
assert!(
!transcript.snippets.is_empty(),
"Transcript has no snippets"
);
for snippet in &transcript.snippets {
assert!(!snippet.text.is_empty(), "Snippet has empty text");
assert!(snippet.start >= 0.0, "Snippet has negative start time");
assert!(
snippet.duration > 0.0,
"Snippet has zero or negative duration"
);
}
}
#[test]
async fn test_translate_transcript() {
let transcript_list = create_mock_transcript_list();
let found_translatable = transcript_list
.manually_created_transcripts
.values()
.any(|t| !t.translation_languages.is_empty());
assert!(found_translatable, "No translatable transcripts found");
}
#[test]
async fn test_preserve_formatting() {
let with_formatting = create_mock_transcript();
let without_formatting = create_mock_transcript();
assert_eq!(with_formatting.video_id, without_formatting.video_id);
assert_eq!(with_formatting.language, without_formatting.language);
assert_eq!(
with_formatting.language_code,
without_formatting.language_code
);
}
#[test]
async fn test_transcript_formatter() {
let transcript_list = create_mock_transcript_list();
let transcript_result = transcript_list.find_transcript(&["en"]);
assert!(
transcript_result.is_ok(),
"Failed to find English transcript"
);
let transcript = transcript_result.unwrap();
let transcript_str = format!("{}", transcript);
assert!(!transcript_str.is_empty());
assert!(transcript_str.contains("en"));
}
#[test]
async fn test_transcriptlist_formatter() {
let transcript_list = create_mock_transcript_list();
let transcript_list_str = format!("{}", transcript_list);
assert!(!transcript_list_str.is_empty());
assert!(transcript_list_str.contains("Available transcripts"));
}
#[test]
async fn test_fetch_microformat() {
let microformat = create_mock_microformat_data();
assert!(microformat.available_countries.is_some());
let countries = microformat.available_countries.unwrap();
assert!(!countries.is_empty());
assert!(countries.contains(&"US".to_string()));
assert_eq!(
microformat.category,
Some("Science & Technology".to_string())
);
assert_eq!(microformat.is_family_safe, Some(true));
if let Some(embed) = microformat.embed {
assert_eq!(embed.height, Some(720));
assert_eq!(embed.width, Some(1280));
assert!(embed.iframe_url.is_some());
} else {
panic!("Embed information is missing");
}
if let Some(thumbnail) = microformat.thumbnail {
if let Some(thumbnails) = thumbnail.thumbnails {
assert!(!thumbnails.is_empty());
let first_thumbnail = &thumbnails[0];
assert_eq!(first_thumbnail.width, 1280);
assert_eq!(first_thumbnail.height, 720);
} else {
panic!("Thumbnails list is None");
}
} else {
panic!("Thumbnail information is missing");
}
}
#[test]
async fn test_fetch_streaming_data() {
use crate::tests::mocks::create_mock_streaming_data;
let streaming_data = create_mock_streaming_data();
assert_eq!(streaming_data.expires_in_seconds, "21540");
assert!(!streaming_data.formats.is_empty());
assert!(!streaming_data.adaptive_formats.is_empty());
let format = &streaming_data.formats[0];
assert_eq!(format.itag, 18);
assert_eq!(format.width, Some(640));
assert_eq!(format.height, Some(360));
assert_eq!(format.quality, "medium");
assert_eq!(format.quality_label, Some("360p".to_string()));
let video_format = streaming_data
.adaptive_formats
.iter()
.find(|f| f.itag == 136)
.expect("Missing expected video format");
assert_eq!(video_format.width, Some(1280));
assert_eq!(video_format.height, Some(720));
assert!(video_format.init_range.is_some());
assert!(video_format.index_range.is_some());
let audio_format = streaming_data
.adaptive_formats
.iter()
.find(|f| f.itag == 140)
.expect("Missing expected audio format");
assert_eq!(
audio_format.audio_quality,
Some("AUDIO_QUALITY_MEDIUM".to_string())
);
assert_eq!(audio_format.audio_sample_rate, Some("44100".to_string()));
assert_eq!(audio_format.audio_channels, Some(2));
assert!(streaming_data.server_abr_streaming_url.is_some());
}