use std::sync::Arc; use application::testing::{InMemoryShareRepository, StubEventPublisher}; use application::sharing::{ GenerateShareLinkCommand, GenerateShareLinkHandler, RevokeShareCommand, RevokeShareHandler, }; use domain::entities::{LinkAccessLevel, ShareableType}; use domain::errors::DomainError; use domain::value_objects::SystemId; #[tokio::test] async fn revokes_share() { let share_repo = Arc::new(InMemoryShareRepository::new()); let event_pub = Arc::new(StubEventPublisher::new()); // Create a scope first via generate_share_link let gen_handler = GenerateShareLinkHandler::new(share_repo.clone()); let (scope, _) = gen_handler.execute(GenerateShareLinkCommand { shareable_type: ShareableType::Album, shareable_id: SystemId::new(), access_level: LinkAccessLevel::ViewOnly, created_by: SystemId::new(), expires_at: None, max_uses: None, }).await.unwrap(); let handler = RevokeShareHandler::new(share_repo, event_pub.clone()); handler.execute(RevokeShareCommand { scope_id: scope.scope_id, revoked_by: SystemId::new(), }).await.unwrap(); let events = event_pub.published().await; assert_eq!(events.len(), 1); } #[tokio::test] async fn rejects_nonexistent_scope() { let share_repo = Arc::new(InMemoryShareRepository::new()); let event_pub = Arc::new(StubEventPublisher::new()); let handler = RevokeShareHandler::new(share_repo, event_pub); let result = handler.execute(RevokeShareCommand { scope_id: SystemId::new(), revoked_by: SystemId::new(), }).await; assert!(matches!(result, Err(DomainError::NotFound(_)))); }