diff --git a/assets/js/common/DismissableToast/DismissableToast.jsx b/assets/js/common/DismissableToast/DismissableToast.jsx index fa9cb18fa0..9036b716e4 100644 --- a/assets/js/common/DismissableToast/DismissableToast.jsx +++ b/assets/js/common/DismissableToast/DismissableToast.jsx @@ -1,14 +1,14 @@ import React from 'react'; import { toast } from 'react-hot-toast'; -function DismissableToast({ text, toastInstance }) { +function DismissableToast({ text, toastID }) { return (

{text}

diff --git a/assets/js/common/DismissableToast/DismissableToast.test.jsx b/assets/js/common/DismissableToast/DismissableToast.test.jsx new file mode 100644 index 0000000000..ba7b50ac9b --- /dev/null +++ b/assets/js/common/DismissableToast/DismissableToast.test.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { toast } from 'react-hot-toast'; +import { screen, render } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import userEvent from '@testing-library/user-event'; + +import DismissableToast from '.'; + +describe('DismissableToast component', () => { + afterEach(() => { + // restore the spy created with spyOn + jest.restoreAllMocks(); + }); + + it('renders the text and forward the onclick event with the provided prop id', async () => { + const spy = jest.spyOn(toast, 'dismiss'); + const toastID = 'toast-1'; + const user = userEvent.setup(); + + render(); + + expect(screen.getByText('test')).toBeVisible(); + await user.click(screen.getByText('Close')); + + expect(spy).toHaveBeenCalled(); + }); +}); diff --git a/assets/js/state/sagas/notifications.jsx b/assets/js/state/sagas/notifications.jsx index 6f09ccc0dc..f90a5696c7 100644 --- a/assets/js/state/sagas/notifications.jsx +++ b/assets/js/state/sagas/notifications.jsx @@ -9,29 +9,31 @@ import { } from '@state/notifications'; import DismissableToast from '@common/DismissableToast'; +const DEFAULT_DURATION = 4000; + export function* notification({ payload }) { - const { text, icon, id, duration } = payload; + const { id, text, icon, duration } = payload; toast(

{text}

, { position: 'top-right', icon, id, - duration: duration || 4000, + duration: duration || DEFAULT_DURATION, }); } export function* dismissableNotification({ payload }) { - const { text, icon, id, duration } = payload; - toast((t) => , { + const { id, text, icon, duration } = payload; + toast((t) => , { position: 'top-right', icon, id, - duration: duration || 4000, + duration: duration || DEFAULT_DURATION, }); } export function* dismissNotification({ payload }) { - const { notificationID } = payload; - toast.dismiss(notificationID); + const { id } = payload; + toast.dismiss(id); } export function* watchNotifications() { diff --git a/assets/js/state/sagas/settings.test.jsx b/assets/js/state/sagas/settings.test.jsx index 33317b2a19..7f740b42de 100644 --- a/assets/js/state/sagas/settings.test.jsx +++ b/assets/js/state/sagas/settings.test.jsx @@ -46,7 +46,7 @@ describe('Settings sagas', () => { expect(dispatched).toEqual([expectedAction]); }); - it('should dispatch an expires in dismissable notification if the api key expiration days are less then 30', async () => { + it('should dispatch a dismissable notification if the api key is to expire in less than 30 days', async () => { axiosMock.onGet('/api/v1/settings/api_key').reply( 200, apiKeySettingsFactory.build({ @@ -63,6 +63,7 @@ describe('Settings sagas', () => { }); expect(dispatched).toEqual([expectedAction]); }); + it('should not dispatch any action if the api key expiration days are more then 30', async () => { axiosMock.onGet('/api/v1/settings/api_key').reply( 200, diff --git a/test/e2e/cypress/e2e/settings.cy.js b/test/e2e/cypress/e2e/settings.cy.js index db7e1bfd77..a83144cb57 100644 --- a/test/e2e/cypress/e2e/settings.cy.js +++ b/test/e2e/cypress/e2e/settings.cy.js @@ -9,6 +9,7 @@ context('Settings page', () => { after(() => { cy.updateApiKeyExpiration(null); }); + describe('Api key expiration notifications', () => { it('should show api key expired notification when first loading the page, when the api key is expired', () => { cy.updateApiKeyExpiration(subDays(new Date(), 1));