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
54a0fa36
Commit
54a0fa36
authored
Mar 18, 2020
by
Miguel Rincon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement separate advanced log filters
Split current function between simple and advanced
parent
e0449925
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
653 additions
and
277 deletions
+653
-277
app/assets/javascripts/logs/components/environment_logs.vue
app/assets/javascripts/logs/components/environment_logs.vue
+48
-157
app/assets/javascripts/logs/components/log_advanced_filters.vue
...sets/javascripts/logs/components/log_advanced_filters.vue
+128
-0
app/assets/javascripts/logs/components/log_simple_filters.vue
...assets/javascripts/logs/components/log_simple_filters.vue
+73
-0
app/assets/javascripts/logs/stores/getters.js
app/assets/javascripts/logs/stores/getters.js
+6
-2
app/assets/stylesheets/pages/builds.scss
app/assets/stylesheets/pages/builds.scss
+8
-14
changelogs/unreleased/207912-implementing-filtered-search-advanced-filters.yml
.../207912-implementing-filtered-search-advanced-filters.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/features/projects/environments_pod_logs_spec.rb
spec/features/projects/environments_pod_logs_spec.rb
+3
-3
spec/frontend/logs/components/environment_logs_spec.js
spec/frontend/logs/components/environment_logs_spec.js
+16
-96
spec/frontend/logs/components/log_advanced_filters_spec.js
spec/frontend/logs/components/log_advanced_filters_spec.js
+185
-0
spec/frontend/logs/components/log_simple_filters_spec.js
spec/frontend/logs/components/log_simple_filters_spec.js
+138
-0
spec/frontend/logs/stores/getters_spec.js
spec/frontend/logs/stores/getters_spec.js
+40
-5
No files found.
app/assets/javascripts/logs/components/environment_logs.vue
View file @
54a0fa36
...
...
@@ -7,17 +7,15 @@ import {
GlAlert
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownDivider
,
GlDropdownItem
,
GlFormGroup
,
GlSearchBoxByClick
,
GlInfiniteScroll
,
}
from
'
@gitlab/ui
'
;
import
{
s__
}
from
'
~/locale
'
;
import
DateTimePicker
from
'
~/vue_shared/components/date_time_picker/date_time_picker.vue
'
;
import
LogSimpleFilters
from
'
./log_simple_filters.vue
'
;
import
LogAdvancedFilters
from
'
./log_advanced_filters.vue
'
;
import
LogControlButtons
from
'
./log_control_buttons.vue
'
;
import
{
timeRanges
,
defaultTimeRange
}
from
'
~/vue_shared/constants
'
;
import
{
defaultTimeRange
}
from
'
~/vue_shared/constants
'
;
import
{
timeRangeFromUrl
}
from
'
~/monitoring/utils
'
;
import
{
formatDate
}
from
'
../utils
'
;
...
...
@@ -28,12 +26,10 @@ export default {
GlAlert
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownDivider
,
GlDropdownItem
,
GlFormGroup
,
GlSearchBoxByClick
,
GlInfiniteScroll
,
DateTimePicker
,
LogSimpleFilters
,
LogAdvancedFilters
,
LogControlButtons
,
},
filters
:
{
...
...
@@ -63,49 +59,22 @@ export default {
traceHeight
:
600
,
data
()
{
return
{
searchQuery
:
''
,
timeRanges
,
isElasticStackCalloutDismissed
:
false
,
scrollDownButtonDisabled
:
true
,
};
},
computed
:
{
...
mapState
(
'
environmentLogs
'
,
[
'
environments
'
,
'
timeRange
'
,
'
logs
'
,
'
pods
'
]),
...
mapGetters
(
'
environmentLogs
'
,
[
'
trace
'
]),
timeRangeModel
:
{
get
()
{
return
this
.
timeRange
.
selected
;
},
set
(
val
)
{
this
.
setTimeRange
(
val
);
},
},
...
mapGetters
(
'
environmentLogs
'
,
[
'
trace
'
,
'
showAdvancedFilters
'
]),
showLoader
()
{
return
this
.
logs
.
isLoading
;
},
advancedFeaturesEnabled
()
{
const
environment
=
this
.
environments
.
options
.
find
(
({
name
})
=>
name
===
this
.
environments
.
current
,
);
return
environment
&&
environment
.
enable_advanced_logs_querying
;
},
disableAdvancedControls
()
{
return
this
.
environments
.
isLoading
||
!
this
.
advancedFeaturesEnabled
;
},
shouldShowElasticStackCallout
()
{
return
!
this
.
isElasticStackCalloutDismissed
&&
this
.
disableAdvancedControls
;
},
podDropdownText
()
{
if
(
this
.
pods
.
current
)
{
return
this
.
pods
.
current
;
}
else
if
(
this
.
advancedFeaturesEnabled
)
{
// "All pods" is a valid option when advanced querying is available
return
s__
(
'
Environments|All pods
'
);
}
return
s__
(
'
Environments|No pod selected
'
);
return
(
!
this
.
isElasticStackCalloutDismissed
&&
(
this
.
environments
.
isLoading
||
!
this
.
showAdvancedFilters
)
);
},
},
mounted
()
{
...
...
@@ -121,7 +90,6 @@ export default {
...
mapActions
(
'
environmentLogs
'
,
[
'
setInitData
'
,
'
setSearch
'
,
'
setTimeRange
'
,
'
showPodLogs
'
,
'
showEnvironment
'
,
'
fetchEnvironments
'
,
...
...
@@ -131,9 +99,6 @@ export default {
isCurrentEnvironment
(
envName
)
{
return
envName
===
this
.
environments
.
current
;
},
isCurrentPod
(
podName
)
{
return
podName
===
this
.
pods
.
current
;
},
topReached
()
{
if
(
!
this
.
logs
.
isLoading
)
{
this
.
fetchMoreLogsPrepend
();
...
...
@@ -167,123 +132,49 @@ export default {
</strong>
</a>
</gl-alert>
<div
class=
"top-bar
js-top-bar d-flex
"
>
<div
class=
"
row mx-n1
"
>
<gl-
form-group
id=
"environments-dropdown
-fg
"
label-size=
"sm
"
label-for=
"environments-dropdown
"
class=
"
col-3 px-1
"
<div
class=
"top-bar
d-md-flex border bg-secondary-50 pt-2 pr-1 pb-0 pl-2
"
>
<div
class=
"
flex-grow-0
"
>
<gl-
dropdown
id=
"environments-dropdown"
:text=
"environments.current
"
:disabled=
"environments.isLoading
"
class=
"
mb-2 gl-h-32 pr-2 d-flex d-md-block js-environments-dropdown
"
>
<gl-dropdown
id=
"environments-dropdown"
:text=
"environments.current"
:disabled=
"environments.isLoading"
class=
"d-flex gl-h-32 js-environments-dropdown"
toggle-class=
"dropdown-menu-toggle"
<gl-dropdown-header
class=
"text-center"
>
{{
s__
(
'
Environments|Select environment
'
)
}}
</gl-dropdown-header>
<gl-dropdown-item
v-for=
"env in environments.options"
:key=
"env.id"
@
click=
"showEnvironment(env.name)"
>
<gl-dropdown-header
class=
"text-center"
>
{{
s__
(
'
Environments|Select environment
'
)
}}
</gl-dropdown-header>
<gl-dropdown-item
v-for=
"env in environments.options"
:key=
"env.id"
@
click=
"showEnvironment(env.name)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: !isCurrentEnvironment(env.name) }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
env
.
name
}}
</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</gl-form-group>
<gl-form-group
id=
"pods-dropdown-fg"
label-size=
"sm"
label-for=
"pods-dropdown"
class=
"col-3 px-1"
>
<gl-dropdown
id=
"pods-dropdown"
:text=
"podDropdownText"
:disabled=
"environments.isLoading"
class=
"d-flex gl-h-32 js-pods-dropdown"
toggle-class=
"dropdown-menu-toggle"
>
<gl-dropdown-header
class=
"text-center"
>
{{
s__
(
'
Environments|Filter by pod
'
)
}}
</gl-dropdown-header>
<template
v-if=
"advancedFeaturesEnabled"
>
<gl-dropdown-item
key=
"all-pods"
@
click=
"showPodLogs(null)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: !isCurrentPod(null) }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
s__
(
'
Environments|All pods
'
)
}}
</div>
</div>
</gl-dropdown-item>
<gl-dropdown-divider
/>
</
template
>
<gl-dropdown-item
v-if=
"!pods.options.length"
:disabled=
"true"
>
<span
class=
"text-muted"
>
{{ s__('Environments|No pods to display') }}
</span>
</gl-dropdown-item>
<gl-dropdown-item
v-for=
"podName in pods.options"
:key=
"podName"
class=
"text-nowrap"
@
click=
"showPodLogs(podName)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"{ invisible: !isCurrentPod(podName) }"
name=
"status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{ podName }}
</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</gl-form-group>
<gl-form-group
id=
"search-fg"
label-size=
"sm"
label-for=
"search"
class=
"col-3 px-1"
>
<gl-search-box-by-click
v-model.trim=
"searchQuery"
:disabled=
"disableAdvancedControls"
:placeholder=
"s__('Environments|Search')"
class=
"js-logs-search"
type=
"search"
autofocus
@
submit=
"setSearch(searchQuery)"
/>
</gl-form-group>
<gl-form-group
id=
"dates-fg"
label-size=
"sm"
label-for=
"time-window-dropdown"
class=
"col-3 px-1"
>
<date-time-picker
ref=
"dateTimePicker"
v-model=
"timeRangeModel"
class=
"w-100 gl-h-32"
right
:disabled=
"disableAdvancedControls"
:options=
"timeRanges"
/>
</gl-form-group>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: !isCurrentEnvironment(env.name) }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
env
.
name
}}
</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</div>
<log-advanced-filters
v-if=
"showAdvancedFilters"
ref=
"log-advanced-filters"
class=
"d-md-flex flex-grow-1"
:disabled=
"environments.isLoading"
/>
<log-simple-filters
v-else
ref=
"log-simple-filters"
class=
"d-md-flex flex-grow-1"
:disabled=
"environments.isLoading"
/>
<log-control-buttons
ref=
"scrollButtons"
class=
"controllers"
class=
"
flex-grow-0 pr-2 mb-2
controllers"
:scroll-down-button-disabled=
"scrollDownButtonDisabled"
@
refresh=
"showPodLogs(pods.current)"
@
scrollDown=
"scrollDown"
...
...
app/assets/javascripts/logs/components/log_advanced_filters.vue
0 → 100644
View file @
54a0fa36
<
script
>
import
{
s__
}
from
'
~/locale
'
;
import
DateTimePicker
from
'
~/vue_shared/components/date_time_picker/date_time_picker.vue
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
GlIcon
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownDivider
,
GlDropdownItem
,
GlSearchBoxByClick
,
}
from
'
@gitlab/ui
'
;
import
{
timeRanges
}
from
'
~/vue_shared/constants
'
;
export
default
{
components
:
{
GlIcon
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownDivider
,
GlDropdownItem
,
GlSearchBoxByClick
,
DateTimePicker
,
},
props
:
{
disabled
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
data
()
{
return
{
timeRanges
,
searchQuery
:
''
,
};
},
computed
:
{
...
mapState
(
'
environmentLogs
'
,
[
'
timeRange
'
,
'
pods
'
]),
timeRangeModel
:
{
get
()
{
return
this
.
timeRange
.
selected
;
},
set
(
val
)
{
this
.
setTimeRange
(
val
);
},
},
podDropdownText
()
{
return
this
.
pods
.
current
||
s__
(
'
Environments|All pods
'
);
},
},
methods
:
{
...
mapActions
(
'
environmentLogs
'
,
[
'
setSearch
'
,
'
showPodLogs
'
,
'
setTimeRange
'
]),
isCurrentPod
(
podName
)
{
return
podName
===
this
.
pods
.
current
;
},
},
};
</
script
>
<
template
>
<div>
<gl-dropdown
ref=
"podsDropdown"
:text=
"podDropdownText"
:disabled=
"disabled"
class=
"mb-2 gl-h-32 pr-2 d-flex d-md-block flex-grow-0 qa-pods-dropdown"
>
<gl-dropdown-header
class=
"text-center"
>
{{
s__
(
'
Environments|Filter by pod
'
)
}}
</gl-dropdown-header>
<gl-dropdown-item
v-if=
"!pods.options.length"
disabled
>
<span
ref=
"noPodsMsg"
class=
"text-muted"
>
{{
s__
(
'
Environments|No pods to display
'
)
}}
</span>
</gl-dropdown-item>
<template
v-else
>
<gl-dropdown-item
ref=
"allPodsOption"
key=
"all-pods"
@
click=
"showPodLogs(null)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: pods.current !== null }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
s__
(
'
Environments|All pods
'
)
}}
</div>
</div>
</gl-dropdown-item>
<gl-dropdown-divider
/>
<gl-dropdown-item
v-for=
"podName in pods.options"
:key=
"podName"
class=
"text-nowrap"
@
click=
"showPodLogs(podName)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: !isCurrentPod(podName) }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
podName
}}
</div>
</div>
</gl-dropdown-item>
</
template
>
</gl-dropdown>
<gl-search-box-by-click
ref=
"searchBox"
v-model.trim=
"searchQuery"
:disabled=
"disabled"
:placeholder=
"s__('Environments|Search')"
class=
"mb-2 pr-2 flex-grow-1"
type=
"search"
autofocus
@
submit=
"setSearch(searchQuery)"
/>
<date-time-picker
ref=
"dateTimePicker"
v-model=
"timeRangeModel"
:disabled=
"disabled"
:options=
"timeRanges"
class=
"mb-2 gl-h-32 pr-2 d-block date-time-picker-wrapper"
right
/>
</div>
</template>
app/assets/javascripts/logs/components/log_simple_filters.vue
0 → 100644
View file @
54a0fa36
<
script
>
import
{
s__
}
from
'
~/locale
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
GlIcon
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlIcon
,
GlDropdown
,
GlDropdownHeader
,
GlDropdownItem
,
},
props
:
{
disabled
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
data
()
{
return
{
searchQuery
:
''
,
};
},
computed
:
{
...
mapState
(
'
environmentLogs
'
,
[
'
pods
'
]),
podDropdownText
()
{
return
this
.
pods
.
current
||
s__
(
'
Environments|No pod selected
'
);
},
},
methods
:
{
...
mapActions
(
'
environmentLogs
'
,
[
'
showPodLogs
'
]),
isCurrentPod
(
podName
)
{
return
podName
===
this
.
pods
.
current
;
},
},
};
</
script
>
<
template
>
<div>
<gl-dropdown
ref=
"podsDropdown"
:text=
"podDropdownText"
:disabled=
"disabled"
class=
"mb-2 gl-h-32 pr-2 d-flex d-md-block flex-grow-0 qa-pods-dropdown"
>
<gl-dropdown-header
class=
"text-center"
>
{{
s__
(
'
Environments|Select pod
'
)
}}
</gl-dropdown-header>
<gl-dropdown-item
v-if=
"!pods.options.length"
disabled
>
<span
ref=
"noPodsMsg"
class=
"text-muted"
>
{{
s__
(
'
Environments|No pods to display
'
)
}}
</span>
</gl-dropdown-item>
<gl-dropdown-item
v-for=
"podName in pods.options"
:key=
"podName"
class=
"text-nowrap"
@
click=
"showPodLogs(podName)"
>
<div
class=
"d-flex"
>
<gl-icon
:class=
"
{ invisible: !isCurrentPod(podName) }"
name="status_success_borderless"
/>
<div
class=
"flex-grow-1"
>
{{
podName
}}
</div>
</div>
</gl-dropdown-item>
</gl-dropdown>
</div>
</
template
>
app/assets/javascripts/logs/stores/getters.js
View file @
54a0fa36
...
...
@@ -5,5 +5,9 @@ const mapTrace = ({ timestamp = null, pod = '', message = '' }) =>
export
const
trace
=
state
=>
state
.
logs
.
lines
.
map
(
mapTrace
).
join
(
'
\n
'
);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export
default
()
=>
{};
export
const
showAdvancedFilters
=
state
=>
{
const
environment
=
state
.
environments
.
options
.
find
(
({
name
})
=>
name
===
state
.
environments
.
current
,
);
return
Boolean
(
environment
?.
enable_advanced_logs_querying
);
};
app/assets/stylesheets/pages/builds.scss
View file @
54a0fa36
...
...
@@ -379,25 +379,19 @@
}
.top-bar
{
@include
build-trace-top-bar
(
$gl-line-height
*
3
);
position
:
relative
;
top
:
0
;
.dropdown-menu-toggle
{
width
:
200px
;
.date-time-picker-wrapper
,
.dropdown-toggle
{
@include
media-breakpoint-up
(
md
)
{
width
:
140px
;
}
@include
media-breakpoint-up
(
sm
)
{
width
:
30
0px
;
@include
media-breakpoint-up
(
lg
)
{
width
:
16
0px
;
}
}
.controllers
{
@include
build-controllers
(
16px
,
flex-end
,
true
,
2
);
}
.refresh-control
{
@include
build-controllers
(
16px
,
flex-end
,
true
,
0
);
margin-left
:
2px
;
@include
build-controllers
(
16px
,
flex-end
,
false
,
2
);
}
}
...
...
changelogs/unreleased/207912-implementing-filtered-search-advanced-filters.yml
0 → 100644
View file @
54a0fa36
---
title
:
Improve logs filters on mobile, simplify kubernetes API logs filters
merge_request
:
27484
author
:
type
:
added
locale/gitlab.pot
View file @
54a0fa36
...
...
@@ -7807,6 +7807,9 @@ msgstr ""
msgid "Environments|Select environment"
msgstr ""
msgid "Environments|Select pod"
msgstr ""
msgid "Environments|Show all"
msgstr ""
...
...
spec/features/projects/environments_pod_logs_spec.rb
View file @
54a0fa36
...
...
@@ -29,7 +29,7 @@ describe 'Environment > Pod Logs', :js do
wait_for_requests
page
.
within
(
'.js-environments-dropdown'
)
do
toggle
=
find
(
".dropdown-
menu-
toggle:not([disabled])"
)
toggle
=
find
(
".dropdown-toggle:not([disabled])"
)
expect
(
toggle
).
to
have_content
(
environment
.
name
)
...
...
@@ -47,8 +47,8 @@ describe 'Environment > Pod Logs', :js do
wait_for_requests
page
.
within
(
'.
js
-pods-dropdown'
)
do
find
(
".dropdown-
menu-
toggle:not([disabled])"
).
click
page
.
within
(
'.
qa
-pods-dropdown'
)
do
find
(
".dropdown-toggle:not([disabled])"
).
click
dropdown_items
=
find
(
".dropdown-menu"
).
all
(
".dropdown-item:not([disabled])"
)
expect
(
dropdown_items
.
size
).
to
eq
(
1
)
...
...
spec/frontend/logs/components/environment_logs_spec.js
View file @
54a0fa36
import
Vue
from
'
vue
'
;
import
{
GlSprintf
,
GlIcon
,
GlDropdown
,
GlDropdownItem
,
GlSearchBoxByClick
}
from
'
@gitlab/ui
'
;
import
{
GlSprintf
,
GlIcon
,
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
DateTimePicker
from
'
~/vue_shared/components/date_time_picker/date_time_picker.vue
'
;
import
EnvironmentLogs
from
'
~/logs/components/environment_logs.vue
'
;
import
{
createStore
}
from
'
~/logs/stores
'
;
...
...
@@ -13,7 +11,6 @@ import {
mockLogsResult
,
mockTrace
,
mockPodName
,
mockSearch
,
mockEnvironmentsEndpoint
,
mockDocumentationPath
,
}
from
'
../mock_data
'
;
...
...
@@ -29,7 +26,6 @@ jest.mock('lodash/throttle', () =>
);
describe
(
'
EnvironmentLogs
'
,
()
=>
{
let
EnvironmentLogsComponent
;
let
store
;
let
dispatch
;
let
wrapper
;
...
...
@@ -44,13 +40,9 @@ describe('EnvironmentLogs', () => {
const
updateControlBtnsMock
=
jest
.
fn
();
const
findEnvironmentsDropdown
=
()
=>
wrapper
.
find
(
'
.js-environments-dropdown
'
);
const
findPodsDropdown
=
()
=>
wrapper
.
find
(
'
.js-pods-dropdown
'
);
const
findPodsDropdownItems
=
()
=>
findPodsDropdown
()
.
findAll
(
GlDropdownItem
)
.
filter
(
itm
=>
!
itm
.
attributes
(
'
disabled
'
));
const
findSearchBar
=
()
=>
wrapper
.
find
(
'
.js-logs-search
'
);
const
findTimeRangePicker
=
()
=>
wrapper
.
find
({
ref
:
'
dateTimePicker
'
});
const
findSimpleFilters
=
()
=>
wrapper
.
find
({
ref
:
'
log-simple-filters
'
});
const
findAdvancedFilters
=
()
=>
wrapper
.
find
({
ref
:
'
log-advanced-filters
'
});
const
findInfoAlert
=
()
=>
wrapper
.
find
(
'
.js-elasticsearch-alert
'
);
const
findLogControlButtons
=
()
=>
wrapper
.
find
({
name
:
'
log-control-buttons-stub
'
});
...
...
@@ -79,7 +71,7 @@ describe('EnvironmentLogs', () => {
};
const
initWrapper
=
()
=>
{
wrapper
=
shallowMount
(
EnvironmentLogs
Component
,
{
wrapper
=
shallowMount
(
EnvironmentLogs
,
{
propsData
,
store
,
stubs
:
{
...
...
@@ -111,7 +103,6 @@ describe('EnvironmentLogs', () => {
beforeEach
(()
=>
{
store
=
createStore
();
state
=
store
.
state
.
environmentLogs
;
EnvironmentLogsComponent
=
Vue
.
extend
(
EnvironmentLogs
);
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockResolvedValue
();
...
...
@@ -132,17 +123,10 @@ describe('EnvironmentLogs', () => {
expect
(
wrapper
.
isVueInstance
()).
toBe
(
true
);
expect
(
wrapper
.
isEmpty
()).
toBe
(
false
);
// top bar
expect
(
findEnvironmentsDropdown
().
is
(
GlDropdown
)).
toBe
(
true
);
expect
(
find
PodsDropdown
().
is
(
GlDropdown
)).
toBe
(
true
);
expect
(
find
SimpleFilters
().
exists
(
)).
toBe
(
true
);
expect
(
findLogControlButtons
().
exists
()).
toBe
(
true
);
expect
(
findSearchBar
().
exists
()).
toBe
(
true
);
expect
(
findSearchBar
().
is
(
GlSearchBoxByClick
)).
toBe
(
true
);
expect
(
findTimeRangePicker
().
exists
()).
toBe
(
true
);
expect
(
findTimeRangePicker
().
is
(
DateTimePicker
)).
toBe
(
true
);
// log trace
expect
(
findInfiniteScroll
().
exists
()).
toBe
(
true
);
expect
(
findLogTrace
().
exists
()).
toBe
(
true
);
});
...
...
@@ -181,20 +165,6 @@ describe('EnvironmentLogs', () => {
expect
(
findEnvironmentsDropdown
().
findAll
(
GlDropdownItem
).
length
).
toBe
(
0
);
});
it
(
'
displays a disabled pods dropdown
'
,
()
=>
{
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
expect
(
findPodsDropdownItems
()).
toHaveLength
(
0
);
});
it
(
'
displays a disabled search bar
'
,
()
=>
{
expect
(
findSearchBar
().
exists
()).
toBe
(
true
);
expect
(
findSearchBar
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
it
(
'
displays a disabled time window dropdown
'
,
()
=>
{
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
it
(
'
does not update buttons state
'
,
()
=>
{
expect
(
updateControlBtnsMock
).
not
.
toHaveBeenCalled
();
});
...
...
@@ -237,17 +207,14 @@ describe('EnvironmentLogs', () => {
initWrapper
();
});
it
(
'
displays a disabled time window dropdown
'
,
()
=>
{
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
it
(
'
displays a disabled search bar
'
,
()
=>
{
expect
(
findSearchBar
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
it
(
'
displays an alert to upgrade to ES
'
,
()
=>
{
expect
(
findInfoAlert
().
exists
()).
toBe
(
true
);
});
it
(
'
displays simple filters for kubernetes logs API
'
,
()
=>
{
expect
(
findSimpleFilters
().
exists
()).
toBe
(
true
);
expect
(
findAdvancedFilters
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
state with data
'
,
()
=>
{
...
...
@@ -271,21 +238,6 @@ describe('EnvironmentLogs', () => {
updateControlBtnsMock
.
mockReset
();
});
it
(
'
displays an enabled search bar
'
,
()
=>
{
expect
(
findSearchBar
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
// input a query and click `search`
findSearchBar
().
vm
.
$emit
(
'
input
'
,
mockSearch
);
findSearchBar
().
vm
.
$emit
(
'
submit
'
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/setInitData`
,
expect
.
any
(
Object
));
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/setSearch`
,
mockSearch
);
});
it
(
'
displays an enabled time window dropdown
'
,
()
=>
{
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
it
(
'
does not display an alert to upgrade to ES
'
,
()
=>
{
expect
(
findInfoAlert
().
exists
()).
toBe
(
false
);
});
...
...
@@ -306,24 +258,16 @@ describe('EnvironmentLogs', () => {
const
item
=
items
.
at
(
i
);
if
(
item
.
text
()
!==
mockEnvName
)
{
expect
(
item
.
find
(
GlIcon
).
classes
(
)).
toContain
(
'
invisible
'
);
expect
(
item
.
find
(
GlIcon
).
classes
(
'
invisible
'
)).
toBe
(
true
);
}
else
{
// selected
expect
(
item
.
find
(
GlIcon
).
classes
()).
not
.
toContain
(
'
invisible
'
);
expect
(
item
.
find
(
GlIcon
).
classes
(
'
invisible
'
)).
toBe
(
false
);
}
});
});
it
(
'
populates pods dropdown
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
mockPodName
);
expect
(
items
.
length
).
toBe
(
mockPods
.
length
+
1
);
expect
(
items
.
at
(
0
).
text
()).
toBe
(
'
All pods
'
);
mockPods
.
forEach
((
pod
,
i
)
=>
{
const
item
=
items
.
at
(
i
+
1
);
expect
(
item
.
text
()).
toBe
(
pod
);
});
it
(
'
displays advanced filters for elasticsearch logs API
'
,
()
=>
{
expect
(
findSimpleFilters
().
exists
()).
toBe
(
false
);
expect
(
findAdvancedFilters
().
exists
()).
toBe
(
true
);
});
it
(
'
shows infinite scroll with height and no content
'
,
()
=>
{
...
...
@@ -331,19 +275,6 @@ describe('EnvironmentLogs', () => {
expect
(
getInfiniteScrollAttr
(
'
fetched-items
'
)).
toBe
(
mockTrace
.
length
);
});
it
(
'
dropdown has one pod selected
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
mockPods
.
forEach
((
pod
,
i
)
=>
{
const
item
=
items
.
at
(
i
);
if
(
item
.
text
()
!==
mockPodName
)
{
expect
(
item
.
find
(
GlIcon
).
classes
()).
toContain
(
'
invisible
'
);
}
else
{
// selected
expect
(
item
.
find
(
GlIcon
).
classes
()).
not
.
toContain
(
'
invisible
'
);
}
});
});
it
(
'
populates logs trace
'
,
()
=>
{
const
trace
=
findLogTrace
();
expect
(
trace
.
text
().
split
(
'
\n
'
).
length
).
toBe
(
mockTrace
.
length
);
...
...
@@ -371,17 +302,6 @@ describe('EnvironmentLogs', () => {
);
});
it
(
'
pod name, trace is refreshed
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
const
index
=
2
;
// any pod
expect
(
dispatch
).
not
.
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
expect
.
anything
());
items
.
at
(
index
+
1
).
vm
.
$emit
(
'
click
'
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
mockPods
[
index
]);
});
it
(
'
refresh button, trace is refreshed
'
,
()
=>
{
expect
(
dispatch
).
not
.
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
expect
.
anything
());
...
...
spec/frontend/logs/components/log_advanced_filters_spec.js
0 → 100644
View file @
54a0fa36
import
{
GlIcon
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
defaultTimeRange
}
from
'
~/vue_shared/constants
'
;
import
{
convertToFixedRange
}
from
'
~/lib/utils/datetime_range
'
;
import
{
createStore
}
from
'
~/logs/stores
'
;
import
{
mockPods
,
mockSearch
}
from
'
../mock_data
'
;
import
LogAdvancedFilters
from
'
~/logs/components/log_advanced_filters.vue
'
;
const
module
=
'
environmentLogs
'
;
describe
(
'
LogAdvancedFilters
'
,
()
=>
{
let
store
;
let
dispatch
;
let
wrapper
;
let
state
;
const
findPodsDropdown
=
()
=>
wrapper
.
find
({
ref
:
'
podsDropdown
'
});
const
findPodsNoPodsText
=
()
=>
wrapper
.
find
({
ref
:
'
noPodsMsg
'
});
const
findPodsDropdownItems
=
()
=>
findPodsDropdown
()
.
findAll
(
GlDropdownItem
)
.
filter
(
item
=>
!
item
.
is
(
'
[disabled]
'
));
const
findPodsDropdownItemsSelected
=
()
=>
findPodsDropdownItems
()
.
filter
(
item
=>
{
return
!
item
.
find
(
GlIcon
).
classes
(
'
invisible
'
);
})
.
at
(
0
);
const
findSearchBox
=
()
=>
wrapper
.
find
({
ref
:
'
searchBox
'
});
const
findTimeRangePicker
=
()
=>
wrapper
.
find
({
ref
:
'
dateTimePicker
'
});
const
mockStateLoading
=
()
=>
{
state
.
timeRange
.
selected
=
defaultTimeRange
;
state
.
timeRange
.
current
=
convertToFixedRange
(
defaultTimeRange
);
state
.
pods
.
options
=
[];
state
.
pods
.
current
=
null
;
};
const
mockStateWithData
=
()
=>
{
state
.
timeRange
.
selected
=
defaultTimeRange
;
state
.
timeRange
.
current
=
convertToFixedRange
(
defaultTimeRange
);
state
.
pods
.
options
=
mockPods
;
state
.
pods
.
current
=
null
;
};
const
initWrapper
=
(
propsData
=
{})
=>
{
wrapper
=
shallowMount
(
LogAdvancedFilters
,
{
propsData
:
{
...
propsData
,
},
store
,
});
};
beforeEach
(()
=>
{
store
=
createStore
();
state
=
store
.
state
.
environmentLogs
;
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockResolvedValue
();
dispatch
=
store
.
dispatch
;
});
afterEach
(()
=>
{
store
.
dispatch
.
mockReset
();
if
(
wrapper
)
{
wrapper
.
destroy
();
}
});
it
(
'
displays UI elements
'
,
()
=>
{
initWrapper
();
expect
(
wrapper
.
isVueInstance
()).
toBe
(
true
);
expect
(
wrapper
.
isEmpty
()).
toBe
(
false
);
expect
(
findPodsDropdown
().
exists
()).
toBe
(
true
);
expect
(
findSearchBox
().
exists
()).
toBe
(
true
);
expect
(
findTimeRangePicker
().
exists
()).
toBe
(
true
);
});
describe
(
'
disabled state
'
,
()
=>
{
beforeEach
(()
=>
{
mockStateLoading
();
initWrapper
({
disabled
:
true
,
});
});
it
(
'
displays disabled filters
'
,
()
=>
{
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
'
All pods
'
);
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeTruthy
();
expect
(
findSearchBox
().
attributes
(
'
disabled
'
)).
toBeTruthy
();
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBeTruthy
();
});
});
describe
(
'
when the state is loading
'
,
()
=>
{
beforeEach
(()
=>
{
mockStateLoading
();
initWrapper
();
});
it
(
'
displays a enabled filters
'
,
()
=>
{
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
'
All pods
'
);
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
expect
(
findSearchBox
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
it
(
'
displays an empty pods dropdown
'
,
()
=>
{
expect
(
findPodsNoPodsText
().
exists
()).
toBe
(
true
);
expect
(
findPodsDropdownItems
()).
toHaveLength
(
0
);
});
});
describe
(
'
when the state has data
'
,
()
=>
{
beforeEach
(()
=>
{
mockStateWithData
();
initWrapper
();
});
it
(
'
displays an enabled pods dropdown
'
,
()
=>
{
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
'
All pods
'
);
});
it
(
'
displays options in a pods dropdown
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
expect
(
items
).
toHaveLength
(
mockPods
.
length
+
1
);
});
it
(
'
displays "all pods" selected in a pods dropdown
'
,
()
=>
{
const
selected
=
findPodsDropdownItemsSelected
();
expect
(
selected
.
text
()).
toBe
(
'
All pods
'
);
});
it
(
'
displays options in date time picker
'
,
()
=>
{
const
options
=
findTimeRangePicker
().
props
(
'
options
'
);
expect
(
options
).
toEqual
(
expect
.
any
(
Array
));
expect
(
options
.
length
).
toBeGreaterThan
(
0
);
});
describe
(
'
when the user interacts
'
,
()
=>
{
it
(
'
clicks on a all options, showPodLogs is dispatched with null
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
items
.
at
(
0
).
vm
.
$emit
(
'
click
'
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
null
);
});
it
(
'
clicks on a pod name, showPodLogs is dispatched with pod name
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
const
index
=
2
;
// any pod
items
.
at
(
index
+
1
).
vm
.
$emit
(
'
click
'
);
// skip "All pods" option
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
mockPods
[
index
]);
});
it
(
'
clicks on search, a serches is done
'
,
()
=>
{
expect
(
findSearchBox
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
// input a query and click `search`
findSearchBox
().
vm
.
$emit
(
'
input
'
,
mockSearch
);
findSearchBox
().
vm
.
$emit
(
'
submit
'
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/setSearch`
,
mockSearch
);
});
it
(
'
selects a new time range
'
,
()
=>
{
expect
(
findTimeRangePicker
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
const
mockRange
=
{
start
:
'
START_DATE
'
,
end
:
'
END_DATE
'
};
findTimeRangePicker
().
vm
.
$emit
(
'
input
'
,
mockRange
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/setTimeRange`
,
mockRange
);
});
});
});
});
spec/frontend/logs/components/log_simple_filters_spec.js
0 → 100644
View file @
54a0fa36
import
{
GlIcon
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
createStore
}
from
'
~/logs/stores
'
;
import
{
mockPods
,
mockPodName
}
from
'
../mock_data
'
;
import
LogSimpleFilters
from
'
~/logs/components/log_simple_filters.vue
'
;
const
module
=
'
environmentLogs
'
;
describe
(
'
LogSimpleFilters
'
,
()
=>
{
let
store
;
let
dispatch
;
let
wrapper
;
let
state
;
const
findPodsDropdown
=
()
=>
wrapper
.
find
({
ref
:
'
podsDropdown
'
});
const
findPodsNoPodsText
=
()
=>
wrapper
.
find
({
ref
:
'
noPodsMsg
'
});
const
findPodsDropdownItems
=
()
=>
findPodsDropdown
()
.
findAll
(
GlDropdownItem
)
.
filter
(
item
=>
!
item
.
is
(
'
[disabled]
'
));
const
mockPodsLoading
=
()
=>
{
state
.
pods
.
options
=
[];
state
.
pods
.
current
=
null
;
};
const
mockPodsLoaded
=
()
=>
{
state
.
pods
.
options
=
mockPods
;
state
.
pods
.
current
=
mockPodName
;
};
const
initWrapper
=
(
propsData
=
{})
=>
{
wrapper
=
shallowMount
(
LogSimpleFilters
,
{
propsData
:
{
...
propsData
,
},
store
,
});
};
beforeEach
(()
=>
{
store
=
createStore
();
state
=
store
.
state
.
environmentLogs
;
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockResolvedValue
();
dispatch
=
store
.
dispatch
;
});
afterEach
(()
=>
{
store
.
dispatch
.
mockReset
();
if
(
wrapper
)
{
wrapper
.
destroy
();
}
});
it
(
'
displays UI elements
'
,
()
=>
{
initWrapper
();
expect
(
wrapper
.
isVueInstance
()).
toBe
(
true
);
expect
(
wrapper
.
isEmpty
()).
toBe
(
false
);
expect
(
findPodsDropdown
().
exists
()).
toBe
(
true
);
});
describe
(
'
disabled state
'
,
()
=>
{
beforeEach
(()
=>
{
mockPodsLoading
();
initWrapper
({
disabled
:
true
,
});
});
it
(
'
displays a disabled pods dropdown
'
,
()
=>
{
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
'
No pod selected
'
);
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeTruthy
();
});
});
describe
(
'
loading state
'
,
()
=>
{
beforeEach
(()
=>
{
mockPodsLoading
();
initWrapper
();
});
it
(
'
displays an enabled pods dropdown
'
,
()
=>
{
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
'
No pod selected
'
);
});
it
(
'
displays an empty pods dropdown
'
,
()
=>
{
expect
(
findPodsNoPodsText
().
exists
()).
toBe
(
true
);
expect
(
findPodsDropdownItems
()).
toHaveLength
(
0
);
});
});
describe
(
'
pods available state
'
,
()
=>
{
beforeEach
(()
=>
{
mockPodsLoaded
();
initWrapper
();
});
it
(
'
displays an enabled pods dropdown
'
,
()
=>
{
expect
(
findPodsDropdown
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
expect
(
findPodsDropdown
().
props
(
'
text
'
)).
toBe
(
mockPods
[
0
]);
});
it
(
'
displays a pods dropdown with items
'
,
()
=>
{
expect
(
findPodsNoPodsText
().
exists
()).
toBe
(
false
);
expect
(
findPodsDropdownItems
()).
toHaveLength
(
mockPods
.
length
);
});
it
(
'
dropdown has one pod selected
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
mockPods
.
forEach
((
pod
,
i
)
=>
{
const
item
=
items
.
at
(
i
);
if
(
item
.
text
()
!==
mockPodName
)
{
expect
(
item
.
find
(
GlIcon
).
classes
(
'
invisible
'
)).
toBe
(
true
);
}
else
{
expect
(
item
.
find
(
GlIcon
).
classes
(
'
invisible
'
)).
toBe
(
false
);
}
});
});
it
(
'
when the user clicks on a pod, showPodLogs is dispatched
'
,
()
=>
{
const
items
=
findPodsDropdownItems
();
const
index
=
2
;
// any pod
expect
(
dispatch
).
not
.
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
expect
.
anything
());
items
.
at
(
index
).
vm
.
$emit
(
'
click
'
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
`
${
module
}
/showPodLogs`
,
mockPods
[
index
]);
});
});
});
spec/frontend/logs/stores/getters_spec.js
View file @
54a0fa36
import
*
as
getters
from
'
~/logs/stores/getters
'
;
import
{
trace
,
showAdvancedFilters
}
from
'
~/logs/stores/getters
'
;
import
logsPageState
from
'
~/logs/stores/state
'
;
import
{
mockLogsResult
,
mockTrace
}
from
'
../mock_data
'
;
import
{
mockLogsResult
,
mockTrace
,
mockEnvName
,
mockEnvironments
}
from
'
../mock_data
'
;
describe
(
'
Logs Store getters
'
,
()
=>
{
let
state
;
...
...
@@ -13,7 +13,7 @@ describe('Logs Store getters', () => {
describe
(
'
trace
'
,
()
=>
{
describe
(
'
when state is initialized
'
,
()
=>
{
it
(
'
returns an empty string
'
,
()
=>
{
expect
(
getters
.
trace
(
state
)).
toEqual
(
''
);
expect
(
trace
(
state
)).
toEqual
(
''
);
});
});
...
...
@@ -23,7 +23,7 @@ describe('Logs Store getters', () => {
});
it
(
'
returns an empty string
'
,
()
=>
{
expect
(
getters
.
trace
(
state
)).
toEqual
(
''
);
expect
(
trace
(
state
)).
toEqual
(
''
);
});
});
...
...
@@ -33,7 +33,42 @@ describe('Logs Store getters', () => {
});
it
(
'
returns an empty string
'
,
()
=>
{
expect
(
getters
.
trace
(
state
)).
toEqual
(
mockTrace
.
join
(
'
\n
'
));
expect
(
trace
(
state
)).
toEqual
(
mockTrace
.
join
(
'
\n
'
));
});
});
});
describe
(
'
showAdvancedFilters
'
,
()
=>
{
describe
(
'
when no environments are set
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
environments
.
current
=
mockEnvName
;
state
.
environments
.
options
=
[];
});
it
(
'
returns false
'
,
()
=>
{
expect
(
showAdvancedFilters
(
state
)).
toBe
(
false
);
});
});
describe
(
'
when the environment supports filters
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
environments
.
current
=
mockEnvName
;
state
.
environments
.
options
=
mockEnvironments
;
});
it
(
'
returns true
'
,
()
=>
{
expect
(
showAdvancedFilters
(
state
)).
toBe
(
true
);
});
});
describe
(
'
when the environment does not support filters
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
environments
.
options
=
mockEnvironments
;
state
.
environments
.
current
=
mockEnvironments
[
1
].
name
;
});
it
(
'
returns true
'
,
()
=>
{
expect
(
showAdvancedFilters
(
state
)).
toBe
(
false
);
});
});
});
...
...
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