Skip to content

Commit e93174e

Browse files
committed
feat: update get notification parameter
1 parent 008b3aa commit e93174e

File tree

10 files changed

+167
-26
lines changed

10 files changed

+167
-26
lines changed
Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,72 @@
1+
export enum NotificationType {
2+
ASSIGNROLE = 'ASSIGNROLE',
3+
REVOKEROLE = 'REVOKEROLE',
4+
CREATEDV = 'CREATEDV',
5+
CREATEDS = 'CREATEDS',
6+
CREATEACC = 'CREATEACC',
7+
SUBMITTEDDS = 'SUBMITTEDDS',
8+
RETURNEDDS = 'RETURNEDDS',
9+
PUBLISHEDDS = 'PUBLISHEDDS',
10+
REQUESTFILEACCESS = 'REQUESTFILEACCESS',
11+
GRANTFILEACCESS = 'GRANTFILEACCESS',
12+
REJECTFILEACCESS = 'REJECTFILEACCESS',
13+
FILESYSTEMIMPORT = 'FILESYSTEMIMPORT',
14+
CHECKSUMIMPORT = 'CHECKSUMIMPORT',
15+
CHECKSUMFAIL = 'CHECKSUMFAIL',
16+
CONFIRMEMAIL = 'CONFIRMEMAIL',
17+
APIGENERATED = 'APIGENERATED',
18+
INGESTCOMPLETED = 'INGESTCOMPLETED',
19+
INGESTCOMPLETEDWITHERRORS = 'INGESTCOMPLETEDWITHERRORS',
20+
PUBLISHFAILED_PIDREG = 'PUBLISHFAILED_PIDREG',
21+
WORKFLOW_SUCCESS = 'WORKFLOW_SUCCESS',
22+
WORKFLOW_FAILURE = 'WORKFLOW_FAILURE',
23+
STATUSUPDATED = 'STATUSUPDATED',
24+
DATASETCREATED = 'DATASETCREATED',
25+
DATASETMENTIONED = 'DATASETMENTIONED',
26+
GLOBUSUPLOADCOMPLETED = 'GLOBUSUPLOADCOMPLETED',
27+
GLOBUSUPLOADCOMPLETEDWITHERRORS = 'GLOBUSUPLOADCOMPLETEDWITHERRORS',
28+
GLOBUSDOWNLOADCOMPLETED = 'GLOBUSDOWNLOADCOMPLETED',
29+
GLOBUSDOWNLOADCOMPLETEDWITHERRORS = 'GLOBUSDOWNLOADCOMPLETEDWITHERRORS',
30+
REQUESTEDFILEACCESS = 'REQUESTEDFILEACCESS',
31+
GLOBUSUPLOADREMOTEFAILURE = 'GLOBUSUPLOADREMOTEFAILURE',
32+
GLOBUSUPLOADLOCALFAILURE = 'GLOBUSUPLOADLOCALFAILURE',
33+
PIDRECONCILED = 'PIDRECONCILED'
34+
}
35+
36+
export interface RoleAssignment {
37+
id: number
38+
assignee: string
39+
definitionPointId: number
40+
roleId: number
41+
roleName: string
42+
_roleAlias: string
43+
}
44+
145
export interface Notification {
246
id: number
3-
type: string
4-
subjectText: string
5-
messageText: string
47+
type: NotificationType
48+
subjectText?: string
49+
messageText?: string
650
sentTimestamp: string
51+
displayAsRead?: boolean
52+
installationBrandName?: string
53+
userGuidesBaseUrl?: string
54+
userGuidesVersion?: string
55+
userGuidesSectionPath?: string
56+
roleAssignments?: RoleAssignment[]
57+
dataverseAlias?: string
58+
dataverseDisplayName?: string
59+
datasetPersistentIdentifier?: string
60+
datasetDisplayName?: string
61+
ownerPersistentIdentifier?: string
62+
ownerAlias?: string
63+
ownerDisplayName?: string
64+
requestorFirstName?: string
65+
requestorLastName?: string
66+
requestorEmail?: string
67+
dataFileId?: number
68+
dataFileDisplayName?: string
69+
currentCurationStatus?: string
70+
additionalInfo?: string
71+
objectDeleted?: boolean
772
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Notification } from '../models/Notification'
22

33
export interface INotificationsRepository {
4-
getAllNotificationsByUser(): Promise<Notification[]>
4+
getAllNotificationsByUser(inAppNotificationFormat?: boolean): Promise<Notification[]>
55
deleteNotification(notificationId: number): Promise<void>
66
}

src/notifications/domain/useCases/GetAllNotificationsByUser.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ export class GetAllNotificationsByUser implements UseCase<Notification[]> {
88
/**
99
* Use case for retrieving all notifications for the current user.
1010
*
11+
* @param inAppNotificationFormat - Optional parameter to retrieve fields needed for in-app notifications
1112
* @returns {Promise<Notification[]>} - A promise that resolves to an array of Notification instances.
1213
*/
13-
async execute(): Promise<Notification[]> {
14-
return (await this.notificationsRepository.getAllNotificationsByUser()) as Notification[]
14+
async execute(inAppNotificationFormat?: boolean): Promise<Notification[]> {
15+
return (await this.notificationsRepository.getAllNotificationsByUser(
16+
inAppNotificationFormat
17+
)) as Notification[]
1518
}
1619
}

src/notifications/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ const deleteNotification = new DeleteNotification(notificationsRepository)
99

1010
export { getAllNotificationsByUser, deleteNotification }
1111

12-
export { Notification } from './domain/models/Notification'
12+
export { Notification, NotificationType, RoleAssignment } from './domain/models/Notification'

src/notifications/infra/repositories/NotificationsRepository.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@ import { Notification } from '../../domain/models/Notification'
55
export class NotificationsRepository extends ApiRepository implements INotificationsRepository {
66
private readonly notificationsResourceName: string = 'notifications'
77

8-
public async getAllNotificationsByUser(): Promise<Notification[]> {
9-
return this.doGet(this.buildApiEndpoint(this.notificationsResourceName, 'all'), true)
8+
public async getAllNotificationsByUser(
9+
inAppNotificationFormat?: boolean
10+
): Promise<Notification[]> {
11+
const queryParams = inAppNotificationFormat ? { inAppNotificationFormat: 'true' } : undefined
12+
return this.doGet(
13+
this.buildApiEndpoint(this.notificationsResourceName, 'all'),
14+
true,
15+
queryParams
16+
)
1017
.then((response) => response.data.data.notifications as Notification[])
1118
.catch((error) => {
1219
throw error

test/environment/.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
POSTGRES_VERSION=17
22
DATAVERSE_DB_USER=dataverse
33
SOLR_VERSION=9.8.0
4-
DATAVERSE_IMAGE_REGISTRY=docker.io
5-
DATAVERSE_IMAGE_TAG=unstable
4+
DATAVERSE_IMAGE_REGISTRY=ghcr.io
5+
DATAVERSE_IMAGE_TAG=11648-notifications-api-extension
66
DATAVERSE_BOOTSTRAP_TIMEOUT=5m

test/functional/notifications/GetAllNotificationsByUser.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,20 @@ describe('execute', () => {
2525
expect(notifications[0]).toHaveProperty('type')
2626
expect(notifications[0]).toHaveProperty('sentTimestamp')
2727
})
28+
29+
test('should have correct in-app notification properties when inAppNotificationFormat is true', async () => {
30+
const notifications = await getAllNotificationsByUser.execute(true)
31+
32+
expect(notifications[0]).toHaveProperty('id')
33+
expect(notifications[0]).toHaveProperty('type')
34+
expect(notifications[0]).toHaveProperty('sentTimestamp')
35+
expect(notifications[0]).toHaveProperty('displayAsRead')
36+
expect(notifications[0]).toHaveProperty('roleAssignments')
37+
expect(notifications[0].roleAssignments).toBeDefined()
38+
expect(notifications[0].roleAssignments?.length).toBeGreaterThan(0)
39+
expect(notifications[0].roleAssignments?.[0]).toHaveProperty('roleName', 'Admin')
40+
expect(notifications[0].roleAssignments?.[0]).toHaveProperty('assignee', '@dataverseAdmin')
41+
expect(notifications[0].roleAssignments?.[0]).toHaveProperty('roleId', 1)
42+
expect(notifications[0].roleAssignments?.[0]).toHaveProperty('definitionPointId', 1)
43+
})
2844
})

test/integration/notifications/NotificationsRepository.test.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ import {
44
} from '../../../src/core/infra/repositories/ApiConfig'
55
import { TestConstants } from '../../testHelpers/TestConstants'
66
import { NotificationsRepository } from '../../../src/notifications/infra/repositories/NotificationsRepository'
7-
import { Notification } from '../../../src/notifications/domain/models/Notification'
8-
import { createDataset } from '../../../src/datasets'
9-
import { publishDatasetViaApi, waitForNoLocks } from '../../testHelpers/datasets/datasetHelper'
7+
import {
8+
Notification,
9+
NotificationType
10+
} from '../../../src/notifications/domain/models/Notification'
11+
import { createDataset, CreatedDatasetIdentifiers } from '../../../src/datasets'
12+
import {
13+
deletePublishedDatasetViaApi,
14+
publishDatasetViaApi,
15+
waitForNoLocks
16+
} from '../../testHelpers/datasets/datasetHelper'
1017
import { WriteError } from '../../../src'
1118

1219
describe('NotificationsRepository', () => {
1320
const sut: NotificationsRepository = new NotificationsRepository()
21+
let testDatasetIds: CreatedDatasetIdentifiers
1422

1523
beforeEach(() => {
1624
ApiConfig.init(
@@ -20,9 +28,13 @@ describe('NotificationsRepository', () => {
2028
)
2129
})
2230

31+
afterAll(async () => {
32+
await deletePublishedDatasetViaApi(testDatasetIds.persistentId)
33+
})
34+
2335
test('should return notifications after creating and publishing a dataset', async () => {
2436
// Create a dataset and publish it so that a notification of Dataset published is created
25-
const testDatasetIds = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
37+
testDatasetIds = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
2638

2739
await publishDatasetViaApi(testDatasetIds.numericId)
2840
await waitForNoLocks(testDatasetIds.numericId, 10)
@@ -32,7 +44,9 @@ describe('NotificationsRepository', () => {
3244
expect(Array.isArray(notifications)).toBe(true)
3345
expect(notifications.length).toBeGreaterThan(0)
3446

35-
const publishedNotification = notifications.find((n) => n.type === 'PUBLISHEDDS')
47+
const publishedNotification = notifications.find(
48+
(n) => n.type === NotificationType.PUBLISHEDDS
49+
) as Notification
3650

3751
expect(publishedNotification).toBeDefined()
3852

@@ -73,4 +87,30 @@ describe('NotificationsRepository', () => {
7387

7488
await expect(sut.deleteNotification(nonExistentNotificationId)).rejects.toThrow(expectedError)
7589
})
90+
91+
test('should return notifications with basic properties when inAppNotificationFormat is true', async () => {
92+
const notifications: Notification[] = await sut.getAllNotificationsByUser(true)
93+
94+
const notification = notifications[0]
95+
expect(notification).toHaveProperty('id')
96+
expect(notification).toHaveProperty('type')
97+
expect(notification.type).toBe(NotificationType.ASSIGNROLE)
98+
expect(notification).toHaveProperty('sentTimestamp')
99+
expect(notification).toHaveProperty('displayAsRead')
100+
expect(notification).toHaveProperty('dataverseDisplayName')
101+
102+
expect(notification).toHaveProperty('roleAssignments')
103+
expect(notification.roleAssignments).toBeDefined()
104+
expect(notification.roleAssignments?.length).toBeGreaterThan(0)
105+
expect(notification.roleAssignments?.[0]).toHaveProperty('roleName', 'Admin')
106+
expect(notification.roleAssignments?.[0]).toHaveProperty('assignee', '@dataverseAdmin')
107+
expect(notification.roleAssignments?.[0]).toHaveProperty('roleId', 1)
108+
expect(notification.roleAssignments?.[0]).toHaveProperty('definitionPointId', 1)
109+
})
110+
111+
test('should return array when inAppNotificationFormat is false', async () => {
112+
const notifications: Notification[] = await sut.getAllNotificationsByUser(false)
113+
114+
expect(Array.isArray(notifications)).toBe(true)
115+
})
76116
})

test/unit/notifications/DeleteNotification.test.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import { DeleteNotification } from '../../../src/notifications/domain/useCases/DeleteNotification'
22
import { INotificationsRepository } from '../../../src/notifications/domain/repositories/INotificationsRepository'
3-
import { Notification } from '../../../src/notifications/domain/models/Notification'
3+
import {
4+
Notification,
5+
NotificationType
6+
} from '../../../src/notifications/domain/models/Notification'
47

58
const mockNotifications: Notification[] = [
69
{
710
id: 1,
8-
type: 'PUBLISHEDDS',
11+
type: NotificationType.PUBLISHEDDS,
912
subjectText: 'Test notification',
1013
messageText: 'Test message',
11-
sentTimestamp: '2025-01-01T00:00:00Z'
14+
sentTimestamp: '2025-01-01T00:00:00Z',
15+
displayAsRead: false
1216
},
1317
{
1418
id: 2,
15-
type: 'ASSIGNROLE',
19+
type: NotificationType.ASSIGNROLE,
1620
subjectText: 'Role assignment',
1721
messageText: 'Role assigned',
18-
sentTimestamp: '2025-01-01T00:00:00Z'
22+
sentTimestamp: '2025-01-01T00:00:00Z',
23+
displayAsRead: false
1924
}
2025
]
2126

test/unit/notifications/GetAllNotificationsByUser.test.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import { GetAllNotificationsByUser } from '../../../src/notifications/domain/useCases/GetAllNotificationsByUser'
22
import { INotificationsRepository } from '../../../src/notifications/domain/repositories/INotificationsRepository'
3-
import { Notification } from '../../../src/notifications/domain/models/Notification'
3+
import {
4+
Notification,
5+
NotificationType
6+
} from '../../../src/notifications/domain/models/Notification'
47

58
const mockNotifications: Notification[] = [
69
{
710
id: 1,
8-
type: 'PUBLISHEDDS',
11+
type: NotificationType.PUBLISHEDDS,
912
subjectText: 'Test notification',
1013
messageText: 'Test message',
11-
sentTimestamp: '2025-01-01T00:00:00Z'
14+
sentTimestamp: '2025-01-01T00:00:00Z',
15+
displayAsRead: false
1216
},
1317
{
1418
id: 2,
15-
type: 'ASSIGNROLE',
19+
type: NotificationType.ASSIGNROLE,
1620
subjectText: 'Role assignment',
1721
messageText: 'Role assigned',
18-
sentTimestamp: '2025-01-01T00:00:00Z'
22+
sentTimestamp: '2025-01-01T00:00:00Z',
23+
displayAsRead: false
1924
}
2025
]
2126

0 commit comments

Comments
 (0)