Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
a1f65ac9
Commit
a1f65ac9
authored
May 07, 2021
by
Coung Ngo
Committed by
Natalia Tepluhina
May 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add None/Any search tokens to issues page refactor
parent
98ae59d0
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
190 additions
and
51 deletions
+190
-51
app/assets/javascripts/issues_list/components/issues_list_app.vue
...ts/javascripts/issues_list/components/issues_list_app.vue
+2
-3
app/assets/javascripts/issues_list/constants.js
app/assets/javascripts/issues_list/constants.js
+101
-28
app/assets/javascripts/issues_list/utils.js
app/assets/javascripts/issues_list/utils.js
+18
-5
app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
...ts/vue_shared/components/filtered_search_bar/constants.js
+13
-10
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue
...red/components/filtered_search_bar/tokens/emoji_token.vue
+2
-2
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/weight_token.vue
...ed/components/filtered_search_bar/tokens/weight_token.vue
+2
-2
spec/frontend/issues_list/mock_data.js
spec/frontend/issues_list/mock_data.js
+28
-0
spec/frontend/issues_list/utils_spec.js
spec/frontend/issues_list/utils_spec.js
+24
-1
No files found.
app/assets/javascripts/issues_list/components/issues_list_app.vue
View file @
a1f65ac9
...
...
@@ -34,6 +34,7 @@ import {
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
convertObjectPropsToCamelCase
,
getParameterByName
}
from
'
~/lib/utils/common_utils
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
DEFAULT_NONE_ANY
}
from
'
~/vue_shared/components/filtered_search_bar/constants
'
;
import
AuthorToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/author_token.vue
'
;
import
EmojiToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue
'
;
import
IterationToken
from
'
~/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue
'
;
...
...
@@ -186,7 +187,7 @@ export default {
token
:
AuthorToken
,
dataType
:
'
user
'
,
unique
:
true
,
defaultAuthors
:
[]
,
defaultAuthors
:
DEFAULT_NONE_ANY
,
fetchAuthors
:
this
.
fetchUsers
,
},
{
...
...
@@ -213,7 +214,6 @@ export default {
token
:
EmojiToken
,
unique
:
true
,
operators
:
[{
value
:
'
=
'
,
description
:
__
(
'
is
'
)
}],
defaultEmojis
:
[],
fetchEmojis
:
this
.
fetchEmojis
,
},
{
...
...
@@ -237,7 +237,6 @@ export default {
icon
:
'
iteration
'
,
token
:
IterationToken
,
unique
:
true
,
defaultIterations
:
[],
fetchIterations
:
this
.
fetchIterations
,
});
}
...
...
app/assets/javascripts/issues_list/constants.js
View file @
a1f65ac9
import
{
__
,
s__
}
from
'
~/locale
'
;
import
{
FILTER_ANY
,
FILTER_CURRENT
,
FILTER_NONE
,
}
from
'
~/vue_shared/components/filtered_search_bar/constants
'
;
// Maps sort order as it appears in the URL query to API `order_by` and `sort` params.
const
PRIORITY
=
'
priority
'
;
...
...
@@ -194,81 +199,149 @@ export const FILTERED_SEARCH_TERM = 'filtered-search-term';
export
const
OPERATOR_IS
=
'
=
'
;
export
const
OPERATOR_IS_NOT
=
'
!=
'
;
export
const
NORMAL_FILTER
=
'
normalFilter
'
;
export
const
SPECIAL_FILTER
=
'
specialFilter
'
;
export
const
SPECIAL_FILTER_VALUES
=
[
FILTER_NONE
,
FILTER_ANY
,
FILTER_CURRENT
];
export
const
filters
=
{
author_username
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
author_username
'
,
[
OPERATOR_IS_NOT
]:
'
not[author_username]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
author_username
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[author_username]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
author_username
'
,
[
OPERATOR_IS_NOT
]:
'
not[author_username]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
author_username
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[author_username]
'
,
},
},
},
assignee_username
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
assignee_username
'
,
[
OPERATOR_IS_NOT
]:
'
not[assignee_username]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
assignee_username
'
,
[
SPECIAL_FILTER
]:
'
assignee_id
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[assignee_username]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
assignee_username[]
'
,
[
OPERATOR_IS_NOT
]:
'
not[assignee_username][]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
assignee_username[]
'
,
[
SPECIAL_FILTER
]:
'
assignee_id
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[assignee_username][]
'
,
},
},
},
milestone
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
milestone
'
,
[
OPERATOR_IS_NOT
]:
'
not[milestone]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
milestone
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[milestone]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
milestone_title
'
,
[
OPERATOR_IS_NOT
]:
'
not[milestone_title]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
milestone_title
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[milestone_title]
'
,
},
},
},
labels
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
labels
'
,
[
OPERATOR_IS_NOT
]:
'
not[labels]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
labels
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[labels]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
label_name[]
'
,
[
OPERATOR_IS_NOT
]:
'
not[label_name][]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
label_name[]
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[label_name][]
'
,
},
},
},
my_reaction_emoji
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
my_reaction_emoji
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
my_reaction_emoji
'
,
[
SPECIAL_FILTER
]:
'
my_reaction_emoji
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
my_reaction_emoji
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
my_reaction_emoji
'
,
[
SPECIAL_FILTER
]:
'
my_reaction_emoji
'
,
},
},
},
confidential
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
confidential
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
confidential
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
confidential
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
confidential
'
,
},
},
},
iteration
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
iteration_title
'
,
[
OPERATOR_IS_NOT
]:
'
not[iteration_title]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
iteration_title
'
,
[
SPECIAL_FILTER
]:
'
iteration_id
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[iteration_title]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
iteration_title
'
,
[
OPERATOR_IS_NOT
]:
'
not[iteration_title]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
iteration_title
'
,
[
SPECIAL_FILTER
]:
'
iteration_id
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[iteration_title]
'
,
},
},
},
weight
:
{
apiParam
:
{
[
OPERATOR_IS
]:
'
weight
'
,
[
OPERATOR_IS_NOT
]:
'
not[weight]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
weight
'
,
[
SPECIAL_FILTER
]:
'
weight
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[weight]
'
,
},
},
urlParam
:
{
[
OPERATOR_IS
]:
'
weight
'
,
[
OPERATOR_IS_NOT
]:
'
not[weight]
'
,
[
OPERATOR_IS
]:
{
[
NORMAL_FILTER
]:
'
weight
'
,
[
SPECIAL_FILTER
]:
'
weight
'
,
},
[
OPERATOR_IS_NOT
]:
{
[
NORMAL_FILTER
]:
'
not[weight]
'
,
},
},
},
};
app/assets/javascripts/issues_list/utils.js
View file @
a1f65ac9
...
...
@@ -11,12 +11,15 @@ import {
LABEL_PRIORITY_DESC
,
MILESTONE_DUE_ASC
,
MILESTONE_DUE_DESC
,
NORMAL_FILTER
,
POPULARITY_ASC
,
POPULARITY_DESC
,
PRIORITY_ASC
,
PRIORITY_DESC
,
RELATIVE_POSITION_ASC
,
sortParams
,
SPECIAL_FILTER
,
SPECIAL_FILTER_VALUES
,
UPDATED_ASC
,
UPDATED_DESC
,
WEIGHT_ASC
,
...
...
@@ -124,13 +127,18 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
const
tokenTypes
=
Object
.
keys
(
filters
);
const
urlParamKeys
=
tokenTypes
.
flatMap
((
key
)
=>
Object
.
values
(
filters
[
key
].
urlParam
));
const
getUrlParams
=
(
tokenType
)
=>
Object
.
values
(
filters
[
tokenType
].
urlParam
).
flatMap
((
filterObj
)
=>
Object
.
values
(
filterObj
));
const
urlParamKeys
=
tokenTypes
.
flatMap
(
getUrlParams
);
const
getTokenTypeFromUrlParamKey
=
(
urlParamKey
)
=>
tokenTypes
.
find
((
key
)
=>
Object
.
values
(
filters
[
key
].
urlParam
).
includes
(
urlParamKey
));
tokenTypes
.
find
((
tokenType
)
=>
getUrlParams
(
tokenType
).
includes
(
urlParamKey
));
const
getOperatorFromUrlParamKey
=
(
tokenType
,
urlParamKey
)
=>
Object
.
entries
(
filters
[
tokenType
].
urlParam
).
find
(([,
urlParam
])
=>
urlParam
===
urlParamKey
)[
0
];
Object
.
entries
(
filters
[
tokenType
].
urlParam
).
find
(([,
filterObj
])
=>
Object
.
values
(
filterObj
).
includes
(
urlParamKey
),
)[
0
];
const
convertToFilteredTokens
=
(
locationSearch
)
=>
Array
.
from
(
new
URLSearchParams
(
locationSearch
).
entries
())
...
...
@@ -164,11 +172,15 @@ 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
apiParam
=
filters
[
token
.
type
].
apiParam
[
token
.
value
.
operator
];
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
,
});
...
...
@@ -178,7 +190,8 @@ export const convertToUrlParams = (filterTokens) =>
filterTokens
.
filter
((
token
)
=>
token
.
type
!==
FILTERED_SEARCH_TERM
)
.
reduce
((
acc
,
token
)
=>
{
const
urlParam
=
filters
[
token
.
type
].
urlParam
[
token
.
value
.
operator
];
const
filterType
=
getFilterType
(
token
.
value
.
data
);
const
urlParam
=
filters
[
token
.
type
].
urlParam
[
token
.
value
.
operator
]?.[
filterType
];
return
Object
.
assign
(
acc
,
{
[
urlParam
]:
acc
[
urlParam
]
?
acc
[
urlParam
].
concat
(
token
.
value
.
data
)
:
[
token
.
value
.
data
],
});
...
...
app/assets/javascripts/vue_shared/components/filtered_search_bar/constants.js
View file @
a1f65ac9
...
...
@@ -3,21 +3,24 @@ import { __ } from '~/locale';
export
const
DEBOUNCE_DELAY
=
200
;
const
DEFAULT_LABEL_NO_LABEL
=
{
value
:
'
No label
'
,
text
:
__
(
'
No label
'
)
};
export
const
DEFAULT_LABEL_NONE
=
{
value
:
'
None
'
,
text
:
__
(
'
None
'
)
};
export
const
DEFAULT_LABEL_ANY
=
{
value
:
'
Any
'
,
text
:
__
(
'
Any
'
)
};
export
const
DEFAULT_LABEL_CURRENT
=
{
value
:
'
Current
'
,
text
:
__
(
'
Current
'
)
};
export
const
FILTER_NONE
=
'
None
'
;
export
const
FILTER_ANY
=
'
Any
'
;
export
const
FILTER_CURRENT
=
'
Current
'
;
export
const
DEFAULT_ITERATIONS
=
[
DEFAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
,
DEFAULT_LABEL_CURRENT
];
export
const
DEFAULT_LABEL_NONE
=
{
value
:
FILTER_NONE
,
text
:
__
(
FILTER_NONE
)
};
export
const
DEFAULT_LABEL_ANY
=
{
value
:
FILTER_ANY
,
text
:
__
(
FILTER_ANY
)
};
export
const
DEFAULT_NONE_ANY
=
[
DEFAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
];
export
const
DEFAULT_LABELS
=
[
DEFAULT_LABEL_NO_LABEL
];
export
const
DEFAULT_ITERATIONS
=
DEFAULT_NONE_ANY
.
concat
([
{
value
:
FILTER_CURRENT
,
text
:
__
(
FILTER_CURRENT
)
},
]);
export
const
DEFAULT_
MILESTONES
=
[
DEFAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
,
export
const
DEFAULT_
LABELS
=
[{
value
:
'
No label
'
,
text
:
__
(
'
No label
'
)
}];
export
const
DEFAULT_MILESTONES
=
DEFAULT_NONE_ANY
.
concat
([
{
value
:
'
Upcoming
'
,
text
:
__
(
'
Upcoming
'
)
},
{
value
:
'
Started
'
,
text
:
__
(
'
Started
'
)
},
];
]
)
;
export
const
SortDirection
=
{
descending
:
'
descending
'
,
...
...
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue
View file @
a1f65ac9
...
...
@@ -10,7 +10,7 @@ import { debounce } from 'lodash';
import
{
deprecatedCreateFlash
as
createFlash
}
from
'
~/flash
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
DE
FAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
,
DEBOUNCE_DELA
Y
}
from
'
../constants
'
;
import
{
DE
BOUNCE_DELAY
,
DEFAULT_NONE_AN
Y
}
from
'
../constants
'
;
import
{
stripQuotes
}
from
'
../filtered_search_utils
'
;
export
default
{
...
...
@@ -33,7 +33,7 @@ export default {
data
()
{
return
{
emojis
:
this
.
config
.
initialEmojis
||
[],
defaultEmojis
:
this
.
config
.
defaultEmojis
||
[
DEFAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
]
,
defaultEmojis
:
this
.
config
.
defaultEmojis
||
DEFAULT_NONE_ANY
,
loading
:
true
,
};
},
...
...
app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/weight_token.vue
View file @
a1f65ac9
<
script
>
import
{
GlDropdownDivider
,
GlFilteredSearchSuggestion
,
GlFilteredSearchToken
}
from
'
@gitlab/ui
'
;
import
{
DEFAULT_
LABEL_ANY
,
DEFAULT_LABEL_NONE
}
from
'
../constants
'
;
import
{
DEFAULT_
NONE_ANY
}
from
'
../constants
'
;
export
default
{
baseWeights
:
[
'
0
'
,
'
1
'
,
'
2
'
,
'
3
'
,
'
4
'
,
'
5
'
],
...
...
@@ -22,7 +22,7 @@ export default {
data
()
{
return
{
weights
:
this
.
$options
.
baseWeights
,
defaultWeights
:
this
.
config
.
defaultWeights
||
[
DEFAULT_LABEL_NONE
,
DEFAULT_LABEL_ANY
]
,
defaultWeights
:
this
.
config
.
defaultWeights
||
DEFAULT_NONE_ANY
,
};
},
methods
:
{
...
...
spec/frontend/issues_list/mock_data.js
View file @
a1f65ac9
...
...
@@ -20,6 +20,13 @@ export const locationSearch = [
'
not[weight]=3
'
,
].
join
(
'
&
'
);
export
const
locationSearchWithSpecialValues
=
[
'
assignee_id=None
'
,
'
my_reaction_emoji=None
'
,
'
iteration_id=Current
'
,
'
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
}
},
...
...
@@ -41,6 +48,13 @@ export const filteredTokens = [
{
type
:
'
filtered-search-term
'
,
value
:
{
data
:
'
issues
'
}
},
];
export
const
filteredTokensWithSpecialValues
=
[
{
type
:
'
assignee_username
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
my_reaction_emoji
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
iteration
'
,
value
:
{
data
:
'
Current
'
,
operator
:
OPERATOR_IS
}
},
{
type
:
'
weight
'
,
value
:
{
data
:
'
None
'
,
operator
:
OPERATOR_IS
}
},
];
export
const
apiParams
=
{
author_username
:
'
homer
'
,
'
not[author_username]
'
:
'
marge
'
,
...
...
@@ -58,6 +72,13 @@ export const apiParams = {
'
not[weight]
'
:
'
3
'
,
};
export
const
apiParamsWithSpecialValues
=
{
assignee_id
:
'
None
'
,
my_reaction_emoji
:
'
None
'
,
iteration_id
:
'
Current
'
,
weight
:
'
None
'
,
};
export
const
urlParams
=
{
author_username
:
[
'
homer
'
],
'
not[author_username]
'
:
[
'
marge
'
],
...
...
@@ -74,3 +95,10 @@ export const urlParams = {
weight
:
[
'
1
'
],
'
not[weight]
'
:
[
'
3
'
],
};
export
const
urlParamsWithSpecialValues
=
{
assignee_id
:
[
'
None
'
],
my_reaction_emoji
:
[
'
None
'
],
iteration_id
:
[
'
Current
'
],
weight
:
[
'
None
'
],
};
spec/frontend/issues_list/utils_spec.js
View file @
a1f65ac9
import
{
apiParams
,
filteredTokens
,
locationSearch
,
urlParams
}
from
'
jest/issues_list/mock_data
'
;
import
{
apiParams
,
apiParamsWithSpecialValues
,
filteredTokens
,
filteredTokensWithSpecialValues
,
locationSearch
,
locationSearchWithSpecialValues
,
urlParams
,
urlParamsWithSpecialValues
,
}
from
'
jest/issues_list/mock_data
'
;
import
{
sortParams
}
from
'
~/issues_list/constants
'
;
import
{
convertToApiParams
,
...
...
@@ -53,18 +62,32 @@ 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
(
'
convertToApiParams
'
,
()
=>
{
it
(
'
returns api params given filtered tokens
'
,
()
=>
{
expect
(
convertToApiParams
(
filteredTokens
)).
toEqual
(
apiParams
);
});
it
(
'
returns api params given filtered tokens with special values
'
,
()
=>
{
expect
(
convertToApiParams
(
filteredTokensWithSpecialValues
)).
toEqual
(
apiParamsWithSpecialValues
);
});
});
describe
(
'
convertToUrlParams
'
,
()
=>
{
it
(
'
returns url params given filtered tokens
'
,
()
=>
{
expect
(
convertToUrlParams
(
filteredTokens
)).
toEqual
(
urlParams
);
});
it
(
'
returns url params given filtered tokens with special values
'
,
()
=>
{
expect
(
convertToUrlParams
(
filteredTokensWithSpecialValues
)).
toEqual
(
urlParamsWithSpecialValues
);
});
});
describe
(
'
convertToSearchQuery
'
,
()
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment