From a5e065daed87cdcd7b9cd14b0578a6f831f21fdc Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 14 Feb 2026 09:27:12 +0100 Subject: [PATCH] fix tests --- src-tauri/src/player/media.rs | 387 +++++++++++++++++++++++++++++++ src/lib/stores/downloads.test.ts | 21 +- 2 files changed, 400 insertions(+), 8 deletions(-) diff --git a/src-tauri/src/player/media.rs b/src-tauri/src/player/media.rs index 4939fca..87ae8e8 100644 --- a/src-tauri/src/player/media.rs +++ b/src-tauri/src/player/media.rs @@ -156,3 +156,390 @@ impl MediaItem { } } } + +#[cfg(test)] +mod tests { + use super::*; + use std::path::PathBuf; + + #[test] + fn test_queue_context_album() { + let context = QueueContext::Album { + album_id: "album-123".to_string(), + album_name: "Test Album".to_string(), + }; + + assert!(matches!(context, QueueContext::Album { .. })); + } + + #[test] + fn test_queue_context_playlist() { + let context = QueueContext::Playlist { + playlist_id: "playlist-456".to_string(), + playlist_name: "Test Playlist".to_string(), + }; + + assert!(matches!(context, QueueContext::Playlist { .. })); + } + + #[test] + fn test_queue_context_custom() { + let context = QueueContext::Custom; + assert!(matches!(context, QueueContext::Custom)); + } + + #[test] + fn test_queue_context_serialization() { + let context = QueueContext::Album { + album_id: "alb-001".to_string(), + album_name: "Album 001".to_string(), + }; + + let json = serde_json::to_string(&context); + assert!(json.is_ok()); + let serialized = json.unwrap(); + assert!(serialized.contains("album")); + } + + #[test] + fn test_queue_context_default() { + let context = QueueContext::default(); + assert!(matches!(context, QueueContext::Custom)); + } + + #[test] + fn test_queue_context_clone() { + let context = QueueContext::Album { + album_id: "clone-alb".to_string(), + album_name: "Clone Album".to_string(), + }; + + let cloned = context.clone(); + assert_eq!(context, cloned); + } + + #[test] + fn test_subtitle_track_creation() { + let track = SubtitleTrack { + index: 0, + url: "https://example.com/subs.vtt".to_string(), + language: Some("eng".to_string()), + label: Some("English".to_string()), + mime_type: "text/vtt".to_string(), + }; + + assert_eq!(track.index, 0); + assert_eq!(track.language, Some("eng".to_string())); + } + + #[test] + fn test_subtitle_track_without_language() { + let track = SubtitleTrack { + index: 1, + url: "https://example.com/subs.srt".to_string(), + language: None, + label: Some("Subtitles".to_string()), + mime_type: "application/x-subrip".to_string(), + }; + + assert!(track.language.is_none()); + assert!(track.label.is_some()); + } + + #[test] + fn test_subtitle_track_serialization() { + let track = SubtitleTrack { + index: 0, + url: "url.vtt".to_string(), + language: Some("eng".to_string()), + label: None, + mime_type: "text/vtt".to_string(), + }; + + let json = serde_json::to_string(&track); + assert!(json.is_ok()); + let serialized = json.unwrap(); + assert!(serialized.contains("0")); + assert!(serialized.contains("eng")); + } + + #[test] + fn test_media_type_audio() { + let media_type = MediaType::Audio; + let json = serde_json::to_string(&media_type).unwrap(); + assert!(json.contains("audio")); + } + + #[test] + fn test_media_type_video() { + let media_type = MediaType::Video; + let json = serde_json::to_string(&media_type).unwrap(); + assert!(json.contains("video")); + } + + #[test] + fn test_media_source_remote() { + let source = MediaSource::Remote { + stream_url: "https://server.com/video.mp4".to_string(), + jellyfin_item_id: "item-123".to_string(), + }; + + assert!(matches!(source, MediaSource::Remote { .. })); + } + + #[test] + fn test_media_source_local() { + let source = MediaSource::Local { + file_path: PathBuf::from("/path/to/video.mp4"), + jellyfin_item_id: Some("item-456".to_string()), + }; + + assert!(matches!(source, MediaSource::Local { .. })); + } + + #[test] + fn test_media_source_local_without_jellyfin_id() { + let source = MediaSource::Local { + file_path: PathBuf::from("/downloads/audio.mp3"), + jellyfin_item_id: None, + }; + + assert!(matches!(source, MediaSource::Local { .. })); + } + + #[test] + fn test_media_source_direct_url() { + let source = MediaSource::DirectUrl { + url: "https://external.com/stream".to_string(), + }; + + assert!(matches!(source, MediaSource::DirectUrl { .. })); + } + + #[test] + fn test_media_source_serialization() { + let source = MediaSource::DirectUrl { + url: "https://example.com/stream".to_string(), + }; + + let json = serde_json::to_string(&source); + assert!(json.is_ok()); + let serialized = json.unwrap(); + assert!(serialized.contains("directurl")); + } + + #[test] + fn test_media_item_creation_minimal() { + let item = MediaItem { + id: "item-1".to_string(), + title: "Test Item".to_string(), + name: None, + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: None, + playlist_id: None, + duration: None, + artwork_url: None, + media_type: MediaType::Video, + source: MediaSource::DirectUrl { + url: "https://example.com/video".to_string(), + }, + video_codec: None, + needs_transcoding: false, + video_width: None, + video_height: None, + subtitles: vec![], + series_id: None, + server_id: None, + }; + + assert_eq!(item.id, "item-1"); + assert_eq!(item.title, "Test Item"); + assert!(!item.needs_transcoding); + } + + #[test] + fn test_media_item_jellyfin_id() { + let item = MediaItem { + id: "item-2".to_string(), + title: "Test".to_string(), + name: None, + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: None, + playlist_id: None, + duration: None, + artwork_url: None, + media_type: MediaType::Audio, + source: MediaSource::Remote { + stream_url: "https://server/stream".to_string(), + jellyfin_item_id: "jf-id-123".to_string(), + }, + video_codec: None, + needs_transcoding: false, + video_width: None, + video_height: None, + subtitles: vec![], + series_id: None, + server_id: None, + }; + + assert_eq!(item.jellyfin_id(), Some("jf-id-123")); + } + + #[test] + fn test_media_item_jellyfin_id_local() { + let item = MediaItem { + id: "item-3".to_string(), + title: "Local".to_string(), + name: None, + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: None, + playlist_id: None, + duration: None, + artwork_url: None, + media_type: MediaType::Video, + source: MediaSource::Local { + file_path: PathBuf::from("/local/video.mp4"), + jellyfin_item_id: Some("jf-local".to_string()), + }, + video_codec: None, + needs_transcoding: false, + video_width: None, + video_height: None, + subtitles: vec![], + series_id: None, + server_id: None, + }; + + assert_eq!(item.jellyfin_id(), Some("jf-local")); + } + + #[test] + fn test_media_item_jellyfin_id_direct_url() { + let item = MediaItem { + id: "item-4".to_string(), + title: "Direct".to_string(), + name: None, + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: None, + playlist_id: None, + duration: None, + artwork_url: None, + media_type: MediaType::Video, + source: MediaSource::DirectUrl { + url: "https://external.com/media".to_string(), + }, + video_codec: None, + needs_transcoding: false, + video_width: None, + video_height: None, + subtitles: vec![], + series_id: None, + server_id: None, + }; + + assert_eq!(item.jellyfin_id(), None); + } + + #[test] + fn test_media_item_with_subtitles() { + let sub = SubtitleTrack { + index: 0, + url: "subs.vtt".to_string(), + language: Some("eng".to_string()), + label: Some("English".to_string()), + mime_type: "text/vtt".to_string(), + }; + + let item = MediaItem { + id: "item-subs".to_string(), + title: "With Subs".to_string(), + name: None, + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: None, + playlist_id: None, + duration: None, + artwork_url: None, + media_type: MediaType::Video, + source: MediaSource::DirectUrl { + url: "video.mp4".to_string(), + }, + video_codec: None, + needs_transcoding: false, + video_width: None, + video_height: None, + subtitles: vec![sub], + series_id: None, + server_id: None, + }; + + assert_eq!(item.subtitles.len(), 1); + assert_eq!(item.subtitles[0].language, Some("eng".to_string())); + } + + #[test] + fn test_media_item_serialization() { + let item = MediaItem { + id: "serial-item".to_string(), + title: "Serial Test".to_string(), + name: Some("Name".to_string()), + artist: None, + album: None, + album_name: None, + album_id: None, + artist_items: None, + artists: None, + primary_image_tag: None, + item_type: Some("Movie".to_string()), + playlist_id: None, + duration: Some(120.0), + artwork_url: None, + media_type: MediaType::Video, + source: MediaSource::DirectUrl { + url: "https://example.com/movie.mp4".to_string(), + }, + video_codec: Some("h264".to_string()), + needs_transcoding: false, + video_width: Some(1920), + video_height: Some(1080), + subtitles: vec![], + series_id: None, + server_id: None, + }; + + let json = serde_json::to_string(&item); + assert!(json.is_ok()); + let serialized = json.unwrap(); + assert!(serialized.contains("serial-item")); + assert!(serialized.contains("Serial Test")); + } +} diff --git a/src/lib/stores/downloads.test.ts b/src/lib/stores/downloads.test.ts index 107e2f6..7745e3b 100644 --- a/src/lib/stores/downloads.test.ts +++ b/src/lib/stores/downloads.test.ts @@ -35,6 +35,11 @@ describe("downloads store", () => { const { cleanupDownloadEvents } = await import("./downloads"); cleanupDownloadEvents(); eventHandler = null; + + // Clear all mocks + vi.clearAllMocks(); + mockInvoke.mockReset(); + mockListen.mockReset(); }); describe("initial state", () => { @@ -409,8 +414,8 @@ describe("downloads store", () => { }, }); - // Wait for async refresh - await new Promise((resolve) => setTimeout(resolve, 10)); + // Wait for async operations to complete + await new Promise((resolve) => setTimeout(resolve, 100)); const state = get(downloads); expect(state.downloads[123].status).toBe("downloading"); @@ -465,8 +470,8 @@ describe("downloads store", () => { }, }); - // Wait for async operations - await new Promise((resolve) => setTimeout(resolve, 10)); + // Wait for async operations to complete + await new Promise((resolve) => setTimeout(resolve, 100)); const state = get(downloads); expect(state.downloads[123].status).toBe("completed"); @@ -523,8 +528,8 @@ describe("downloads store", () => { }, }); - // Wait for async operations - await new Promise((resolve) => setTimeout(resolve, 10)); + // Wait for async operations to complete + await new Promise((resolve) => setTimeout(resolve, 100)); const state = get(downloads); expect(state.downloads[123].status).toBe("failed"); @@ -576,8 +581,8 @@ describe("downloads store", () => { }, }); - // Wait for async operations - await new Promise((resolve) => setTimeout(resolve, 10)); + // Wait for async operations to complete + await new Promise((resolve) => setTimeout(resolve, 100)); const state = get(downloads); expect(state.downloads[123]).toBeUndefined();