feat: account deletion request and active-user check

This commit is contained in:
2026-10-26 02:11:44 +01:00
parent 83bb5d9847
commit 0b5d18c4ee
27 changed files with 577 additions and 151 deletions

View File

@@ -1,4 +1,4 @@
use crate::support::{AcceptingAuth, test_app_state, test_app_state_with_follow_graph};
use crate::support::{AcceptingAuth, test_app_state, test_app_state_with_repos};
use axum::{
Router,
body::Body,
@@ -6,6 +6,8 @@ use axum::{
routing::get,
};
use domain::errors::DomainError;
use domain::ports::UserRepository;
use domain::testing::InMemoryStore;
use std::sync::Arc;
use tower::ServiceExt;
use uuid::Uuid;
@@ -257,8 +259,19 @@ impl domain::ports::FollowGraphQuery for FixedPendingCount {
#[tokio::test]
async fn pending_count_endpoint_reports_the_use_case_result() {
let uid = domain::value_objects::UserId::from_uuid(Uuid::new_v4());
let state = test_app_state_with_follow_graph(
Arc::new(FixedPendingCount(3)),
let users = InMemoryStore::new();
users
.save(&domain::testing::test_user_with_role(
uid.clone(),
domain::models::UserRole::Standard,
))
.await
.unwrap();
let state = test_app_state_with_repos(
|repos| {
repos.follow_graph = Arc::new(FixedPendingCount(3));
repos.user = users as _;
},
Arc::new(AcceptingAuth(uid)),
);
let app = Router::new()

View File

@@ -246,7 +246,8 @@ async fn admin_api_user_rejects_an_unknown_user() {
)
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
// An account the store does not hold is inactive, so it is unauthenticated.
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
}
#[tokio::test]
@@ -337,7 +338,9 @@ async fn admin_user_rejects_an_unknown_user() {
)
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
// An account the store does not hold is inactive: back to the login page.
assert_eq!(resp.status(), StatusCode::SEE_OTHER);
assert_eq!(resp.headers().get("location").unwrap(), "/login");
}
#[tokio::test]

View File

@@ -7,7 +7,7 @@ use bootstrap::Repositories;
use domain::{
errors::DomainError,
models::GeneratedToken,
ports::{AuthService, FollowGraphQuery, PersonQuery, SearchPort, UserRepository},
ports::{AuthService, PersonQuery, SearchPort, UserRepository},
testing::{
PanicAuthService, PanicDiaryExporter, PanicDiaryQuery, PanicDocumentParser,
PanicEventPublisher, PanicGoalCommand, PanicGoalQuery, PanicImportProfileRepository,
@@ -168,15 +168,15 @@ pub fn test_app_state_with_search_port(
build_test_state_from(repos, Arc::new(PanicAuthService))
}
/// Test state with `follow_graph` overridden BEFORE `build_deps` runs, so the
/// stub is visible from both `app_ctx.repos.follow_graph` and the prebuilt
/// `deps.social.query` that the social handlers actually read from.
pub fn test_app_state_with_follow_graph(
follow_graph: Arc<dyn FollowGraphQuery>,
/// Test state whose repositories are adjusted by `adjust` BEFORE `build_deps`
/// runs, for tests that need more than one stub swapped in (e.g. a follow graph
/// plus the live user that authenticated routes now look up).
pub fn test_app_state_with_repos(
adjust: impl FnOnce(&mut Repositories),
auth_service: Arc<dyn AuthService>,
) -> http_axum::state::AppState {
let mut repos = test_repositories();
repos.follow_graph = follow_graph;
adjust(&mut repos);
build_test_state_from(repos, auth_service)
}