LuminaLP/tests/integration_tests.rs
Benjamin Slingo c76e61ea59 Initial commit: Core LuminaLP architecture with plugin system
Features implemented:
- Clean trait-based plugin architecture (no global registries)
- SQLite database with centralized SQL operations
- Songs plugin: CCLI support, lyrics search and display
- Bible plugin: Multi-translation verse lookup and rendering
- Media plugin: Auto-detection for images/video/audio files
- Presentations plugin: LibreOffice integration with HTML/XHTML combo parsing
- Service management: Add items, navigation, current slide tracking
- Comprehensive integration tests with real database operations

Architecture follows KISS/DRY principles:
- All SQL operations centralized in core/database.rs
- Plugins focus on business logic only
- No complex state management or global registries
- Clean separation of concerns throughout

Ready for church presentation use with PowerPoint theme preservation.
2025-09-01 22:53:26 -04:00

176 lines
6.1 KiB
Rust

use lumina_core::App;
use lumina_songs::{Song, SongsPlugin};
use lumina_bible::{BibleVerse, BiblePlugin};
use lumina_media::MediaPlugin;
use lumina_presentations::PresentationsPlugin;
use tokio;
#[tokio::test]
async fn test_songs_plugin_full_workflow() {
// Use in-memory database for tests
let mut app = App::new(":memory:").await.unwrap();
let songs_plugin = SongsPlugin::new(app.db.clone());
// Add a real song
let song = Song {
id: 0, // Will be set by DB
title: "Amazing Grace".to_string(),
lyrics: "Amazing grace how sweet the sound\nThat saved a wretch like me\n\nI once was lost but now am found\nWas blind but now I see".to_string(),
author: Some("John Newton".to_string()),
ccli: Some("12345".to_string()),
};
let song_id = songs_plugin.add_song(song).await.unwrap();
assert!(song_id > 0);
app.register_plugin(Box::new(songs_plugin));
// Search for the song
let results = app.search("songs", "Amazing").await.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].title, "Amazing Grace");
assert_eq!(results[0].plugin, "songs");
// Test rendering
let rendered = app.plugins.get("songs").unwrap().render(&results[0]).await.unwrap();
assert!(rendered.html.contains("Amazing Grace"));
assert!(rendered.html.contains("Amazing grace how sweet the sound"));
assert!(rendered.html.contains("John Newton"));
assert!(rendered.html.contains("CCLI: 12345"));
assert!(rendered.css.is_some());
}
#[tokio::test]
async fn test_bible_plugin_full_workflow() {
let mut app = App::new(":memory:").await.unwrap();
let bible_plugin = BiblePlugin::new(app.db.clone());
// Add a real verse
let verse = BibleVerse {
id: 0,
book: "John".to_string(),
chapter: 3,
verse: 16,
text: "For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.".to_string(),
translation: "KJV".to_string(),
};
let verse_id = bible_plugin.add_verse(verse).await.unwrap();
assert!(verse_id > 0);
app.register_plugin(Box::new(bible_plugin));
// Search for the verse
let results = app.search("bible", "God so loved").await.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].title, "John 3:16 (KJV)");
assert_eq!(results[0].plugin, "bible");
// Test rendering
let rendered = app.plugins.get("bible").unwrap().render(&results[0]).await.unwrap();
assert!(rendered.html.contains("For God so loved the world"));
assert!(rendered.html.contains("John 3:16 (KJV)"));
assert!(rendered.css.is_some());
}
#[tokio::test]
async fn test_media_plugin_full_workflow() {
let mut app = App::new(":memory:").await.unwrap();
let media_plugin = MediaPlugin::new(app.db.clone());
// Add a media item
let media_id = media_plugin.add_media(
"Church Logo".to_string(),
"/path/to/church_logo.jpg".to_string()
).await.unwrap();
assert!(media_id > 0);
app.register_plugin(Box::new(media_plugin));
// Search for media
let results = app.search("media", "Church").await.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].title, "Church Logo");
assert_eq!(results[0].plugin, "media");
// Test rendering
let rendered = app.plugins.get("media").unwrap().render(&results[0]).await.unwrap();
assert!(rendered.html.contains("church_logo.jpg"));
assert!(rendered.html.contains("img src"));
assert!(rendered.css.is_some());
}
#[tokio::test]
async fn test_service_management() {
let mut app = App::new(":memory:").await.unwrap();
let songs_plugin = SongsPlugin::new(app.db.clone());
// Add some songs
let song1 = Song {
id: 0,
title: "Song 1".to_string(),
lyrics: "Verse 1 content".to_string(),
author: None,
ccli: None,
};
let song2 = Song {
id: 0,
title: "Song 2".to_string(),
lyrics: "Verse 2 content".to_string(),
author: None,
ccli: None,
};
songs_plugin.add_song(song1).await.unwrap();
songs_plugin.add_song(song2).await.unwrap();
app.register_plugin(Box::new(songs_plugin));
// Search and add to service
let song1_results = app.search("songs", "Song 1").await.unwrap();
let song2_results = app.search("songs", "Song 2").await.unwrap();
app.service.add_item(song1_results[0].clone());
app.service.add_item(song2_results[0].clone());
// Test service navigation
assert_eq!(app.service.items.len(), 2);
assert_eq!(app.service.current_index, 0);
let current = app.service.current().unwrap();
assert_eq!(current.title, "Song 1");
let next = app.service.next().unwrap();
assert_eq!(next.title, "Song 2");
assert_eq!(app.service.current_index, 1);
let prev = app.service.previous().unwrap();
assert_eq!(prev.title, "Song 1");
assert_eq!(app.service.current_index, 0);
}
#[tokio::test]
async fn test_multiple_plugins_together() {
let mut app = App::new(":memory:").await.unwrap();
// Register all plugins
let songs_plugin = SongsPlugin::new(app.db.clone());
let bible_plugin = BiblePlugin::new(app.db.clone());
let media_plugin = MediaPlugin::new(app.db.clone());
let presentations_plugin = PresentationsPlugin::new(app.db.clone());
app.register_plugin(Box::new(songs_plugin));
app.register_plugin(Box::new(bible_plugin));
app.register_plugin(Box::new(media_plugin));
app.register_plugin(Box::new(presentations_plugin));
// Verify all plugins are registered
assert_eq!(app.plugins.len(), 4);
assert!(app.plugins.contains_key("songs"));
assert!(app.plugins.contains_key("bible"));
assert!(app.plugins.contains_key("media"));
assert!(app.plugins.contains_key("presentations"));
// Test that each plugin returns empty results for unknown queries
let empty_results = app.search("songs", "nonexistent").await.unwrap();
assert_eq!(empty_results.len(), 0);
}