+
{{ index + 1 }}
@@ -205,9 +203,7 @@
v-if="!assessmentItems.length"
class="red--text"
>
-
+
{{ $tr('noQuestionsError') }}
@@ -239,9 +235,7 @@
v-if="isExercise && noMasteryModel"
class="red--text"
>
-
+
{{ $tr('noMasteryModelError') }}
@@ -424,9 +418,7 @@
v-if="noLicense"
class="red--text"
>
-
+
{{ $tr('noLicenseError') }}
@@ -436,9 +428,7 @@
v-if="noLicenseDescription"
class="red--text"
>
-
+
{{ $tr('noLicenseDescriptionError') }}
-
+
{{ $tr('noCopyrightHolderError') }}
-
+
{{ $tr('noFilesError') }}
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.spec.js
index c38a07bf02..0c21ecbbd4 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.spec.js
@@ -86,7 +86,7 @@ function getItems(wrapper) {
describe('StudioTree', () => {
it('smoke test', () => {
const wrapper = initWrapper();
- expect(wrapper.isVueInstance()).toBe(true);
+ expect(wrapper.exists()).toBe(true);
});
describe('when mounted', () => {
@@ -359,8 +359,11 @@ describe('StudioTree', () => {
propsData: { nodeId: 'root-topic', root: true },
getters,
});
- await nextTickWaitFor(wrapper, () => !wrapper.contains('[data-test="editMenu"]'));
- expect(wrapper.contains('[data-test="editMenu"]')).toBe(false);
+ await nextTickWaitFor(
+ wrapper,
+ () => !wrapper.findComponent('[data-test="editMenu"]').exists(),
+ );
+ expect(wrapper.findComponent('[data-test="editMenu"]').exists()).toBe(false);
});
it('renders edit menu when editing is allowed', async () => {
@@ -369,8 +372,10 @@ describe('StudioTree', () => {
getters,
});
- await nextTickWaitFor(wrapper, () => wrapper.contains('[data-test="editMenu"]'));
- expect(wrapper.contains('[data-test="editMenu"]')).toBe(true);
+ await nextTickWaitFor(wrapper, () =>
+ wrapper.findComponent('[data-test="editMenu"]').exists(),
+ );
+ expect(wrapper.findComponent('[data-test="editMenu"]').exists()).toBe(true);
});
it("doesn't display context edit menu on right-click by default", async () => {
@@ -382,8 +387,11 @@ describe('StudioTree', () => {
const item = getItems(wrapper).at(0);
item.trigger('contextmenu');
- await nextTickWaitFor(wrapper, () => !item.contains('[data-test="contextMenu"]'));
- expect(item.contains('[data-test="contextMenu"]')).toBe(false);
+ await nextTickWaitFor(
+ wrapper,
+ () => !item.findComponent('[data-test="contextMenu"]').exists(),
+ );
+ expect(item.findComponent('[data-test="contextMenu"]').exists()).toBe(false);
});
it('displays context edit menu on right-click when editing is allowed', async () => {
@@ -395,7 +403,9 @@ describe('StudioTree', () => {
const item = getItems(wrapper).at(0);
item.trigger('contextmenu');
- await nextTickWaitFor(wrapper, () => item.contains('[data-test="contextMenu"]'));
+ await nextTickWaitFor(wrapper, () =>
+ item.findComponent('[data-test="contextMenu"]').exists(),
+ );
const menu = item.findAll('[data-test="contextMenu"]').at(0);
expect(menu.isVisible()).toBe(true);
});
@@ -424,7 +434,7 @@ describe('StudioTree', () => {
const items = getItems(wrapper);
const subTopic2 = items.at(3);
- expect(subTopic2.contains('[data-test="expansionToggle"]')).toBe(false);
+ expect(subTopic2.findComponent('[data-test="expansionToggle"]').exists()).toBe(false);
});
it('renders expansion toggle when a topic contains subtopics', async () => {
@@ -436,7 +446,7 @@ describe('StudioTree', () => {
const items = getItems(wrapper);
const subTopic1 = items.at(0);
- expect(subTopic1.contains('[data-test="expansionToggle"]')).toBe(true);
+ expect(subTopic1.findComponent('[data-test="expansionToggle"]').exists()).toBe(true);
});
it('commits toggle mutation when expansion toggle is clicked', async () => {
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.vue b/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.vue
index f045a48a74..a4f2bb0e83 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/StudioTree/StudioTree.vue
@@ -11,7 +11,11 @@
wrap
:class="{ 'is-root': root }"
>
-
+
-
-
+
+
-
-
+
+
- {{ node.resource_count ? "folder" : "folder_open" }}
+ {{ node.resource_count ? 'folder' : 'folder_open' }}
{{ getTitle(node) }}
@@ -80,26 +99,38 @@
class="caption px-1 text-truncate"
:class="getTitleClass(node)"
>
-
+
{{ getTitle(node) }}
-
+
{{ $tr('missingTitle') }}
-
+
-
+
-
-
-
+
+
-
+
{{ getTitle(node) }}
@@ -160,7 +197,11 @@
-
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue
index 2bb801094f..cceab440aa 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/DetailsTabView.vue
@@ -1,7 +1,15 @@
-
-
+
+
-
+
{{ $tr('basicInfoHeader') }}
@@ -32,7 +44,10 @@
box
@focus="trackClick('Title')"
/>
-
+
-
+
{{ $tr('assessmentOptionsLabel') }}
@@ -135,13 +155,18 @@
v-model="randomizeOrder"
:label="$tr('randomizeQuestionLabel')"
:indeterminate="!isUnique(randomizeOrder)"
- style="font-size: 16px;"
+ style="font-size: 16px"
/>
-
+
{{ $tr('completionLabel') }}
@@ -156,8 +181,15 @@
-
-
+
+
{{ $tr('thumbnailHeader') }}
@@ -174,7 +206,11 @@
-
+
{{ $tr('audienceHeader') }}
@@ -207,9 +243,12 @@
id="beginners"
ref="beginners"
:checked="forBeginners"
- @change="value => forBeginners = value"
+ @change="value => (forBeginners = value)"
>
-
+
{{ translateMetadataString('forBeginners') }}
@@ -217,7 +256,11 @@
-
+
@@ -233,13 +276,23 @@
-
+
-
+
{{ $tr('sourceHeader') }}
-
+
{{ detectedImportText }}
@@ -262,15 +315,22 @@
box
:placeholder="getPlaceholder('author')"
:value="author && author.toString()"
- @input.native="(e) => (author = e.srcElement.value)"
+ @input.native="e => (author = e.srcElement.value)"
@input="author = $event"
@focus="trackClick('Author')"
>
-
+
-
+
{{ helpTextString.$tr('cannotEditPublic') }}
@@ -286,12 +346,16 @@
autoSelectFirst
box
:value="provider && provider.toString()"
- @input.native="(e) => (provider = e.srcElement.value)"
+ @input.native="e => (provider = e.srcElement.value)"
@input="provider = $event"
@focus="trackClick('Provider')"
>
-
+
@@ -307,12 +371,16 @@
:placeholder="getPlaceholder('aggregator')"
box
:value="aggregator && aggregator.toString()"
- @input.native="(e) => (aggregator = e.srcElement.value)"
+ @input.native="e => (aggregator = e.srcElement.value)"
@input="aggregator = $event"
@focus="trackClick('Aggregator')"
>
-
+
@@ -344,11 +412,14 @@
:disabled="disableSourceEdits"
box
:value="copyright_holder && copyright_holder.toString()"
- @input.native="(e) => (copyright_holder = e.srcElement.value)"
+ @input.native="e => (copyright_holder = e.srcElement.value)"
@input="copyright_holder = $event"
@focus="trackClick('Copyright holder')"
/>
-
+
{{ helpTextString.$tr('cannotEditPublic') }}
@@ -356,7 +427,12 @@
-
+
-
+
@@ -378,6 +458,7 @@
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/accessibilityOptions.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/accessibilityOptions.spec.js
index 9bc5d81c04..3248b7180e 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/accessibilityOptions.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/accessibilityOptions.spec.js
@@ -1,10 +1,6 @@
-import Vue from 'vue';
-import Vuetify from 'vuetify';
import { shallowMount, mount } from '@vue/test-utils';
import AccessibilityOptions from '../AccessibilityOptions.vue';
-Vue.use(Vuetify);
-
describe('AccessibilityOptions', () => {
it('smoke test', () => {
const wrapper = shallowMount(AccessibilityOptions, {
@@ -12,7 +8,7 @@ describe('AccessibilityOptions', () => {
kind: 'document',
},
});
- expect(wrapper.isVueInstance()).toBe(true);
+ expect(wrapper.exists()).toBe(true);
});
it('should display the correct list of accessibility options if resource is a document', () => {
@@ -22,11 +18,11 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-altText"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-highContrast"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-taggedPdf"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
});
it('should display the correct list of accessibility options if resource is a video', () => {
@@ -36,13 +32,13 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-altText"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-highContrast"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-signLanguage"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-audioDescription"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false);
});
it('should display the correct list of accessibility options if resource is an exercise/practice', () => {
@@ -52,11 +48,11 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-altText"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-highContrast"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
});
it('should display the correct list of accessibility options if resource is html5/zip', () => {
@@ -66,11 +62,11 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-altText"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-highContrast"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
});
it('should display the correct list of accessibility options if resource is an audio', () => {
@@ -80,8 +76,8 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-captionsSubtitles"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="tooltip-captionsSubtitles"]').exists()).toBe(false);
});
it('should render appropriate tooltips along with the checkbox', () => {
@@ -91,15 +87,15 @@ describe('AccessibilityOptions', () => {
},
});
- expect(wrapper.find('[data-test="checkbox-altText"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="tooltip-altText"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-highContrast"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="tooltip-highContrast"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-taggedPdf"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="tooltip-taggedPdf"]').exists()).toBe(true);
- expect(wrapper.find('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="tooltip-signLanguage"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="tooltip-audioDescription"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-altText"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="tooltip-altText"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-highContrast"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="tooltip-highContrast"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-taggedPdf"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="tooltip-taggedPdf"]').exists()).toBe(true);
+ expect(wrapper.findComponent('[data-test="checkbox-signLanguage"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="tooltip-signLanguage"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox-audioDescription"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="tooltip-audioDescription"]').exists()).toBe(false);
});
});
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/data.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/data.js
index bbb5db29b0..9e69b55821 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/data.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/data.js
@@ -22,9 +22,7 @@ const specialPermissions = find(LicensesList, { is_custom: true });
export function generateNode(props = {}) {
const data = {};
editableFields.forEach(f => {
- data[f] = Math.random()
- .toString(36)
- .substring(7);
+ data[f] = Math.random().toString(36).substring(7);
});
const extra_fields = {
@@ -33,9 +31,7 @@ export function generateNode(props = {}) {
};
return {
- id: Math.random()
- .toString(36)
- .substring(7),
+ id: Math.random().toString(36).substring(7),
kind: 'topic',
prerequisite: [],
is_prerequisite_of: [],
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/detailsTabView.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/detailsTabView.spec.js
index 48a68f99a1..99dc13cf10 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/detailsTabView.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/detailsTabView.spec.js
@@ -1,4 +1,6 @@
import find from 'lodash/find';
+import findIndex from 'lodash/findIndex';
+import pick from 'lodash/pick';
import Vue from 'vue';
import Vuetify from 'vuetify';
import { mount } from '@vue/test-utils';
@@ -31,7 +33,7 @@ function makeWrapper(props = {}) {
// See: https://github.com/vuejs/vue-test-utils/issues/1130
sync: false,
store: localStore,
- attachToDocument: true,
+ attachTo: document.body,
propsData: {
viewOnly: false,
...props,
@@ -51,10 +53,10 @@ window.Urls = {
describe.skip('detailsTabView', () => {
let wrapper;
- const topicIndex = _.findIndex(testNodes, { id: DEFAULT_TOPIC.id });
- const videoIndex = _.findIndex(testNodes, { id: DEFAULT_VIDEO.id });
- const exerciseIndex = _.findIndex(testNodes, { id: DEFAULT_EXERCISE.id });
- const exercise2Index = _.findIndex(testNodes, { id: DEFAULT_EXERCISE2.id });
+ const topicIndex = findIndex(testNodes, { id: DEFAULT_TOPIC.id });
+ const videoIndex = findIndex(testNodes, { id: DEFAULT_VIDEO.id });
+ const exerciseIndex = findIndex(testNodes, { id: DEFAULT_EXERCISE.id });
+ const exercise2Index = findIndex(testNodes, { id: DEFAULT_EXERCISE2.id });
beforeEach(() => {
localStore.commit('edit_modal/SET_NODE', exerciseIndex);
wrapper = makeWrapper();
@@ -77,8 +79,8 @@ describe.skip('detailsTabView', () => {
'randomizeOrder',
'copyrightHolder',
];
- expect(_.pick(wrapper.vm, keys)).toEqual({
- ..._.pick(DEFAULT_EXERCISE, keys),
+ expect(pick(wrapper.vm, keys)).toEqual({
+ ...pick(DEFAULT_EXERCISE, keys),
license: {
license: DEFAULT_EXERCISE.license,
description: DEFAULT_EXERCISE.license_description,
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editList.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editList.spec.js
index 749da3b6b0..761dfeac51 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editList.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editList.spec.js
@@ -28,7 +28,7 @@ function makeWrapper() {
localStore.commit('edit_modal/SET_NODES', ContentNodes);
return mount(EditList, {
store: localStore,
- attachToDocument: true,
+ attachTo: document.body,
stubs: {
EditListItem: true,
},
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editListItem.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editListItem.spec.js
index 50d73334c6..b5e02ed40a 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editListItem.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editListItem.spec.js
@@ -12,7 +12,7 @@ const ContentNode = {
function makeWrapper(props = {}) {
return mount(EditListItem, {
store: localStore,
- attachToDocument: true,
+ attachTo: document.body,
propsData: {
nodeId: 'node-1',
...props,
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editModal.spec.js
index 6f69faefbc..22c726f64a 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editModal.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editModal.spec.js
@@ -10,7 +10,7 @@ const testNodes = [DEFAULT_TOPIC, DEFAULT_TOPIC2];
function makeWrapper(props = {}) {
const wrapper = mount(EditModal, {
store: localStore,
- attachToDocument: true,
+ attachTo: document.body,
propsData: props,
stubs: ['SavingIndicator'],
});
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editView.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editView.spec.js
index e6e1f74448..f67d854f43 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editView.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/edit/__tests__/editView.spec.js
@@ -13,7 +13,7 @@ const testNodes = [DEFAULT_TOPIC, DEFAULT_VIDEO, DEFAULT_EXERCISE];
function makeWrapper(props = {}) {
const wrapper = mount(EditView, {
store: localStore,
- attachToDocument: true,
+ attachTo: document.body,
propsData: props,
});
return wrapper;
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/move/MoveModal.vue b/contentcuration/contentcuration/frontend/channelEdit/components/move/MoveModal.vue
index 31c188b442..5ff2386397 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/move/MoveModal.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/move/MoveModal.vue
@@ -1,19 +1,29 @@
-
+
{{ moveHeader }}
- {{ currentNode.title }}
+ {{ currentNode.title }}
-
-
+
+
{{ getTitle(item) }}
@@ -21,12 +31,19 @@
-
- {{ $tr("addTopic") }}
+
+ {{ $tr('addTopic') }}
-
+
-
+
{{ $tr('emptyTopicText') }}
@@ -44,7 +65,7 @@
align-content-start
style="height: calc(100vh - 192px)"
>
-
+
-
-
+
+
-
+
{{ getTitle(node) }}
-
+
{{ $tr('resourcesCount', { count: node.resource_count || 0 }) }}
-
+
-
+
-
+
-
+
{{ showMoreLabel }}
@@ -111,13 +152,20 @@
/>
-
-
-
- {{ $tr("cancel") }}
+
+
+ {{ $tr('cancel') }}
- {{ $tr("moveHere") }}
+ {{ $tr('moveHere') }}
@@ -138,6 +186,8 @@
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/moveModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/moveModal.spec.js
index 762ff8f9f3..378b0aa4e3 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/moveModal.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/moveModal.spec.js
@@ -46,11 +46,6 @@ function makeWrapper(selected) {
return false;
},
},
- methods: {
- getChildren() {
- return Promise.resolve();
- },
- },
stubs: {
Breadcrumbs: true,
ResourceDrawer: true,
@@ -61,66 +56,63 @@ function makeWrapper(selected) {
describe('moveModal', () => {
let wrapper;
+
beforeEach(() => {
wrapper = makeWrapper();
+ jest.spyOn(wrapper.vm, 'getChildren').mockResolvedValue();
});
+
describe('on load', () => {
it('items that are selected to be moved should be disabled', () => {
const testWrapper = makeWrapper([testVideo.id]);
expect(testWrapper.vm.isDisabled(testVideo)).toBe(true);
});
});
+
describe('topic tree navigation', () => {
- it('clicking a topic should navigate to that topic', () => {
- wrapper
- .findAll('[data-test="listitem"]')
- .at(1)
- .trigger('click');
+ it('clicking a topic should navigate to that topic', async () => {
+ await wrapper.findAll('[data-test="listitem"]').at(1).trigger('click');
expect(wrapper.vm.targetNodeId).toBe(testChildTopic.id);
});
- it('clicking a non-topic should not do anything', () => {
- wrapper.setData({ targetNodeId: testNode.id });
- wrapper.find('[data-test="listitem"]').trigger('click');
+
+ it('clicking a non-topic should not do anything', async () => {
+ await wrapper.setData({ targetNodeId: testNode.id });
+ await wrapper.findComponent('[data-test="listitem"]').trigger('click');
expect(wrapper.vm.targetNodeId).toBe(testNode.id);
});
- it('clicking details button should open the node information', () => {
- wrapper.find('[data-test="details"]').trigger('click');
+
+ it('clicking details button should open the node information', async () => {
+ await wrapper.findComponent('[data-test="details"]').trigger('click');
expect(wrapper.vm.previewNodeId).toBe(testVideo.id);
});
});
+
describe('new topic actions', () => {
- it('clicking NEW TOPIC button should open NewTopicModal', () => {
- wrapper.find('[data-test="newtopic"]').trigger('click');
+ it('clicking NEW TOPIC button should open NewTopicModal', async () => {
+ await wrapper.findComponent('[data-test="newtopic"]').trigger('click');
expect(wrapper.vm.showNewTopicModal).toBe(true);
});
- it('NewTopicModal emitted createTopic event should trigger createContentNode', () => {
+
+ it('NewTopicModal emitted createTopic event should trigger createContentNode', async () => {
const newTopicTitle = 'New topic title';
- const createTopic = jest.fn();
- wrapper.setMethods({ createTopic });
- wrapper.setData({ showNewTopicModal: true });
- wrapper.find('[data-test="newtopicmodal"]').vm.$emit('createTopic', newTopicTitle);
+ const createTopic = jest.spyOn(wrapper.vm, 'createTopic').mockResolvedValue();
+ await wrapper.setData({ showNewTopicModal: true });
+ wrapper.findComponent('[data-test="newtopicmodal"]').vm.$emit('createTopic', newTopicTitle);
expect(createTopic).toHaveBeenCalledWith(newTopicTitle);
});
});
+
describe('move actions', () => {
- it('MOVE button should be disabled if moving to current location', () => {
- wrapper.setData({ targetNodeId: testNodeId });
+ it('MOVE button should be disabled if moving to current location', async () => {
+ await wrapper.setData({ targetNodeId: testNodeId });
expect(wrapper.find('[data-test="move"]').vm.disabled).toBe(true);
});
- it('clicking MOVE button should call moveNodes', () => {
- const moveNodes = jest.fn();
- wrapper.setMethods({ moveNodes });
- wrapper.setData({ targetNodeId: testChildTopic.id });
- wrapper.find('[data-test="move"]').trigger('click');
- expect(moveNodes).toHaveBeenCalled();
- });
- it('clicking MOVE button should emit the targetNodeId', () => {
- const moveContentNodes = jest.fn().mockReturnValue(Promise.resolve());
- wrapper.setMethods({ moveContentNodes });
- wrapper.setData({ targetNodeId: testChildTopic.id });
- wrapper.find('[data-test="move"]').trigger('click');
- expect(wrapper.emitted().target[0]).toEqual([testChildTopic.id]);
+ it('clicking MOVE button should call moveNodes', async () => {
+ const moveNodes = jest.spyOn(wrapper.vm, 'moveNodes').mockResolvedValue();
+ await wrapper.setData({ targetNodeId: testChildTopic.id });
+ await wrapper.findComponent('[data-test="move"]').trigger('click');
+ expect(moveNodes).toHaveBeenCalled();
});
});
});
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/newTopicModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/newTopicModal.spec.js
index 2aaf88705f..ff9089d600 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/newTopicModal.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/move/__tests__/newTopicModal.spec.js
@@ -18,27 +18,33 @@ describe('newTopicModal', () => {
beforeEach(() => {
wrapper = makeWrapper();
});
- it('dialog should reflect v-model value', () => {
+ it('dialog should reflect v-model value', async () => {
expect(wrapper.vm.dialog).toBe(true);
wrapper.setProps({ value: false });
+ await wrapper.vm.$nextTick();
expect(wrapper.vm.dialog).toBe(false);
});
- it('create button should validate form', () => {
+ it('create button should validate form', async () => {
wrapper.find('[data-test="create"]').trigger('click');
- expect(wrapper.find({ ref: 'form' }).vm.value).toBe(false);
+ await wrapper.vm.$nextTick();
+ expect(wrapper.findComponent({ ref: 'form' }).vm.value).toBe(false);
expect(wrapper.emitted('createTopic')).toBeFalsy();
});
- it('create button should emit createTopic event if valid', () => {
+ it('create button should emit createTopic event if valid', async () => {
wrapper.setData({ title: 'test title' });
- wrapper.find('[data-test="create"]').trigger('click');
+ await wrapper.vm.$nextTick();
+ wrapper.findComponent('[data-test="create"]').trigger('click');
+ await wrapper.vm.$nextTick();
expect(wrapper.emitted('createTopic')[0][0]).toBe('test title');
});
- it('close button should emit input event with false value', () => {
- wrapper.find('[data-test="close"]').trigger('click');
+ it('close button should emit input event with false value', async () => {
+ wrapper.findComponent('[data-test="close"]').trigger('click');
+ await wrapper.vm.$nextTick();
expect(wrapper.emitted('input')[0][0]).toBe(false);
});
- it('closing modal should clear title', () => {
- wrapper.find('[data-test="close"]').trigger('click');
+ it('closing modal should clear title', async () => {
+ wrapper.findComponent('[data-test="close"]').trigger('click');
+ await wrapper.vm.$nextTick();
expect(wrapper.vm.title).toBe('');
});
});
diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/publish/PublishModal.vue b/contentcuration/contentcuration/frontend/channelEdit/components/publish/PublishModal.vue
index 58b929de80..ba47272bcd 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/components/publish/PublishModal.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/components/publish/PublishModal.vue
@@ -45,7 +45,10 @@
-
+
-
+
-
+
-
-
+
+
@@ -83,6 +98,7 @@
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/ImportFromChannelsModal.vue b/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/ImportFromChannelsModal.vue
index 51c25ffd47..d61f54b023 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/ImportFromChannelsModal.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/ImportFromChannelsModal.vue
@@ -1,9 +1,21 @@
-
-
-
-
+
+
+
+
@@ -15,7 +27,10 @@
>
-
+
-
-
- check_circle
-
+
+ check_circle
{{ $tr('addedText') }}
-
+
{{ $tr('removeButton') }}
-
+
{{ $tr('addButton') }}
@@ -71,6 +95,7 @@
+
+
diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/files/thumbnails/ThumbnailGenerator.vue b/contentcuration/contentcuration/frontend/channelEdit/views/files/thumbnails/ThumbnailGenerator.vue
index e321a89898..c43bc6920f 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/views/files/thumbnails/ThumbnailGenerator.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/views/files/thumbnails/ThumbnailGenerator.vue
@@ -11,6 +11,7 @@
+
-
-
diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/template/__tests__/template.spec.js b/contentcuration/contentcuration/frontend/channelEdit/views/template/__tests__/template.spec.js
deleted file mode 100644
index 87fff6e493..0000000000
--- a/contentcuration/contentcuration/frontend/channelEdit/views/template/__tests__/template.spec.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import Template from '../Template.vue';
-
-// Delete this test in your copy
-describe('sample test', () => {
- it('should always pass', () => {
- expect(Template).toBeTruthy();
- });
-});
diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue b/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue
index ae03346c9d..e9dce6b9bf 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue
+++ b/contentcuration/contentcuration/frontend/channelEdit/views/trash/TrashModal.vue
@@ -1,8 +1,18 @@
-
-
-
+
+
+
{{ $tr('trashEmptyText') }}
@@ -15,12 +25,25 @@
fluid
class="pa-4"
data-test="list"
- style="max-height: calc(100vh - 128px); overflow-y: auto;"
+ style="max-height: calc(100vh - 128px); overflow-y: auto"
>
-
-
+
+
-
+
-
+
|
-
+
-
+
-
+
-
+
{{ showMoreLabel }}
-
+
{{ getSelectedTopicAndResourceCountText(selected) }}
@@ -109,10 +151,18 @@
:text="$tr('deleteConfirmationText')"
>
-
+
{{ $tr('deleteConfirmationCancelButton') }}
-
+
{{ $tr('deleteConfirmationDeleteButton') }}
@@ -128,6 +178,8 @@
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogFilterBar.vue b/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogFilterBar.vue
index dc6bdbd80c..832d75bce4 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogFilterBar.vue
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogFilterBar.vue
@@ -23,19 +23,20 @@
+
+
+
\ No newline at end of file
+
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogList.vue b/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogList.vue
index d7e5120170..2014b8ad85 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogList.vue
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/CatalogList.vue
@@ -3,7 +3,12 @@
-
+
@@ -13,11 +18,19 @@
:style="`margin-top: ${offline ? 48 : 0}`"
>
-
+
-
+
- {{ $tr("resultsText", { count: page.count }) }}
+ {{ $tr('resultsText', { count: page.count }) }}
-
+
-
+
-
+
@@ -61,37 +84,59 @@
data-test="toolbar"
:appearanceOverrides="{ height: $vuetify.breakpoint.xsOnly ? '72px' : '56px' }"
>
-
-
- {{ $tr("channelSelectionCount", { count: selectedCount }) }}
+
+
+ {{ $tr('channelSelectionCount', { count: selectedCount }) }}
-
+
-
- {{ $tr("cancelButton") }}
+
+ {{ $tr('cancelButton') }}
-
+
@@ -101,6 +146,7 @@
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/ChannelItem.vue b/contentcuration/contentcuration/frontend/channelList/views/Channel/ChannelItem.vue
index 1b94439e23..c4fb7abf95 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/ChannelItem.vue
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/ChannelItem.vue
@@ -11,31 +11,47 @@
:to="linkToChannelTree ? null : channelDetailsLink"
@click="goToChannelRoute"
>
-
-
+
+
-
+
-
- {{ $tr('resourceCount', { 'count': channel.count || 0 }) }}
+ {{ $tr('resourceCount', { count: channel.count || 0 }) }}
{{ language }}
-
+
{{ channel.description }}
@@ -44,23 +60,29 @@
-
+
-
+
- {{ $tr(
- 'lastPublished',
- {
- 'last_published': $formatRelative(
- channel.last_published,
- { now: new Date() }
- )
+ {{
+ $tr('lastPublished', {
+ last_published: $formatRelative(channel.last_published, { now: new Date() }),
})
}}
-
+
{{ $tr('unpublishedText') }}
@@ -69,13 +91,9 @@
placement="bottom"
:refs="$refs"
>
- {{ $tr(
- 'lastUpdated',
- {
- 'updated': $formatRelative(
- channel.modified,
- { now: new Date() }
- )
+ {{
+ $tr('lastUpdated', {
+ updated: $formatRelative(channel.modified, { now: new Date() }),
})
}}
@@ -91,7 +109,6 @@
v-if="!libraryMode"
:to="channelDetailsLink"
>
-
-
-
+
-
+
+
+
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/catalogList.spec.js b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/catalogList.spec.js
index 31ad15eee5..1d6be7054b 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/catalogList.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/catalogList.spec.js
@@ -10,8 +10,13 @@ router.push({ name: RouteNames.CATALOG_ITEMS });
const results = ['channel-1', 'channel-2'];
-function makeWrapper(computed = {}, methods = {}) {
- return mount(CatalogList, {
+function makeWrapper(computed = {}) {
+ const loadCatalog = jest.spyOn(CatalogList.methods, 'loadCatalog');
+ loadCatalog.mockImplementation(() => Promise.resolve());
+
+ const downloadCSV = jest.spyOn(CatalogList.methods, 'downloadCSV');
+
+ const wrapper = mount(CatalogList, {
router,
store,
computed: {
@@ -23,24 +28,24 @@ function makeWrapper(computed = {}, methods = {}) {
},
...computed,
},
- methods,
stubs: {
CatalogFilters: true,
},
});
+ return [wrapper, { loadCatalog, downloadCSV }];
}
describe('catalogFilterBar', () => {
- let wrapper;
- beforeEach(() => {
- wrapper = makeWrapper();
- wrapper.setData({ loading: false });
+ let wrapper, mocks;
+
+ beforeEach(async () => {
+ [wrapper, mocks] = makeWrapper();
+ await wrapper.setData({ loading: false });
});
it('should call loadCatalog on mount', () => {
- const loadCatalog = jest.fn();
- wrapper = makeWrapper({}, { loadCatalog });
- expect(loadCatalog).toHaveBeenCalled();
+ [wrapper, mocks] = makeWrapper();
+ expect(mocks.loadCatalog).toHaveBeenCalled();
});
describe('on query change', () => {
@@ -49,29 +54,30 @@ describe('catalogFilterBar', () => {
beforeEach(() => {
router.replace({ query: {} }).catch(() => {});
searchCatalogMock.mockReset();
- wrapper = makeWrapper({
+ [wrapper, mocks] = makeWrapper({
debouncedSearch() {
return searchCatalogMock;
},
});
});
- it('should call debouncedSearch', () => {
+
+ it('should call debouncedSearch', async () => {
const keywords = 'search catalog test';
router.push({ query: { keywords } }).catch(() => {});
- wrapper.vm.$nextTick(() => {
- expect(searchCatalogMock).toHaveBeenCalled();
- });
+ await wrapper.vm.$nextTick();
+ expect(searchCatalogMock).toHaveBeenCalled();
});
- it('should reset excluded if a filter changed', () => {
+
+ it('should reset excluded if a filter changed', async () => {
const keywords = 'search reset test';
- wrapper.setData({ excluded: ['item 1'] });
+ await wrapper.setData({ excluded: ['item 1'] });
router.push({ query: { keywords } }).catch(() => {});
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.excluded).toEqual([]);
- });
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.excluded).toEqual([]);
});
- it('should keep excluded if page number changed', () => {
- wrapper.setData({ excluded: ['item 1'] });
+
+ it('should keep excluded if page number changed', async () => {
+ await wrapper.setData({ excluded: ['item 1'] });
router
.push({
query: {
@@ -80,29 +86,31 @@ describe('catalogFilterBar', () => {
},
})
.catch(() => {});
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.excluded).toEqual(['item 1']);
- });
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.excluded).toEqual(['item 1']);
});
});
describe('download workflow', () => {
describe('toggling selection mode', () => {
it('checkboxes and toolbar should be hidden if selecting is false', () => {
- expect(wrapper.find('[data-test="checkbox"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="toolbar"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="checkbox"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="toolbar"]').exists()).toBe(false);
});
- it('should activate when select button is clicked', () => {
- wrapper.find('[data-test="select"]').trigger('click');
+
+ it('should activate when select button is clicked', async () => {
+ await wrapper.findComponent('[data-test="select"]').trigger('click');
expect(wrapper.vm.selecting).toBe(true);
});
- it('clicking cancel should exit selection mode', () => {
- wrapper.setData({ selecting: true });
- wrapper.find('[data-test="cancel"]').trigger('click');
+
+ it('clicking cancel should exit selection mode', async () => {
+ await wrapper.setData({ selecting: true });
+ await wrapper.findComponent('[data-test="cancel"]').trigger('click');
expect(wrapper.vm.selecting).toBe(false);
});
- it('excluded should reset when selection mode is exited', () => {
- wrapper.setData({ selecting: true, excluded: ['item-1', 'item-2'] });
+
+ it('excluded should reset when selection mode is exited', async () => {
+ await wrapper.setData({ selecting: true, excluded: ['item-1', 'item-2'] });
wrapper.vm.setSelection(false);
expect(wrapper.vm.excluded).toHaveLength(0);
});
@@ -110,29 +118,34 @@ describe('catalogFilterBar', () => {
describe('selecting channels', () => {
const excluded = ['item-1'];
- beforeEach(() => {
- wrapper.setData({
+
+ beforeEach(async () => {
+ await wrapper.setData({
selecting: true,
excluded,
});
});
- it('selecting all should select all items on the page', () => {
- wrapper.setData({ excluded: excluded.concat(results) });
+
+ it('selecting all should select all items on the page', async () => {
+ await wrapper.setData({ excluded: excluded.concat(results) });
wrapper.vm.selectAll = true;
expect(wrapper.vm.excluded).toEqual(excluded);
expect(wrapper.vm.selected).toEqual(results);
});
+
it('deselecting all should select all items on the page', () => {
wrapper.vm.selectAll = false;
expect(wrapper.vm.excluded).toEqual(excluded.concat(results));
expect(wrapper.vm.selected).toEqual([]);
});
- it('selecting a channel should remove it from excluded', () => {
- wrapper.setData({ excluded: excluded.concat(results) });
+
+ it('selecting a channel should remove it from excluded', async () => {
+ await wrapper.setData({ excluded: excluded.concat(results) });
wrapper.vm.selected = [results[0]];
expect(wrapper.vm.excluded).toEqual(excluded.concat([results[1]]));
expect(wrapper.vm.selected).toEqual([results[0]]);
});
+
it('deselecting a channel should add it to excluded', () => {
wrapper.vm.selected = [results[0]];
expect(wrapper.vm.excluded).toEqual(excluded.concat([results[1]]));
@@ -141,31 +154,35 @@ describe('catalogFilterBar', () => {
});
describe('download csv', () => {
- const downloadChannelsCSV = jest.fn();
+ let downloadChannelsCSV;
const excluded = ['item-1', 'item-2'];
- beforeEach(() => {
- downloadChannelsCSV.mockReset();
- wrapper.setData({ selecting: true, excluded });
- wrapper.setMethods({ downloadChannelsCSV });
+
+ beforeEach(async () => {
+ await wrapper.setData({ selecting: true, excluded });
+ downloadChannelsCSV = jest.spyOn(wrapper.vm, 'downloadChannelsCSV');
+ downloadChannelsCSV.mockImplementation(() => Promise.resolve());
});
- it('clicking download CSV should call downloadCSV', () => {
- const downloadCSV = jest.fn();
- wrapper.setMethods({ downloadCSV });
- wrapper.find('[data-test="download-csv"]').trigger('click');
- expect(downloadCSV).toHaveBeenCalled();
+
+ it('clicking download CSV should call downloadCSV', async () => {
+ mocks.downloadCSV.mockImplementationOnce(() => Promise.resolve());
+ await wrapper.findComponent('[data-test="download-csv"]').trigger('click');
+ expect(mocks.downloadCSV).toHaveBeenCalled();
});
- it('downloadCSV should call downloadChannelsCSV with current parameters', () => {
+
+ it('downloadCSV should call downloadChannelsCSV with current parameters', async () => {
const keywords = 'Download csv keywords test';
router.replace({ query: { keywords } });
- wrapper.vm.downloadCSV();
+ await wrapper.vm.downloadCSV();
expect(downloadChannelsCSV.mock.calls[0][0].keywords).toBe(keywords);
});
- it('downloadCSV should call downloadChannelsCSV with list of excluded items', () => {
- wrapper.vm.downloadCSV();
+
+ it('downloadCSV should call downloadChannelsCSV with list of excluded items', async () => {
+ await wrapper.vm.downloadCSV();
expect(downloadChannelsCSV.mock.calls[0][0].excluded).toEqual(excluded);
});
- it('downloadCSV should exit selection mode', () => {
- wrapper.vm.downloadCSV();
+
+ it('downloadCSV should exit selection mode', async () => {
+ await wrapper.vm.downloadCSV();
expect(wrapper.vm.selecting).toBe(false);
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelInvitation.spec.js b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelInvitation.spec.js
index ee43657298..42a2e9a922 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelInvitation.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelInvitation.spec.js
@@ -24,23 +24,27 @@ function makeWrapper() {
describe('channelInvitation', () => {
let wrapper;
+
beforeEach(() => {
wrapper = makeWrapper();
});
- it('clicking on the accept button should accept the invitation', () => {
- const acceptInvitation = jest.fn().mockReturnValue(Promise.resolve());
- wrapper.setMethods({ acceptInvitation });
- wrapper.find('[data-test="accept"]').trigger('click');
+
+ it('clicking on the accept button should accept the invitation', async () => {
+ const acceptInvitation = jest.spyOn(wrapper.vm, 'acceptInvitation');
+ acceptInvitation.mockImplementation(() => Promise.resolve());
+ await wrapper.find('[data-test="accept"]').trigger('click');
expect(acceptInvitation).toHaveBeenCalledWith(invitationID);
});
- it('clicking on the decline button should open confirmation modal', () => {
- wrapper.find('[data-test="decline"]').trigger('click');
+
+ it('clicking on the decline button should open confirmation modal', async () => {
+ await wrapper.find('[data-test="decline"]').trigger('click');
expect(wrapper.vm.dialog).toBe(true);
});
- it('clicking on the decline button should decline the invitation', () => {
- const declineInvitation = jest.fn().mockReturnValue(Promise.resolve());
- wrapper.setMethods({ declineInvitation });
- wrapper.find('[data-test="decline-close"]').trigger('click');
+
+ it('clicking on the decline button should decline the invitation', async () => {
+ const declineInvitation = jest.spyOn(wrapper.vm, 'declineInvitation');
+ declineInvitation.mockImplementation(() => Promise.resolve());
+ await wrapper.find('[data-test="decline-close"]').trigger('click');
expect(declineInvitation).toHaveBeenCalledWith(invitationID);
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelItem.spec.js b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelItem.spec.js
index 1e8b9d63d4..bee20bfd13 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelItem.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/channelItem.spec.js
@@ -1,6 +1,4 @@
-import Vue from 'vue';
import { mount } from '@vue/test-utils';
-import VueRouter from 'vue-router';
import { factory } from '../../../store';
import router from '../../../router';
import { RouteNames } from '../../../constants';
@@ -8,12 +6,13 @@ import ChannelItem from '../ChannelItem.vue';
const store = factory();
-Vue.use(VueRouter);
const channelId = 'testing';
const channel = {
id: channelId,
edit: true,
published: true,
+ last_published: new Date().getTime() - 100000,
+ modified: new Date().getTime() - 100000,
};
store.state.session.currentUser.id = 0;
@@ -38,75 +37,76 @@ function makeWrapper(allowEdit, deleteStub, libraryMode) {
},
},
});
- wrapper.setMethods({
- handleDelete: deleteStub,
- });
+ const deleteSpy = jest.spyOn(wrapper.vm, 'deleteChannel');
+ if (deleteStub) {
+ deleteSpy.mockImplementation(deleteStub);
+ } else {
+ deleteSpy.mockImplementation(() => {});
+ }
return wrapper;
}
describe('channelItem', () => {
let wrapper;
const deleteStub = jest.fn();
+
beforeEach(() => {
deleteStub.mockReset();
wrapper = makeWrapper(true, deleteStub);
});
- afterEach(() => {
+
+ afterEach(async () => {
// Delete dialog and token dialog use primary modal component, so
// leaving either to be true will block subsequent modals from opening
- wrapper.setData({ deleteDialog: false, tokenDialog: false });
+ await wrapper.setData({ deleteDialog: false, tokenDialog: false });
});
+
it('edit options should be hidden if edit mode is off', () => {
wrapper = makeWrapper(false, deleteStub);
- expect(wrapper.find('[data-test="edit-channel"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="edit-channel"]').exists()).toBe(false);
});
- it('clicking the channel should open the channel', () => {
- wrapper.find('[data-test="channel-card"]').trigger('click');
+
+ it('clicking the channel should open the channel', async () => {
+ await wrapper.findComponent('[data-test="channel-card"]').trigger('click');
expect(wrapper.vm.$route.name).toEqual(RouteNames.CHANNELS_EDITABLE);
});
- it('clicking edit channel should open a channel editor modal', () => {
- wrapper.find('[data-test="edit-channel"]').trigger('click');
+
+ it('clicking edit channel should open a channel editor modal', async () => {
+ await wrapper.findComponent('[data-test="edit-channel"]').trigger('click');
expect(wrapper.vm.$route.name).toEqual(RouteNames.CHANNEL_EDIT);
});
- it('clicking the info icon should open a channel details modal ', () => {
- wrapper.find('[data-test="details-button"]').trigger('click');
+
+ it('clicking the info icon should open a channel details modal ', async () => {
+ await wrapper.findComponent('[data-test="details-button"]').trigger('click');
expect(wrapper.vm.$route.name).toEqual(RouteNames.CHANNEL_DETAILS);
});
- it('clicking the token option should open the token modal', () => {
- wrapper.find('[data-test="token-listitem"]').trigger('click');
+
+ it('clicking the token option should open the token modal', async () => {
+ await wrapper.findComponent('[data-test="token-listitem"]').trigger('click');
expect(wrapper.vm.tokenDialog).toBe(true);
});
+
it('when user can edit, clicking delete button in dialog should call deleteChannel', async () => {
- const deleteChannelSpy = jest.fn().mockResolvedValue();
- const removeViewerSpy = jest.fn().mockResolvedValue();
- wrapper = makeWrapper(true, deleteStub);
- wrapper.setMethods({
- deleteChannel: deleteChannelSpy,
- removeViewer: removeViewerSpy,
- });
+ const removeViewerSpy = jest.spyOn(wrapper.vm, 'removeViewer');
+ removeViewerSpy.mockResolvedValue();
- wrapper.setData({ deleteDialog: true });
- wrapper.find('[data-test="delete-modal"]').trigger('submit');
+ await wrapper.setData({ deleteDialog: true });
+ await wrapper.findComponent('[data-test="delete-modal"]').trigger('submit');
await wrapper.vm.$nextTick(() => {
- expect(deleteChannelSpy).toHaveBeenCalledWith(channelId);
+ expect(deleteStub).toHaveBeenCalledWith(channelId);
expect(removeViewerSpy).not.toHaveBeenCalled();
});
});
it('when user cannot edit, clicking delete button in dialog should call removeViewer', async () => {
- const deleteChannelSpy = jest.fn().mockResolvedValue();
- const removeViewerSpy = jest.fn().mockResolvedValue();
- wrapper = makeWrapper(false, deleteStub);
- wrapper.setMethods({
- deleteChannel: deleteChannelSpy,
- removeViewer: removeViewerSpy,
- });
+ const removeViewerSpy = jest.spyOn(wrapper.vm, 'removeViewer');
+ removeViewerSpy.mockResolvedValue();
- wrapper.setData({ deleteDialog: true });
- wrapper.find('[data-test="delete-modal"]').trigger('submit');
+ await wrapper.setData({ deleteDialog: true });
+ await wrapper.findComponent('[data-test="delete-modal"]').trigger('submit');
await wrapper.vm.$nextTick(() => {
expect(removeViewerSpy).toHaveBeenCalledWith({ channelId, userId: 0 });
- expect(deleteChannelSpy).not.toHaveBeenCalled();
+ expect(deleteStub).not.toHaveBeenCalled();
});
});
@@ -114,20 +114,23 @@ describe('channelItem', () => {
beforeEach(() => {
wrapper = makeWrapper(false, null, true);
});
- it('clicking channel card should open details modal', () => {
- wrapper.find('[data-test="channel-card"]').trigger('click');
+
+ it('clicking channel card should open details modal', async () => {
+ await wrapper.findComponent('[data-test="channel-card"]').trigger('click');
expect(wrapper.vm.$route.name).toEqual(RouteNames.CHANNEL_DETAILS);
});
- it('clicking the token button should open the token modal', () => {
- wrapper.setData({ tokenDialog: false });
- wrapper.find('[data-test="token-button"]').trigger('click');
+
+ it('clicking the token button should open the token modal', async () => {
+ await wrapper.setData({ tokenDialog: false });
+ await wrapper.findComponent('[data-test="token-button"]').trigger('click');
expect(wrapper.vm.tokenDialog).toBe(true);
});
+
it('certain menu options should be hidden', () => {
- expect(wrapper.find('[data-test="edit-channel"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="delete-channel"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="token-listitem"]').exists()).toBe(false);
- expect(wrapper.find('[data-test="details-button"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="edit-channel"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="delete-channel"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="token-listitem"]').exists()).toBe(false);
+ expect(wrapper.findComponent('[data-test="details-button"]').exists()).toBe(false);
});
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/mixins.spec.js b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/mixins.spec.js
index 299d75b435..29c366e4f6 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/mixins.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/mixins.spec.js
@@ -11,7 +11,7 @@ describe('mixins', () => {
{
mixins: [catalogFilterMixin],
},
- { router }
+ { router },
);
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/star.spec.js b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/star.spec.js
index c1a33b60cf..12c69f8460 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/star.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/__tests__/star.spec.js
@@ -10,9 +10,7 @@ function makeWrapper(bookmark, toggleStub) {
channelId,
},
});
- wrapper.setMethods({
- toggleStar: toggleStub,
- });
+ jest.spyOn(wrapper.vm, 'toggleStar').mockImplementation(toggleStub);
return wrapper;
}
@@ -20,16 +18,19 @@ describe('star', () => {
let starredWrapper;
let unstarredWrapper;
const toggleStub = jest.fn();
+
beforeEach(() => {
starredWrapper = makeWrapper(true, toggleStub);
unstarredWrapper = makeWrapper(false, toggleStub);
});
+
it('should reflect correct star on load', () => {
expect(starredWrapper.find('[data-test="button"]').vm.icon).toBe('star');
expect(unstarredWrapper.find('[data-test="button"]').vm.icon).toBe('starBorder');
});
- it('toggle the bookmark when clicked', () => {
- starredWrapper.find('[data-test="button"]').trigger('click');
+
+ it('toggle the bookmark when clicked', async () => {
+ await starredWrapper.findComponent('[data-test="button"]').trigger('click');
expect(toggleStub).toHaveBeenCalled();
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vue b/contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vue
index 3bb72c61c2..40ceee7887 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vue
+++ b/contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vue
@@ -18,9 +18,15 @@
@blur="resetScroll"
>
-
+
-
+
{{ item.name }}
@@ -38,9 +44,16 @@
class="mb-0 mt-1 scroll-margin"
:labelDir="null"
>
-
+
-
+
{{ item.name }}
@@ -123,6 +136,7 @@
+
+
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
index b35725f43a..a7befd7c43 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vuex from 'vuex';
+import { Store } from 'vuex';
import ChannelSelectionList from '../ChannelSelectionList';
import { ChannelListTypes } from 'shared/constants';
@@ -35,7 +35,7 @@ const actions = {
loadChannelList: jest.fn(() => Promise.resolve()),
};
-const store = new Vuex.Store({
+const store = new Store({
modules: {
channel: {
namespaced: true,
@@ -46,8 +46,10 @@ const store = new Vuex.Store({
});
function makeWrapper() {
- return mount(ChannelSelectionList, {
- sync: false,
+ const loadChannelList = jest.spyOn(ChannelSelectionList.methods, 'loadChannelList');
+ loadChannelList.mockImplementation(() => Promise.resolve());
+
+ const wrapper = mount(ChannelSelectionList, {
propsData: {
listType: ChannelListTypes.EDITABLE,
},
@@ -56,54 +58,62 @@ function makeWrapper() {
return [editChannel, editChannel2, publicChannel];
},
},
- methods: {
- loadChannelList() {
- return Promise.resolve();
- },
- },
store,
});
+
+ return [wrapper, { loadChannelList }];
}
describe('channelSelectionList', () => {
- let wrapper;
+ let wrapper, mocks;
+
beforeEach(() => {
- wrapper = makeWrapper();
+ [wrapper, mocks] = makeWrapper();
+ });
+
+ afterEach(() => {
+ mocks.loadChannelList.mockRestore();
});
- it('should show the correct channels based on listType', () => {
- wrapper.setData({ loading: false });
+
+ it('should show the correct channels based on listType', async () => {
+ await wrapper.setData({ loading: false });
expect(wrapper.vm.listChannels.find(c => c.id === editChannel.id)).toBeTruthy();
expect(wrapper.vm.listChannels.find(c => c.id === editChannel2.id)).toBeTruthy();
expect(wrapper.vm.listChannels.find(c => c.id === publicChannel.id)).toBeFalsy();
});
- it('should select channels when the channel has been checked', () => {
- wrapper.setData({ loading: false });
- wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click();
+
+ it('should select channels when the channel has been checked', async () => {
+ await wrapper.setData({ loading: false });
+ await wrapper.findComponent(`[data-test="checkbox-${editChannel.id}"]`).trigger('click');
expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]);
});
- it('should deselect channels when the channel has been unchecked', () => {
- wrapper.setData({ loading: false });
- wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click(); // Check the channel
- wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click(); // Uncheck the channel
+
+ it('should deselect channels when the channel has been unchecked', async () => {
+ await wrapper.setData({ loading: false });
+ await wrapper.findComponent(`[data-test="checkbox-${editChannel.id}"]`).trigger('click'); // Check the channel
+ await wrapper.findComponent(`[data-test="checkbox-${editChannel.id}"]`).trigger('click'); // Uncheck the channel
expect(wrapper.emitted('input')[0].length).toEqual(1); // Only one event should be emitted (corresponding to the initial check)
expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]); // The initial check event should be emitted
});
- it('should filter channels based on the search text', () => {
- wrapper.setData({ loading: false, search: searchWord });
+
+ it('should filter channels based on the search text', async () => {
+ await wrapper.setData({ loading: false, search: searchWord });
expect(wrapper.vm.listChannels.find(c => c.id === editChannel.id)).toBeTruthy();
expect(wrapper.vm.listChannels.find(c => c.id === editChannel2.id)).toBeFalsy();
});
- it('should select channels when the channel card has been clicked', () => {
- wrapper.setData({ loading: false });
- wrapper.find(`[data-test="channel-item-${editChannel.id}"]`).trigger('click');
+
+ it('should select channels when the channel card has been clicked', async () => {
+ await wrapper.setData({ loading: false });
+ await wrapper.findComponent(`[data-test="channel-item-${editChannel.id}"]`).trigger('click');
expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]);
});
- it('should deselect channels when the channel card has been clicked', () => {
- wrapper.setData({ loading: false });
- wrapper.find(`[data-test="channel-item-${editChannel.id}"]`).element.click(); // Check the channel
- wrapper.find(`[data-test="channel-item-${editChannel.id}"]`).element.click(); // Uncheck the channel
+
+ it('should deselect channels when the channel card has been clicked', async () => {
+ await wrapper.setData({ loading: false });
+ await wrapper.findComponent(`[data-test="channel-item-${editChannel.id}"]`).trigger('click'); // Check the channel
+ await wrapper.findComponent(`[data-test="channel-item-${editChannel.id}"]`).trigger('click'); // Uncheck the channel
expect(wrapper.emitted('input')[0].length).toEqual(1); // Only one event should be emitted (corresponding to the initial check)
expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]); // The initial check event should be emitted
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetItem.spec.js b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetItem.spec.js
index bd6f048c68..bbb57080e3 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetItem.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetItem.spec.js
@@ -14,33 +14,33 @@ const channelSet = {
store.commit('channelSet/ADD_CHANNELSET', channelSet);
-function makeWrapper(deleteStub) {
+function makeWrapper() {
const wrapper = mount(ChannelSetItem, {
router,
store,
sync: false,
propsData: { channelSetId: channelSet.id },
});
- wrapper.setMethods({
- deleteChannelSet: deleteStub,
- });
- return wrapper;
+ const deleteChannelSet = jest.spyOn(wrapper.vm, 'deleteChannelSet');
+ deleteChannelSet.mockImplementation(() => Promise.resolve());
+ return [wrapper, { deleteChannelSet }];
}
describe('channelSetItem', () => {
- let wrapper;
- const deleteStub = jest.fn();
+ let wrapper, mocks;
+
beforeEach(() => {
- deleteStub.mockReset();
- wrapper = makeWrapper(deleteStub);
+ [wrapper, mocks] = makeWrapper();
});
+
it('clicking the edit option should open the channel set edit modal', () => {
wrapper.find('[data-test="edit"]').trigger('click');
expect(wrapper.vm.$route.name).toEqual(RouteNames.CHANNEL_SET_DETAILS);
});
+
it('clicking delete button in dialog should delete the channel set', () => {
wrapper.vm.deleteDialog = true;
wrapper.find('[data-test="delete"]').trigger('click');
- expect(deleteStub).toHaveBeenCalled();
+ expect(mocks.deleteChannelSet).toHaveBeenCalled();
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetList.spec.js b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetList.spec.js
index 22eb2189e8..61fb53847a 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetList.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetList.spec.js
@@ -6,26 +6,21 @@ import ChannelSetList from '../ChannelSetList.vue';
const store = factory();
-const id = '00000000000000000000000000000000';
-
-function makeWrapper(createChannelSetStub) {
+function makeWrapper() {
router.push({
name: RouteNames.CHANNEL_SETS,
});
- const wrapper = mount(ChannelSetList, { store, router });
- wrapper.setMethods({
- createChannelSet: createChannelSetStub,
- });
- return wrapper;
+ return mount(ChannelSetList, { store, router });
}
describe('channelSetList', () => {
let wrapper;
- const createChannelSetStub = jest.fn().mockImplementation(() => Promise.resolve(id));
- beforeEach(() => {
- wrapper = makeWrapper(createChannelSetStub);
- wrapper.setData({ loading: false });
+
+ beforeEach(async () => {
+ wrapper = makeWrapper();
+ await wrapper.setData({ loading: false });
});
+
it('should open a new channel set modal when new set button is clicked', async () => {
const push = jest.fn();
wrapper.vm.$router.push = push;
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetModal.spec.js b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetModal.spec.js
index 5c417f3fcc..959b677c5e 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetModal.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSetModal.spec.js
@@ -38,13 +38,6 @@ const CHANNEL_SET = {
},
};
-const loadChannelSetMock = (cs, store) => {
- return jest.fn().mockImplementation(() => {
- store.commit('channelSet/ADD_CHANNELSET', cs);
- return Promise.resolve(cs);
- });
-};
-
const makeWrapper = ({ store, channelSetId }) => {
if (router.currentRoute.name !== RouteNames.CHANNEL_SET_DETAILS) {
router.push({
@@ -55,48 +48,47 @@ const makeWrapper = ({ store, channelSetId }) => {
});
}
- const loadChannelSet = loadChannelSetMock(CHANNEL_SET, store);
- const loadChannelList = jest.fn().mockImplementation(() => Promise.resolve(CHANNEL_SET.channels));
+ const loadChannelSet = jest.spyOn(ChannelSetModal.methods, 'loadChannelSet');
+ loadChannelSet.mockImplementation(() => {
+ store.commit('channelSet/ADD_CHANNELSET', CHANNEL_SET);
+ return Promise.resolve(CHANNEL_SET);
+ });
+ const loadChannelList = jest.spyOn(ChannelSetModal.methods, 'loadChannelList');
+ loadChannelList.mockImplementation(() => Promise.resolve(CHANNEL_SET.channels));
const wrapper = mount(ChannelSetModal, {
propsData: {
channelSetId,
},
- methods: {
- loadChannelSet,
- loadChannelList,
- },
router,
localVue,
store,
});
- wrapper.loadChannelSet = loadChannelSet;
- wrapper.loadChannelList = loadChannelList;
- return wrapper;
+ return [wrapper, { loadChannelSet, loadChannelList }];
};
const getCollectionNameInput = wrapper => {
- return wrapper.find('[data-test="input-name"]');
+ return wrapper.findComponent('[data-test="input-name"]');
};
const getUnsavedDialog = wrapper => {
- return wrapper.find('[data-test="dialog-unsaved"]');
+ return wrapper.findComponent('[data-test="dialog-unsaved"]');
};
const getCloseButton = wrapper => {
- return wrapper.find('[data-test="close"]');
+ return wrapper.findComponent('[data-test="close"]');
};
const getSaveButton = wrapper => {
- return wrapper.find('[data-test="button-save"]');
+ return wrapper.findComponent('[data-test="button-save"]');
};
const getSelectChannelsButton = wrapper => {
- return wrapper.find('[data-test="button-select"]');
+ return wrapper.findComponent('[data-test="button-select"]');
};
const getFinishButton = wrapper => {
- return wrapper.find('[data-test="button-finish"]');
+ return wrapper.findComponent('[data-test="button-finish"]');
};
describe('ChannelSetModal', () => {
@@ -107,51 +99,52 @@ describe('ChannelSetModal', () => {
it('should show collection channels view at first', () => {
const storeConfig = cloneDeep(STORE_CONFIG);
const store = storeFactory(storeConfig);
- const wrapper = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
+ const [wrapper] = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
expect(wrapper.find('[data-test="collection-channels-view"]').isVisible()).toBe(true);
});
describe('if there are no data for a channel set yet', () => {
- let wrapper;
+ let mocks;
+
beforeEach(() => {
const storeConfig = cloneDeep(STORE_CONFIG);
const store = storeFactory(storeConfig);
- wrapper = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
+ mocks = makeWrapper({ store, channelSetId: CHANNEL_SET.id })[1];
});
it('should load the channel set', () => {
- expect(wrapper.loadChannelSet).toHaveBeenCalledTimes(1);
- expect(wrapper.loadChannelSet.mock.calls[0][0]).toBe(CHANNEL_SET.id);
+ expect(mocks.loadChannelSet).toHaveBeenCalledTimes(1);
+ expect(mocks.loadChannelSet.mock.calls[0][0]).toBe(CHANNEL_SET.id);
});
it('should load channels of the channel set', () => {
- expect(wrapper.loadChannelList).toHaveBeenCalledTimes(1);
- expect(wrapper.loadChannelList.mock.calls[0][0]).toEqual({
+ expect(mocks.loadChannelList).toHaveBeenCalledTimes(1);
+ expect(mocks.loadChannelList.mock.calls[0][0]).toEqual({
id__in: [CHANNEL_1.id, CHANNEL_2.id],
});
});
});
describe('if a channel set has been already loaded', () => {
- let store, wrapper;
+ let store, mocks;
beforeEach(() => {
const storeConfig = cloneDeep(STORE_CONFIG);
store = storeFactory(storeConfig);
store.commit('channelSet/ADD_CHANNELSET', CHANNEL_SET);
- wrapper = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
+ mocks = makeWrapper({ store, channelSetId: CHANNEL_SET.id })[1];
});
it("shouldn't load the channel set", () => {
- expect(wrapper.loadChannelSet).not.toHaveBeenCalled();
+ expect(mocks.loadChannelSet).not.toHaveBeenCalled();
});
it('should load channels from the channel set', () => {
- expect(wrapper.loadChannelList).toHaveBeenCalledTimes(1);
- expect(wrapper.loadChannelList.mock.calls[0][0]).toEqual({
+ expect(mocks.loadChannelList).toHaveBeenCalledTimes(1);
+ expect(mocks.loadChannelList.mock.calls[0][0]).toEqual({
id__in: [CHANNEL_1.id, CHANNEL_2.id],
});
});
@@ -169,7 +162,7 @@ describe('ChannelSetModal', () => {
store.commit('channelSet/ADD_CHANNELSET', CHANNEL_SET);
store.commit('channel/ADD_CHANNELS', [CHANNEL_1, CHANNEL_2]);
- wrapper = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
+ [wrapper] = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
});
it('should render a collection name input', () => {
@@ -189,53 +182,45 @@ describe('ChannelSetModal', () => {
});
it('should render a correct channels count', () => {
- expect(wrapper.find('.subheading').html()).toContain('2 channels');
+ expect(wrapper.findComponent('.subheading').html()).toContain('2 channels');
});
it("should render channels' names, descriptions and remove buttons", () => {
- const channelItems = wrapper.findAll({ name: 'ChannelItem' });
+ const channelItems = wrapper.findAllComponents({ name: 'ChannelItem' });
expect(channelItems.length).toBe(2);
expect(channelItems.at(0).html()).toContain('Channel 1');
expect(channelItems.at(0).html()).toContain('First channel description');
- expect(
- channelItems
- .at(0)
- .find('button')
- .text()
- ).toBe('Remove');
+ expect(channelItems.at(0).find('button').text()).toBe('Remove');
expect(channelItems.at(1).html()).toContain('Channel 2');
expect(channelItems.at(1).html()).toContain('Second channel description');
- expect(
- channelItems
- .at(1)
- .find('button')
- .text()
- ).toBe('Remove');
+ expect(channelItems.at(1).find('button').text()).toBe('Remove');
});
it('clicking select channels button should navigate to channels selection view', async () => {
- getSelectChannelsButton(wrapper).trigger('click');
+ await getSelectChannelsButton(wrapper).trigger('click');
await wrapper.vm.$nextTick();
- expect(wrapper.find('[data-test="collection-channels-view"]').isVisible()).toBe(false);
- expect(wrapper.find('[data-test="channels-selection-view"]').isVisible()).toBe(true);
+ expect(wrapper.findComponent('[data-test="collection-channels-view"]').isVisible()).toBe(
+ false,
+ );
+ expect(wrapper.findComponent('[data-test="channels-selection-view"]').isVisible()).toBe(true);
});
describe('clicking close button', () => {
- it('should redirect to channel sets page', () => {
- getCloseButton(wrapper).trigger('click');
+ it('should redirect to channel sets page', async () => {
+ await getCloseButton(wrapper).trigger('click');
expect(wrapper.vm.$route.name).toBe(RouteNames.CHANNEL_SETS);
});
- it('should prompt user if there are unsaved changes', () => {
+ it('should prompt user if there are unsaved changes', async () => {
expect(getUnsavedDialog(wrapper).attributes('data-test-visible')).toBeFalsy();
- getCollectionNameInput(wrapper).setValue('My collection');
- getCloseButton(wrapper).trigger('click');
+ await getCollectionNameInput(wrapper).setValue('My collection');
+ await getCloseButton(wrapper).trigger('click');
expect(getUnsavedDialog(wrapper).attributes('data-test-visible')).toBeTruthy();
});
@@ -243,24 +228,24 @@ describe('ChannelSetModal', () => {
describe('clicking save button', () => {
it("shouldn't update a channel set when a collection name is missing", async () => {
- getCollectionNameInput(wrapper).setValue('');
- getSaveButton(wrapper).trigger('click');
+ await getCollectionNameInput(wrapper).setValue('');
+ await getSaveButton(wrapper).trigger('click');
await flushPromises();
expect(updateChannelSet).not.toHaveBeenCalled();
});
it("shouldn't update a channel set when a collection name is made of empty characters", async () => {
- getCollectionNameInput(wrapper).setValue(' ');
- getSaveButton(wrapper).trigger('click');
+ await getCollectionNameInput(wrapper).setValue(' ');
+ await getSaveButton(wrapper).trigger('click');
await flushPromises();
expect(updateChannelSet).not.toHaveBeenCalled();
});
it('should update a channel set when a collection name is valid', async () => {
- getCollectionNameInput(wrapper).setValue('My collection');
- getSaveButton(wrapper).trigger('click');
+ await getCollectionNameInput(wrapper).setValue('My collection');
+ await getSaveButton(wrapper).trigger('click');
await flushPromises();
expect(updateChannelSet).toHaveBeenCalledTimes(1);
@@ -282,26 +267,31 @@ describe('ChannelSetModal', () => {
store.commit('channelSet/ADD_CHANNELSET', CHANNEL_SET);
store.commit('channel/ADD_CHANNELS', [CHANNEL_1, CHANNEL_2]);
- wrapper = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
+ [wrapper] = makeWrapper({ store, channelSetId: CHANNEL_SET.id });
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
- getSelectChannelsButton(wrapper).trigger('click');
+ await getSelectChannelsButton(wrapper).trigger('click');
await wrapper.vm.$nextTick();
- expect(wrapper.find('[data-test="channels-selection-view"]').isVisible()).toBe(true);
+ expect(wrapper.findComponent('[data-test="channels-selection-view"]').isVisible()).toBe(true);
});
- it('should render finish button', () => {
+ it('should render finish button', async () => {
+ expect(wrapper.vm.step).toBe(2);
expect(getFinishButton(wrapper).isVisible()).toBe(true);
});
it('clicking finish button should navigate back to collection channels view', async () => {
- getFinishButton(wrapper).trigger('click');
+ await getFinishButton(wrapper).trigger('click');
await wrapper.vm.$nextTick();
- expect(wrapper.find('[data-test="channels-selection-view"]').isVisible()).toBe(false);
- expect(wrapper.find('[data-test="collection-channels-view"]').isVisible()).toBe(true);
+ expect(wrapper.findComponent('[data-test="channels-selection-view"]').isVisible()).toBe(
+ false,
+ );
+ expect(wrapper.findComponent('[data-test="collection-channels-view"]').isVisible()).toBe(
+ true,
+ );
});
});
});
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/actions.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/actions.js
index 93cf0405c4..a6ad8b7802 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/actions.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/actions.js
@@ -48,7 +48,7 @@ export function loadInvitationList(context) {
}).then(invitations => {
context.commit(
'SET_INVITATION_LIST',
- invitations.filter(i => !i.accepted && !i.declined && !i.revoked)
+ invitations.filter(i => !i.accepted && !i.declined && !i.revoked),
);
return invitations;
});
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/getters.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/getters.js
index 93e35359f7..614dd8ebd2 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/getters.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/getters.js
@@ -3,13 +3,13 @@ export function invitations(state) {
}
export function getInvitation(state) {
- return function(invitationId) {
+ return function (invitationId) {
return state.invitationsMap[invitationId];
};
}
export function getChannelDetails(state) {
- return function(channelId) {
+ return function (channelId) {
return state.channelDetailsMap[channelId];
};
}
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/mutations.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/mutations.js
index fa019b99be..f5e334d21f 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelList/mutations.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelList/mutations.js
@@ -10,7 +10,7 @@ export function SET_PAGE(
count = null,
total_pages = null,
results = [],
- } = {}
+ } = {},
) {
state.page.next = next;
state.page.previous = previous;
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/actions.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/actions.js
index 01832ea1e9..0a9556f3f0 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/actions.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/actions.js
@@ -39,7 +39,7 @@ export function createChannelSet(context) {
export function commitChannelSet(
context,
- { id, name = NOVALUE, description = NOVALUE, channels = [] } = {}
+ { id, name = NOVALUE, description = NOVALUE, channels = [] } = {},
) {
const channelSetData = {};
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/getters.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/getters.js
index 15844d468a..a7c0c71348 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/getters.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/getters.js
@@ -3,7 +3,7 @@ export function channelSets(state) {
}
export function getChannelSet(state) {
- return function(channelSetId) {
+ return function (channelSetId) {
const channelSet = state.channelSetsMap[channelSetId];
if (channelSet) {
return {
@@ -16,7 +16,7 @@ export function getChannelSet(state) {
}
export function getChannelSetIsValid(state) {
- return function(channelSetId) {
+ return function (channelSetId) {
const set = state.channelSetsMap[channelSetId];
return set && set.name && set.name.length > 0;
};
diff --git a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/mutations.js b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/mutations.js
index bbca8457ad..d2371db718 100644
--- a/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/mutations.js
+++ b/contentcuration/contentcuration/frontend/channelList/vuex/channelSet/mutations.js
@@ -1,4 +1,4 @@
-import Vue from 'vue';
+import Vue, { set } from 'vue';
import { NEW_OBJECT } from 'shared/constants';
import { applyMods } from 'shared/data/applyRemoteChanges';
@@ -34,12 +34,12 @@ export function UPDATE_CHANNELSET(state, { id, ...payload }) {
export function UPDATE_CHANNELSET_FROM_INDEXEDDB(state, { id, ...mods }) {
if (id && state.channelSetsMap[id]) {
- Vue.set(state.channelSetsMap, id, { ...applyMods(state.channelSetsMap[id], mods) });
+ set(state.channelSetsMap, id, { ...applyMods(state.channelSetsMap[id], mods) });
}
}
export function ADD_CHANNEL_TO_CHANNELSET(state, { channelSetId, channelId }) {
- Vue.set(state.channelSetsMap[channelSetId].channels, channelId, true);
+ set(state.channelSetsMap[channelSetId].channels, channelId, true);
}
export function REMOVE_CHANNEL_FROM_CHANNELSET(state, { channelSetId, channelId }) {
diff --git a/contentcuration/contentcuration/frontend/settings/pages/Account/ChangePasswordForm.vue b/contentcuration/contentcuration/frontend/settings/pages/Account/ChangePasswordForm.vue
index 8394fb4e2c..eaae2e1826 100644
--- a/contentcuration/contentcuration/frontend/settings/pages/Account/ChangePasswordForm.vue
+++ b/contentcuration/contentcuration/frontend/settings/pages/Account/ChangePasswordForm.vue
@@ -9,7 +9,10 @@
@cancel="dialog = false"
>
-
+
+
-
+
diff --git a/contentcuration/contentcuration/frontend/settings/pages/Account/DeleteAccountForm.vue b/contentcuration/contentcuration/frontend/settings/pages/Account/DeleteAccountForm.vue
index da2ecc9ec4..438a4f1c93 100644
--- a/contentcuration/contentcuration/frontend/settings/pages/Account/DeleteAccountForm.vue
+++ b/contentcuration/contentcuration/frontend/settings/pages/Account/DeleteAccountForm.vue
@@ -29,6 +29,7 @@
+
+
diff --git a/contentcuration/contentcuration/frontend/settings/pages/SettingsIndex.vue b/contentcuration/contentcuration/frontend/settings/pages/SettingsIndex.vue
index 6bcc512626..3950a6f140 100644
--- a/contentcuration/contentcuration/frontend/settings/pages/SettingsIndex.vue
+++ b/contentcuration/contentcuration/frontend/settings/pages/SettingsIndex.vue
@@ -17,14 +17,20 @@
-
+
-
+
diff --git a/contentcuration/contentcuration/frontend/settings/pages/Storage/RequestForm.vue b/contentcuration/contentcuration/frontend/settings/pages/Storage/RequestForm.vue
index 1786e73991..e400c8a57f 100644
--- a/contentcuration/contentcuration/frontend/settings/pages/Storage/RequestForm.vue
+++ b/contentcuration/contentcuration/frontend/settings/pages/Storage/RequestForm.vue
@@ -1,7 +1,9 @@
- |