diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js index a4b53e891..a43c5fe7c 100644 --- a/src/i18n/en/index.js +++ b/src/i18n/en/index.js @@ -361,6 +361,7 @@ export default { list: 'List', basicData: 'Basic data', summary: 'Summary', + notifications: 'Notifications', }, list: { name: 'Name', @@ -394,6 +395,12 @@ export default { role: 'Role', sipExtension: 'Extension', }, + notificationsManager: { + activeNotifications: 'Active notifications', + availableNotifications: 'Available notifications', + subscribed: 'Subscribed to the notification', + unsubscribed: 'Unsubscribed from the notification', + }, imageNotFound: 'Image not found', }, wagon: { diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index cd052fe3f..6328c8f5d 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -361,6 +361,7 @@ export default { list: 'Listado', basicData: 'Datos básicos', summary: 'Resumen', + notifications: 'Notificaciones', }, list: { name: 'Nombre', @@ -394,6 +395,12 @@ export default { role: 'Rol', sipExtension: 'Extensión', }, + notificationsManager: { + activeNotifications: 'Notificaciones activas', + availableNotifications: 'Notificaciones disponibles', + subscribed: 'Se ha suscrito a la notificación', + unsubscribed: 'Se ha dado de baja de la notificación', + }, imageNotFound: 'No se ha encontrado la imagen', }, wagon: { diff --git a/src/pages/Worker/Card/WorkerNotificationsManager.vue b/src/pages/Worker/Card/WorkerNotificationsManager.vue new file mode 100644 index 000000000..13c9b3de2 --- /dev/null +++ b/src/pages/Worker/Card/WorkerNotificationsManager.vue @@ -0,0 +1,142 @@ + + diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index b1b67fd4d..17a937c64 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -11,7 +11,7 @@ export default { redirect: { name: 'WorkerMain' }, menus: { main: ['WorkerList'], - card: [], + card: ['WorkerNotificationsManager'], }, children: [ { @@ -42,9 +42,19 @@ export default { path: 'summary', meta: { title: 'summary', + icon: 'launch', }, component: () => import('src/pages/Worker/Card/WorkerSummary.vue'), }, + { + name: 'WorkerNotificationsManager', + path: 'notifications', + meta: { + title: 'notifications', + icon: 'notifications', + }, + component: () => import('src/pages/Worker/Card/WorkerNotificationsManager.vue'), + }, ], }, ], diff --git a/test/cypress/integration/workerNotificationsManager.spec.js b/test/cypress/integration/workerNotificationsManager.spec.js new file mode 100644 index 000000000..6c5aa21fb --- /dev/null +++ b/test/cypress/integration/workerNotificationsManager.spec.js @@ -0,0 +1,27 @@ +describe('WorkerNotificationsManager', () => { + beforeEach(() => { + const workerId = 1110; + cy.viewport(1280, 720); + cy.login('salesBoss'); + cy.visit(`/#/worker/${workerId}/notifications`); + }); + + it('should unsubscribe 2 notifications, check the unsubscription has been saved, subscribe to other one and should check the data has been saved', () => { + cy.get('.q-chip').should('have.length', 3); + cy.get('.q-toggle__thumb').eq(0).click(); + cy.get('.q-notification__message').should('have.text', 'Unsubscribed from the notification'); + cy.get('.q-chip > .q-icon').eq(0).click(); + + cy.reload(); + + cy.get('.q-chip').should('have.length', 1); + cy.get('.q-toggle__thumb').should('have.length', 3).eq(0).click(); + cy.get('.q-notification__message').should('have.text', 'Subscribed to the notification'); + cy.get('.q-toggle__thumb').should('have.length', 3).eq(1).click(); + cy.get('.q-notification__message').should('have.text', 'Subscribed to the notification'); + + cy.reload(); + + cy.get('.q-chip').should('have.length', 3); + }); +}); diff --git a/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js b/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js new file mode 100644 index 000000000..744346078 --- /dev/null +++ b/test/vitest/__tests__/pages/Worker/WorkerNotificationsManager.spec.js @@ -0,0 +1,100 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper, axios } from 'app/test/vitest/helper'; +import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue'; + +describe('WorkerNotificationsManager', () => { + let vm; + const entityId = 1110; + + beforeAll(() => { + vm = createWrapper(WorkerNotificationsManager, { + propsData: { + id: entityId, + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('fetch()', () => { + it('should fetch notification subscriptions and role mappings', async () => { + vi.spyOn(axios, 'get') + .mockResolvedValueOnce({ + data: [ + { + id: 1, + name: 'Name 1', + description: 'Description 1', + notificationFk: 1, + active: true + }, + ], + }); + await vm.fetch(); + + expect(axios.get).toHaveBeenCalledWith(`NotificationSubscriptions/${entityId}/getList`); + expect(vm.notifications).toEqual([ + { + id: 1, + notificationFk: 1, + name: 'Name 1', + description: 'Description 1', + active: true, + }, + ]); + }); + }); + + describe('disableNotification()', () => { + it('should disable the notification', async () => { + vi.spyOn(axios, 'delete').mockResolvedValue({ data: { count: 1 } }); + vi.spyOn(vm.quasar, 'notify'); + const subscriptionId = 1; + vm.notifications = [{ id: 1, active: true }]; + + await vm.disableNotification(vm.notifications[0]); + + expect(axios.delete).toHaveBeenCalledWith( + `NotificationSubscriptions/${subscriptionId}` + ); + expect(vm.notifications[0].id).toBeNull(); + expect(vm.notifications[0].id).toBeFalsy(); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'positive' }) + ); + }); + }); + + describe('toggleNotification()', () => { + it('should activate the notification', async () => { + vi.spyOn(axios, 'post').mockResolvedValue({ + data: { id: 1, notificationFk: 1 }, + }); + vm.notifications = [{ id: null, active: true, notificationFk: 1 }]; + + await vm.toggleNotification(vm.notifications[0]); + + expect(axios.post).toHaveBeenCalledWith('NotificationSubscriptions', { + notificationFk: 1, + userFk: entityId, + }); + expect(vm.notifications[0].id).toBe(1); + expect(vm.notifications[0].active).toBeTruthy(); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'positive' }) + ); + }); + + it('should disable the notification', async () => { + vi.spyOn(vm, 'disableNotification'); + vm.notifications = [{ id: 1, active: false, notificationFk: 1 }]; + + await vm.toggleNotification(vm.notifications[0]); + + expect(vm.notifications[0].id).toBe(null); + expect(vm.notifications[0].active).toBeFalsy(); + }); + }); +});