diff --git a/src/app/features/settings/notifications/constants/notifications-constants.ts b/src/app/features/settings/notifications/constants/notifications-constants.ts index 1988f384c..399e99dd0 100644 --- a/src/app/features/settings/notifications/constants/notifications-constants.ts +++ b/src/app/features/settings/notifications/constants/notifications-constants.ts @@ -12,3 +12,14 @@ export const SUBSCRIPTION_EVENTS: SubscriptionEventModel[] = [ labelKey: 'settings.notifications.notificationPreferences.items.preprints', }, ]; + +export const FORM_EVENT_TO_API_EVENT: Record = { + new_pending_submissions: 'new_pending_submissions', + files_updated: 'files_updated', + global_file_updated: 'global_file_updated', +}; + +export const API_EVENT_TO_FORM_EVENT: Record = { + new_pending_submissions: 'new_pending_submissions', + files_updated: 'global_file_updated', +}; diff --git a/src/app/features/settings/notifications/notifications.component.spec.ts b/src/app/features/settings/notifications/notifications.component.spec.ts index 20bbb53af..03950cb0c 100644 --- a/src/app/features/settings/notifications/notifications.component.spec.ts +++ b/src/app/features/settings/notifications/notifications.component.spec.ts @@ -41,13 +41,19 @@ describe('NotificationsComponent', () => { subscribeOsfHelpEmail: false, }; + // new_pending_submissions → global_reviews + // files_updated → global_file_updated const mockNotificationSubscriptions = [ - { id: 'id1', event: SubscriptionEvent.GlobalFileUpdated, frequency: SubscriptionFrequency.Daily }, { - id: 'id2', - event: SubscriptionEvent.GlobalFileUpdated, + id: 'osf_new_pending_submissions', + event: 'new_pending_submissions', frequency: SubscriptionFrequency.Instant, }, + { + id: 'cuzg4_global_file_updated', + event: 'files_updated', + frequency: SubscriptionFrequency.Daily, + }, ]; beforeEach(async () => { @@ -77,7 +83,7 @@ describe('NotificationsComponent', () => { return signal(null); }); - MOCK_STORE.dispatch.mockImplementation(() => of()); + MOCK_STORE.dispatch.mockReturnValue(of({})); await TestBed.configureTestingModule({ imports: [ @@ -116,9 +122,9 @@ describe('NotificationsComponent', () => { return signal(null); }); - component.emailPreferencesFormSubmit(); - expect(loaderService.hide).not.toHaveBeenCalled(); + component.emailPreferencesFormSubmit(); + expect(loaderService.hide).toHaveBeenCalledTimes(1); }); it('should handle subscription completion correctly', () => { @@ -136,11 +142,15 @@ describe('NotificationsComponent', () => { it('should call dispatch only once per subscription change', () => { const mockDispatch = jest.fn().mockReturnValue(of({})); MOCK_STORE.dispatch.mockImplementation(mockDispatch); - const event = SubscriptionEvent.GlobalFileUpdated; - const frequency = SubscriptionFrequency.Daily; - component.onSubscriptionChange(event, frequency); + component.onSubscriptionChange(SubscriptionEvent.GlobalFileUpdated, SubscriptionFrequency.Daily); expect(mockDispatch).toHaveBeenCalledTimes(1); }); + + it('should default to API value', () => { + const subs = component.notificationSubscriptionsForm.value; + expect(subs.new_pending_submissions).toBe(SubscriptionFrequency.Instant); + expect(subs.global_file_updated).toBe(SubscriptionFrequency.Daily); + }); }); diff --git a/src/app/features/settings/notifications/notifications.component.ts b/src/app/features/settings/notifications/notifications.component.ts index 327ae68ec..ab6d3d0a1 100644 --- a/src/app/features/settings/notifications/notifications.component.ts +++ b/src/app/features/settings/notifications/notifications.component.ts @@ -21,7 +21,7 @@ import { ToastService } from '@osf/shared/services/toast.service'; import { AccountSettings } from '../account-settings/models'; import { AccountSettingsSelectors, GetAccountSettings, UpdateAccountSettings } from '../account-settings/store'; -import { SUBSCRIPTION_EVENTS } from './constants'; +import { API_EVENT_TO_FORM_EVENT, FORM_EVENT_TO_API_EVENT, SUBSCRIPTION_EVENTS } from './constants'; import { EmailPreferencesForm, EmailPreferencesFormControls } from './models'; import { GetAllGlobalNotificationSubscriptions, @@ -80,7 +80,9 @@ export class NotificationsComponent implements OnInit { notificationSubscriptionsForm = this.fb.group( SUBSCRIPTION_EVENTS.reduce( (control, { event }) => { - control[event] = this.fb.control(SubscriptionFrequency.Never, { nonNullable: true }); + control[event as string] = this.fb.control(SubscriptionFrequency.Never, { + nonNullable: true, + }); return control; }, {} as Record> @@ -128,7 +130,24 @@ export class NotificationsComponent implements OnInit { onSubscriptionChange(event: SubscriptionEvent, frequency: SubscriptionFrequency) { const user = this.currentUser(); if (!user) return; - const id = `${user.id}_${event}`; + + const eventKey = event as unknown as string; + + const apiEventName = FORM_EVENT_TO_API_EVENT[eventKey] ?? eventKey; + + let id: string | undefined; + + if (event === SubscriptionEvent.GlobalReviews) { + const subs = this.notificationSubscriptions(); + const match = subs.find((s) => (s.event as string) === 'new_pending_submissions'); + if (match) { + id = match.id; + } else { + return; + } + } else { + id = `${user.id}_${apiEventName}`; + } this.loaderService.show(); this.actions.updateNotificationSubscription({ id, frequency }).subscribe(() => { @@ -145,10 +164,24 @@ export class NotificationsComponent implements OnInit { } private updateNotificationSubscriptionsForm() { + const subs = this.notificationSubscriptions(); + if (!subs?.length) { + return; + } + const patch: Record = {}; - for (const sub of this.notificationSubscriptions()) { - patch[sub.event] = sub.frequency; + for (const sub of subs) { + const apiEvent = sub.event as string | null; + if (!apiEvent) { + continue; + } + + const formEventKey = API_EVENT_TO_FORM_EVENT[apiEvent]; + + if (formEventKey) { + patch[formEventKey] = sub.frequency; + } } this.notificationSubscriptionsForm.patchValue(patch); diff --git a/src/app/shared/enums/subscriptions/subscription-event.enum.ts b/src/app/shared/enums/subscriptions/subscription-event.enum.ts index 3ce040bfe..c98ba610a 100644 --- a/src/app/shared/enums/subscriptions/subscription-event.enum.ts +++ b/src/app/shared/enums/subscriptions/subscription-event.enum.ts @@ -1,5 +1,5 @@ export enum SubscriptionEvent { GlobalFileUpdated = 'global_file_updated', - GlobalReviews = 'global_reviews', + GlobalReviews = 'new_pending_submissions', FileUpdated = 'file_updated', }