From 941e18d4997fd1fe0a423fdd5d99e9e37697ea4d Mon Sep 17 00:00:00 2001 From: Riya Dhawan Date: Fri, 27 Oct 2023 16:15:26 +0530 Subject: [PATCH] moved fireConfetti to execute-challenge-saga (#51938) --- .../components/completion-modal.test.tsx | 73 ++++++++++++++++++- .../components/completion-modal.tsx | 19 +---- .../redux/execute-challenge-saga.js | 11 ++- 3 files changed, 80 insertions(+), 23 deletions(-) diff --git a/client/src/templates/Challenges/components/completion-modal.test.tsx b/client/src/templates/Challenges/components/completion-modal.test.tsx index 3f17a48f380..1469a053c27 100644 --- a/client/src/templates/Challenges/components/completion-modal.test.tsx +++ b/client/src/templates/Challenges/components/completion-modal.test.tsx @@ -1,15 +1,48 @@ import React from 'react'; +import { runSaga } from 'redux-saga'; import { render } from '../../../../utils/test-utils'; import { getCompletedPercentage } from '../../../utils/get-completion-percentage'; import { fireConfetti } from '../../../utils/fire-confetti'; import { createStore } from '../../../redux/create-store'; +import { executeChallengeSaga } from '../redux/execute-challenge-saga'; +import { + challengeDataSelector, + challengeMetaSelector, + challengeTestsSelector, + isBuildEnabledSelector, + isBlockNewlyCompletedSelector +} from '../redux/selectors'; +import { buildChallenge, getTestRunner } from '../utils/build'; import CompletionModal from './completion-modal'; jest.mock('../../../analytics'); jest.mock('../../../utils/fire-confetti'); jest.mock('../../../components/ProgressBar'); +jest.mock('../redux/selectors'); +jest.mock('../utils/build'); const mockFireConfetti = fireConfetti as jest.Mock; +const mockTestRunner = jest.fn().mockReturnValue({ pass: true }); +const mockBuildEnabledSelector = isBuildEnabledSelector as jest.Mock; +const mockChallengeTestsSelector = challengeTestsSelector as jest.Mock; +const mockChallengeMetaSelector = challengeMetaSelector as jest.Mock; +const mockChallengeDataSelector = challengeDataSelector as jest.Mock; +const mockIsBlockNewlyCompletedSelector = + isBlockNewlyCompletedSelector as jest.Mock; +const mockBuildChallenge = buildChallenge as jest.Mock; +const mockGetTestRunner = getTestRunner as jest.Mock; +mockBuildEnabledSelector.mockReturnValue(true); +mockChallengeTestsSelector.mockReturnValue([ + { text: 'Test 1', testString: 'mock test code' } +]); +mockChallengeMetaSelector.mockReturnValue({ + challengeType: 'mock_challenge_type' +}); +mockChallengeDataSelector.mockReturnValue({ + challengeFiles: ['mock_challenge_files'] +}); +mockBuildChallenge.mockReturnValue({ challengeType: 'mock_challenge_type' }); +mockGetTestRunner.mockReturnValue(mockTestRunner); const completedChallengesIds = ['1', '3', '5'], currentBlockIds = ['1', '3', '5', '7'], @@ -21,7 +54,41 @@ describe('', () => { beforeEach(() => { mockFireConfetti.mockClear(); }); - test('should fire if certification project has been completed', () => { + test('should fire when block is completed', async () => { + const payload = { showCompletionModal: true }; + const store = createStore({ + challenge: { + modal: { completion: true }, + challengeMeta: { + id: 'bd7158d8c442eddfaeb5bd18', + certification: 'responsive-web-design' // Make sure the certification matches + } + } + }); + mockIsBlockNewlyCompletedSelector.mockReturnValue(true); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await runSaga(store, executeChallengeSaga, { payload }).done; + expect(mockFireConfetti).toHaveBeenCalledTimes(1); + }); + test('should not fire when block is not completed', async () => { + const payload = { showCompletionModal: true }; + const store = createStore({ + challenge: { + modal: { completion: true }, + challengeMeta: { + id: 'bd7158d8c442eddfaeb5bd18', + certification: 'responsive-web-design' // Make sure the certification matches + } + } + }); + mockIsBlockNewlyCompletedSelector.mockReturnValue(false); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await runSaga(store, executeChallengeSaga, { payload }).done; + expect(mockFireConfetti).toHaveBeenCalledTimes(0); + }); + test('should not fire if certification project has been completed', () => { const store = createStore({ challenge: { modal: { completion: true }, @@ -31,12 +98,10 @@ describe('', () => { } } }); - render(, store); - expect(mockFireConfetti).toHaveBeenCalledTimes(1); + expect(mockFireConfetti).toHaveBeenCalledTimes(0); }); - test('should NOT fire if the challenge is not a project', () => { const store = createStore({ challenge: { diff --git a/client/src/templates/Challenges/components/completion-modal.tsx b/client/src/templates/Challenges/components/completion-modal.tsx index c131df70666..40ea4aa6c34 100644 --- a/client/src/templates/Challenges/components/completion-modal.tsx +++ b/client/src/templates/Challenges/components/completion-modal.tsx @@ -28,8 +28,6 @@ import ProgressBar from '../../../components/ProgressBar'; import GreenPass from '../../../assets/icons/green-pass'; import './completion-modal.css'; -import { fireConfetti } from '../../../utils/fire-confetti'; -import { certsToProjects } from '../../../../config/cert-and-project-map'; const mapStateToProps = createSelector( challengeFilesSelector, @@ -81,11 +79,6 @@ interface CompletionModalState { downloadURL: null | string; } -const isCertificationProject = (id: string) => - Object.values(certsToProjects).some(cert => - cert.some(project => project.id === id) - ); - class CompletionModal extends Component< CompletionModalsProps, CompletionModalState @@ -157,26 +150,18 @@ class CompletionModal extends Component< const { close, isOpen, - id, isSignedIn, isSubmitting, message, t, dashedName, - submitChallenge, - completedChallengesIds + submitChallenge } = this.props; if (isOpen) { executeGA({ event: 'pageview', pagePath: '/completion-modal' }); - if ( - isCertificationProject(id) && - !completedChallengesIds.includes(id) && - !isSubmitting - ) { - fireConfetti(); - } } + return ( test.pass && !test.err); + const isBlockCompleted = yield select(isBlockNewlyCompletedSelector); if (challengeComplete) { playTone('tests-completed'); + if (isBlockCompleted) { + fireConfetti(); + } } else { playTone('tests-failed'); if (challengeMeta.certification === 'responsive-web-design') { @@ -141,6 +147,7 @@ function* executeChallengeSaga({ payload }) { ); } } + if (challengeComplete && payload?.showCompletionModal) { yield put(openModal('completion')); }