diff --git a/core/notifications/src/account_notification_settings/entity.rs b/core/notifications/src/account_notification_settings/entity.rs index d7e47c0f1e..8766ba9e60 100644 --- a/core/notifications/src/account_notification_settings/entity.rs +++ b/core/notifications/src/account_notification_settings/entity.rs @@ -2,6 +2,8 @@ use derive_builder::Builder; use es_entity::*; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + use crate::primitives::*; #[derive(Debug, Serialize, Deserialize)] @@ -17,6 +19,14 @@ pub enum AccountNotificationSettingsEvent { ChannelEnabled { channel: NotificationChannel, }, + CategoryDisabled { + channel: NotificationChannel, + category: NotificationCategory, + }, + CategoryEnabled { + channel: NotificationChannel, + category: NotificationCategory, + }, } impl EntityEvent for AccountNotificationSettingsEvent { @@ -66,6 +76,54 @@ impl AccountNotificationSettings { _ => acc, }) } + + pub fn disable_category( + &mut self, + channel: NotificationChannel, + category: NotificationCategory, + ) { + if self.disabled_categories_for(channel).contains(&category) { + return; + } + self.events + .push(AccountNotificationSettingsEvent::CategoryDisabled { channel, category }); + } + + pub fn enable_category( + &mut self, + channel: NotificationChannel, + category: NotificationCategory, + ) { + if !self.disabled_categories_for(channel).contains(&category) { + return; + } + self.events + .push(AccountNotificationSettingsEvent::CategoryEnabled { channel, category }); + } + + pub fn disabled_categories_for( + &self, + channel: NotificationChannel, + ) -> HashSet { + self.events.iter().fold(HashSet::new(), |mut acc, event| { + match event { + AccountNotificationSettingsEvent::CategoryDisabled { + channel: c, + category, + } if c == &channel => { + acc.insert(*category); + } + AccountNotificationSettingsEvent::CategoryEnabled { + channel: c, + category, + } if c == &channel => { + acc.remove(category); + } + _ => (), + } + acc + }) + } } impl TryFrom> for AccountNotificationSettings { @@ -131,4 +189,40 @@ mod tests { settings.enable_channel(NotificationChannel::Push); assert!(settings.is_channel_enabled(NotificationChannel::Push)); } + + #[test] + fn no_categories_initially_disabled() { + let events = initial_events(); + let settings = AccountNotificationSettings::try_from(events).expect("Could not hydrate"); + assert_eq!( + settings.disabled_categories_for(NotificationChannel::Push), + HashSet::new(), + ); + } + + #[test] + fn can_disable_categories() { + let events = initial_events(); + let mut settings = + AccountNotificationSettings::try_from(events).expect("Could not hydrate"); + settings.disable_category(NotificationChannel::Push, NotificationCategory::Circles); + assert_eq!( + settings.disabled_categories_for(NotificationChannel::Push), + HashSet::from([NotificationCategory::Circles]) + ); + } + + #[test] + fn can_enable_categories() { + let events = initial_events(); + let mut settings = + AccountNotificationSettings::try_from(events).expect("Could not hydrate"); + settings.disable_category(NotificationChannel::Push, NotificationCategory::Circles); + settings.disable_category(NotificationChannel::Push, NotificationCategory::Payments); + settings.enable_category(NotificationChannel::Push, NotificationCategory::Circles); + assert_eq!( + settings.disabled_categories_for(NotificationChannel::Push), + HashSet::from([NotificationCategory::Payments]) + ); + } } diff --git a/core/notifications/src/graphql/convert.rs b/core/notifications/src/graphql/convert.rs index f75955e2a9..6f5dfe9adc 100644 --- a/core/notifications/src/graphql/convert.rs +++ b/core/notifications/src/graphql/convert.rs @@ -1,14 +1,16 @@ -use super::types::NotificationSettingsAlt; +use super::types::*; use crate::{account_notification_settings::*, primitives::*}; impl From for NotificationSettingsAlt { fn from(settings: AccountNotificationSettings) -> Self { - // NotificationSettingsAlt { - // push: NotificationChannelSettingsAlt { - // enabled: settings.is_channel_enabled(NotificationChannel::Push), - // disabled_categories: settings.dissabled_categories_for(NotificationChannel::Push), - // }, - // } - unimplemented!() + NotificationSettingsAlt { + push: NotificationChannelSettingsAlt { + enabled: settings.is_channel_enabled(NotificationChannel::Push), + disabled_categories: settings + .disabled_categories_for(NotificationChannel::Push) + .into_iter() + .collect(), + }, + } } } diff --git a/core/notifications/src/primitives.rs b/core/notifications/src/primitives.rs index 52e434ba00..eef63c087d 100644 --- a/core/notifications/src/primitives.rs +++ b/core/notifications/src/primitives.rs @@ -28,8 +28,9 @@ pub enum NotificationChannel { Push, } -#[derive(async_graphql::Enum, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)] +#[derive(async_graphql::Enum, Debug, Hash, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)] #[graphql(name = "NotificationCategoryAlt")] pub enum NotificationCategory { Circles, + Payments, }