
Some checks are pending
iOS UniFFI Build / build-ios (push) Waiting to run
Add church management API library with cross-platform support for iOS, Android, and WASM. Features include event management, bulletin handling, contact forms, and authentication.
367 lines
14 KiB
Rust
367 lines
14 KiB
Rust
use church_core::{
|
|
ChurchApiClient, ChurchCoreConfig,
|
|
models::*,
|
|
error::ChurchApiError,
|
|
};
|
|
use mockito::{self, mock};
|
|
use serde_json::json;
|
|
use std::time::Duration;
|
|
use tokio_test;
|
|
|
|
#[cfg(test)]
|
|
mod integration_tests {
|
|
use super::*;
|
|
|
|
fn create_test_client() -> ChurchApiClient {
|
|
let config = ChurchCoreConfig::new()
|
|
.with_base_url(&mockito::server_url())
|
|
.with_timeout(Duration::from_secs(5))
|
|
.with_retry_attempts(1)
|
|
.with_offline_mode(false);
|
|
|
|
ChurchApiClient::new(config).unwrap()
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_upcoming_events_success() {
|
|
let _m = mock("GET", "/events/upcoming")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": [{
|
|
"id": "event-1",
|
|
"title": "Sunday Service",
|
|
"description": "Weekly worship service",
|
|
"start_time": "2024-07-14T11:00:00Z",
|
|
"end_time": "2024-07-14T12:30:00Z",
|
|
"location": "Main Sanctuary",
|
|
"location_url": null,
|
|
"image": null,
|
|
"thumbnail": null,
|
|
"category": "service",
|
|
"is_featured": true,
|
|
"recurring_type": "weekly",
|
|
"tags": ["worship", "sunday"],
|
|
"contact_email": null,
|
|
"contact_phone": null,
|
|
"registration_url": null,
|
|
"max_attendees": null,
|
|
"current_attendees": null,
|
|
"created_at": "2024-07-01T10:00:00Z",
|
|
"updated_at": "2024-07-01T10:00:00Z"
|
|
}]
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let events = client.get_upcoming_events(None).await.unwrap();
|
|
|
|
assert_eq!(events.len(), 1);
|
|
assert_eq!(events[0].id, "event-1");
|
|
assert_eq!(events[0].title, "Sunday Service");
|
|
assert_eq!(events[0].category, EventCategory::Service);
|
|
assert!(events[0].is_featured);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_upcoming_events_with_limit() {
|
|
let _m = mock("GET", "/events/upcoming?limit=5")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": []
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let events = client.get_upcoming_events(Some(5)).await.unwrap();
|
|
assert_eq!(events.len(), 0);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_event_success() {
|
|
let _m = mock("GET", "/events/event-123")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": {
|
|
"id": "event-123",
|
|
"title": "Bible Study",
|
|
"description": "Weekly Bible study group",
|
|
"start_time": "2024-07-15T19:00:00Z",
|
|
"end_time": "2024-07-15T21:00:00Z",
|
|
"location": "Fellowship Hall",
|
|
"location_url": null,
|
|
"image": null,
|
|
"thumbnail": null,
|
|
"category": "education",
|
|
"is_featured": false,
|
|
"recurring_type": null,
|
|
"tags": ["bible", "study"],
|
|
"contact_email": "study@church.org",
|
|
"contact_phone": null,
|
|
"registration_url": null,
|
|
"max_attendees": 20,
|
|
"current_attendees": 12,
|
|
"created_at": "2024-07-01T10:00:00Z",
|
|
"updated_at": "2024-07-01T10:00:00Z"
|
|
}
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let event = client.get_event("event-123").await.unwrap();
|
|
|
|
assert!(event.is_some());
|
|
let event = event.unwrap();
|
|
assert_eq!(event.id, "event-123");
|
|
assert_eq!(event.title, "Bible Study");
|
|
assert_eq!(event.category, EventCategory::Education);
|
|
assert_eq!(event.spots_remaining(), Some(8));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_event_not_found() {
|
|
let _m = mock("GET", "/events/nonexistent")
|
|
.with_status(404)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": false,
|
|
"error": "Event not found"
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let event = client.get_event("nonexistent").await.unwrap();
|
|
assert!(event.is_none());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_create_event_success() {
|
|
let _m = mock("POST", "/events")
|
|
.with_status(201)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": "new-event-id"
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let new_event = NewEvent {
|
|
title: "New Event".to_string(),
|
|
description: "A new event".to_string(),
|
|
start_time: chrono::Utc::now(),
|
|
end_time: chrono::Utc::now() + chrono::Duration::hours(2),
|
|
location: "Main Hall".to_string(),
|
|
location_url: None,
|
|
image: None,
|
|
category: EventCategory::Ministry,
|
|
is_featured: false,
|
|
recurring_type: None,
|
|
tags: None,
|
|
contact_email: None,
|
|
contact_phone: None,
|
|
registration_url: None,
|
|
max_attendees: None,
|
|
};
|
|
|
|
let event_id = client.create_event(new_event).await.unwrap();
|
|
assert_eq!(event_id, "new-event-id");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_current_bulletin_success() {
|
|
let _m = mock("GET", "/bulletins/current")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": {
|
|
"id": "bulletin-current",
|
|
"title": "This Week's Bulletin",
|
|
"date": "2024-07-13",
|
|
"sabbath_school": "9:30 AM",
|
|
"divine_worship": "11:00 AM",
|
|
"scripture_reading": "Psalm 23",
|
|
"sunset": "7:45 PM",
|
|
"pdf_path": "/bulletins/current.pdf",
|
|
"cover_image": "/images/cover.jpg",
|
|
"is_active": true,
|
|
"announcements": [{
|
|
"id": "ann-1",
|
|
"title": "Potluck Next Week",
|
|
"content": "Join us for fellowship after service",
|
|
"category": "social",
|
|
"is_urgent": false,
|
|
"contact_info": null,
|
|
"expires_at": "2025-12-31T00:00:00Z"
|
|
}],
|
|
"hymns": [{
|
|
"number": 1,
|
|
"title": "Holy, Holy, Holy",
|
|
"category": "opening",
|
|
"verses": [1, 2, 3]
|
|
}],
|
|
"special_music": null,
|
|
"offering_type": "Local Church Budget",
|
|
"sermon_title": "Walking by Faith",
|
|
"speaker": "Pastor Smith",
|
|
"liturgy": null,
|
|
"created_at": "2024-07-01T10:00:00Z",
|
|
"updated_at": "2024-07-13T08:00:00Z"
|
|
}
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let bulletin = client.get_current_bulletin().await.unwrap();
|
|
|
|
assert!(bulletin.is_some());
|
|
let bulletin = bulletin.unwrap();
|
|
assert_eq!(bulletin.id, "bulletin-current");
|
|
assert_eq!(bulletin.title, "This Week's Bulletin");
|
|
assert!(bulletin.has_pdf());
|
|
assert!(bulletin.has_cover_image());
|
|
assert_eq!(bulletin.active_announcements().len(), 1);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_current_bulletin_not_found() {
|
|
let _m = mock("GET", "/bulletins/current")
|
|
.with_status(404)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": false,
|
|
"error": "No current bulletin found"
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let bulletin = client.get_current_bulletin().await.unwrap();
|
|
assert!(bulletin.is_none());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_config_success() {
|
|
let _m = mock("GET", "/config")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": {
|
|
"church_name": "Test Church",
|
|
"church_address": "123 Faith Street, Hometown, ST 12345",
|
|
"contact_phone": "555-123-4567",
|
|
"contact_email": "info@testchurch.org",
|
|
"website_url": "https://testchurch.org",
|
|
"google_maps_url": "https://maps.google.com/test",
|
|
"facebook_url": "https://facebook.com/testchurch",
|
|
"youtube_url": null,
|
|
"instagram_url": null,
|
|
"about_text": "A welcoming church community",
|
|
"mission_statement": "Spreading God's love",
|
|
"service_times": {
|
|
"sabbath_school": "9:30 AM",
|
|
"divine_worship": "11:00 AM",
|
|
"prayer_meeting": "7:00 PM Wednesday",
|
|
"youth_service": null,
|
|
"special_services": null
|
|
},
|
|
"pastoral_staff": [{
|
|
"name": "Pastor John Smith",
|
|
"title": "Senior Pastor",
|
|
"email": "pastor@testchurch.org",
|
|
"phone": "555-123-4568",
|
|
"photo": null,
|
|
"bio": "Leading our church with love",
|
|
"responsibilities": ["Preaching", "Pastoral Care"]
|
|
}],
|
|
"ministries": null,
|
|
"app_settings": {
|
|
"enable_notifications": true,
|
|
"enable_calendar_sync": true,
|
|
"enable_offline_mode": true,
|
|
"theme": "system",
|
|
"default_language": "en",
|
|
"jellyfin_server": null,
|
|
"owncast_server": null,
|
|
"bible_version": "KJV",
|
|
"hymnal_version": "1985",
|
|
"cache_duration_minutes": 60,
|
|
"auto_refresh_interval_minutes": 15
|
|
},
|
|
"emergency_contacts": null
|
|
}
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let config = client.get_config().await.unwrap();
|
|
|
|
assert_eq!(config.church_name, Some("Test Church".to_string()));
|
|
assert_eq!(config.contact_phone, Some("555-123-4567".to_string()));
|
|
assert_eq!(config.get_display_name(), "Test Church");
|
|
assert!(config.has_social_media());
|
|
assert_eq!(config.get_contact_info().len(), 3); // phone, email, address
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_submit_contact_form_success() {
|
|
let _m = mock("POST", "/contact")
|
|
.with_status(201)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": true,
|
|
"data": "contact-submission-123"
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let contact_form = ContactForm::new(
|
|
"Jane Doe".to_string(),
|
|
"jane@example.com".to_string(),
|
|
"Question about baptism".to_string(),
|
|
"I'm interested in learning about baptism.".to_string(),
|
|
).with_category(ContactCategory::Baptism);
|
|
|
|
let submission_id = client.submit_contact_form(contact_form).await.unwrap();
|
|
assert_eq!(submission_id, "contact-submission-123");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_api_error_handling() {
|
|
let _m = mock("GET", "/events/upcoming")
|
|
.with_status(500)
|
|
.with_header("content-type", "application/json")
|
|
.with_body(json!({
|
|
"success": false,
|
|
"error": "Internal server error"
|
|
}).to_string())
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let result = client.get_upcoming_events(None).await;
|
|
|
|
assert!(result.is_err());
|
|
if let Err(error) = result {
|
|
assert!(matches!(error, ChurchApiError::Http(_)));
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_health_check() {
|
|
let _m = mock("GET", "/health")
|
|
.with_status(200)
|
|
.with_header("content-type", "application/json")
|
|
.with_body("OK")
|
|
.create();
|
|
|
|
let client = create_test_client();
|
|
let is_healthy = client.health_check().await.unwrap();
|
|
assert!(is_healthy);
|
|
}
|
|
} |