diff --git a/app/assets/javascripts/issues_list/components/issues_list_app.vue b/app/assets/javascripts/issues_list/components/issues_list_app.vue
index 6059beee07896e52225ad93ea8f2b53069ab1d0d..93ba338a6b3486a4483b73b13778c4575c4378fa 100644
--- a/app/assets/javascripts/issues_list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues_list/components/issues_list_app.vue
@@ -16,22 +16,25 @@ 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 {
+  API_PARAM,
   apiSortParams,
   CREATED_DESC,
   i18n,
   MAX_LIST_SIZE,
   PAGE_SIZE,
+  PARAM_DUE_DATE,
   PARAM_PAGE,
   PARAM_SORT,
   PARAM_STATE,
   RELATIVE_POSITION_DESC,
   UPDATED_DESC,
+  URL_PARAM,
   urlSortParams,
 } from '~/issues_list/constants';
 import {
-  convertToApiParams,
+  convertToParams,
   convertToSearchQuery,
-  convertToUrlParams,
+  getDueDateValue,
   getFilterTokens,
   getSortKey,
   getSortOptions,
@@ -113,6 +116,9 @@ export default {
     hasIssueWeightsFeature: {
       default: false,
     },
+    hasMultipleIssueAssigneesFeature: {
+      default: false,
+    },
     initialEmail: {
       default: '',
     },
@@ -155,6 +161,7 @@ export default {
     const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
 
     return {
+      dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
       exportCsvPathWithQuery: this.getExportCsvPathWithQuery(),
       filterTokens: getFilterTokens(window.location.search),
       isLoading: false,
@@ -177,10 +184,10 @@ export default {
       return this.state === IssuableStates.Opened;
     },
     apiFilterParams() {
-      return convertToApiParams(this.filterTokens);
+      return convertToParams(this.filterTokens, API_PARAM);
     },
     urlFilterParams() {
-      return convertToUrlParams(this.filterTokens);
+      return convertToParams(this.filterTokens, URL_PARAM);
     },
     searchQuery() {
       return convertToSearchQuery(this.filterTokens) || undefined;
@@ -203,7 +210,7 @@ export default {
           icon: 'user',
           token: AuthorToken,
           dataType: 'user',
-          unique: true,
+          unique: !this.hasMultipleIssueAssigneesFeature,
           defaultAuthors: DEFAULT_NONE_ANY,
           fetchAuthors: this.fetchUsers,
         },
@@ -298,6 +305,7 @@ export default {
     },
     urlParams() {
       return {
+        due_date: this.dueDateFilter,
         page: this.page,
         search: this.searchQuery,
         state: this.state,
@@ -366,6 +374,7 @@ export default {
       return axios
         .get(this.endpoint, {
           params: {
+            due_date: this.dueDateFilter,
             page: this.page,
             per_page: PAGE_SIZE,
             search: this.searchQuery,
diff --git a/app/assets/javascripts/issues_list/constants.js b/app/assets/javascripts/issues_list/constants.js
index 5f0bbd2145dd3734476ded56c14ff5b65b7bc082..54e9668d3007ecebbd3f2d3d752223b2cdbff973 100644
--- a/app/assets/javascripts/issues_list/constants.js
+++ b/app/assets/javascripts/issues_list/constants.js
@@ -100,10 +100,26 @@ export const i18n = {
 
 export const JIRA_IMPORT_SUCCESS_ALERT_HIDE_MAP_KEY = 'jira-import-success-alert-hide-map';
 
+export const PARAM_DUE_DATE = 'due_date';
 export const PARAM_PAGE = 'page';
 export const PARAM_SORT = 'sort';
 export const PARAM_STATE = 'state';
 
+export const DUE_DATE_NONE = '0';
+export const DUE_DATE_ANY = '';
+export const DUE_DATE_OVERDUE = 'overdue';
+export const DUE_DATE_WEEK = 'week';
+export const DUE_DATE_MONTH = 'month';
+export const DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS = 'next_month_and_previous_two_weeks';
+export const DUE_DATE_VALUES = [
+  DUE_DATE_NONE,
+  DUE_DATE_ANY,
+  DUE_DATE_OVERDUE,
+  DUE_DATE_WEEK,
+  DUE_DATE_MONTH,
+  DUE_DATE_NEXT_MONTH_AND_PREVIOUS_TWO_WEEKS,
+];
+
 export const BLOCKING_ISSUES_DESC = 'BLOCKING_ISSUES_DESC';
 export const CREATED_ASC = 'CREATED_ASC';
 export const CREATED_DESC = 'CREATED_DESC';
@@ -258,13 +274,16 @@ export const urlSortParams = {
 
 export const MAX_LIST_SIZE = 10;
 
+export const API_PARAM = 'apiParam';
+export const URL_PARAM = 'urlParam';
 export const NORMAL_FILTER = 'normalFilter';
 export const SPECIAL_FILTER = 'specialFilter';
+export const ALTERNATIVE_FILTER = 'alternativeFilter';
 export const SPECIAL_FILTER_VALUES = [FILTER_NONE, FILTER_ANY, FILTER_CURRENT];
 
 export const filters = {
   author_username: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'author_username',
       },
@@ -272,7 +291,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[author_username]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'author_username',
       },
@@ -282,7 +301,7 @@ export const filters = {
     },
   },
   assignee_username: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'assignee_username',
         [SPECIAL_FILTER]: 'assignee_id',
@@ -291,10 +310,11 @@ export const filters = {
         [NORMAL_FILTER]: 'not[assignee_username]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'assignee_username[]',
         [SPECIAL_FILTER]: 'assignee_id',
+        [ALTERNATIVE_FILTER]: 'assignee_username',
       },
       [OPERATOR_IS_NOT]: {
         [NORMAL_FILTER]: 'not[assignee_username][]',
@@ -302,7 +322,7 @@ export const filters = {
     },
   },
   milestone: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'milestone',
       },
@@ -310,7 +330,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[milestone]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'milestone_title',
       },
@@ -320,7 +340,7 @@ export const filters = {
     },
   },
   labels: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'labels',
       },
@@ -328,7 +348,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[labels]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'label_name[]',
       },
@@ -338,13 +358,13 @@ export const filters = {
     },
   },
   my_reaction_emoji: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'my_reaction_emoji',
         [SPECIAL_FILTER]: 'my_reaction_emoji',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'my_reaction_emoji',
         [SPECIAL_FILTER]: 'my_reaction_emoji',
@@ -352,19 +372,19 @@ export const filters = {
     },
   },
   confidential: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'confidential',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'confidential',
       },
     },
   },
   iteration: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'iteration_title',
         [SPECIAL_FILTER]: 'iteration_id',
@@ -373,7 +393,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[iteration_title]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'iteration_title',
         [SPECIAL_FILTER]: 'iteration_id',
@@ -384,7 +404,7 @@ export const filters = {
     },
   },
   epic_id: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'epic_id',
         [SPECIAL_FILTER]: 'epic_id',
@@ -393,7 +413,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[epic_id]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'epic_id',
         [SPECIAL_FILTER]: 'epic_id',
@@ -404,7 +424,7 @@ export const filters = {
     },
   },
   weight: {
-    apiParam: {
+    [API_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'weight',
         [SPECIAL_FILTER]: 'weight',
@@ -413,7 +433,7 @@ export const filters = {
         [NORMAL_FILTER]: 'not[weight]',
       },
     },
-    urlParam: {
+    [URL_PARAM]: {
       [OPERATOR_IS]: {
         [NORMAL_FILTER]: 'weight',
         [SPECIAL_FILTER]: 'weight',
diff --git a/app/assets/javascripts/issues_list/index.js b/app/assets/javascripts/issues_list/index.js
index c4bd62bce5956d406ac31c7fbcc8191805dff56d..55719f6449bb07d857645f7e341ade5f57768c16 100644
--- a/app/assets/javascripts/issues_list/index.js
+++ b/app/assets/javascripts/issues_list/index.js
@@ -90,6 +90,7 @@ export function mountIssuesListApp() {
     hasIssuableHealthStatusFeature,
     hasIssues,
     hasIssueWeightsFeature,
+    hasMultipleIssueAssigneesFeature,
     importCsvIssuesPath,
     initialEmail,
     isSignedIn,
@@ -127,6 +128,7 @@ export function mountIssuesListApp() {
       hasIssuableHealthStatusFeature: parseBoolean(hasIssuableHealthStatusFeature),
       hasIssues: parseBoolean(hasIssues),
       hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
+      hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
       isSignedIn: parseBoolean(isSignedIn),
       issuesPath,
       jiraIntegrationPath,
diff --git a/app/assets/javascripts/issues_list/utils.js b/app/assets/javascripts/issues_list/utils.js
index b6551eb4ac85f2fb9dc0eb5a7c633d12dd2ac3ef..234fd59ca8d1a7f0e82edbdcab7cd2f7c7c9e7a4 100644
--- a/app/assets/javascripts/issues_list/utils.js
+++ b/app/assets/javascripts/issues_list/utils.js
@@ -4,6 +4,7 @@ import {
   CREATED_DESC,
   DUE_DATE_ASC,
   DUE_DATE_DESC,
+  DUE_DATE_VALUES,
   filters,
   LABEL_PRIORITY_DESC,
   MILESTONE_DUE_ASC,
@@ -21,12 +22,15 @@ import {
   WEIGHT_ASC,
   WEIGHT_DESC,
 } from '~/issues_list/constants';
+import { isPositiveInteger } from '~/lib/utils/number_utils';
 import { __ } from '~/locale';
 import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
 
 export const getSortKey = (sort) =>
   Object.keys(urlSortParams).find((key) => urlSortParams[key].sort === sort);
 
+export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined);
+
 export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) => {
   const sortOptions = [
     {
@@ -167,28 +171,20 @@ export const getFilterTokens = (locationSearch) => {
   return filterTokens.concat(searchTokens);
 };
 
-const getFilterType = (data) =>
-  SPECIAL_FILTER_VALUES.includes(data) ? SPECIAL_FILTER : NORMAL_FILTER;
-
-export const convertToApiParams = (filterTokens) =>
-  filterTokens
-    .filter((token) => token.type !== FILTERED_SEARCH_TERM)
-    .reduce((acc, token) => {
-      const filterType = getFilterType(token.value.data);
-      const apiParam = filters[token.type].apiParam[token.value.operator][filterType];
-      return Object.assign(acc, {
-        [apiParam]: acc[apiParam] ? `${acc[apiParam]},${token.value.data}` : token.value.data,
-      });
-    }, {});
+const getFilterType = (data, tokenType = '') =>
+  SPECIAL_FILTER_VALUES.includes(data) ||
+  (tokenType === 'assignee_username' && isPositiveInteger(data))
+    ? SPECIAL_FILTER
+    : NORMAL_FILTER;
 
-export const convertToUrlParams = (filterTokens) =>
+export const convertToParams = (filterTokens, paramType) =>
   filterTokens
     .filter((token) => token.type !== FILTERED_SEARCH_TERM)
     .reduce((acc, token) => {
-      const filterType = getFilterType(token.value.data);
-      const urlParam = filters[token.type].urlParam[token.value.operator]?.[filterType];
+      const filterType = getFilterType(token.value.data, token.type);
+      const param = filters[token.type][paramType][token.value.operator]?.[filterType];
       return Object.assign(acc, {
-        [urlParam]: acc[urlParam] ? acc[urlParam].concat(token.value.data) : [token.value.data],
+        [param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data,
       });
     }, {});
 
diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js
index 63feb6f9b1d1114ce539ae28f212288839b48c80..e3500d02a79d33beffe5cece67142b3a280c614c 100644
--- a/app/assets/javascripts/lib/utils/number_utils.js
+++ b/app/assets/javascripts/lib/utils/number_utils.js
@@ -171,3 +171,13 @@ export const formattedChangeInPercent = (firstY, lastY, { nonFiniteResult = '-'
 export const isNumeric = (value) => {
   return !Number.isNaN(parseInt(value, 10));
 };
+
+const numberRegex = /^[0-9]+$/;
+
+/**
+ * Checks whether the value is a positive number or 0, or a string with equivalent value
+ *
+ * @param value
+ * @return {boolean}
+ */
+export const isPositiveInteger = (value) => numberRegex.test(value);
diff --git a/ee/app/helpers/ee/issues_helper.rb b/ee/app/helpers/ee/issues_helper.rb
index cf5aa8c7adf8b3ea8cab837f0c5abf964230d4bc..7837ec5311a5b66d1d20ce3d3d98444796c0fcf7 100644
--- a/ee/app/helpers/ee/issues_helper.rb
+++ b/ee/app/helpers/ee/issues_helper.rb
@@ -47,7 +47,8 @@ def issues_list_data(project, current_user, finder)
       data = super.merge!(
         has_blocked_issues_feature: project.feature_available?(:blocked_issues).to_s,
         has_issuable_health_status_feature: project.feature_available?(:issuable_health_status).to_s,
-        has_issue_weights_feature: project.feature_available?(:issue_weights).to_s
+        has_issue_weights_feature: project.feature_available?(:issue_weights).to_s,
+        has_multiple_issue_assignees_feature: project.feature_available?(:multiple_issue_assignees).to_s
       )
 
       if project.feature_available?(:epics) && project.group
diff --git a/ee/spec/helpers/ee/issues_helper_spec.rb b/ee/spec/helpers/ee/issues_helper_spec.rb
index 34e540d9f4efce76f07fd20b0848daf39c2a6cf4..2c6f22388fc2854166baefc9d03388c6b24282af 100644
--- a/ee/spec/helpers/ee/issues_helper_spec.rb
+++ b/ee/spec/helpers/ee/issues_helper_spec.rb
@@ -137,7 +137,7 @@
 
     context 'when features are enabled' do
       before do
-        stub_licensed_features(epics: true, iterations: true, issue_weights: true, issuable_health_status: true, blocked_issues: true)
+        stub_licensed_features(epics: true, iterations: true, issue_weights: true, issuable_health_status: true, blocked_issues: true, multiple_issue_assignees: true)
       end
 
       it 'returns data with licensed features enabled' do
@@ -145,6 +145,7 @@
           has_blocked_issues_feature: 'true',
           has_issuable_health_status_feature: 'true',
           has_issue_weights_feature: 'true',
+          has_multiple_issue_assignees_feature: 'true',
           group_epics_path: group_epics_path(project.group, format: :json),
           project_iterations_path: api_v4_projects_iterations_path(id: project.id)
         }
@@ -163,17 +164,19 @@
 
     context 'when features are disabled' do
       before do
-        stub_licensed_features(epics: false, iterations: false, issue_weights: false, issuable_health_status: false, blocked_issues: false)
+        stub_licensed_features(epics: false, iterations: false, issue_weights: false, issuable_health_status: false, blocked_issues: false, multiple_issue_assignees: false)
       end
 
       it 'returns data with licensed features disabled' do
         expected = {
           has_blocked_issues_feature: 'false',
           has_issuable_health_status_feature: 'false',
-          has_issue_weights_feature: 'false'
+          has_issue_weights_feature: 'false',
+          has_multiple_issue_assignees_feature: 'false'
         }
 
         result = helper.issues_list_data(project, current_user, finder)
+
         expect(result).to include(expected)
         expect(result).not_to include(:group_epics_path)
         expect(result).not_to include(:project_iterations_path)
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 9fbbeadb1d004a9f2d7a08c91f9189c79096be82..5d83bf0142f397b5f4e56e00be3dfb40a814d230 100644
--- a/spec/frontend/issues_list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues_list/components/issues_list_app_spec.js
@@ -13,8 +13,10 @@ import IssuesListApp from '~/issues_list/components/issues_list_app.vue';
 import {
   apiSortParams,
   CREATED_DESC,
+  DUE_DATE_OVERDUE,
   PAGE_SIZE,
   PAGE_SIZE_MANUAL,
+  PARAM_DUE_DATE,
   RELATIVE_POSITION_DESC,
   urlSortParams,
 } from '~/issues_list/constants';
@@ -217,6 +219,16 @@ 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;
diff --git a/spec/frontend/issues_list/mock_data.js b/spec/frontend/issues_list/mock_data.js
index 5892a65e4342fac29d6393d1493d99ee3b65a6f3..ce2880d177a46466314a144cc731c456679982f1 100644
--- a/spec/frontend/issues_list/mock_data.js
+++ b/spec/frontend/issues_list/mock_data.js
@@ -8,7 +8,9 @@ export const locationSearch = [
   'author_username=homer',
   'not[author_username]=marge',
   'assignee_username[]=bart',
-  'not[assignee_username][]=lisa',
+  'assignee_username[]=lisa',
+  'not[assignee_username][]=patty',
+  'not[assignee_username][]=selma',
   'milestone_title=season+4',
   'not[milestone_title]=season+20',
   'label_name[]=cartoon',
@@ -26,7 +28,8 @@ export const locationSearch = [
 ].join('&');
 
 export const locationSearchWithSpecialValues = [
-  'assignee_id=None',
+  'assignee_id=123',
+  'assignee_username=bart',
   'my_reaction_emoji=None',
   'iteration_id=Current',
   'epic_id=None',
@@ -37,7 +40,9 @@ 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_NOT } },
+  { 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 } },
@@ -57,7 +62,8 @@ export const filteredTokens = [
 ];
 
 export const filteredTokensWithSpecialValues = [
-  { type: 'assignee_username', value: { data: 'None', operator: OPERATOR_IS } },
+  { 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 } },
@@ -67,12 +73,12 @@ export const filteredTokensWithSpecialValues = [
 export const apiParams = {
   author_username: 'homer',
   'not[author_username]': 'marge',
-  assignee_username: 'bart',
-  'not[assignee_username]': 'lisa',
+  assignee_username: ['bart', 'lisa'],
+  'not[assignee_username]': ['patty', 'selma'],
   milestone: 'season 4',
   'not[milestone]': 'season 20',
-  labels: 'cartoon,tv',
-  'not[labels]': 'live action,drama',
+  labels: ['cartoon', 'tv'],
+  'not[labels]': ['live action', 'drama'],
   my_reaction_emoji: 'thumbsup',
   confidential: 'no',
   iteration_title: 'season: #4',
@@ -84,7 +90,8 @@ export const apiParams = {
 };
 
 export const apiParamsWithSpecialValues = {
-  assignee_id: 'None',
+  assignee_id: '123',
+  assignee_username: 'bart',
   my_reaction_emoji: 'None',
   iteration_id: 'Current',
   epic_id: 'None',
@@ -92,28 +99,29 @@ export const apiParamsWithSpecialValues = {
 };
 
 export const urlParams = {
-  author_username: ['homer'],
-  'not[author_username]': ['marge'],
-  'assignee_username[]': ['bart'],
-  'not[assignee_username][]': ['lisa'],
-  milestone_title: ['season 4'],
-  'not[milestone_title]': ['season 20'],
+  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'],
+  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: ['None'],
-  my_reaction_emoji: ['None'],
-  iteration_id: ['Current'],
-  epic_id: ['None'],
-  weight: ['None'],
+  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
index 76a2383268748afe6a9629cd103a796c38c06541..17127753972c4f62e0570445b318402b726dba90 100644
--- a/spec/frontend/issues_list/utils_spec.js
+++ b/spec/frontend/issues_list/utils_spec.js
@@ -8,11 +8,11 @@ import {
   urlParams,
   urlParamsWithSpecialValues,
 } from 'jest/issues_list/mock_data';
-import { urlSortParams } from '~/issues_list/constants';
+import { API_PARAM, DUE_DATE_VALUES, URL_PARAM, urlSortParams } from '~/issues_list/constants';
 import {
-  convertToApiParams,
+  convertToParams,
   convertToSearchQuery,
-  convertToUrlParams,
+  getDueDateValue,
   getFilterTokens,
   getSortKey,
   getSortOptions,
@@ -25,6 +25,16 @@ describe('getSortKey', () => {
   });
 });
 
+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
@@ -70,23 +80,25 @@ describe('getFilterTokens', () => {
   });
 });
 
-describe('convertToApiParams', () => {
+describe('convertToParams', () => {
   it('returns api params given filtered tokens', () => {
-    expect(convertToApiParams(filteredTokens)).toEqual(apiParams);
+    expect(convertToParams(filteredTokens, API_PARAM)).toEqual(apiParams);
   });
 
   it('returns api params given filtered tokens with special values', () => {
-    expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues);
+    expect(convertToParams(filteredTokensWithSpecialValues, API_PARAM)).toEqual(
+      apiParamsWithSpecialValues,
+    );
   });
-});
 
-describe('convertToUrlParams', () => {
   it('returns url params given filtered tokens', () => {
-    expect(convertToUrlParams(filteredTokens)).toEqual(urlParams);
+    expect(convertToParams(filteredTokens, URL_PARAM)).toEqual(urlParams);
   });
 
   it('returns url params given filtered tokens with special values', () => {
-    expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues);
+    expect(convertToParams(filteredTokensWithSpecialValues, URL_PARAM)).toEqual(
+      urlParamsWithSpecialValues,
+    );
   });
 });
 
diff --git a/spec/frontend/lib/utils/number_utility_spec.js b/spec/frontend/lib/utils/number_utility_spec.js
index 4dcd92116970d4dee7f80e4bd8b2e33c57b83d0f..f4483f5098b5e87e9f3a9ea226a1aedefe9fcd1e 100644
--- a/spec/frontend/lib/utils/number_utility_spec.js
+++ b/spec/frontend/lib/utils/number_utility_spec.js
@@ -10,6 +10,7 @@ import {
   changeInPercent,
   formattedChangeInPercent,
   isNumeric,
+  isPositiveInteger,
 } from '~/lib/utils/number_utils';
 
 describe('Number Utils', () => {
@@ -184,4 +185,29 @@ describe('Number Utils', () => {
       expect(isNumeric(value)).toBe(outcome);
     });
   });
+
+  describe.each`
+    value        | outcome
+    ${0}         | ${true}
+    ${'0'}       | ${true}
+    ${12345}     | ${true}
+    ${'12345'}   | ${true}
+    ${-1}        | ${false}
+    ${'-1'}      | ${false}
+    ${1.01}      | ${false}
+    ${'1.01'}    | ${false}
+    ${'abcd'}    | ${false}
+    ${'100abcd'} | ${false}
+    ${'abcd100'} | ${false}
+    ${''}        | ${false}
+    ${false}     | ${false}
+    ${true}      | ${false}
+    ${undefined} | ${false}
+    ${null}      | ${false}
+    ${Infinity}  | ${false}
+  `('isPositiveInteger', ({ value, outcome }) => {
+    it(`when called with ${typeof value} ${value} it returns ${outcome}`, () => {
+      expect(isPositiveInteger(value)).toBe(outcome);
+    });
+  });
 });