From 228bf6225c4245711d100622799ba2f06ecd73e5 Mon Sep 17 00:00:00 2001 From: bouzuya Date: Thu, 8 Sep 2022 07:07:19 +0900 Subject: [PATCH] twiq: Add User::fetch_request --- twiq/crates/domain/src/aggregate/user.rs | 66 ++++++++++++++----- .../crates/domain/src/aggregate/user/event.rs | 47 +++++++++++-- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/twiq/crates/domain/src/aggregate/user.rs b/twiq/crates/domain/src/aggregate/user.rs index 860e579b..c708655a 100644 --- a/twiq/crates/domain/src/aggregate/user.rs +++ b/twiq/crates/domain/src/aggregate/user.rs @@ -8,11 +8,8 @@ use event_store_core::{ use self::{ event::{Event, UserCreated, UserFetchRequested, UserUpdated}, value::{ - at::At, - twitter_user_id::{self, TwitterUserId}, - twitter_user_name::TwitterUserName, - user_id::UserId, - version::Version, + at::At, twitter_user_id::TwitterUserId, twitter_user_name::TwitterUserName, + user_id::UserId, version::Version, }, }; @@ -24,8 +21,9 @@ pub type Result = std::result::Result; pub struct User { events: Vec, + fetch_requested_at: Option, twitter_user_id: TwitterUserId, - updated_at: At, + updated_at: Option, user_id: UserId, version: Version, } @@ -49,23 +47,47 @@ impl User { stream_seq, twitter_user_id.clone(), ))], + fetch_requested_at: None, twitter_user_id, - updated_at: at, + updated_at: None, user_id, version: Version::from(stream_seq), }) } - pub fn fetch_request(&mut self) -> Result<()> { - // TODO - self.events.push(Event::FetchRequested(UserFetchRequested)); + pub fn fetch_request(&mut self, at: At) -> Result<()> { + if let Some(fetch_requested_at) = self.fetch_requested_at { + if at <= fetch_requested_at.plus_1day() { + // TODo: error handling + return Err(Error); + } + } + let id = EventId::generate(); + let user_id = self.user_id; + let stream_id = EventStreamId::try_from(u128::from(user_id)).map_err(|_| { + // TODO: error handling + Error + })?; + let stream_seq = EventStreamSeq::from(u32::from(EventStreamSeq::from(self.version)) + 1); + self.events + .push(Event::FetchRequested(UserFetchRequested::new( + id, + at, + stream_id, + stream_seq, + self.twitter_user_id.clone(), + ))); + self.fetch_requested_at = Some(at); + self.version = Version::from(stream_seq); Ok(()) } pub fn update(&mut self, name: TwitterUserName, at: At) -> Result<()> { - if at <= self.updated_at { - // TODo: error handling - return Err(Error); + if let Some(updated_at) = self.updated_at { + if at <= updated_at { + // TODo: error handling + return Err(Error); + } } let id = EventId::generate(); let at = At::now(); @@ -83,6 +105,8 @@ impl User { self.twitter_user_id.clone(), name, ))); + self.updated_at = Some(at); + self.version = Version::from(stream_seq); Ok(()) } } @@ -103,16 +127,24 @@ mod tests { } #[test] - fn fetch_request_test() { - // TODO + fn fetch_request_test() -> anyhow::Result<()> { + let twitter_user_id = "123".parse::()?; + let mut user = User::create(twitter_user_id)?; + let at = At::now(); + user.fetch_request(at)?; + assert!(matches!(user.events[1], Event::FetchRequested(_))); + let at = At::now(); + assert!(user.fetch_request(at).is_err()); + assert_eq!(user.events.len(), 2); + Ok(()) } #[test] fn update_test() -> anyhow::Result<()> { - let twitter_user_id = "bouzuya".parse::()?; + let twitter_user_id = "123".parse::()?; let mut user = User::create(twitter_user_id)?; let at = At::now(); - let name = TwitterUserName::from_str("bouzuya2")?; + let name = TwitterUserName::from_str("bouzuya")?; user.update(name, at)?; assert!(matches!(user.events[1], Event::Updated(_))); Ok(()) diff --git a/twiq/crates/domain/src/aggregate/user/event.rs b/twiq/crates/domain/src/aggregate/user/event.rs index 4c241256..eb599ac9 100644 --- a/twiq/crates/domain/src/aggregate/user/event.rs +++ b/twiq/crates/domain/src/aggregate/user/event.rs @@ -2,11 +2,7 @@ use event_store_core::{ event_id::EventId, event_stream_id::EventStreamId, event_stream_seq::EventStreamSeq, }; -use super::value::{ - at::At, - twitter_user_id::TwitterUserId, - twitter_user_name::{self, TwitterUserName}, -}; +use super::value::{at::At, twitter_user_id::TwitterUserId, twitter_user_name::TwitterUserName}; #[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] pub struct UserCreated { @@ -35,7 +31,32 @@ impl UserCreated { } } -pub struct UserFetchRequested; +#[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] +pub struct UserFetchRequested { + id: String, + at: String, + stream_id: String, + stream_seq: u32, + twitter_user_id: String, +} + +impl UserFetchRequested { + pub(crate) fn new( + id: EventId, + at: At, + stream_id: EventStreamId, + stream_seq: EventStreamSeq, + twitter_user_id: TwitterUserId, + ) -> UserFetchRequested { + Self { + id: id.to_string(), + at: at.to_string(), + stream_id: stream_id.to_string(), + stream_seq: u32::from(stream_seq), + twitter_user_id: twitter_user_id.to_string(), + } + } +} #[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] pub struct UserUpdated { @@ -103,7 +124,19 @@ mod tests { #[test] fn user_fetch_requested_test() -> anyhow::Result<()> { - // TODO + let deserialized: UserFetchRequested = serde_json::from_str( + r#"{"id":"0ecb46f3-01a1-49b2-9405-0b4c40ecefe8","at":"2022-09-06T22:58:00.000000000Z","stream_id":"a748c956-7e53-45ef-b1f0-1c52676a467c","stream_seq":1,"twitter_user_id":"twitter_user_id1"}"#, + )?; + assert_eq!( + deserialized, + UserFetchRequested { + id: "0ecb46f3-01a1-49b2-9405-0b4c40ecefe8".to_owned(), + at: "2022-09-06T22:58:00.000000000Z".to_owned(), + stream_id: "a748c956-7e53-45ef-b1f0-1c52676a467c".to_owned(), + stream_seq: 1, + twitter_user_id: "twitter_user_id1".to_owned(), + } + ); Ok(()) }