@@ -5,15 +5,6 @@ use uuid::Uuid;
|
||||
|
||||
use crate::users::deps::AuthorizeAdminDeps;
|
||||
|
||||
/// Whether `user_id` is an admin, for the two extractors (`AdminApiUser`,
|
||||
/// `AdminUser`) that gate admin-only routes.
|
||||
///
|
||||
/// Returns `Ok(None)` when the user row does not exist — a distinct success
|
||||
/// value, not folded into `DomainError::NotFound`, specifically so callers can
|
||||
/// tell "row missing" apart from "repository call failed" without depending on
|
||||
/// which `DomainError` variant a lookup failure happens to produce. Each
|
||||
/// extractor rejects those two cases differently (missing row is a 401/404,
|
||||
/// a repository error is a 500) and that distinction must stay exact.
|
||||
pub async fn execute(
|
||||
deps: &AuthorizeAdminDeps,
|
||||
user_id: Uuid,
|
||||
|
||||
@@ -7,9 +7,6 @@ use domain::ports::{
|
||||
};
|
||||
use domain::value_objects::InstanceIdentity;
|
||||
|
||||
/// The local half of the former `GetProfileDeps` split (ADR-0004). `user` and
|
||||
/// `instance` build the always-populated `ProfileIdentity`; `stats`/`diary`/
|
||||
/// `social_query` are unchanged from before the split.
|
||||
pub struct GetLocalProfileDeps {
|
||||
pub stats: Arc<dyn StatsRepository>,
|
||||
pub diary: Arc<dyn DiaryQuery>,
|
||||
@@ -18,18 +15,12 @@ pub struct GetLocalProfileDeps {
|
||||
pub instance: InstanceIdentity,
|
||||
}
|
||||
|
||||
/// The federated half of the former `GetProfileDeps` split. No `user`/`instance` —
|
||||
/// the federated handler builds identity from the resolved remote actor and never
|
||||
/// reads a local user row for this path.
|
||||
pub struct GetFederatedProfileStatsDeps {
|
||||
pub stats: Arc<dyn StatsRepository>,
|
||||
pub diary: Arc<dyn DiaryQuery>,
|
||||
pub social_query: Arc<dyn FollowGraphQuery>,
|
||||
}
|
||||
|
||||
/// Backs page-chrome data (email/role badge, pending-follow badge). See the error
|
||||
/// policy note on `get_page_viewer::execute`: this deliberately propagates errors
|
||||
/// rather than degrading internally — the caller decides chrome degrades.
|
||||
pub struct GetPageViewerDeps {
|
||||
pub user: Arc<dyn UserRepository>,
|
||||
pub follow_graph: Arc<dyn FollowGraphQuery>,
|
||||
@@ -82,9 +73,6 @@ pub struct AuthorizeAdminDeps {
|
||||
pub user: Arc<dyn UserRepository>,
|
||||
}
|
||||
|
||||
/// `Option` mirrors `Repositories::federated_profile` — genuine optional
|
||||
/// configuration (federation on/off), not a container-shape workaround. Same
|
||||
/// exemption as `Services::person_enrichment`.
|
||||
pub struct GetFederatedProfileDeps {
|
||||
pub federated_profile: Option<Arc<dyn FederatedProfileQuery>>,
|
||||
}
|
||||
|
||||
@@ -4,18 +4,6 @@ use uuid::Uuid;
|
||||
|
||||
use crate::users::deps::GetFederatedProfileDeps;
|
||||
|
||||
/// Looks up a federated (remote) profile by synthetic user id — the fallback
|
||||
/// path `get_user_profile` (`handlers/users.rs`) takes when the local-profile
|
||||
/// lookup comes back `NotFound`.
|
||||
///
|
||||
/// Federation being disabled (`deps.federated_profile` is `None`) collapses to
|
||||
/// `Ok(None)`, the same value a present-but-empty lookup would return. That's
|
||||
/// deliberate: the handler's `if let Ok(Some(fed)) = ...` treats "port absent",
|
||||
/// "call returned `Ok(None)`", and "call returned `Err`" identically — all three
|
||||
/// fall through to a 404 — and this use case must not make any of those three
|
||||
/// distinguishable to a caller that cannot act on the difference. An `Err` from
|
||||
/// the port is propagated unchanged; the swallow stays at the handler, exactly
|
||||
/// where it already was.
|
||||
pub async fn execute(
|
||||
deps: &GetFederatedProfileDeps,
|
||||
user_id: Uuid,
|
||||
|
||||
@@ -30,10 +30,6 @@ pub struct ProfileIdentity {
|
||||
pub actor_url: String,
|
||||
pub avatar_url: Option<String>,
|
||||
pub banner_url: Option<String>,
|
||||
/// Only the HTML profile handler reads this (it derives its "display name"
|
||||
/// from the email's local part, not from `username` — see
|
||||
/// `handlers/users.rs::get_user_profile_html`). Sourced from the same local
|
||||
/// `User` row as every other identity field.
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
//! Absorbs BOTH of `handlers/users.rs::get_profile_settings`'s repository calls:
|
||||
//! the user lookup (`repos.user.find_by_id`) and the profile_fields join
|
||||
//! (`repos.profile_fields.get_fields`) — plus the avatar/banner URL derivation via
|
||||
//! `InstanceIdentity`, following the same pattern `get_local_profile` uses.
|
||||
//!
|
||||
//! Error policy: profile fields are primary content for this page (it's the page
|
||||
//! whose entire job is editing them), not page chrome, so a failed join
|
||||
//! propagates as `Err` rather than silently degrading to an empty list.
|
||||
|
||||
use domain::{errors::DomainError, value_objects::UserId};
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -18,10 +9,6 @@ pub struct ProfileSettings {
|
||||
pub bio: Option<String>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub banner_url: Option<String>,
|
||||
/// Not in the brief's interface sketch, but the deleted handler code read
|
||||
/// `user.also_known_as()` and rendered it in `ProfileSettingsTemplate` — this
|
||||
/// use case absorbs that read too, or the settings page would silently stop
|
||||
/// showing it.
|
||||
pub also_known_as: Option<String>,
|
||||
pub fields: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
@@ -3,14 +3,6 @@ use crate::users::deps::GetFederatedProfileStatsDeps;
|
||||
use crate::users::get_federated_profile_stats;
|
||||
use crate::users::queries::{GetUserProfileQuery, ProfileView};
|
||||
|
||||
/// Mirrors exactly how `build_federated_profile_response`
|
||||
/// (`crates/presentation/src/handlers/users.rs`) calls `execute`: a `user_id` that
|
||||
/// has no row in the local `users` table (a federated/remote profile uses a
|
||||
/// synthetic id — see `FederatedProfileQuery`), `is_own_profile: false`,
|
||||
/// `include_remote: true`. Before ADR-0004's split this was the tolerant branch of
|
||||
/// the unified `get_profile`; now it's simply this function's only behavior — it
|
||||
/// never looks at the local `users` table at all, so there is nothing to be
|
||||
/// tolerant about.
|
||||
#[tokio::test]
|
||||
async fn succeeds_for_a_user_id_with_no_local_row() {
|
||||
let b = TestContextBuilder::new();
|
||||
|
||||
@@ -54,10 +54,6 @@ fn unknown_query(user_id: uuid::Uuid) -> GetUserProfileQuery {
|
||||
}
|
||||
}
|
||||
|
||||
/// `get_local_profile` is the local-only half of the former `get_profile` split
|
||||
/// (ADR-0004's closed wart). Unlike the old tolerant behavior, a user id with no
|
||||
/// local row must be `NotFound` here — the empty-string identity sentinel this
|
||||
/// replaces cannot be represented in `LocalProfileData` at all.
|
||||
#[tokio::test]
|
||||
async fn get_local_profile_is_not_found_for_unknown_user() {
|
||||
let b = TestContextBuilder::new();
|
||||
@@ -272,10 +268,6 @@ async fn populates_handle_and_actor_url_for_a_local_user() {
|
||||
let user = user_repo.find_by_email(&email).await.unwrap().unwrap();
|
||||
let uid = user.id().value();
|
||||
|
||||
// `InMemoryUserRepository::update_profile` now actually persists (previously a
|
||||
// no-op stub) — use it to give this test a real display_name/bio to assert,
|
||||
// rather than asserting `None` for a mapping that could just as easily be
|
||||
// wrong, inverted, or hardcoded.
|
||||
let update_deps = UpdateProfileDeps {
|
||||
user: user_repo.clone(),
|
||||
object_storage: b.object_storage.clone(),
|
||||
|
||||
@@ -34,9 +34,6 @@ async fn setup_user(b: &TestContextBuilder, email: &str, username: &str) -> uuid
|
||||
user.id().value()
|
||||
}
|
||||
|
||||
/// `get_page_viewer` absorbs `helpers.rs::build_page_context`'s inline pending-count
|
||||
/// computation. It must reuse `FollowGraphQuery::count_pending_followers` rather than
|
||||
/// re-deriving the count from raw follow rows.
|
||||
#[tokio::test]
|
||||
async fn get_page_viewer_reports_pending_follower_count() {
|
||||
let b = TestContextBuilder::new();
|
||||
|
||||
@@ -8,10 +8,6 @@ use crate::test_helpers::TestContextBuilder;
|
||||
use crate::users::deps::GetProfileSettingsDeps;
|
||||
use crate::users::get_profile_settings;
|
||||
|
||||
/// `get_profile_settings` absorbs BOTH of the handler's calls: the user lookup
|
||||
/// (`repos.user.find_by_id`) and the profile_fields join
|
||||
/// (`repos.profile_fields.get_fields`). This proves the join actually moved in,
|
||||
/// not just the user lookup.
|
||||
#[tokio::test]
|
||||
async fn get_profile_settings_includes_profile_fields() {
|
||||
let b = TestContextBuilder::new();
|
||||
|
||||
@@ -4,9 +4,6 @@ use crate::test_helpers::TestContextBuilder;
|
||||
use crate::users::deps::ResolveUsernameDeps;
|
||||
use crate::users::resolve_username_to_id;
|
||||
|
||||
/// `resolve_username_to_id` absorbs `handlers/users.rs::get_user_by_username`'s
|
||||
/// `repos.user.find_by_username()` call. Unknown usernames must resolve to `None`,
|
||||
/// not an error — the handler turns `None` into a 404, same as today.
|
||||
#[tokio::test]
|
||||
async fn resolve_username_to_id_returns_none_for_unknown() {
|
||||
let b = TestContextBuilder::new();
|
||||
|
||||
Reference in New Issue
Block a user