Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/issues_list')
-rw-r--r--spec/frontend/issues_list/components/issues_list_app_spec.js191
-rw-r--r--spec/frontend/issues_list/mock_data.js127
-rw-r--r--spec/frontend/issues_list/utils_spec.js109
3 files changed, 356 insertions, 71 deletions
diff --git a/spec/frontend/issues_list/components/issues_list_app_spec.js b/spec/frontend/issues_list/components/issues_list_app_spec.js
index 476804bda12..5d83bf0142f 100644
--- a/spec/frontend/issues_list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues_list/components/issues_list_app_spec.js
@@ -3,45 +3,51 @@ import { mount, shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
+import { apiParams, filteredTokens, locationSearch, urlParams } from 'jest/issues_list/mock_data';
import createFlash from '~/flash';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
+import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants';
import IssuesListApp from '~/issues_list/components/issues_list_app.vue';
-
import {
+ apiSortParams,
CREATED_DESC,
+ DUE_DATE_OVERDUE,
PAGE_SIZE,
PAGE_SIZE_MANUAL,
- RELATIVE_POSITION_ASC,
- sortOptions,
- sortParams,
+ PARAM_DUE_DATE,
+ RELATIVE_POSITION_DESC,
+ urlSortParams,
} from '~/issues_list/constants';
import eventHub from '~/issues_list/eventhub';
+import { getSortOptions } from '~/issues_list/utils';
import axios from '~/lib/utils/axios_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
jest.mock('~/flash');
describe('IssuesListApp component', () => {
- const originalWindowLocation = window.location;
let axiosMock;
let wrapper;
const defaultProvide = {
+ autocompleteUsersPath: 'autocomplete/users/path',
calendarPath: 'calendar/path',
canBulkUpdate: false,
emptyStateSvgPath: 'empty-state.svg',
endpoint: 'api/endpoint',
exportCsvPath: 'export/csv/path',
- fullPath: 'path/to/project',
+ hasBlockedIssuesFeature: true,
hasIssues: true,
+ hasIssueWeightsFeature: true,
isSignedIn: false,
issuesPath: 'path/to/issues',
jiraIntegrationPath: 'jira/integration/path',
newIssuePath: 'new/issue/path',
+ projectLabelsPath: 'project/labels/path',
+ projectPath: 'path/to/project',
rssPath: 'rss/path',
- showImportButton: true,
showNewIssueLink: true,
signInPath: 'sign/in/path',
};
@@ -63,6 +69,7 @@ describe('IssuesListApp component', () => {
};
const findCsvImportExportButtons = () => wrapper.findComponent(CsvImportExportButtons);
+ const findIssuableByEmail = () => wrapper.findComponent(IssuableByEmail);
const findGlButton = () => wrapper.findComponent(GlButton);
const findGlButtons = () => wrapper.findAllComponents(GlButton);
const findGlButtonAt = (index) => findGlButtons().at(index);
@@ -86,7 +93,7 @@ describe('IssuesListApp component', () => {
});
afterEach(() => {
- window.location = originalWindowLocation;
+ global.jsdom.reconfigure({ url: TEST_HOST });
axiosMock.reset();
wrapper.destroy();
});
@@ -99,10 +106,10 @@ describe('IssuesListApp component', () => {
it('renders', () => {
expect(findIssuableList().props()).toMatchObject({
- namespace: defaultProvide.fullPath,
+ namespace: defaultProvide.projectPath,
recentSearchesStorageKey: 'issues',
searchInputPlaceholder: 'Search or filter results…',
- sortOptions,
+ sortOptions: getSortOptions(true, true),
initialSortBy: CREATED_DESC,
tabs: IssuableListTabs,
currentTab: IssuableStates.Opened,
@@ -120,46 +127,58 @@ describe('IssuesListApp component', () => {
describe('header action buttons', () => {
it('renders rss button', () => {
- wrapper = mountComponent();
+ wrapper = mountComponent({ mountFn: mount });
+ expect(findGlButtonAt(0).props('icon')).toBe('rss');
expect(findGlButtonAt(0).attributes()).toMatchObject({
href: defaultProvide.rssPath,
- icon: 'rss',
'aria-label': IssuesListApp.i18n.rssLabel,
});
});
it('renders calendar button', () => {
- wrapper = mountComponent();
+ wrapper = mountComponent({ mountFn: mount });
+ expect(findGlButtonAt(1).props('icon')).toBe('calendar');
expect(findGlButtonAt(1).attributes()).toMatchObject({
href: defaultProvide.calendarPath,
- icon: 'calendar',
'aria-label': IssuesListApp.i18n.calendarLabel,
});
});
- it('renders csv import/export component', async () => {
- const search = '?page=1&search=refactor';
+ describe('csv import/export component', () => {
+ describe('when user is signed in', () => {
+ it('renders', async () => {
+ const search = '?page=1&search=refactor&state=opened&sort=created_date';
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { search },
- });
+ global.jsdom.reconfigure({ url: `${TEST_HOST}${search}` });
- wrapper = mountComponent();
+ wrapper = mountComponent({
+ provide: { ...defaultProvide, isSignedIn: true },
+ mountFn: mount,
+ });
- await waitForPromises();
+ await waitForPromises();
+
+ expect(findCsvImportExportButtons().props()).toMatchObject({
+ exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
+ issuableCount: xTotal,
+ });
+ });
+ });
- expect(findCsvImportExportButtons().props()).toMatchObject({
- exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
- issuableCount: xTotal,
+ describe('when user is not signed in', () => {
+ it('does not render', () => {
+ wrapper = mountComponent({ provide: { ...defaultProvide, isSignedIn: false } });
+
+ expect(findCsvImportExportButtons().exists()).toBe(false);
+ });
});
});
describe('bulk edit button', () => {
it('renders when user has permissions', () => {
- wrapper = mountComponent({ provide: { canBulkUpdate: true } });
+ wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
expect(findGlButtonAt(2).text()).toBe('Edit issues');
});
@@ -170,20 +189,22 @@ describe('IssuesListApp component', () => {
expect(findGlButtons().filter((button) => button.text() === 'Edit issues')).toHaveLength(0);
});
- it('emits "issuables:enableBulkEdit" event to legacy bulk edit class', () => {
- wrapper = mountComponent({ provide: { canBulkUpdate: true } });
+ it('emits "issuables:enableBulkEdit" event to legacy bulk edit class', async () => {
+ wrapper = mountComponent({ provide: { canBulkUpdate: true }, mountFn: mount });
jest.spyOn(eventHub, '$emit');
findGlButtonAt(2).vm.$emit('click');
+ await waitForPromises();
+
expect(eventHub.$emit).toHaveBeenCalledWith('issuables:enableBulkEdit');
});
});
describe('new issue button', () => {
it('renders when user has permissions', () => {
- wrapper = mountComponent({ provide: { showNewIssueLink: true } });
+ wrapper = mountComponent({ provide: { showNewIssueLink: true }, mountFn: mount });
expect(findGlButtonAt(2).text()).toBe('New issue');
expect(findGlButtonAt(2).attributes('href')).toBe(defaultProvide.newIssuePath);
@@ -198,14 +219,21 @@ describe('IssuesListApp component', () => {
});
describe('initial url params', () => {
+ describe('due_date', () => {
+ it('is set from the url params', () => {
+ global.jsdom.reconfigure({ url: `${TEST_HOST}?${PARAM_DUE_DATE}=${DUE_DATE_OVERDUE}` });
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({ due_date: DUE_DATE_OVERDUE });
+ });
+ });
+
describe('page', () => {
it('is set from the url params', () => {
const page = 5;
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { href: setUrlParams({ page }, TEST_HOST) },
- });
+ global.jsdom.reconfigure({ url: setUrlParams({ page }, TEST_HOST) });
wrapper = mountComponent();
@@ -213,18 +241,25 @@ describe('IssuesListApp component', () => {
});
});
+ describe('search', () => {
+ it('is set from the url params', () => {
+ global.jsdom.reconfigure({ url: `${TEST_HOST}${locationSearch}` });
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({ search: 'find issues' });
+ });
+ });
+
describe('sort', () => {
- it.each(Object.keys(sortParams))('is set as %s from the url params', (sortKey) => {
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { href: setUrlParams(sortParams[sortKey], TEST_HOST) },
- });
+ it.each(Object.keys(urlSortParams))('is set as %s from the url params', (sortKey) => {
+ global.jsdom.reconfigure({ url: setUrlParams(urlSortParams[sortKey], TEST_HOST) });
wrapper = mountComponent();
expect(findIssuableList().props()).toMatchObject({
initialSortBy: sortKey,
- urlParams: sortParams[sortKey],
+ urlParams: urlSortParams[sortKey],
});
});
});
@@ -233,16 +268,23 @@ describe('IssuesListApp component', () => {
it('is set from the url params', () => {
const initialState = IssuableStates.All;
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { href: setUrlParams({ state: initialState }, TEST_HOST) },
- });
+ global.jsdom.reconfigure({ url: setUrlParams({ state: initialState }, TEST_HOST) });
wrapper = mountComponent();
expect(findIssuableList().props('currentTab')).toBe(initialState);
});
});
+
+ describe('filter tokens', () => {
+ it('is set from the url params', () => {
+ global.jsdom.reconfigure({ url: `${TEST_HOST}${locationSearch}` });
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('initialFilterValue')).toEqual(filteredTokens);
+ });
+ });
});
describe('bulk edit', () => {
@@ -262,16 +304,23 @@ describe('IssuesListApp component', () => {
);
});
+ describe('IssuableByEmail component', () => {
+ describe.each([true, false])(`when issue creation by email is enabled=%s`, (enabled) => {
+ it(`${enabled ? 'renders' : 'does not render'}`, () => {
+ wrapper = mountComponent({ provide: { initialEmail: enabled } });
+
+ expect(findIssuableByEmail().exists()).toBe(enabled);
+ });
+ });
+ });
+
describe('empty states', () => {
describe('when there are issues', () => {
describe('when search returns no results', () => {
beforeEach(async () => {
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { href: setUrlParams({ search: 'no results' }, TEST_HOST) },
- });
+ global.jsdom.reconfigure({ url: `${TEST_HOST}?search=no+results` });
- wrapper = mountComponent({ provide: { hasIssues: true } });
+ wrapper = mountComponent({ provide: { hasIssues: true }, mountFn: mount });
await waitForPromises();
});
@@ -286,8 +335,10 @@ describe('IssuesListApp component', () => {
});
describe('when "Open" tab has no issues', () => {
- beforeEach(() => {
- wrapper = mountComponent({ provide: { hasIssues: true } });
+ beforeEach(async () => {
+ wrapper = mountComponent({ provide: { hasIssues: true }, mountFn: mount });
+
+ await waitForPromises();
});
it('shows empty state', () => {
@@ -301,12 +352,13 @@ describe('IssuesListApp component', () => {
describe('when "Closed" tab has no issues', () => {
beforeEach(async () => {
- Object.defineProperty(window, 'location', {
- writable: true,
- value: { href: setUrlParams({ state: IssuableStates.Closed }, TEST_HOST) },
+ global.jsdom.reconfigure({
+ url: setUrlParams({ state: IssuableStates.Closed }, TEST_HOST),
});
- wrapper = mountComponent({ provide: { hasIssues: true } });
+ wrapper = mountComponent({ provide: { hasIssues: true }, mountFn: mount });
+
+ await waitForPromises();
});
it('shows empty state', () => {
@@ -346,11 +398,11 @@ describe('IssuesListApp component', () => {
it('shows Jira integration information', () => {
const paragraphs = wrapper.findAll('p');
- expect(paragraphs.at(2).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
- expect(paragraphs.at(3).text()).toContain(
+ expect(paragraphs.at(1).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
+ expect(paragraphs.at(2).text()).toContain(
'Enable the Jira integration to view your Jira issues in GitLab.',
);
- expect(paragraphs.at(4).text()).toContain(
+ expect(paragraphs.at(3).text()).toContain(
IssuesListApp.i18n.jiraIntegrationSecondaryMessage,
);
expect(findGlLink().text()).toBe('Enable the Jira integration');
@@ -418,7 +470,7 @@ describe('IssuesListApp component', () => {
});
it('fetches issues with expected params', () => {
- expect(axiosMock.history.get[1].params).toEqual({
+ expect(axiosMock.history.get[1].params).toMatchObject({
page,
per_page: PAGE_SIZE,
state,
@@ -489,7 +541,7 @@ describe('IssuesListApp component', () => {
});
describe('when "sort" event is emitted by IssuableList', () => {
- it.each(Object.keys(sortParams))(
+ it.each(Object.keys(apiSortParams))(
'fetches issues with correct params with payload `%s`',
async (sortKey) => {
wrapper = mountComponent();
@@ -500,10 +552,10 @@ describe('IssuesListApp component', () => {
expect(axiosMock.history.get[1].params).toEqual({
page: xPage,
- per_page: sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE,
+ per_page: sortKey === RELATIVE_POSITION_DESC ? PAGE_SIZE_MANUAL : PAGE_SIZE,
state,
with_labels_details: true,
- ...sortParams[sortKey],
+ ...apiSortParams[sortKey],
});
},
);
@@ -525,21 +577,18 @@ describe('IssuesListApp component', () => {
});
describe('when "filter" event is emitted by IssuableList', () => {
- beforeEach(async () => {
+ beforeEach(() => {
wrapper = mountComponent();
- const payload = [
- { type: 'filtered-search-term', value: { data: 'no' } },
- { type: 'filtered-search-term', value: { data: 'issues' } },
- ];
-
- findIssuableList().vm.$emit('filter', payload);
-
- await waitForPromises();
+ findIssuableList().vm.$emit('filter', filteredTokens);
});
it('makes an API call to search for issues with the search term', () => {
- expect(axiosMock.history.get[1].params).toMatchObject({ search: 'no issues' });
+ expect(axiosMock.history.get[1].params).toMatchObject(apiParams);
+ });
+
+ it('updates IssuableList with url params', () => {
+ expect(findIssuableList().props('urlParams')).toMatchObject(urlParams);
});
});
});
diff --git a/spec/frontend/issues_list/mock_data.js b/spec/frontend/issues_list/mock_data.js
new file mode 100644
index 00000000000..ce2880d177a
--- /dev/null
+++ b/spec/frontend/issues_list/mock_data.js
@@ -0,0 +1,127 @@
+import {
+ OPERATOR_IS,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
+
+export const locationSearch = [
+ '?search=find+issues',
+ 'author_username=homer',
+ 'not[author_username]=marge',
+ 'assignee_username[]=bart',
+ 'assignee_username[]=lisa',
+ 'not[assignee_username][]=patty',
+ 'not[assignee_username][]=selma',
+ 'milestone_title=season+4',
+ 'not[milestone_title]=season+20',
+ 'label_name[]=cartoon',
+ 'label_name[]=tv',
+ 'not[label_name][]=live action',
+ 'not[label_name][]=drama',
+ 'my_reaction_emoji=thumbsup',
+ 'confidential=no',
+ 'iteration_title=season:+%234',
+ 'not[iteration_title]=season:+%2320',
+ 'epic_id=12',
+ 'not[epic_id]=34',
+ 'weight=1',
+ 'not[weight]=3',
+].join('&');
+
+export const locationSearchWithSpecialValues = [
+ 'assignee_id=123',
+ 'assignee_username=bart',
+ 'my_reaction_emoji=None',
+ 'iteration_id=Current',
+ 'epic_id=None',
+ 'weight=None',
+].join('&');
+
+export const filteredTokens = [
+ { type: 'author_username', value: { data: 'homer', operator: OPERATOR_IS } },
+ { type: 'author_username', value: { data: 'marge', operator: OPERATOR_IS_NOT } },
+ { type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } },
+ { type: 'assignee_username', value: { data: 'lisa', operator: OPERATOR_IS } },
+ { type: 'assignee_username', value: { data: 'patty', operator: OPERATOR_IS_NOT } },
+ { type: 'assignee_username', value: { data: 'selma', operator: OPERATOR_IS_NOT } },
+ { type: 'milestone', value: { data: 'season 4', operator: OPERATOR_IS } },
+ { type: 'milestone', value: { data: 'season 20', operator: OPERATOR_IS_NOT } },
+ { type: 'labels', value: { data: 'cartoon', operator: OPERATOR_IS } },
+ { type: 'labels', value: { data: 'tv', operator: OPERATOR_IS } },
+ { type: 'labels', value: { data: 'live action', operator: OPERATOR_IS_NOT } },
+ { type: 'labels', value: { data: 'drama', operator: OPERATOR_IS_NOT } },
+ { type: 'my_reaction_emoji', value: { data: 'thumbsup', operator: OPERATOR_IS } },
+ { type: 'confidential', value: { data: 'no', operator: OPERATOR_IS } },
+ { type: 'iteration', value: { data: 'season: #4', operator: OPERATOR_IS } },
+ { type: 'iteration', value: { data: 'season: #20', operator: OPERATOR_IS_NOT } },
+ { type: 'epic_id', value: { data: '12', operator: OPERATOR_IS } },
+ { type: 'epic_id', value: { data: '34', operator: OPERATOR_IS_NOT } },
+ { type: 'weight', value: { data: '1', operator: OPERATOR_IS } },
+ { type: 'weight', value: { data: '3', operator: OPERATOR_IS_NOT } },
+ { type: 'filtered-search-term', value: { data: 'find' } },
+ { type: 'filtered-search-term', value: { data: 'issues' } },
+];
+
+export const filteredTokensWithSpecialValues = [
+ { type: 'assignee_username', value: { data: '123', operator: OPERATOR_IS } },
+ { type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } },
+ { type: 'my_reaction_emoji', value: { data: 'None', operator: OPERATOR_IS } },
+ { type: 'iteration', value: { data: 'Current', operator: OPERATOR_IS } },
+ { type: 'epic_id', value: { data: 'None', operator: OPERATOR_IS } },
+ { type: 'weight', value: { data: 'None', operator: OPERATOR_IS } },
+];
+
+export const apiParams = {
+ author_username: 'homer',
+ 'not[author_username]': 'marge',
+ assignee_username: ['bart', 'lisa'],
+ 'not[assignee_username]': ['patty', 'selma'],
+ milestone: 'season 4',
+ 'not[milestone]': 'season 20',
+ labels: ['cartoon', 'tv'],
+ 'not[labels]': ['live action', 'drama'],
+ my_reaction_emoji: 'thumbsup',
+ confidential: 'no',
+ iteration_title: 'season: #4',
+ 'not[iteration_title]': 'season: #20',
+ epic_id: '12',
+ 'not[epic_id]': '34',
+ weight: '1',
+ 'not[weight]': '3',
+};
+
+export const apiParamsWithSpecialValues = {
+ assignee_id: '123',
+ assignee_username: 'bart',
+ my_reaction_emoji: 'None',
+ iteration_id: 'Current',
+ epic_id: 'None',
+ weight: 'None',
+};
+
+export const urlParams = {
+ author_username: 'homer',
+ 'not[author_username]': 'marge',
+ 'assignee_username[]': ['bart', 'lisa'],
+ 'not[assignee_username][]': ['patty', 'selma'],
+ milestone_title: 'season 4',
+ 'not[milestone_title]': 'season 20',
+ 'label_name[]': ['cartoon', 'tv'],
+ 'not[label_name][]': ['live action', 'drama'],
+ my_reaction_emoji: 'thumbsup',
+ confidential: 'no',
+ iteration_title: 'season: #4',
+ 'not[iteration_title]': 'season: #20',
+ epic_id: '12',
+ 'not[epic_id]': '34',
+ weight: '1',
+ 'not[weight]': '3',
+};
+
+export const urlParamsWithSpecialValues = {
+ assignee_id: '123',
+ 'assignee_username[]': 'bart',
+ my_reaction_emoji: 'None',
+ iteration_id: 'Current',
+ epic_id: 'None',
+ weight: 'None',
+};
diff --git a/spec/frontend/issues_list/utils_spec.js b/spec/frontend/issues_list/utils_spec.js
new file mode 100644
index 00000000000..17127753972
--- /dev/null
+++ b/spec/frontend/issues_list/utils_spec.js
@@ -0,0 +1,109 @@
+import {
+ apiParams,
+ apiParamsWithSpecialValues,
+ filteredTokens,
+ filteredTokensWithSpecialValues,
+ locationSearch,
+ locationSearchWithSpecialValues,
+ urlParams,
+ urlParamsWithSpecialValues,
+} from 'jest/issues_list/mock_data';
+import { API_PARAM, DUE_DATE_VALUES, URL_PARAM, urlSortParams } from '~/issues_list/constants';
+import {
+ convertToParams,
+ convertToSearchQuery,
+ getDueDateValue,
+ getFilterTokens,
+ getSortKey,
+ getSortOptions,
+} from '~/issues_list/utils';
+
+describe('getSortKey', () => {
+ it.each(Object.keys(urlSortParams))('returns %s given the correct inputs', (sortKey) => {
+ const { sort } = urlSortParams[sortKey];
+ expect(getSortKey(sort)).toBe(sortKey);
+ });
+});
+
+describe('getDueDateValue', () => {
+ it.each(DUE_DATE_VALUES)('returns the argument when it is `%s`', (value) => {
+ expect(getDueDateValue(value)).toBe(value);
+ });
+
+ it('returns undefined when the argument is invalid', () => {
+ expect(getDueDateValue('invalid value')).toBeUndefined();
+ });
+});
+
+describe('getSortOptions', () => {
+ describe.each`
+ hasIssueWeightsFeature | hasBlockedIssuesFeature | length | containsWeight | containsBlocking
+ ${false} | ${false} | ${8} | ${false} | ${false}
+ ${true} | ${false} | ${9} | ${true} | ${false}
+ ${false} | ${true} | ${9} | ${false} | ${true}
+ ${true} | ${true} | ${10} | ${true} | ${true}
+ `(
+ 'when hasIssueWeightsFeature=$hasIssueWeightsFeature and hasBlockedIssuesFeature=$hasBlockedIssuesFeature',
+ ({
+ hasIssueWeightsFeature,
+ hasBlockedIssuesFeature,
+ length,
+ containsWeight,
+ containsBlocking,
+ }) => {
+ const sortOptions = getSortOptions(hasIssueWeightsFeature, hasBlockedIssuesFeature);
+
+ it('returns the correct length of sort options', () => {
+ expect(sortOptions).toHaveLength(length);
+ });
+
+ it(`${containsWeight ? 'contains' : 'does not contain'} weight option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Weight')).toBe(containsWeight);
+ });
+
+ it(`${containsBlocking ? 'contains' : 'does not contain'} blocking option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Blocking')).toBe(containsBlocking);
+ });
+ },
+ );
+});
+
+describe('getFilterTokens', () => {
+ it('returns filtered tokens given "window.location.search"', () => {
+ expect(getFilterTokens(locationSearch)).toEqual(filteredTokens);
+ });
+
+ it('returns filtered tokens given "window.location.search" with special values', () => {
+ expect(getFilterTokens(locationSearchWithSpecialValues)).toEqual(
+ filteredTokensWithSpecialValues,
+ );
+ });
+});
+
+describe('convertToParams', () => {
+ it('returns api params given filtered tokens', () => {
+ expect(convertToParams(filteredTokens, API_PARAM)).toEqual(apiParams);
+ });
+
+ it('returns api params given filtered tokens with special values', () => {
+ expect(convertToParams(filteredTokensWithSpecialValues, API_PARAM)).toEqual(
+ apiParamsWithSpecialValues,
+ );
+ });
+
+ it('returns url params given filtered tokens', () => {
+ expect(convertToParams(filteredTokens, URL_PARAM)).toEqual(urlParams);
+ });
+
+ it('returns url params given filtered tokens with special values', () => {
+ expect(convertToParams(filteredTokensWithSpecialValues, URL_PARAM)).toEqual(
+ urlParamsWithSpecialValues,
+ );
+ });
+});
+
+describe('convertToSearchQuery', () => {
+ it('returns search string given filtered tokens', () => {
+ expect(convertToSearchQuery(filteredTokens)).toBe('find issues');
+ });
+});