Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were moved to be their own test files

Original file line number Diff line number Diff line change
@@ -1,53 +1,13 @@
/* eslint-disable vue/one-component-per-file */
import { defineComponent, ref } from 'vue';
import { mount } from '@vue/test-utils';

import VueRouter from 'vue-router';
import { useTable } from '../useTable';
import { useKeywordSearch } from '../useKeywordSearch';
import { useFilter } from '../useFilter';

// Because we are testing composables that use the router,
// we need to create a dummy component that uses the composable
// and test that component with a router instance.

function makeFilterWrapper() {
const router = new VueRouter({
routes: [],
});
const component = defineComponent({
setup() {
const filterMap = ref({});
return {
...useFilter({ name: 'testFilter', filterMap }),
// eslint-disable-next-line vue/no-unused-properties
filterMap,
};
},
});

return mount(component, {
router,
});
}

function makeKeywordSearchWrapper() {
const router = new VueRouter({
routes: [],
});
const component = defineComponent({
setup() {
return {
...useKeywordSearch(),
};
},
});

return mount(component, {
router,
});
}

function makeTableWrapper() {
const router = new VueRouter({
routes: [],
Expand All @@ -74,114 +34,6 @@ function makeTableWrapper() {
});
}

describe('useFilter', () => {
let wrapper;
beforeEach(() => {
wrapper = makeFilterWrapper();
wrapper.vm.$router.push({ query: {} }).catch(() => {});
});

it('setting filter sets query params', () => {
wrapper.vm.filterMap = {
a: { label: 'A', params: { a: '1', b: '2' } },
b: { label: 'B', params: { b: '3', c: '4' } },
};
wrapper.vm.$router.push({ query: { testFilter: 'b', otherParam: 'value' } });

wrapper.vm.filter = 'a';
expect(wrapper.vm.$route.query).toEqual({ testFilter: 'a', otherParam: 'value' });
});

describe('filter is determined from query params', () => {
it('when filter params are provided', () => {
wrapper.vm.filterMap = {
a: { label: 'A', params: { a: '1', b: '2' } },
b: { label: 'B', params: { b: '3', c: '4' } },
};
wrapper.vm.$router.push({ query: { testFilter: 'a', otherParam: 'value' } });
expect(wrapper.vm.filter).toBe('a');
});

it('when filter params are not provided', () => {
wrapper.vm.filterMap = {
a: { label: 'A', params: { a: '1', b: '2' } },
b: { label: 'B', params: { b: '3', c: '4' } },
};
wrapper.vm.$router.push({ query: { otherParam: 'value' } });
expect(wrapper.vm.filter).toBe(undefined);
});
});

it('setting the filter updates fetch query params', () => {
wrapper.vm.filterMap = {
a: { label: 'A', params: { a: '1', b: '2' } },
b: { label: 'B', params: { b: '3', c: '4' } },
};
wrapper.vm.filter = 'a';
expect(wrapper.vm.fetchQueryParams).toEqual({ a: '1', b: '2' });
});

it('filters are correctly computed from filterMap', () => {
wrapper.vm.filterMap = {
a: { label: 'A', params: { a: '1', b: '2' } },
b: { label: 'B', params: { b: '3', c: '4' } },
};
expect(wrapper.vm.filters).toEqual([
{ key: 'a', label: 'A' },
{ key: 'b', label: 'B' },
]);
});
});

describe('useKeywordSearch', () => {
let wrapper;
beforeEach(() => {
wrapper = makeKeywordSearchWrapper();
wrapper.vm.$router.push({ query: {} }).catch(() => {});
});

it('setting keywords sets query params', () => {
wrapper.vm.$router.push({ query: { a: '1', page: '2' } });
wrapper.vm.keywordInput = 'test';

jest.useFakeTimers();
wrapper.vm.setKeywords();
jest.runAllTimers();
jest.useRealTimers();

expect(wrapper.vm.$route.query).toEqual({ a: '1', keywords: 'test', page: '2' });
});

it('setting query params sets keywords', async () => {
wrapper.vm.$router.push({ query: { keywords: 'test' } });
await wrapper.vm.$nextTick();

expect(wrapper.vm.keywordInput).toBe('test');
});

it('calling clearSearch clears keywords and query param', async () => {
wrapper.vm.$router.push({ query: { keywords: 'test', a: '1', page: '2' } });
await wrapper.vm.$nextTick();

wrapper.vm.clearSearch();
await wrapper.vm.$nextTick();

expect(wrapper.vm.keywordInput).toBe('');
expect(wrapper.vm.$route.query).toEqual({ a: '1', page: '2' });
});

it('setting keywords updates fetch query params', () => {
wrapper.vm.keywordInput = 'test';

jest.useFakeTimers();
wrapper.vm.setKeywords();
jest.runAllTimers();
jest.useRealTimers();

expect(wrapper.vm.fetchQueryParams).toEqual({ keywords: 'test' });
});
});

describe('useTable', () => {
let wrapper;
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { pickBy, isEqual } from 'lodash';
import { ref, computed, unref, watch, nextTick } from 'vue';
import { useRoute } from 'vue-router/composables';
import { useQueryParams } from './useQueryParams';
import { useQueryParams } from 'shared/composables/useQueryParams';

/**
* @typedef {Object} Pagination
Expand Down Expand Up @@ -99,7 +99,10 @@ export function useTable({ fetchFunc, filterFetchQueryParams }) {

watch(
allFetchQueryParams,
() => {
(newValue, oldValue) => {
if (isEqual(newValue, oldValue)) {
return;
}
// Use nextTick to ensure that pagination can be updated before fetching
nextTick().then(() => {
loadItems();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
>
<VSelect
v-model="channelTypeFilter"
:items="channelTypeFilters"
:items="channelTypeOptions"
item-text="label"
item-value="key"
label="Channel Type"
Expand All @@ -34,7 +34,7 @@
>
<VSelect
v-model="channelStatusFilter"
:items="channelStatusFilters"
:items="channelStatusOptions"
item-text="label"
item-value="key"
label="Channel Status"
Expand Down Expand Up @@ -146,9 +146,9 @@
import { transform } from 'lodash';
import { RouteNames, rowsPerPageItems } from '../../constants';
import { useTable } from '../../composables/useTable';
import { useKeywordSearch } from '../../composables/useKeywordSearch';
import { useFilter } from '../../composables/useFilter';
import ChannelItem from './ChannelItem';
import { useKeywordSearch } from 'shared/composables/useKeywordSearch';
import { useFilter } from 'shared/composables/useFilter';
import { channelExportMixin } from 'shared/views/channel/mixins';
import { routerMixin } from 'shared/mixins';
import Checkbox from 'shared/views/form/Checkbox';
Expand Down Expand Up @@ -224,27 +224,55 @@
});

const {
filter: channelTypeFilter,
filters: channelTypeFilters,
filter: _channelTypeFilter,
options: channelTypeOptions,
fetchQueryParams: channelTypeFetchQueryParams,
} = useFilter({
name: 'channelType',
filterMap: channelTypeFilterMap,
});
// Temporal wrapper, must be removed after migrating to KSelect
const channelTypeFilter = computed({
get: () => _channelTypeFilter.value.value || undefined,
set: value => {
_channelTypeFilter.value =
channelTypeOptions.value.find(option => option.value === value) || {};
},
});

const {
filter: channelStatusFilter,
filters: channelStatusFilters,
filter: _channelStatusFilter,
options: channelStatusOptions,
fetchQueryParams: channelStatusFetchQueryParams,
} = useFilter({
name: 'channelStatus',
filterMap: statusFilterMap,
});
// Temporal wrapper, must be removed after migrating to KSelect
const channelStatusFilter = computed({
get: () => _channelStatusFilter.value.value || undefined,
set: value => {
_channelStatusFilter.value =
channelStatusOptions.value.find(option => option.value === value) || {};
},
});

const { filter: languageFilter, fetchQueryParams: languageFetchQueryParams } = useFilter({
const {
filter: _languageFilter,
options: languageOptions,
fetchQueryParams: languageFetchQueryParams,
} = useFilter({
name: 'language',
filterMap: languageFilterMap,
});
// Temporal wrapper, must be removed after migrating to KSelect
const languageFilter = computed({
get: () => _languageFilter.value.value || undefined,
set: value => {
_languageFilter.value =
languageOptions.value.find(option => option.value === value) || {};
},
});

const {
keywordInput,
Expand All @@ -254,8 +282,8 @@
} = useKeywordSearch();

watch(channelTypeFilter, () => {
const filters = channelStatusFilters.value;
channelStatusFilter.value = filters.length ? filters[0].key : null;
const options = channelStatusOptions.value;
channelStatusFilter.value = options.length ? options[0].key : null;
});

const filterFetchQueryParams = computed(() => {
Expand All @@ -278,9 +306,9 @@

return {
channelTypeFilter,
channelTypeFilters,
channelTypeOptions,
channelStatusFilter,
channelStatusFilters,
channelStatusOptions,
languageFilter,
languageDropdown,
keywordInput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
>
<VSelect
v-model="userTypeFilter"
:items="userTypeFilters"
:items="userTypeOptions"
item-text="label"
item-value="key"
label="User Type"
Expand Down Expand Up @@ -141,11 +141,11 @@
import { mapGetters } from 'vuex';
import transform from 'lodash/transform';
import { useTable } from '../../composables/useTable';
import { useKeywordSearch } from '../../composables/useKeywordSearch';
import { useFilter } from '../../composables/useFilter';
import { RouteNames, rowsPerPageItems } from '../../constants';
import EmailUsersDialog from './EmailUsersDialog';
import UserItem from './UserItem';
import { useFilter } from 'shared/composables/useFilter';
import { useKeywordSearch } from 'shared/composables/useKeywordSearch';
import { routerMixin } from 'shared/mixins';
import IconButton from 'shared/views/IconButton';
import Checkbox from 'shared/views/form/Checkbox';
Expand Down Expand Up @@ -174,13 +174,21 @@
const store = proxy.$store;

const {
filter: userTypeFilter,
filters: userTypeFilters,
filter: _userTypeFilter,
options: userTypeOptions,
fetchQueryParams: userTypeFetchQueryParams,
} = useFilter({
name: 'userType',
filterMap: userTypeFilterMap,
});
// Temporal wrapper, must be removed after migrating to KSelect
const userTypeFilter = computed({
get: () => _userTypeFilter.value.value || undefined,
set: value => {
_userTypeFilter.value =
userTypeOptions.value.find(option => option.value === value) || {};
},
});

const {
keywordInput,
Expand All @@ -192,10 +200,22 @@
const locationFilterMap = ref({});
const locationDropdown = ref(null);

const { filter: locationFilter, fetchQueryParams: locationFetchQueryParams } = useFilter({
const {
filter: _locationFilter,
options: locationOptions,
fetchQueryParams: locationFetchQueryParams,
} = useFilter({
name: 'location',
filterMap: locationFilterMap,
});
// Temporal wrapper, must be removed after migrating to KSelect
const locationFilter = computed({
get: () => _locationFilter.value.value || undefined,
set: value => {
_locationFilter.value =
locationOptions.value.find(option => option.value === value) || {};
},
});

onMounted(() => {
// The locationFilterMap is built from the options in the CountryField component,
Expand Down Expand Up @@ -233,7 +253,7 @@

return {
userTypeFilter,
userTypeFilters,
userTypeOptions,
locationDropdown,
locationFilter,
keywordInput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { factory } from '../../../../store';

import SubmitToCommunityLibrarySidePanel from '../';
import Box from '../Box.vue';
import StatusChip from '../StatusChip.vue';

import { usePublishedData } from '../composables/usePublishedData';
import { useLatestCommunityLibrarySubmission } from '../composables/useLatestCommunityLibrarySubmission';
import StatusChip from 'shared/views/communityLibrary/StatusChip.vue';
import { Categories, CommunityLibraryStatus } from 'shared/constants';
import { communityChannelsStrings } from 'shared/strings/communityChannelsStrings';
import { CommunityLibrarySubmission } from 'shared/data/resources';
Expand Down
Loading