use application::sharing::{ AccessSharedResourceHandler, AccessSharedResourceQuery, GenerateShareLinkCommand, GenerateShareLinkHandler, }; use application::testing::InMemoryShareRepository; use chrono::{DateTime, Utc}; use domain::entities::{LinkAccessLevel, ShareableType}; use domain::errors::DomainError; use domain::value_objects::{DateTimeStamp, SystemId}; use std::sync::Arc; async fn create_link( repo: &Arc, expires_at: Option, max_uses: Option, ) -> String { let handler = GenerateShareLinkHandler::new(repo.clone()); let (_, link) = handler .execute(GenerateShareLinkCommand { shareable_type: ShareableType::Album, shareable_id: SystemId::new(), access_level: LinkAccessLevel::ViewOnly, created_by: SystemId::new(), expires_at, max_uses, }) .await .unwrap(); link.token } #[tokio::test] async fn valid_link_returns_scope() { let repo = Arc::new(InMemoryShareRepository::new()); let token = create_link(&repo, None, None).await; let handler = AccessSharedResourceHandler::new(repo); let (scope, access_level) = handler .execute(AccessSharedResourceQuery { token }) .await .unwrap(); assert_eq!(access_level, LinkAccessLevel::ViewOnly); assert_eq!(scope.shareable_type, ShareableType::Album); } #[tokio::test] async fn expired_link_rejected() { let repo = Arc::new(InMemoryShareRepository::new()); // Create link with past expiry let past = DateTimeStamp::from_datetime(DateTime::::from_timestamp(0, 0).unwrap()); let token = create_link(&repo, Some(past), None).await; let handler = AccessSharedResourceHandler::new(repo); let result = handler.execute(AccessSharedResourceQuery { token }).await; assert!(matches!(result, Err(DomainError::Forbidden(_)))); } #[tokio::test] async fn exhausted_link_rejected() { let repo = Arc::new(InMemoryShareRepository::new()); let token = create_link(&repo, None, Some(1)).await; // Use it once let handler = AccessSharedResourceHandler::new(repo.clone()); handler .execute(AccessSharedResourceQuery { token: token.clone(), }) .await .unwrap(); // Second use should fail let result = handler.execute(AccessSharedResourceQuery { token }).await; assert!(matches!(result, Err(DomainError::Forbidden(_)))); }