From c0e13041eb704849198309d551eb507728eb6074 Mon Sep 17 00:00:00 2001 From: Samson Akol Date: Fri, 10 Oct 2025 18:14:20 +0300 Subject: [PATCH 01/12] Adds defensive check when generating language text in the language dropdown --- .../shared/views/LanguageDropdown.vue | 3 +- .../views/__tests__/languageDropdown.spec.js | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue b/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue index ddf39fdfee..5f174e53df 100644 --- a/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue +++ b/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue @@ -113,7 +113,8 @@ }, methods: { languageText(item) { - const firstNativeName = item.native_name.split(',')[0].trim(); + const nativeName = item?.native_name || ''; + const firstNativeName = nativeName.split(',')[0].trim(); return this.$tr('languageItemText', { language: firstNativeName, code: item.id }); }, }, diff --git a/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js b/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js index f478ebcd9b..77d2de819e 100644 --- a/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js +++ b/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js @@ -1,4 +1,4 @@ -import { mount } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; import LanguageDropdown from '../LanguageDropdown.vue'; import TestForm from './TestForm.vue'; import { LanguagesList } from 'shared/leUtils/Languages'; @@ -61,4 +61,34 @@ describe('languageDropdown', () => { await wrapper.vm.$nextTick(); expect(wrapper.find('.error--text').exists()).toBe(true); }); + + it('returns formatted language text when native_name is present', () => { + const wrapper = shallowMount(LanguageDropdown, { + mocks: { + $tr: (key, params) => `${params.language} (${params.code})`, + }, + }); + const item = { native_name: 'Español,Spanish', id: 'es' }; + expect(wrapper.vm.languageText(item)).toBe('Español (es)'); + }); + + it('returns formatted language text when native_name is an empty string', () => { + const wrapper = shallowMount(LanguageDropdown, { + mocks: { + $tr: (key, params) => `${params.language} (${params.code})`, + }, + }); + const item = { native_name: '', id: 'de' }; + expect(wrapper.vm.languageText(item)).toBe(' (de)'); + }); + + it('returns formatted language text when native_name is missing', () => { + const wrapper = shallowMount(LanguageDropdown, { + mocks: { + $tr: (key, params) => `${params.language} (${params.code})`, + }, + }); + const item = { id: 'fr' }; + expect(wrapper.vm.languageText(item)).toBe(' (fr)'); + }); }); From 3e43f885aa64937682416f497a5ba30811c9c4f9 Mon Sep 17 00:00:00 2001 From: Samson Akol Date: Thu, 30 Oct 2025 09:22:19 +0300 Subject: [PATCH 02/12] Display multiple languages option if multiple nodes with different languages are selected --- .../components/edit/DetailsTabView.vue | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue index 3002797c94..5bf41ca0c7 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue @@ -499,6 +499,7 @@ } from 'shared/constants'; import { constantsTranslationMixin, metadataTranslationMixin } from 'shared/mixins'; import { crossComponentTranslator } from 'shared/i18n'; + import { LanguagesNames } from 'shared/leUtils/Languages'; function getValueFromResults(results) { if (results.length === 0) { @@ -715,7 +716,20 @@ }, }, role: generateGetterSetter('role_visibility'), - language: generateGetterSetter('language'), + language: { + get() { + if (this.multipleSelected) { + const languages = this.selectedLanguages; + return languages.length > 1 ? LanguagesNames.MUL : languages[0] || null; + } + return this.getValueFromNodes('language'); + }, + set(value) { + if (value !== LanguagesNames.MUL) { + this.update({ language: value }); + } + }, + }, accessibility: generateNestedNodesGetterSetter('accessibility_labels'), contentLevel: generateNestedNodesGetterSetterObject('grade_levels'), resourcesNeeded: generateNestedNodesGetterSetterObject('learner_needs'), @@ -803,6 +817,18 @@ oneSelected() { return this.nodes.length === 1; }, + multipleSelected() { + return this.nodes.length > 1; + }, + selectedLanguages() { + return [ + ...new Set( + this.nodes.map(node => { + return this.diffTracker[node.id]?.language ?? node.language; + }), + ), + ]; + }, languageHint() { const topLevel = this.nodes.some(node => node.parent === this.currentChannel.main_tree); return topLevel ? this.$tr('languageChannelHelpText') : this.$tr('languageHelpText'); From c49d7671319f6588e82953fe961c38c4f13a140a Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Thu, 30 Oct 2025 16:13:26 +0300 Subject: [PATCH 03/12] Add focus trapping to resource preview side panel (#5505) * 000 * fixes tab navigation on VTab * revert pilllow down grade * remove px-2 * Replace custom 'outline-spacing' class with standard 'pa-1 * Fixes tab styling inconsistencies introduced in previous commits. --- .../frontend/channelEdit/components/ResourcePanel.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/ResourcePanel.vue b/contentcuration/contentcuration/frontend/channelEdit/components/ResourcePanel.vue index 674bcfa160..e8616b3c1e 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/ResourcePanel.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/ResourcePanel.vue @@ -74,7 +74,8 @@ slider-color="primary" > @@ -86,7 +87,8 @@ /> From ee6a3af32967d3553945eec09b7328d05c7c8f97 Mon Sep 17 00:00:00 2001 From: Samson Akol Date: Mon, 3 Nov 2025 18:54:37 +0300 Subject: [PATCH 04/12] Improve language check + clean up --- .../components/edit/DetailsTabView.vue | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue index 5bf41ca0c7..d7e6021ee9 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue @@ -718,14 +718,11 @@ role: generateGetterSetter('role_visibility'), language: { get() { - if (this.multipleSelected) { - const languages = this.selectedLanguages; - return languages.length > 1 ? LanguagesNames.MUL : languages[0] || null; - } - return this.getValueFromNodes('language'); + const value = this.getValueFromNodes('language'); + return value === nonUniqueValue ? LanguagesNames.MUL : value; }, set(value) { - if (value !== LanguagesNames.MUL) { + if (!(value === LanguagesNames.MUL && this.language === LanguagesNames.MUL)) { this.update({ language: value }); } }, @@ -817,18 +814,6 @@ oneSelected() { return this.nodes.length === 1; }, - multipleSelected() { - return this.nodes.length > 1; - }, - selectedLanguages() { - return [ - ...new Set( - this.nodes.map(node => { - return this.diffTracker[node.id]?.language ?? node.language; - }), - ), - ]; - }, languageHint() { const topLevel = this.nodes.some(node => node.parent === this.currentChannel.main_tree); return topLevel ? this.$tr('languageChannelHelpText') : this.$tr('languageHelpText'); From da2ae21a88dc89fd29edd3dea7154def991ab1c8 Mon Sep 17 00:00:00 2001 From: Samson Akol Date: Tue, 11 Nov 2025 20:15:59 +0300 Subject: [PATCH 05/12] Reverts null check in LanguageDropdown --- .../frontend/shared/views/LanguageDropdown.vue | 3 +-- .../shared/views/__tests__/languageDropdown.spec.js | 10 ---------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue b/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue index 5f174e53df..ddf39fdfee 100644 --- a/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue +++ b/contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue @@ -113,8 +113,7 @@ }, methods: { languageText(item) { - const nativeName = item?.native_name || ''; - const firstNativeName = nativeName.split(',')[0].trim(); + const firstNativeName = item.native_name.split(',')[0].trim(); return this.$tr('languageItemText', { language: firstNativeName, code: item.id }); }, }, diff --git a/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js b/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js index 77d2de819e..8bdcd165fd 100644 --- a/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js +++ b/contentcuration/contentcuration/frontend/shared/views/__tests__/languageDropdown.spec.js @@ -81,14 +81,4 @@ describe('languageDropdown', () => { const item = { native_name: '', id: 'de' }; expect(wrapper.vm.languageText(item)).toBe(' (de)'); }); - - it('returns formatted language text when native_name is missing', () => { - const wrapper = shallowMount(LanguageDropdown, { - mocks: { - $tr: (key, params) => `${params.language} (${params.code})`, - }, - }); - const item = { id: 'fr' }; - expect(wrapper.vm.languageText(item)).toBe(' (fr)'); - }); }); From d4e579acfa10764f109cf5f4eccd9f8541d9cfb3 Mon Sep 17 00:00:00 2001 From: ozer550 Date: Thu, 13 Nov 2025 11:56:48 +0530 Subject: [PATCH 06/12] reset pagination for trashModal --- .../channelEdit/views/trash/TrashModal.vue | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue b/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue index 9052cf5720..271d12a8d0 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue @@ -281,19 +281,24 @@ 'moveContentNodes', 'loadContentNodes', 'loadAncestors', + 'removeContentNodes', ]), loadNodes() { this.loading = true; + this.more = null; + this.moreLoading = false; if (!this.trashId) { this.loading = false; return; } - this.loadChildren({ parent: this.trashId, ordering: '-modified' }).then( - childrenResponse => { - this.loading = false; - this.more = childrenResponse.more || null; - }, - ); + this.removeContentNodes({ parentId: this.trashId }).then(() => { + this.loadChildren({ parent: this.trashId, ordering: '-modified' }).then( + childrenResponse => { + this.loading = false; + this.more = childrenResponse.more || null; + }, + ); + }); }, moveNodes(target) { return this.moveContentNodes({ From eed17200defb4861fec2a70297cc310fd70638c5 Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 15 Apr 2025 17:29:39 +0300 Subject: [PATCH 07/12] 000 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9863c77097..551f5a0f76 100644 --- a/requirements.txt +++ b/requirements.txt @@ -178,7 +178,7 @@ packaging==25.0 # google-cloud-error-reporting # google-cloud-kms # gunicorn -pillow==11.3.0 +pillow==11.1.0 # via -r requirements.in prometheus-client==0.10.1 # via django-prometheus From 1b2c0b7fdeaab523d4bdebbefd87e0cf63e2220e Mon Sep 17 00:00:00 2001 From: ozer550 Date: Mon, 24 Nov 2025 12:24:34 +0530 Subject: [PATCH 08/12] push new modififed field to sync --- .../contentcuration/frontend/shared/data/resources.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contentcuration/contentcuration/frontend/shared/data/resources.js b/contentcuration/contentcuration/frontend/shared/data/resources.js index 37c307d850..1ddc0cdbfe 100644 --- a/contentcuration/contentcuration/frontend/shared/data/resources.js +++ b/contentcuration/contentcuration/frontend/shared/data/resources.js @@ -1687,6 +1687,10 @@ export const ContentNode = new TreeResource({ async tableMove({ node, parent, payload }) { // Do direct table writes here rather than using add/update methods to avoid // creating unnecessary additional change events. + payload = { + ...payload, + modified: new Date().toISOString(), + }; const updated = await this.table.update(node.id, payload); // Update didn't succeed, this node probably doesn't exist, do a put instead, // but need to add in other parent info. From 8311bde0668c3d4d87d33b3b2e901a013f507d42 Mon Sep 17 00:00:00 2001 From: Marcella Maki Date: Fri, 23 May 2025 10:42:11 -0400 Subject: [PATCH 09/12] set 'updateDescendants' to true, so nested resources are edited by default in bulk/quick editing --- .../QuickEditModal/EditBooleanMapModal.vue | 2 +- .../QuickEditModal/EditLanguageModal.vue | 2 +- .../__tests__/EditBooleanMapModal.spec.js | 6 ++--- .../__tests__/EditLanguageModal.spec.js | 27 ++++++++++--------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditBooleanMapModal.vue b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditBooleanMapModal.vue index a8b621bd13..93f34bc587 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditBooleanMapModal.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditBooleanMapModal.vue @@ -95,7 +95,7 @@ }, data() { return { - updateDescendants: false, + updateDescendants: true, error: '', /** * selectedValues is an object with the following structure: diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditLanguageModal.vue b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditLanguageModal.vue index 6287b14dd5..381afcf60f 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditLanguageModal.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditLanguageModal.vue @@ -92,7 +92,7 @@ return { selectedLanguage: '', searchQuery: '', - updateDescendants: false, + updateDescendants: true, isMultipleNodeLanguages: false, changed: false, }; diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditBooleanMapModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditBooleanMapModal.spec.js index 2d4306846b..aa96754a67 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditBooleanMapModal.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditBooleanMapModal.spec.js @@ -275,10 +275,11 @@ describe('EditBooleanMapModal', () => { expect(wrapper.find('[data-test="update-descendants-checkbox"]').exists()).toBeFalsy(); }); - test('should call updateContentNode on success submit if the user does not check the update descendants checkbox', async () => { + test('should call updateContentNode on success submit if the user uncheck the update descendants checkbox', async () => { nodes['node1'].kind = ContentKindsNames.TOPIC; const wrapper = makeWrapper({ nodeIds: ['node1'], isDescendantsUpdatable: true }); + wrapper.find('[data-test="update-descendants-checkbox"]').element.click(); await wrapper.vm.handleSave(); expect(contentNodeActions.updateContentNode).toHaveBeenCalledWith(expect.anything(), { @@ -287,11 +288,10 @@ describe('EditBooleanMapModal', () => { }); }); - test('should call updateContentNodeDescendants on success submit if the user checks the descendants checkbox', async () => { + test('should call updateContentNodeDescendants on success submit if the user does not uncheck the update descendants checkbox', async () => { nodes['node1'].kind = ContentKindsNames.TOPIC; const wrapper = makeWrapper({ nodeIds: ['node1'], isDescendantsUpdatable: true }); - wrapper.find('[data-test="update-descendants-checkbox"]').element.click(); await wrapper.vm.handleSave(); expect(contentNodeActions.updateContentNodeDescendants).toHaveBeenCalledWith( diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditLanguageModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditLanguageModal.spec.js index c9716d55da..2c2cb791ff 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditLanguageModal.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditLanguageModal.spec.js @@ -220,8 +220,8 @@ describe('EditLanguageModal', () => { }); describe('topic nodes present', () => { - it('should display the checkbox to apply change to descendants if a topic is present', () => { - [wrapper] = makeWrapper(['test-en-topic', 'test-en-res']); + test('should display a selected checkbox to apply change to descendants if a topic is present', () => { + const [wrapper] = makeWrapper(['test-en-topic', 'test-en-res']); expect( wrapper.findComponent('[data-test="update-descendants-checkbox"]').exists(), @@ -236,30 +236,33 @@ describe('EditLanguageModal', () => { ).toBeFalsy(); }); - it('should call updateContentNode with the right language on success submit if the user does not check the checkbox', async () => { - [wrapper, mocks] = makeWrapper(['test-en-topic', 'test-en-res']); + test('should call updateContentNodeDescendants with the right language on success submit by default', async () => { + const [wrapper, mocks] = makeWrapper(['test-en-topic', 'test-en-res']); await chooseLanguage(wrapper, 'es'); await wrapper.vm.handleSave(); - await wrapper.vm.$nextTick(); - expect(mocks.updateContentNode).toHaveBeenCalledWith({ + expect(mocks.updateContentNodeDescendants).toHaveBeenCalledWith({ id: 'test-en-topic', language: 'es', }); }); - it('should call updateContentNodeDescendants with the right language on success submit if the user checks the checkbox', async () => { - [wrapper, mocks] = makeWrapper(['test-en-topic', 'test-en-res']); + test('should call updateContentNode with the right language on success submit if the user unchecks check the checkbox', async () => { + const [wrapper, mocks] = makeWrapper(['test-en-topic', 'test-en-res']); await chooseLanguage(wrapper, 'es'); - wrapper.findComponent('[data-test="update-descendants-checkbox"]').vm.$emit('change', true); + + // Uncheck the descendants checkbox + const descendantsCheckbox = wrapper.findComponent( + '[data-test="update-descendants-checkbox"]', + ); + descendantsCheckbox.vm.$emit('change', false); await wrapper.vm.$nextTick(); - expect(wrapper.vm.updateDescendants).toBe(true); + await wrapper.vm.handleSave(); - await wrapper.vm.$nextTick(); - expect(mocks.updateContentNodeDescendants).toHaveBeenCalledWith({ + expect(mocks.updateContentNode).toHaveBeenCalledWith({ id: 'test-en-topic', language: 'es', }); From 4ae92df777ac36859c8cef3335b1ceb58f40efda Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:06:33 +0300 Subject: [PATCH 10/12] uses KGrid to handle responsiveness --- .../ImportFromChannels/SearchResultsList.vue | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/SearchResultsList.vue b/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/SearchResultsList.vue index 4f95c2cd99..2862ff2146 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/SearchResultsList.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/SearchResultsList.vue @@ -3,13 +3,22 @@
- - - - - - - + + + + +

@@ -105,8 +114,8 @@

- - + + From 76ae31b4fc4b73b6b5130762e0ce70d9e50854fa Mon Sep 17 00:00:00 2001 From: Allan Otodi Opeto <103313919+AllanOXDi@users.noreply.github.com> Date: Tue, 25 Nov 2025 14:07:31 +0300 Subject: [PATCH 11/12] Fixes folders or resources with missing title remain 'incomplete' after editing just the title (#5539) * 000 * updates the completion status when quick editing a channel folder * update assertions in EditTitleDescriptionModa * revert pilow to pillow==11.3.0 * replace objectContaining with full payload check --- .../QuickEditModal/EditTitleDescriptionModal.vue | 1 + .../__tests__/EditTitleDescriptionModal.spec.js | 9 ++++----- requirements.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditTitleDescriptionModal.vue b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditTitleDescriptionModal.vue index 3acdde0ad2..15b271664e 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditTitleDescriptionModal.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/EditTitleDescriptionModal.vue @@ -98,6 +98,7 @@ id: nodeId, title: title.trim(), description: description.trim(), + checkComplete: true, }); /* eslint-disable-next-line kolibri/vue-no-undefined-string-uses */ this.$store.dispatch('showSnackbarSimple', commonStrings.$tr('changesSaved')); diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditTitleDescriptionModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditTitleDescriptionModal.spec.js index 464a8e9026..632f364fe1 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditTitleDescriptionModal.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/QuickEditModal/__tests__/EditTitleDescriptionModal.spec.js @@ -33,9 +33,7 @@ describe('EditTitleDescriptionModal', () => { }, }, }), - propsData: { - nodeId, - }, + propsData: { nodeId }, }); updateContentNode = jest.spyOn(wrapper.vm, 'updateContentNode').mockImplementation(() => {}); @@ -70,7 +68,8 @@ describe('EditTitleDescriptionModal', () => { expect(updateContentNode).toHaveBeenCalledWith({ id: nodeId, title: newTitle, - description: newDescription, + description: newDescription ?? '', + checkComplete: true, }); }); @@ -80,11 +79,11 @@ describe('EditTitleDescriptionModal', () => { descriptionInput.vm.$emit('input', ''); modal.vm.$emit('submit'); - expect(updateContentNode).toHaveBeenCalledWith({ id: nodeId, title: newTitle, description: '', + checkComplete: true, }); }); diff --git a/requirements.txt b/requirements.txt index 551f5a0f76..9863c77097 100644 --- a/requirements.txt +++ b/requirements.txt @@ -178,7 +178,7 @@ packaging==25.0 # google-cloud-error-reporting # google-cloud-kms # gunicorn -pillow==11.1.0 +pillow==11.3.0 # via -r requirements.in prometheus-client==0.10.1 # via django-prometheus From 52a27d5db422ebdcab1ffc5dc6c754f50329b9c9 Mon Sep 17 00:00:00 2001 From: ozer550 Date: Tue, 2 Dec 2025 10:59:43 +0530 Subject: [PATCH 12/12] make changes in test to reflect new modified field operational changes --- .../__tests__/ContentNodeResource.spec.js | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/contentcuration/contentcuration/frontend/shared/data/__tests__/ContentNodeResource.spec.js b/contentcuration/contentcuration/frontend/shared/data/__tests__/ContentNodeResource.spec.js index 3f16719252..31bcb53bb4 100644 --- a/contentcuration/contentcuration/frontend/shared/data/__tests__/ContentNodeResource.spec.js +++ b/contentcuration/contentcuration/frontend/shared/data/__tests__/ContentNodeResource.spec.js @@ -574,8 +574,12 @@ describe('ContentNode methods', () => { it('should update the node with the payload', async () => { node.parent = parent.id; - await expect(ContentNode.tableMove({ node, parent, payload, change })).resolves.toBe(payload); - expect(table.update).toHaveBeenCalledWith(node.id, payload); + const result = await ContentNode.tableMove({ node, parent, payload, change }); + expect(result).toMatchObject({ ...payload, modified: expect.any(String) }); + expect(table.update).toHaveBeenCalledTimes(1); + const [updateId, updatePayload] = table.update.mock.calls[0]; + expect(updateId).toBe(node.id); + expect(updatePayload).toBe(result); expect(table.put).not.toBeCalled(); expect(table.update).not.toHaveBeenCalledWith(node.parent, { changed: true }); }); @@ -584,19 +588,23 @@ describe('ContentNode methods', () => { node.parent = parent.id; updated = false; const newPayload = { ...payload, root_id: parent.root_id }; - await expect(ContentNode.tableMove({ node, parent, payload, change })).resolves.toMatchObject( - newPayload, + const result = await ContentNode.tableMove({ node, parent, payload, change }); + expect(result).toMatchObject({ ...newPayload, modified: expect.any(String) }); + expect(table.update).toHaveBeenCalledWith( + node.id, + expect.objectContaining({ ...payload, modified: expect.any(String) }), ); - expect(table.update).toHaveBeenCalledWith(node.id, payload); - expect(table.put).toHaveBeenCalledWith(newPayload); + expect(table.put).toHaveBeenCalledWith(result); expect(table.update).not.toHaveBeenCalledWith(node.parent, { changed: true }); }); it('should mark the old parent as changed', async () => { - await expect(ContentNode.tableMove({ node, parent, payload, change })).resolves.toMatchObject( - payload, + const result = await ContentNode.tableMove({ node, parent, payload, change }); + expect(result).toMatchObject({ ...payload, modified: expect.any(String) }); + expect(table.update).toHaveBeenCalledWith( + node.id, + expect.objectContaining({ ...payload, modified: expect.any(String) }), ); - expect(table.update).toHaveBeenCalledWith(node.id, payload); expect(table.put).not.toBeCalled(); expect(table.update).toHaveBeenCalledWith(node.parent, { changed: true }); });