Website : rimsha.abasa.com
backdoor
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
canvas
/
ui
/
features
/
discussion_topics_index
/
react
/
__tests__
/
Filename :
actionsSpec.js
back
Copy
/* * Copyright (C) 2018 - present Instructure, Inc. * * This file is part of Canvas. * * Canvas is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, version 3 of the License. * * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ import actions from '../actions' import * as apiClient from '../apiClient' import $ from 'jquery' import 'jquery-migrate' import '@canvas/rails-flash-notifications' function getState() { return [{id: 1}, {id: 2, shouldGetFocus: true}] } let sandbox = [] const mockApiClient = (method, res) => { sandbox.push(sinon.createSandbox()) sandbox[sandbox.length - 1].stub(apiClient, method).returns(res) } const mockSuccess = (method, data = {}) => mockApiClient(method, Promise.resolve(data)) const mockFail = (method, err = new Error('Request Failed')) => mockApiClient(method, Promise.reject(err)) QUnit.module('Discussions redux actions', { teardown() { sandbox.forEach(mock => mock.restore()) sandbox = [] }, }) test('updateDiscussion dispatches UPDATE_DISCUSSION_SUCCESS', assert => { const done = assert.async() mockSuccess('updateDiscussion', {data: {locked: false, pinned: true}}) const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: false, locked: false} const updateFields = {pinned: true} const dispatchSpy = sinon.spy() actions.updateDiscussion(discussion, updateFields, {})(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: { locked: false, pinned: true, }, }, type: 'UPDATE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('updateDiscussion calls apiClient.updateDiscussion', () => { const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: true, locked: true} const updateFields = {pinned: false} const dispatchSpy = sinon.spy() mockSuccess('updateDiscussion', {}) actions.updateDiscussion(discussion, updateFields, {})(dispatchSpy, () => state) deepEqual(apiClient.updateDiscussion.firstCall.args[1], discussion) deepEqual(apiClient.updateDiscussion.firstCall.args[2], updateFields) }) test('updateDiscussion dispatches UPDATE_DISCUSSION_FAIL if promise fails', assert => { const done = assert.async() const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: true, locked: false} const updateFields = {locked: true} const dispatchSpy = sinon.spy() mockFail('updateDiscussion', 'something bad happened') actions.updateDiscussion(discussion, updateFields, {})(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { err: 'something bad happened', message: 'Updating discussion failed', }, type: 'UPDATE_DISCUSSION_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('updateDiscussion calls screenReaderFlash if successful and success message present', assert => { const done = assert.async() const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: true, locked: false} const updateFields = {locked: true} const flashMessages = {successMessage: 'success message'} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('updateDiscussion', {}) actions.updateDiscussion(discussion, updateFields, flashMessages)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['success message']) flashStub.restore() done() }) }) test('updateDiscussion does not call screenReaderFlash if successful and no success message present', assert => { const done = assert.async() const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: true, locked: false} const updateFields = {locked: true} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('updateDiscussion', {}) actions.updateDiscussion(discussion, updateFields, {})(dispatchSpy, () => state) setTimeout(() => { equal(flashStub.callCount, 0) flashStub.restore() done() }) }) test('updateDiscussion calls screenReaderFlash if unsuccessful with custom flash message', assert => { const done = assert.async() const state = {discussions: {pages: {1: {items: []}}, currentPage: 1}} const discussion = {pinned: true, locked: false} const updateFields = {locked: true} const flashMessages = {failMessage: 'fail message'} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockFail('updateDiscussion', 'badness occurres') actions.updateDiscussion(discussion, updateFields, flashMessages)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['fail message']) flashStub.restore() done() }) }) test('handleDrop throws exception if updating a field that does not exist on the discussion', assert => { const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } const discussion = {pinned: true, locked: false} const updateFields = {foobar: true} const dispatchSpy = sinon.spy() assert.throws(() => { actions.handleDrop(discussion, updateFields, {})(dispatchSpy, () => state) }, 'field foobar does not exist in the discussion') }) test('handleDrop dispatches DRAG_AND_DROP_START', assert => { const done = assert.async() mockSuccess('updateDiscussion', {}) mockSuccess('reorderPinnedDiscussions', {}) const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } actions.handleDrop({id: 1, pinned: false}, {pinned: true}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 1, pinned: true}, order: [1, 2], }, type: 'DRAG_AND_DROP_START', }, ] deepEqual(dispatchSpy.firstCall.args, expected) done() }) }) test('handleDrop dispatches DRAG_AND_DROP_SUCCESS if no api calls fail', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockSuccess('updateDiscussion', {}) mockSuccess('reorderPinnedDiscussions', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: true}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { deepEqual(dispatchSpy.secondCall.args, [{type: 'DRAG_AND_DROP_SUCCESS'}]) done() }) }) test('handleDrop dispatches DRAG_AND_DROP_FAIL if updateDiscussion api call fails', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockFail('updateDiscussion', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: true}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { order: [2], discussion: { id: 1, pinned: false, }, err: {}, message: 'Failed to update discussion', }, type: 'DRAG_AND_DROP_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('handleDrop dispatches DRAG_AND_DROP_FAIL if reorderPinnedDiscussions api call fails', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockSuccess('updateDiscussion', {}) mockFail('reorderPinnedDiscussions', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: true}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { order: [2, 1], discussion: { id: 1, pinned: true, }, err: {}, message: 'Failed to update discussion', }, type: 'DRAG_AND_DROP_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('handleDrop calls reorderPinnedDiscussions if pinned and order present', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockSuccess('updateDiscussion', {}) mockSuccess('reorderPinnedDiscussions', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: true}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { deepEqual(apiClient.reorderPinnedDiscussions.firstCall.args[1], [1, 2]) done() }) }) test('handleDrop does not call reorderPinnedDiscussions if discussion is not pinned', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockSuccess('updateDiscussion', {}) mockSuccess('reorderPinnedDiscussions', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: false}, [1, 2])(dispatchSpy, () => state) setTimeout(() => { deepEqual(apiClient.reorderPinnedDiscussions.called, false) done() }) }) test('handleDrop does not call reorderPinnedDiscussions if ordering not present', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const state = { allDiscussions: { 1: {id: 1, pinned: false}, 2: {id: 2, pinned: true}, }, pinnedDiscussionIds: [2], unpinnedDiscussionIds: [1], closedForCommentsDiscussions: [], } mockSuccess('updateDiscussion', {}) mockSuccess('reorderPinnedDiscussions', {}) actions.handleDrop({id: 1, pinned: false}, {pinned: true})(dispatchSpy, () => state) setTimeout(() => { deepEqual(apiClient.reorderPinnedDiscussions.called, false) done() }) }) test('does not call the API if the discussion has a subscription_hold', () => { const dispatchSpy = sinon.spy() const discussion = {subscription_hold: 'test hold'} actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) equal(dispatchSpy.callCount, 0) }) test('calls unsubscribeFromTopic if the discussion is currently subscribed', () => { const dispatchSpy = sinon.spy() const discussion = {id: 1, subscribed: true} mockSuccess('unsubscribeFromTopic', {}) actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) equal(apiClient.unsubscribeFromTopic.callCount, 1) deepEqual(apiClient.unsubscribeFromTopic.firstCall.args, [getState(), discussion]) }) test('calls subscribeToTopic if the discussion is currently unsubscribed', () => { const dispatchSpy = sinon.spy() const discussion = {id: 1, subscribed: false} mockSuccess('subscribeToTopic', {}) actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) equal(apiClient.subscribeToTopic.callCount, 1) deepEqual(apiClient.subscribeToTopic.firstCall.args, [getState(), discussion]) }) test('dispatches toggleSubscribeSuccess with unsubscription status if currently subscribed', assert => { const dispatchSpy = sinon.spy() const done = assert.async() const discussion = {id: 1, subscribed: true} mockSuccess('unsubscribeFromTopic', {}) actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) setTimeout(() => { const expectedArgs = [ { payload: {id: 1, subscribed: false}, type: 'TOGGLE_SUBSCRIBE_SUCCESS', }, ] deepEqual(dispatchSpy.secondCall.args, expectedArgs) done() }) }) test('dispatches toggleSubscribeSuccess with subscription status if currently unsubscribed', assert => { const dispatchSpy = sinon.spy() const done = assert.async() const discussion = {id: 1, subscribed: false} mockSuccess('subscribeToTopic', {}) actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) setTimeout(() => { const expectedArgs = [ { payload: {id: 1, subscribed: true}, type: 'TOGGLE_SUBSCRIBE_SUCCESS', }, ] deepEqual(dispatchSpy.secondCall.args, expectedArgs) done() }) }) test('dispatches toggleSubscribeFail in an error occures on the API call', assert => { const dispatchSpy = sinon.spy() const done = assert.async() const flashStub = sinon.spy($, 'screenReaderFlashMessageExclusive') const discussion = {id: 1, subscribed: false} mockFail('subscribeToTopic', 'test error message') actions.toggleSubscriptionState(discussion)(dispatchSpy, getState) setTimeout(() => { const expectedArgs = [ { payload: {message: 'Subscribe failed', err: 'test error message'}, type: 'TOGGLE_SUBSCRIBE_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expectedArgs) deepEqual(flashStub.firstCall.args, ['Subscribe failed']) flashStub.restore() done() }) }) test('saveSettings dispatches SAVING_SETTINGS_START', assert => { const done = assert.async() mockSuccess('saveUserSettings', {}) mockSuccess('saveCourseSettings', {}) const courseSettings = { allow_student_discussion_topics: true, allow_student_forum_attachments: true, allow_student_discussion_editing: true, grading_standard_enabled: false, grading_standard_id: null, allow_student_organized_groups: true, hide_final_grades: false, hide_distribution_graphs: false, lock_all_announcements: true, restrict_student_past_view: false, restrict_student_future_view: false, show_announcements_on_home_page: false, home_page_announcement_limit: 3, image_url: null, image_id: null, image: null, } const userSettings = { manual_mark_as_read: false, collapse_global_nav: false, } const state = {contextId: '1', currentUserId: '1', userSettings} const dispatchSpy = sinon.spy() actions.saveSettings(userSettings, courseSettings)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { type: 'SAVING_SETTINGS_START', }, ] deepEqual(dispatchSpy.firstCall.args, expected) done() }) }) test('saveSettings calls screenReaderFlash if successful with only user settings', assert => { const done = assert.async() const userSettings = { markAsRead: false, collapse_global_nav: false, } const state = {contextId: '1', currentUserId: '1', userSettings} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('saveUserSettings', {}) actions.saveSettings(userSettings)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['Saved discussion settings successfully']) flashStub.restore() done() }) }) test('saveSettings calls screenReaderFlash if successful with course settings', assert => { const done = assert.async() const userSettings = { markAsRead: false, collapse_global_nav: false, } const courseSettings = { allow_student_discussion_topics: true, allow_student_forum_attachments: true, allow_student_discussion_editing: true, grading_standard_enabled: false, grading_standard_id: null, allow_student_organized_groups: true, hide_final_grades: false, } const state = {contextId: '1', currentUserId: '1', userSettings} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('saveUserSettings', {}) mockSuccess('saveCourseSettings', {}) actions.saveSettings(userSettings, courseSettings)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['Saved discussion settings successfully']) flashStub.restore() done() }) }) test('saveSettings calls screenReaderFlash if failed with course settings', assert => { const done = assert.async() const userSettings = { markAsRead: false, collapse_global_nav: false, } const courseSettings = { allow_student_discussion_topics: true, allow_student_forum_attachments: true, allow_student_discussion_editing: true, grading_standard_enabled: false, grading_standard_id: null, allow_student_organized_groups: true, hide_final_grades: false, } const state = {contextId: '1', currentUserId: '1', userSettings} const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('saveUserSettings', {}) mockFail('saveCourseSettings', {}) actions.saveSettings(userSettings, courseSettings)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['Error saving discussion settings']) flashStub.restore() done() }) }) test('calls api for duplicating if requested', () => { const dispatchSpy = sinon.spy() mockSuccess('duplicateDiscussion', {}) actions.duplicateDiscussion(1)(dispatchSpy, getState) equal(apiClient.duplicateDiscussion.callCount, 1) deepEqual(apiClient.duplicateDiscussion.firstCall.args, [getState(), 1]) }) test('dispatches duplicateDiscussionSuccess if api call succeeds', assert => { const dispatchSpy = sinon.spy() const done = assert.async() mockSuccess('duplicateDiscussion', {data: {id: 3}}) actions.duplicateDiscussion(1)(dispatchSpy, getState) setTimeout(() => { const expectedArgs = [ { payload: {originalId: 1, newDiscussion: {id: 3, focusOn: 'title'}}, type: 'DUPLICATE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.secondCall.args, expectedArgs) done() }) }) test('dispatches duplicateDiscussionFail if api call fails', assert => { const dispatchSpy = sinon.spy() const done = assert.async() const discussion = {id: 1} mockFail('duplicateDiscussion', 'YOU FAILED, YOU IDIOT') actions.duplicateDiscussion(discussion.id)(dispatchSpy, getState) setTimeout(() => { const expectedArgs = [ { payload: {message: 'Duplication failed', err: 'YOU FAILED, YOU IDIOT'}, type: 'DUPLICATE_DISCUSSION_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expectedArgs) done() }) }) test('searchDiscussions dispatches UPDATE_DISCUSSIONS_SEARCH', () => { const dispatchSpy = sinon.spy() const state = { allDiscussions: {}, pinnedDiscussionIds: [], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } actions.searchDiscussions({searchTerm: 'foobar', filter: 'unread'})(dispatchSpy, () => state) const expected = [ { payload: { searchTerm: 'foobar', filter: 'unread', }, type: 'UPDATE_DISCUSSIONS_SEARCH', }, ] deepEqual(dispatchSpy.firstCall.args, expected) }) test('searchDiscussions announces number of results found to screenreader', assert => { const done = assert.async() const dispatchSpy = sinon.spy() const flashStub = sinon.spy($, 'screenReaderFlashMessageExclusive') const state = { allDiscussions: { 1: {id: 1, filtered: true}, 2: {id: 2, filtered: false}, 3: {id: 3, filtered: true}, 4: {id: 4, filtered: false}, 5: {id: 5, filtered: true}, 6: {id: 6, filtered: false}, }, pinnedDiscussions: [1, 2], unpinnedDiscussions: [3, 4], closedForCommentsDiscussions: [5, 6], } actions.searchDiscussions({searchTerm: 'foobar', filter: 'unread'})(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['3 discussions found.']) flashStub.restore() done() }) }) test('deleteDiscussion dispatches DELETE_DISCUSSION_SUCCESS on success', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 1}, nextFocusDiscussion: { focusId: undefined, focusOn: undefined, }, }, type: 'DELETE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.thirdCall.args, expected) done() }) }) test('deleteDiscussion dispatches DELETE_FOCUS_PENDING on success', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { type: 'DELETE_FOCUS_PENDING', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('deleteDiscussion dispatches DELETE_DISCUSSION_FAIL on failure', assert => { const done = assert.async() mockFail('deleteDiscussion', 'test_error') const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1, title: 'foo'} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { message: 'Failed to delete discussion foo', discussion: {id: 1, title: 'foo'}, err: 'test_error', }, type: 'DELETE_DISCUSSION_FAIL', }, ] deepEqual(dispatchSpy.secondCall.args, expected) done() }) }) test('deleteDiscussion calls screenReaderFlash on success', assert => { const done = assert.async() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1, title: 'foo'} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['Successfully deleted discussion foo']) flashStub.restore() done() }) }) test('deleteDiscussion calls screenReaderFlash on failure', assert => { const done = assert.async() const flashStub = sinon.spy($, 'screenReaderFlashMessage') mockFail('deleteDiscussion', 'test_error') const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1, title: 'foo'} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { deepEqual(flashStub.firstCall.args, ['Failed to delete discussion foo']) flashStub.restore() done() }) }) test('deleteDiscussion does not set focusOn if collection is empty after delete', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: {1: {id: 1}}, pinnedDiscussionIds: [1], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 1}, nextFocusDiscussion: { focusId: undefined, focusOn: undefined, }, }, type: 'DELETE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.thirdCall.args, expected) done() }) }) test('deleteDiscussion sets focusOn to toggleButton if deleting first item in collection', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: { 1: {id: 1}, 2: {id: 2}, }, pinnedDiscussionIds: [1, 2], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 1} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 1}, nextFocusDiscussion: { focusId: 2, focusOn: 'toggleButton', }, }, type: 'DELETE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.thirdCall.args, expected) done() }) }) test('deleteDiscussion sets focusOn to manageMenu if user has delete perms', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: { 1: {id: 1, permissions: {delete: true}}, 2: {id: 2, permissions: {delete: true}}, }, pinnedDiscussionIds: [1, 2], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 2} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 2}, nextFocusDiscussion: { focusId: 1, focusOn: 'manageMenu', }, }, type: 'DELETE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.thirdCall.args, expected) done() }) }) test('deleteDiscussion sets focusOn to title if user does not have delete perms', assert => { const done = assert.async() mockSuccess('deleteDiscussion', {}) const state = { allDiscussions: { 1: {id: 1, permissions: {delete: false}}, 2: {id: 2, permissions: {delete: false}}, }, pinnedDiscussionIds: [1, 2], unpinnedDiscussionIds: [], closedForCommentsDiscussionIds: [], } const discussion = {id: 2} const dispatchSpy = sinon.spy() actions.deleteDiscussion(discussion)(dispatchSpy, () => state) setTimeout(() => { const expected = [ { payload: { discussion: {id: 2}, nextFocusDiscussion: { focusId: 1, focusOn: 'title', }, }, type: 'DELETE_DISCUSSION_SUCCESS', }, ] deepEqual(dispatchSpy.thirdCall.args, expected) done() }) }) test('deleteFocusDone dispatches DELETE_FOCUS_CLEANUP', assert => { const done = assert.async() const dispatchSpy = sinon.spy() actions.deleteFocusDone()(dispatchSpy, () => {}) setTimeout(() => { const expected = [{type: 'DELETE_FOCUS_CLEANUP'}] deepEqual(dispatchSpy.firstCall.args, expected) done() }) })