Refactor IAM tests: Remove unused repository tests, streamline service tests, and enhance validation checks for team and user services

This commit is contained in:
MythEclipse
2025-09-27 17:58:15 +07:00
parent 3e52223730
commit ac462ea771
23 changed files with 5286 additions and 1118 deletions
@@ -3,80 +3,290 @@ mod tests {
use crate::get_meta_request_dto;
use imphnen_cms::{
v1::landing::events::{
events_controller::EventsController,
events_service::EventsService,
events_dto::{EventsCreateRequestDto, EventsUpdateRequestDto},
events_schema::EventsSchema,
},
};
use chrono::{DateTime, Utc};
#[tokio::test]
async fn test_get_event_list_controller() {
let app_state = crate::get_app_state().await;
let response = EventsController::get_event_list(&app_state, get_meta_request_dto(1, 10)).await;
let response = EventsService::get_event_list(&app_state, get_meta_request_dto(1, 10))
.await;
assert_eq!(response.status(), 200);
}
#[tokio::test]
async fn test_get_event_by_id_controller_found() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Get event by ID through controller
let response = EventsService::get_event_by_id(&app_state, event_id.clone())
.await;
// Verify response
assert_eq!(response.status(), 200);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_get_event_by_id_controller_not_found() {
let app_state = crate::get_app_state().await;
let response = EventsController::get_event_by_id(&app_state, "non-existent-uuid-123456789".to_string()).await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Get non-existent event by ID through controller
let response = EventsService::get_event_by_id(&app_state, non_existent_id)
.await;
// Verify not found response
assert_eq!(response.status(), 404);
}
#[tokio::test]
async fn test_create_event_controller() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Test data
let event_request = EventsCreateRequestDto {
name: "Test Event".to_string(),
description: "Test event description".to_string(),
detail_link: Some("https://example.com/event".to_string()),
price: Some(100.0),
is_online: Some(true),
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
description: "Test event description for controller test".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
start_date: DateTime::parse_from_rfc3339("2024-01-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-01-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Online".to_string()),
};
let response = EventsController::create_event(&app_state, event_request).await;
// Create event through controller
let response = EventsService::create_event(&app_state, event_request.clone())
.await;
// Verify response
assert_eq!(response.status(), 201);
// Verify event was created in database
let created_events = repo.query_event_list(get_meta_request_dto(1, 10)).await.unwrap();
assert!(created_events.data.iter().any(|e| e.name == event_request.name));
// Clean up
let created_event = repo.query_event_list(get_meta_request_dto(1, 10)).await.unwrap();
for e in created_events.data {
if e.name == event_request.name {
let _ = repo.query_delete_event(e.id.id.to_raw()).await;
}
}
}
#[tokio::test]
async fn test_create_event_controller_invalid_data() {
let app_state = crate::get_app_state().await;
// Test data with empty name (should fail validation)
let event_request = EventsCreateRequestDto {
name: "".to_string(),
description: "".to_string(),
detail_link: None,
price: None,
is_online: None,
start_date: "invalid-date".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
location: None,
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
start_date: DateTime::parse_from_rfc3339("2024-01-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-01-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Online".to_string()),
};
let response = EventsController::create_event(&app_state, event_request).await;
// Create event through controller
let response = EventsService::create_event(&app_state, event_request)
.await;
// Verify bad request response (validation error)
assert_eq!(response.status(), 400);
}
#[tokio::test]
async fn test_update_event_controller() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let original_name = "Original Event Name".to_string();
let new_name = "Updated Event Name".to_string();
let event = EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: original_name.clone(),
description: "Test event description for update test".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Prepare update request
let update_request = EventsUpdateRequestDto {
name: new_name.clone(),
description: "Updated event description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
start_date: DateTime::parse_from_rfc3339("2024-02-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-02-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Offline Location".to_string()),
};
// Update event through controller
let response = EventsService::update_event(&app_state, event_id.clone(), update_request)
.await;
// Verify response
assert_eq!(response.status(), 200);
// Verify event was updated in database
let updated_event = repo
.query_event_by_id(event_id.clone())
.await
.unwrap();
assert_eq!(updated_event.name, new_name);
assert_eq!(updated_event.price, 150.0);
assert!(!updated_event.is_online);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_update_event_controller_not_found() {
let app_state = crate::get_app_state().await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Prepare update request
let update_request = EventsUpdateRequestDto {
name: Some("Updated Event".to_string()),
description: Some("Updated description".to_string()),
detail_link: Some("https://example.com/updated".to_string()),
price: Some(150.0),
is_online: Some(false),
start_date: Some("2024-02-01T00:00:00Z".to_string()),
end_date: Some("2024-02-02T00:00:00Z".to_string()),
name: "Updated Event".to_string(),
description: "Updated description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
start_date: DateTime::parse_from_rfc3339("2024-02-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-02-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Offline".to_string()),
};
let response = EventsController::update_event(&app_state, "non-existent-uuid-123456789".to_string(), update_request).await;
// Update non-existent event through controller
let response = EventsService::update_event(&app_state, non_existent_id, update_request)
.await;
// Verify not found response
assert_eq!(response.status(), 400);
}
#[tokio::test]
async fn test_delete_event_controller() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Delete".to_string(),
description: "Test event description for delete test".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Verify event exists before deletion
let exists_before = repo.query_event_by_id(event_id.clone()).await.is_ok();
assert!(exists_before);
// Delete event through controller
let response = EventsService::delete_event(&app_state, event_id.clone())
.await;
// Verify response
assert_eq!(response.status(), 200);
// Verify event was soft-deleted from database
let deleted_event = repo.query_event_by_id(event_id.clone()).await;
assert!(deleted_event.is_err());
// Clean up - no need since it's already soft-deleted
}
#[tokio::test]
async fn test_delete_event_controller_not_found() {
let app_state = crate::get_app_state().await;
let response = EventsController::delete_event(&app_state, "non-existent-uuid-123456789".to_string()).await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Delete non-existent event through controller
let response = EventsService::delete_event(&app_state, non_existent_id)
.await;
// Verify not found response
assert_eq!(response.status(), 400);
}
}
@@ -1,10 +1,9 @@
#[cfg(test)]
mod tests {
use imphnen_cms::{
v1::landing::events::{
events_repository::EventsRepository,
events_schema::EventsSchema,
},
use crate::get_meta_request_dto;
use imphnen_cms::v1::landing::events::{
events_repository::EventsRepository,
events_schema::EventsSchema,
};
use imphnen_utils::make_thing_from_enum;
@@ -12,67 +11,444 @@ mod tests {
async fn test_query_event_list() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
let result = repo.query_event_list(crate::get_meta_request_dto(1, 10)).await;
// Create test events
let num_events = 5;
let event_names = vec![
"Event 1".to_string(),
"Event 2".to_string(),
"Event 3".to_string(),
"Event 4".to_string(),
"Event 5".to_string(),
];
for (i, name) in event_names.iter().enumerate() {
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: name.clone(),
description: format!("Description for {}", name),
detail_link: format!("https://example.com/event{}", i + 1),
price: (i + 1) as f64 * 10.0,
is_online: i % 2 == 0,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: if i % 2 == 0 { Some("Online".to_string()) } else { Some("Offline Venue".to_string()) },
};
let _ = repo.query_create_event(event).await;
}
// Test with pagination
let result = repo.query_event_list(get_meta_request_dto(1, 10)).await;
assert!(result.is_ok());
let response = result.unwrap();
assert_eq!(response.data.len(), num_events);
// Test with smaller page size
let result = repo.query_event_list(get_meta_request_dto(1, 2)).await;
assert!(result.is_ok());
let response = result.unwrap();
assert_eq!(response.data.len(), 2);
// Clean up - delete all created events
for name in event_names {
let events = repo.query_event_list(get_meta_request_dto(1, 10)).await.unwrap();
for e in events.data {
if e.name == name {
let _ = repo.query_delete_event(e.id.id.to_raw()).await;
}
}
}
}
#[tokio::test]
async fn test_query_event_by_id_found() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let event_name = "Test Event for By ID".to_string();
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: event_name.clone(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Query event by ID
let result = repo.query_event_by_id(event_id.clone()).await;
assert!(result.is_ok());
let found_event = result.unwrap();
assert_eq!(found_event.name, event_name);
assert_eq!(found_event.price, 100.0);
assert!(found_event.is_online);
assert!(!found_event.is_deleted);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_query_event_by_id_not_found() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
let result = repo.query_event_by_id("non-existent-uuid-123456789".to_string()).await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Query non-existent event by ID
let result = repo.query_event_by_id(non_existent_id).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event not found");
}
#[tokio::test]
async fn test_query_event_by_id_deleted() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Deleted".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Soft delete the event
let _ = repo.query_delete_event(event_id.clone()).await;
// Try to query deleted event by ID
let result = repo.query_event_by_id(event_id).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event not found");
// Clean up - already deleted
}
#[tokio::test]
async fn test_query_create_event() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event data
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event".to_string(),
description: "Test description".to_string(),
detail_link: Some("https://example.com".to_string()),
price: Some(100.0),
name: "Test Event for Create".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
location: Some("Online".to_string()),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
is_deleted: false,
location: Some("Online".to_string()),
};
let result = repo.query_create_event(event).await;
// Create event
let result = repo.query_create_event(event.clone()).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Success create event");
// Verify it was created in database
let found_event = repo.query_event_by_id(event.id.id.to_raw()).await;
assert!(found_event.is_ok());
assert_eq!(found_event.unwrap().name, event.name);
// Clean up
let _ = repo.query_delete_event(event.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_query_update_event() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let original_name = "Original Event Name".to_string();
let new_name = "Updated Event Name".to_string();
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: original_name.clone(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Prepare updated event
let updated_event = EventsSchema {
id: created_event.id,
name: new_name.clone(),
description: "Updated description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
is_deleted: false,
start_date: "2024-02-01T00:00:00Z".to_string(),
end_date: "2024-02-02T00:00:00Z".to_string(),
created_at: created_event.created_at,
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Offline Venue".to_string()),
};
// Update event
let result = repo.query_update_event(updated_event).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Success update event");
// Verify it was updated in database
let found_event = repo.query_event_by_id(event_id).await;
assert!(found_event.is_ok());
let updated = found_event.unwrap();
assert_eq!(updated.name, new_name);
assert_eq!(updated.price, 150.0);
assert!(!updated.is_online);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_query_update_event_not_found() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
let event = EventsSchema {
id: make_thing_from_enum("events", &"non-existent-uuid-123456789".to_string()),
// Create non-existent event ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Prepare updated event with non-existent ID
let updated_event = EventsSchema {
id: make_thing_from_enum("events", &non_existent_id),
name: "Updated Event".to_string(),
description: "Updated description".to_string(),
detail_link: Some("https://example.com/updated".to_string()),
price: Some(150.0),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
is_deleted: false,
start_date: "2024-02-01T00:00:00Z".to_string(),
end_date: "2024-02-02T00:00:00Z".to_string(),
location: Some("Offline".to_string()),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
is_deleted: false,
location: Some("Offline".to_string()),
};
let result = repo.query_update_event(event).await;
// Try to update non-existent event
let result = repo.query_update_event(updated_event).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event not found");
}
#[tokio::test]
async fn test_query_update_event_deleted() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Deleted Update".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Soft delete the event
let _ = repo.query_delete_event(event_id.clone()).await;
// Prepare updated event
let updated_event = EventsSchema {
id: created_event.id,
name: "Updated Event".to_string(),
description: "Updated description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
is_deleted: false,
start_date: "2024-02-01T00:00:00Z".to_string(),
end_date: "2024-02-02T00:00:00Z".to_string(),
created_at: created_event.created_at,
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Offline".to_string()),
};
// Try to update deleted event
let result = repo.query_update_event(updated_event).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event already deleted");
// Clean up - already deleted
}
#[tokio::test]
async fn test_query_delete_event() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Delete".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Verify event exists before deletion
let exists_before = repo.query_event_by_id(event_id.clone()).await.is_ok();
assert!(exists_before);
// Delete event
let result = repo.query_delete_event(event_id.clone()).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Success delete event");
// Verify event was soft-deleted from database
let deleted_event = repo.query_event_by_id(event_id.clone()).await;
assert!(deleted_event.is_err());
assert_eq!(deleted_event.unwrap_err().to_string(), "Event not found");
// Clean up - already deleted
}
#[tokio::test]
async fn test_query_delete_event_not_found() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
let result = repo.query_delete_event("non-existent-uuid-123456789".to_string()).await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Try to delete non-existent event
let result = repo.query_delete_event(non_existent_id).await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event not found");
}
#[tokio::test]
async fn test_query_delete_event_already_deleted() {
let app_state = crate::get_app_state().await;
let repo = EventsRepository::new(&app_state);
// Create test event
let event = EventsSchema {
id: make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Already Deleted".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Soft delete the event twice
let _ = repo.query_delete_event(event_id.clone()).await;
let result = repo.query_delete_event(event_id).await;
// Verify second deletion fails
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Event not found");
// Clean up - already deleted
}
}
@@ -79,4 +79,268 @@ mod tests {
let response = EventsService::delete_event(&app_state, "non-existent-uuid-123456789".to_string()).await;
assert_eq!(response.status(), 400);
}
#[tokio::test]
async fn test_get_event_by_id_service_found() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let event = imphnen_cms::v1::landing::events::events_schema::EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event".to_string(),
description: "Test event description".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Get event by ID through service
let response = EventsService::get_event_by_id(&app_state, event_id.clone())
.await;
// Verify response
assert_eq!(response.status(), 200);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_update_event_service() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let original_name = "Original Event Name".to_string();
let new_name = "Updated Event Name".to_string();
let event = imphnen_cms::v1::landing::events::events_schema::EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: original_name.clone(),
description: "Test event description for update test".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Prepare update request
let update_request = EventsUpdateRequestDto {
name: new_name.clone(),
description: "Updated event description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: 150.0,
is_online: false,
start_date: DateTime::parse_from_rfc3339("2024-02-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-02-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Offline Location".to_string()),
};
// Update event through service
let response = EventsService::update_event(&app_state, event_id.clone(), update_request)
.await;
// Verify response
assert_eq!(response.status(), 200);
// Verify event was updated in database
let updated_event = repo
.query_event_by_id(event_id.clone())
.await
.unwrap();
assert_eq!(updated_event.name, new_name);
assert_eq!(updated_event.price, 150.0);
assert!(!updated_event.is_online);
// Clean up
let _ = repo.query_delete_event(event_id).await;
}
#[tokio::test]
async fn test_update_event_service_invalid_data() {
let app_state = crate::get_app_state().await;
// Use non-existent ID
let non_existent_id = "non-existent-uuid-123456789".to_string();
// Prepare update request with invalid data (negative price)
let update_request = EventsUpdateRequestDto {
name: "Updated Event".to_string(),
description: "Updated description".to_string(),
detail_link: "https://example.com/updated".to_string(),
price: -50.0, // Negative price should fail validation
is_online: false,
start_date: DateTime::parse_from_rfc3339("2024-02-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-02-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Offline".to_string()),
};
// Update event through service
let response = EventsService::update_event(&app_state, non_existent_id, update_request)
.await;
// Verify bad request response (validation error)
assert_eq!(response.status(), 400);
}
#[tokio::test]
async fn test_delete_event_service() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create test event
let event = imphnen_cms::v1::landing::events::events_schema::EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: "Test Event for Delete".to_string(),
description: "Test event description for delete test".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some("Online".to_string()),
};
let create_result = repo.query_create_event(event.clone()).await;
assert!(create_result.is_ok());
// Get created event to get ID
let created_event = repo
.query_event_by_id(event.id.id.to_raw())
.await
.unwrap();
let event_id = created_event.id.id.to_raw();
// Verify event exists before deletion
let exists_before = repo.query_event_by_id(event_id.clone()).await.is_ok();
assert!(exists_before);
// Delete event through service
let response = EventsService::delete_event(&app_state, event_id.clone())
.await;
// Verify response
assert_eq!(response.status(), 200);
// Verify event was soft-deleted from database
let deleted_event = repo.query_event_by_id(event_id.clone()).await;
assert!(deleted_event.is_err());
// Clean up - already deleted
}
#[tokio::test]
async fn test_create_event_service_edge_cases() {
let app_state = crate::get_app_state().await;
// Test with end date before start date (should fail validation if implemented)
let event_request = EventsCreateRequestDto {
name: "Invalid Date Event".to_string(),
description: "Event with invalid dates".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
start_date: DateTime::parse_from_rfc3339("2024-01-02T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-01-01T00:00:00Z").unwrap().with_timezone(&Utc), // Before start
location: Some("Online".to_string()),
};
let response = EventsService::create_event(&app_state, event_request).await;
// This might not be validated in the service, but let's check
// For now, assume it passes or fails based on implementation
// Test with very long name (boundary test)
let long_name = "A".repeat(1000); // Very long name
let event_request_long = EventsCreateRequestDto {
name: long_name,
description: "Event with very long name".to_string(),
detail_link: "https://example.com/event".to_string(),
price: 100.0,
is_online: true,
start_date: DateTime::parse_from_rfc3339("2024-01-01T00:00:00Z").unwrap().with_timezone(&Utc),
end_date: DateTime::parse_from_rfc3339("2024-01-02T00:00:00Z").unwrap().with_timezone(&Utc),
location: Some("Online".to_string()),
};
let response_long = EventsService::create_event(&app_state, event_request_long).await;
// Should pass or fail based on validation - if no length limit, it passes
}
#[tokio::test]
async fn test_get_event_list_service_with_pagination() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::events::events_repository::EventsRepository::new(&app_state);
// Create multiple test events
for i in 1..=5 {
let event = imphnen_cms::v1::landing::events::events_schema::EventsSchema {
id: imphnen_utils::make_thing_from_enum("events", &uuid::Uuid::new_v4().to_string()),
name: format!("Test Event {}", i),
description: format!("Description {}", i),
detail_link: format!("https://example.com/event{}", i),
price: i as f64 * 10.0,
is_online: i % 2 == 0,
is_deleted: false,
start_date: "2024-01-01T00:00:00Z".to_string(),
end_date: "2024-01-02T00:00:00Z".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
location: Some(format!("Location {}", i)),
};
let _ = repo.query_create_event(event).await;
}
// Test pagination with page 1, per_page 2
let meta = imphnen_libs::MetaRequestDto {
page: Some(1),
per_page: Some(2),
search: None,
sort_by: None,
order: None,
filter: None,
filter_by: None,
};
let response = EventsService::get_event_list(&app_state, meta).await;
assert_eq!(response.status(), 200);
// Clean up - delete all created events
let events = repo.query_event_list(crate::get_meta_request_dto(1, 10)).await.unwrap();
for e in events.data {
if e.name.starts_with("Test Event ") {
let _ = repo.query_delete_event(e.id.id.to_raw()).await;
}
}
}
}
}
@@ -386,4 +386,234 @@ mod tests {
// Clean up
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_create_testimonial_controller_content_boundary() {
let app_state = crate::get_app_state().await;
// Create test user for authentication
let user = UsersSchema {
id: make_thing_from_enum("users", &uuid::Uuid::new_v4().to_string()),
fullname: "Test Admin".to_string(),
email: "admin@example.com".to_string(),
..Default::default()
};
let _ = UsersRepository::new(&app_state).query_create_user(user.clone()).await;
// Test data with content exactly 500 characters (boundary test)
let content_500 = "A".repeat(500);
let testimonial_request = TestimonialsCreateRequestDto {
role: "Mentor".to_string(),
content: content_500.clone(),
};
// Create testimonial through controller
let response = TestimonialsController::create_testimonial(
&app_state,
testimonial_request.clone(),
&user,
)
.await;
// Should succeed (boundary)
assert_eq!(response.status(), StatusCode::CREATED);
// Verify testimonial was created
let created_testimonials = repo.query_testimonial_list(get_meta_request_dto(1, 10)).await.unwrap();
assert!(created_testimonials.data.iter().any(|t| t.content == testimonial_request.content));
// Clean up
for t in created_testimonials.data {
if t.content == testimonial_request.content {
let _ = repo.query_delete_testimonial(t.id.id.to_raw()).await;
}
}
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_create_testimonial_controller_content_too_long() {
let app_state = crate::get_app_state().await;
// Create test user for authentication
let user = UsersSchema {
id: make_thing_from_enum("users", &uuid::Uuid::new_v4().to_string()),
fullname: "Test Admin".to_string(),
email: "admin@example.com".to_string(),
..Default::default()
};
let _ = UsersRepository::new(&app_state).query_create_user(user.clone()).await;
// Test data with content over 500 characters (should fail validation)
let content_501 = "A".repeat(501);
let testimonial_request = TestimonialsCreateRequestDto {
role: "Mentor".to_string(),
content: content_501,
};
// Create testimonial through controller
let response = TestimonialsController::create_testimonial(
&app_state,
testimonial_request,
&user,
)
.await;
// Should fail validation
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
// Clean up
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_create_testimonial_controller_empty_role() {
let app_state = crate::get_app_state().await;
// Create test user for authentication
let user = UsersSchema {
id: make_thing_from_enum("users", &uuid::Uuid::new_v4().to_string()),
fullname: "Test Admin".to_string(),
email: "admin@example.com".to_string(),
..Default::default()
};
let _ = UsersRepository::new(&app_state).query_create_user(user.clone()).await;
// Test data with empty role (should fail validation)
let testimonial_request = TestimonialsCreateRequestDto {
role: "".to_string(),
content: "Valid content".to_string(),
};
// Create testimonial through controller
let response = TestimonialsController::create_testimonial(
&app_state,
testimonial_request,
&user,
)
.await;
// Should fail validation
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
// Clean up
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_update_testimonial_controller_content_boundary() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::testimonials::testimonials_repository::TestimonialsRepository::new(&app_state);
// Create test user for authentication
let user = UsersSchema {
id: make_thing_from_enum("users", &uuid::Uuid::new_v4().to_string()),
fullname: "Test Admin".to_string(),
email: "admin@example.com".to_string(),
..Default::default()
};
let _ = UsersRepository::new(&app_state).query_create_user(user.clone()).await;
// Create test testimonial
let testimonial = TestimonialsSchema {
id: make_thing_from_enum("testimonials", &uuid::Uuid::new_v4().to_string()),
user: user.id,
role: "Mentor".to_string(),
content: "Original content".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
is_deleted: false,
};
let create_result = repo.query_create_testimonial(testimonial.clone()).await;
assert!(create_result.is_ok());
// Get created testimonial to get ID
let created_testimonial = repo
.query_testimonial_by_id(testimonial.id.id.to_raw())
.await
.unwrap();
let testimonial_id = created_testimonial.id.id.to_raw();
// Prepare update request with content exactly 500 characters
let content_500 = "B".repeat(500);
let update_request = TestimonialsUpdateRequestDto {
role: Some("Updated Mentor".to_string()),
content: Some(content_500.clone()),
};
// Update testimonial through controller
let response = TestimonialsController::update_testimonial(
&app_state, update_request, testimonial_id.clone(), &user,
)
.await;
// Should succeed
assert_eq!(response.status(), StatusCode::OK);
// Verify testimonial was updated
let updated_testimonial = repo
.query_testimonial_by_id(testimonial_id.clone())
.await
.unwrap();
assert_eq!(updated_testimonial.content, content_500);
// Clean up
let _ = repo.query_delete_testimonial(testimonial_id).await;
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
#[tokio::test]
async fn test_update_testimonial_controller_content_too_long() {
let app_state = crate::get_app_state().await;
let repo = imphnen_cms::v1::landing::testimonials::testimonials_repository::TestimonialsRepository::new(&app_state);
// Create test user for authentication
let user = UsersSchema {
id: make_thing_from_enum("users", &uuid::Uuid::new_v4().to_string()),
fullname: "Test Admin".to_string(),
email: "admin@example.com".to_string(),
..Default::default()
};
let _ = UsersRepository::new(&app_state).query_create_user(user.clone()).await;
// Create test testimonial
let testimonial = TestimonialsSchema {
id: make_thing_from_enum("testimonials", &uuid::Uuid::new_v4().to_string()),
user: user.id,
role: "Mentor".to_string(),
content: "Original content".to_string(),
created_at: chrono::Utc::now().to_rfc3339(),
updated_at: chrono::Utc::now().to_rfc3339(),
is_deleted: false,
};
let create_result = repo.query_create_testimonial(testimonial.clone()).await;
assert!(create_result.is_ok());
// Get created testimonial to get ID
let created_testimonial = repo
.query_testimonial_by_id(testimonial.id.id.to_raw())
.await
.unwrap();
let testimonial_id = created_testimonial.id.id.to_raw();
// Prepare update request with content over 500 characters
let content_501 = "B".repeat(501);
let update_request = TestimonialsUpdateRequestDto {
role: Some("Updated Mentor".to_string()),
content: Some(content_501),
};
// Update testimonial through controller
let response = TestimonialsController::update_testimonial(
&app_state, update_request, testimonial_id.clone(), &user,
)
.await;
// Should fail validation
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
// Clean up
let _ = repo.query_delete_testimonial(testimonial_id).await;
let _ = UsersRepository::new(&app_state).query_delete_user(user.id.id.to_raw()).await;
}
}
}