From 76a99cadde93383f1d514fef9b43d91b87efcf82 Mon Sep 17 00:00:00 2001 From: Awais Ansari <79941147+awais-ansari@users.noreply.github.com> Date: Tue, 8 Jun 2021 23:17:35 +0500 Subject: [PATCH] test: add test cases for discussion topics (#129) * test: add test cases for discussion topics --- .../discussion-topics/DiscussionTopics.jsx | 1 - .../DiscussionTopics.test.jsx | 172 ++++++++++++++++++ .../shared/discussion-topics/TopicItem.jsx | 1 + 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.jsx index dc1f02e98..79b47f1b5 100644 --- a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.jsx +++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.jsx @@ -65,7 +65,6 @@ const DiscussionTopics = ({ intl }) => { onDelete={() => handleTopicDelete(index, topic.id, remove)} /> )) - }
diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx new file mode 100644 index 000000000..726926859 --- /dev/null +++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx @@ -0,0 +1,172 @@ +import React from 'react'; +import { + act, + queryByLabelText, + queryByText, + render, + fireEvent, +} from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; +import { initializeMockApp } from '@edx/frontend-platform'; +import { AppProvider } from '@edx/frontend-platform/react'; +import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import MockAdapter from 'axios-mock-adapter'; +import { Formik } from 'formik'; +import userEvent from '@testing-library/user-event'; + +import DiscussionTopics from './DiscussionTopics'; +import initializeStore from '../../../../../../store'; +import { getAppsUrl } from '../../../../data/api'; +import { fetchApps } from '../../../../data/thunks'; +import executeThunk from '../../../../../../utils'; +import { legacyApiResponse } from '../../../../factories/mockApiResponses'; + +const appConfig = { + id: 'legacy', + divideByCohorts: false, + divideCourseTopicsByCohorts: false, + discussionTopics: [ + { name: 'General', id: 'course' }, + { name: 'Edx', id: '13f106c6-6735-4e84-b097-0456cff55960' }, + ], + divideDiscussionIds: [], + allowAnonymousPosts: false, + allowAnonymousPostsPeers: false, + allowDivisionByUnit: false, + blackoutDates: '[]', +}; + +const courseId = 'course-v1:edX+TestX+Test_Course'; + +describe('DiscussionTopics', () => { + let axiosMock; + let store; + let container; + + beforeEach(() => { + initializeMockApp({ + authenticatedUser: { + userId: 3, + username: 'abc123', + administrator: true, + roles: [], + }, + }); + + axiosMock = new MockAdapter(getAuthenticatedHttpClient()); + store = initializeStore(); + }); + + afterEach(() => { + axiosMock.reset(); + }); + + const createComponent = (data) => { + const wrapper = render( + + + + + + + , + ); + container = wrapper.container; + }; + + const mockStore = async (mockResponse) => { + axiosMock.onGet(getAppsUrl(courseId)).reply(200, mockResponse); + await executeThunk(fetchApps(courseId), store.dispatch); + }; + + test('displays a collapsible card for each discussion topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + + expect(container.querySelectorAll('.collapsible-card')).toHaveLength(2); + + expect(container.querySelector('[id="course"]')).toBeInTheDocument(); + expect(container.querySelector('[id="13f106c6-6735-4e84-b097-0456cff55960"]')).toBeInTheDocument(); + }); + + test('displays collapse view of general discussion topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + + const generalTopicNode = container.querySelector('[id="course"]'); + + expect(generalTopicNode.querySelector('button[aria-label="Expand"]')).toBeInTheDocument(); + expect(generalTopicNode.querySelector('button[aria-label="Collapse"]')).not.toBeInTheDocument(); + expect(queryByText(generalTopicNode, 'General')).toBeInTheDocument(); + }); + + test('displays collapse view of additional discussion topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + + const topicNode = container.querySelector('[id="13f106c6-6735-4e84-b097-0456cff55960"]'); + + expect(topicNode.querySelector('button[aria-label="Expand"]')).toBeInTheDocument(); + expect(topicNode.querySelector('button[aria-label="Collapse"]')).not.toBeInTheDocument(); + expect(queryByText(topicNode, 'Edx')).toBeInTheDocument(); + }); + + test('displays expand view of general discussion topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + const generalTopicNode = container.querySelector('[id="course"]'); + + userEvent.click(queryByLabelText(generalTopicNode, 'Expand')); + + expect(generalTopicNode.querySelector('button[aria-label="Collapse"]')).toBeInTheDocument(); + expect(generalTopicNode.querySelector('button[aria-label="Expand"]')).not.toBeInTheDocument(); + expect(generalTopicNode.querySelector('button[aria-label="Delete Topic"]')).not.toBeInTheDocument(); + expect(generalTopicNode.querySelector('input')).toBeInTheDocument(); + }); + + test('displays expand view of additional discussion topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + const topicNode = container.querySelector('[id="13f106c6-6735-4e84-b097-0456cff55960"]'); + + userEvent.click(queryByLabelText(topicNode, 'Expand')); + + expect(topicNode.querySelector('button[aria-label="Expand"]')).not.toBeInTheDocument(); + expect(topicNode.querySelector('button[aria-label="Collapse"]')).toBeInTheDocument(); + expect(topicNode.querySelector('button[aria-label="Delete Topic"]')).toBeInTheDocument(); + expect(topicNode.querySelector('input')).toBeInTheDocument(); + }); + + test('displays updated discussion topic list after delete an additional topic', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + const topicNode = container.querySelector('[id= "13f106c6-6735-4e84-b097-0456cff55960"]'); + + userEvent.click(queryByLabelText(topicNode, 'Expand')); + userEvent.click(queryByLabelText(topicNode, 'Delete Topic')); + + expect(container.querySelectorAll('.card')).toHaveLength(1); + + await act(async () => { + userEvent.click(container.querySelector('.btn-outline-brand')); + }); + + expect(container.querySelectorAll('.collapsible-card')).toHaveLength(1); + }); + + test('updates discussion topic name', async () => { + await mockStore(legacyApiResponse); + createComponent(appConfig); + const topicNode = container.querySelector('[id= "13f106c6-6735-4e84-b097-0456cff55960"]'); + + userEvent.click(queryByLabelText(topicNode, 'Expand')); + await act(async () => { + fireEvent.change(topicNode.querySelector('input'), { target: { value: 'new name' } }); + }); + userEvent.click(queryByLabelText(topicNode, 'Collapse')); + + expect(queryByText(topicNode, 'new name')).toBeInTheDocument(); + }); +}); diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/TopicItem.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/TopicItem.jsx index d4aa11b6a..d6e892cdf 100644 --- a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/TopicItem.jsx +++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/TopicItem.jsx @@ -107,6 +107,7 @@ const TopicItem = ({ className="collapsible-card rounded mb-3 px-3 py-2" onToggle={handleToggle} defaultOpen={!title} + id={id} >