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