allsource_core/application/use_cases/
manage_tenant.rs1use crate::{
2 application::dto::{
3 CreateTenantRequest, CreateTenantResponse, ListTenantsResponse, TenantDto,
4 UpdateTenantRequest, UpdateTenantResponse,
5 },
6 domain::{entities::Tenant, value_objects::TenantId},
7 error::Result,
8};
9
10pub struct CreateTenantUseCase;
14
15impl CreateTenantUseCase {
16 pub fn execute(request: CreateTenantRequest) -> Result<CreateTenantResponse> {
17 let tenant_id = TenantId::new(request.tenant_id)?;
19
20 let tenant = if let Some(quotas_dto) = request.quotas {
22 Tenant::new(tenant_id, request.name, quotas_dto.into())?
23 } else {
24 Tenant::new(
26 tenant_id,
27 request.name,
28 crate::domain::entities::TenantQuotas::free_tier(),
29 )?
30 };
31
32 Ok(CreateTenantResponse {
33 tenant: TenantDto::from(&tenant),
34 })
35 }
36}
37
38pub struct UpdateTenantUseCase;
42
43impl UpdateTenantUseCase {
44 pub fn execute(
45 mut tenant: Tenant,
46 request: UpdateTenantRequest,
47 ) -> Result<UpdateTenantResponse> {
48 if let Some(name) = request.name {
50 tenant.update_name(name)?;
51 }
52
53 if let Some(quotas_dto) = request.quotas {
55 tenant.update_quotas(quotas_dto.into());
56 }
57
58 Ok(UpdateTenantResponse {
59 tenant: TenantDto::from(&tenant),
60 })
61 }
62}
63
64pub struct ActivateTenantUseCase;
68
69impl ActivateTenantUseCase {
70 pub fn execute(mut tenant: Tenant) -> Result<TenantDto> {
71 tenant.activate();
72 Ok(TenantDto::from(&tenant))
73 }
74}
75
76pub struct DeactivateTenantUseCase;
80
81impl DeactivateTenantUseCase {
82 pub fn execute(mut tenant: Tenant) -> Result<TenantDto> {
83 tenant.deactivate();
84 Ok(TenantDto::from(&tenant))
85 }
86}
87
88pub struct ListTenantsUseCase;
92
93impl ListTenantsUseCase {
94 pub fn execute(tenants: &[Tenant]) -> ListTenantsResponse {
95 let tenant_dtos: Vec<TenantDto> = tenants.iter().map(TenantDto::from).collect();
96 let count = tenant_dtos.len();
97
98 ListTenantsResponse {
99 tenants: tenant_dtos,
100 count,
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use crate::application::dto::TenantQuotasDto;
109
110 #[test]
111 fn test_create_tenant_with_default_quotas() {
112 let request = CreateTenantRequest {
113 tenant_id: "test-tenant".to_string(),
114 name: "Test Tenant".to_string(),
115 quotas: None,
116 };
117
118 let response = CreateTenantUseCase::execute(request);
119 assert!(response.is_ok());
120
121 let response = response.unwrap();
122 assert_eq!(response.tenant.name, "Test Tenant");
123 assert_eq!(response.tenant.tenant_id, "test-tenant");
124 assert!(response.tenant.is_active);
125 }
126
127 #[test]
128 fn test_create_tenant_with_custom_quotas() {
129 let request = CreateTenantRequest {
130 tenant_id: "premium-tenant".to_string(),
131 name: "Premium Tenant".to_string(),
132 quotas: Some(TenantQuotasDto {
133 max_events_per_day: Some(1_000_000),
134 max_storage_bytes: Some(10_000_000_000),
135 max_queries_per_hour: Some(10_000),
136 max_api_keys: Some(50),
137 max_projections: Some(100),
138 max_pipelines: Some(50),
139 }),
140 };
141
142 let response = CreateTenantUseCase::execute(request);
143 assert!(response.is_ok());
144
145 let response = response.unwrap();
146 assert_eq!(response.tenant.quotas.max_events_per_day, Some(1_000_000));
147 }
148
149 #[test]
150 fn test_update_tenant_name() {
151 let tenant_id = TenantId::new("test-tenant".to_string()).unwrap();
152 let tenant = Tenant::new(
153 tenant_id,
154 "Old Name".to_string(),
155 crate::domain::entities::TenantQuotas::free_tier(),
156 )
157 .unwrap();
158
159 let request = UpdateTenantRequest {
160 name: Some("New Name".to_string()),
161 quotas: None,
162 };
163
164 let response = UpdateTenantUseCase::execute(tenant, request);
165 assert!(response.is_ok());
166
167 let response = response.unwrap();
168 assert_eq!(response.tenant.name, "New Name");
169 }
170
171 #[test]
172 fn test_activate_deactivate_tenant() {
173 let tenant_id = TenantId::new("test-tenant".to_string()).unwrap();
174 let tenant = Tenant::new(
175 tenant_id,
176 "Test".to_string(),
177 crate::domain::entities::TenantQuotas::free_tier(),
178 )
179 .unwrap();
180
181 let result = DeactivateTenantUseCase::execute(tenant.clone());
183 assert!(result.is_ok());
184 assert!(!result.unwrap().is_active);
185
186 let mut deactivated = tenant.clone();
188 deactivated.deactivate();
189 let result = ActivateTenantUseCase::execute(deactivated);
190 assert!(result.is_ok());
191 assert!(result.unwrap().is_active);
192 }
193
194 #[test]
195 fn test_list_tenants() {
196 let tenants = vec![
197 Tenant::new(
198 TenantId::new("tenant-1".to_string()).unwrap(),
199 "Tenant 1".to_string(),
200 crate::domain::entities::TenantQuotas::free_tier(),
201 )
202 .unwrap(),
203 Tenant::new(
204 TenantId::new("tenant-2".to_string()).unwrap(),
205 "Tenant 2".to_string(),
206 crate::domain::entities::TenantQuotas::standard(),
207 )
208 .unwrap(),
209 ];
210
211 let response = ListTenantsUseCase::execute(&tenants);
212 assert_eq!(response.count, 2);
213 assert_eq!(response.tenants.len(), 2);
214 }
215}