refactor: replace long arg lists with input/config structs and builder
- Thought::new_local → NewThought struct (7 args → 1) - UserWriter::update_profile → UpdateProfileInput struct (6 args → 2) - update_profile use case → UpdateProfileInput (8 args → 3) - ActivityPubService::new → builder pattern (9 args → 5 required + 4 optional setters) - accept_note → AcceptNoteInput struct (8 args → 1) - ThoughtNote::new_public → ThoughtNoteInput struct (8 args → 1) Remove all #[allow(clippy::too_many_arguments)] annotations.
This commit is contained in:
@@ -5,7 +5,7 @@ use async_trait::async_trait;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
models::thought::{Thought, Visibility},
|
||||
models::thought::{NewThought, Thought, Visibility},
|
||||
models::user::User,
|
||||
testing::TestStore,
|
||||
value_objects::*,
|
||||
@@ -92,15 +92,15 @@ fn alice() -> User {
|
||||
}
|
||||
|
||||
fn local_thought(author_id: UserId) -> Thought {
|
||||
Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
author_id,
|
||||
Content::new_local("hello").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: author_id,
|
||||
content: Content::new_local("hello").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn svc(store: &TestStore, spy: Arc<SpyPort>) -> FederationEventService {
|
||||
@@ -275,15 +275,15 @@ async fn boost_of_remote_thought_announces_remote_ap_id() {
|
||||
async fn direct_thought_created_does_not_broadcast() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("private").unwrap(),
|
||||
None,
|
||||
Visibility::Direct,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("private").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Direct,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.users.lock().unwrap().push(alice.clone());
|
||||
store.thoughts.lock().unwrap().push(thought.clone());
|
||||
|
||||
@@ -304,15 +304,15 @@ async fn direct_thought_created_does_not_broadcast() {
|
||||
async fn followers_only_thought_does_not_broadcast_publicly() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("for followers").unwrap(),
|
||||
None,
|
||||
Visibility::Followers,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("for followers").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Followers,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.users.lock().unwrap().push(alice.clone());
|
||||
store.thoughts.lock().unwrap().push(thought.clone());
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::*;
|
||||
use domain::{
|
||||
models::{
|
||||
notification::NotificationKind,
|
||||
thought::{Thought, Visibility},
|
||||
thought::{NewThought, Thought, Visibility},
|
||||
user::User,
|
||||
},
|
||||
testing::TestStore,
|
||||
@@ -24,15 +24,15 @@ async fn like_creates_notification_for_thought_author() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let bob_id = UserId::new();
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("hello").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("hello").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.thoughts.lock().unwrap().push(thought.clone());
|
||||
let svc = NotificationEventService {
|
||||
thoughts: Arc::new(store.clone()),
|
||||
@@ -54,15 +54,15 @@ async fn like_creates_notification_for_thought_author() {
|
||||
async fn self_like_creates_no_notification() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("hello").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("hello").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.thoughts.lock().unwrap().push(thought.clone());
|
||||
let svc = NotificationEventService {
|
||||
thoughts: Arc::new(store.clone()),
|
||||
@@ -103,15 +103,15 @@ async fn reply_creates_notification_for_original_author() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let bob_id = UserId::new();
|
||||
let original = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("original").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let original = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("original").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.thoughts.lock().unwrap().push(original.clone());
|
||||
let svc = NotificationEventService {
|
||||
thoughts: Arc::new(store.clone()),
|
||||
@@ -133,15 +133,15 @@ async fn reply_creates_notification_for_original_author() {
|
||||
async fn self_reply_creates_no_notification() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let original = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("original").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let original = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("original").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.thoughts.lock().unwrap().push(original.clone());
|
||||
let svc = NotificationEventService {
|
||||
thoughts: Arc::new(store.clone()),
|
||||
@@ -161,15 +161,15 @@ async fn self_reply_creates_no_notification() {
|
||||
async fn self_boost_creates_no_notification() {
|
||||
let store = TestStore::default();
|
||||
let alice = alice();
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("hello").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("hello").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
store.thoughts.lock().unwrap().push(thought.clone());
|
||||
let svc = NotificationEventService {
|
||||
thoughts: Arc::new(store.clone()),
|
||||
|
||||
@@ -95,14 +95,7 @@ impl ActivityPubRepository for TestApRepo {
|
||||
}
|
||||
async fn accept_note(
|
||||
&self,
|
||||
_ap_id: &str,
|
||||
_author_id: &UserId,
|
||||
_content: &str,
|
||||
_published: chrono::DateTime<chrono::Utc>,
|
||||
_sensitive: bool,
|
||||
_content_warning: Option<String>,
|
||||
_visibility: &str,
|
||||
_in_reply_to: Option<&str>,
|
||||
_input: activitypub_base::AcceptNoteInput<'_>,
|
||||
) -> Result<ThoughtId, DomainError> {
|
||||
Ok(ThoughtId::from_uuid(uuid::Uuid::new_v4()))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use domain::{
|
||||
events::DomainEvent,
|
||||
models::{
|
||||
feed::{PageParams, Paginated, UserSummary},
|
||||
user::User,
|
||||
user::{UpdateProfileInput, User},
|
||||
},
|
||||
ports::{AuthService, GeneratedToken, PasswordHasher, UserReader, UserWriter},
|
||||
testing::{NoOpEventPublisher, TestStore},
|
||||
@@ -56,22 +56,9 @@ impl UserWriter for ConflictOnSaveStore {
|
||||
async fn update_profile(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
display_name: Option<String>,
|
||||
bio: Option<String>,
|
||||
avatar_url: Option<String>,
|
||||
header_url: Option<String>,
|
||||
custom_css: Option<String>,
|
||||
input: UpdateProfileInput,
|
||||
) -> Result<(), DomainError> {
|
||||
self.0
|
||||
.update_profile(
|
||||
user_id,
|
||||
display_name,
|
||||
bio,
|
||||
avatar_url,
|
||||
header_url,
|
||||
custom_css,
|
||||
)
|
||||
.await
|
||||
self.0.update_profile(user_id, input).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,22 +101,9 @@ impl UserWriter for EmailConflictOnSaveStore {
|
||||
async fn update_profile(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
display_name: Option<String>,
|
||||
bio: Option<String>,
|
||||
avatar_url: Option<String>,
|
||||
header_url: Option<String>,
|
||||
custom_css: Option<String>,
|
||||
input: UpdateProfileInput,
|
||||
) -> Result<(), DomainError> {
|
||||
self.0
|
||||
.update_profile(
|
||||
user_id,
|
||||
display_name,
|
||||
bio,
|
||||
avatar_url,
|
||||
header_url,
|
||||
custom_css,
|
||||
)
|
||||
.await
|
||||
self.0.update_profile(user_id, input).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@ const MAX_TOP_FRIENDS: usize = 8;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
models::{top_friend::TopFriend, user::User},
|
||||
models::{
|
||||
top_friend::TopFriend,
|
||||
user::{UpdateProfileInput, User},
|
||||
},
|
||||
ports::{EventPublisher, TopFriendRepository, UserReader, UserWriter},
|
||||
value_objects::{UserId, Username},
|
||||
};
|
||||
@@ -41,27 +44,13 @@ pub async fn get_user_by_id_or_username(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn update_profile(
|
||||
users: &dyn UserWriter,
|
||||
events: &dyn EventPublisher,
|
||||
user_id: &UserId,
|
||||
display_name: Option<String>,
|
||||
bio: Option<String>,
|
||||
avatar_url: Option<String>,
|
||||
header_url: Option<String>,
|
||||
custom_css: Option<String>,
|
||||
input: UpdateProfileInput,
|
||||
) -> Result<(), DomainError> {
|
||||
users
|
||||
.update_profile(
|
||||
user_id,
|
||||
display_name,
|
||||
bio,
|
||||
avatar_url,
|
||||
header_url,
|
||||
custom_css,
|
||||
)
|
||||
.await?;
|
||||
users.update_profile(user_id, input).await?;
|
||||
events
|
||||
.publish(&DomainEvent::ProfileUpdated {
|
||||
user_id: user_id.clone(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::*;
|
||||
use domain::{
|
||||
models::{
|
||||
thought::{Thought, Visibility},
|
||||
thought::{NewThought, Thought, Visibility},
|
||||
user::User,
|
||||
},
|
||||
testing::TestStore,
|
||||
@@ -22,15 +22,19 @@ async fn like_and_unlike() {
|
||||
let store = TestStore::default();
|
||||
let alice = user("alice");
|
||||
let tid = ThoughtId::new();
|
||||
store.thoughts.lock().unwrap().push(Thought::new_local(
|
||||
tid.clone(),
|
||||
alice.id.clone(),
|
||||
Content::new_local("hi").unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
));
|
||||
store
|
||||
.thoughts
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Thought::new_local(NewThought {
|
||||
id: tid.clone(),
|
||||
user_id: alice.id.clone(),
|
||||
content: Content::new_local("hi").unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
}));
|
||||
like_thought(&store, &store, &alice.id, &tid).await.unwrap();
|
||||
assert_eq!(store.likes.lock().unwrap().len(), 1);
|
||||
unlike_thought(&store, &store, &alice.id, &tid)
|
||||
|
||||
@@ -3,7 +3,7 @@ use domain::{
|
||||
events::DomainEvent,
|
||||
models::{
|
||||
feed::{EngagementStats, FeedEntry},
|
||||
thought::{Thought, Visibility},
|
||||
thought::{NewThought, Thought, Visibility},
|
||||
},
|
||||
ports::{
|
||||
EngagementRepository, EventPublisher, OutboxWriter, TagRepository, ThoughtRepository,
|
||||
@@ -46,15 +46,15 @@ pub async fn create_thought(
|
||||
Some("direct") => Visibility::Direct,
|
||||
_ => Visibility::Public,
|
||||
};
|
||||
let thought = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
input.user_id,
|
||||
content.clone(),
|
||||
input.in_reply_to_id.clone(),
|
||||
let thought = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: input.user_id,
|
||||
content: content.clone(),
|
||||
in_reply_to_id: input.in_reply_to_id.clone(),
|
||||
visibility,
|
||||
input.content_warning,
|
||||
input.sensitive,
|
||||
);
|
||||
content_warning: input.content_warning,
|
||||
sensitive: input.sensitive,
|
||||
});
|
||||
thoughts.save(&thought).await?;
|
||||
|
||||
// Extract and attach hashtags from content.
|
||||
|
||||
@@ -222,7 +222,7 @@ async fn create_reply_sets_in_reply_to_id() {
|
||||
|
||||
// enrichment_tests (combined from second cfg(test) block)
|
||||
|
||||
use domain::models::thought::{Thought, Visibility};
|
||||
use domain::models::thought::{NewThought, Thought, Visibility};
|
||||
use domain::ports::{ThoughtRepository, UserWriter};
|
||||
|
||||
fn make_user() -> User {
|
||||
@@ -235,15 +235,15 @@ fn make_user() -> User {
|
||||
}
|
||||
|
||||
fn make_thought(user_id: UserId) -> Thought {
|
||||
Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id,
|
||||
Content::new_local(String::from("hello")).unwrap(),
|
||||
None,
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
content: Content::new_local(String::from("hello")).unwrap(),
|
||||
in_reply_to_id: None,
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
})
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -287,15 +287,15 @@ async fn get_thread_views_batches_correctly() {
|
||||
<TestStore as ThoughtRepository>::save(&store, &root)
|
||||
.await
|
||||
.unwrap();
|
||||
let reply = Thought::new_local(
|
||||
ThoughtId::new(),
|
||||
user.id.clone(),
|
||||
Content::new_local(String::from("reply")).unwrap(),
|
||||
Some(root.id.clone()),
|
||||
Visibility::Public,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let reply = Thought::new_local(NewThought {
|
||||
id: ThoughtId::new(),
|
||||
user_id: user.id.clone(),
|
||||
content: Content::new_local(String::from("reply")).unwrap(),
|
||||
in_reply_to_id: Some(root.id.clone()),
|
||||
visibility: Visibility::Public,
|
||||
content_warning: None,
|
||||
sensitive: false,
|
||||
});
|
||||
<TestStore as ThoughtRepository>::save(&store, &reply)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user