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
840b6f01
Commit
840b6f01
authored
May 27, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
1fb99d7c
7f2f3f2c
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
631 additions
and
6078 deletions
+631
-6078
app/assets/javascripts/monitoring/components/dashboard.vue
app/assets/javascripts/monitoring/components/dashboard.vue
+24
-50
app/assets/javascripts/monitoring/monitoring_bundle.js
app/assets/javascripts/monitoring/monitoring_bundle.js
+2
-0
app/assets/javascripts/monitoring/services/monitoring_service.js
...ets/javascripts/monitoring/services/monitoring_service.js
+0
-75
app/assets/javascripts/monitoring/stores/actions.js
app/assets/javascripts/monitoring/stores/actions.js
+117
-0
app/assets/javascripts/monitoring/stores/index.js
app/assets/javascripts/monitoring/stores/index.js
+21
-0
app/assets/javascripts/monitoring/stores/mutation_types.js
app/assets/javascripts/monitoring/stores/mutation_types.js
+15
-0
app/assets/javascripts/monitoring/stores/mutations.js
app/assets/javascripts/monitoring/stores/mutations.js
+45
-0
app/assets/javascripts/monitoring/stores/state.js
app/assets/javascripts/monitoring/stores/state.js
+12
-0
app/assets/javascripts/monitoring/stores/utils.js
app/assets/javascripts/monitoring/stores/utils.js
+8
-36
changelogs/unreleased/jivl-migrate-dashboard-store-vuex.yml
changelogs/unreleased/jivl-migrate-dashboard-store-vuex.yml
+5
-0
spec/javascripts/monitoring/charts/area_spec.js
spec/javascripts/monitoring/charts/area_spec.js
+8
-6
spec/javascripts/monitoring/dashboard_spec.js
spec/javascripts/monitoring/dashboard_spec.js
+75
-22
spec/javascripts/monitoring/helpers.js
spec/javascripts/monitoring/helpers.js
+8
-0
spec/javascripts/monitoring/mock_data.js
spec/javascripts/monitoring/mock_data.js
+41
-5830
spec/javascripts/monitoring/monitoring_store_spec.js
spec/javascripts/monitoring/monitoring_store_spec.js
+0
-59
spec/javascripts/monitoring/store/actions_spec.js
spec/javascripts/monitoring/store/actions_spec.js
+158
-0
spec/javascripts/monitoring/store/mutations_spec.js
spec/javascripts/monitoring/store/mutations_spec.js
+92
-0
No files found.
app/assets/javascripts/monitoring/components/dashboard.vue
View file @
840b6f01
...
...
@@ -8,16 +8,14 @@ import {
GlLink
,
}
from
'
@gitlab/ui
'
;
import
_
from
'
underscore
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
s__
}
from
'
~/locale
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
'
~/vue_shared/mixins/is_ee
'
;
import
{
getParameterValues
}
from
'
~/lib/utils/url_utility
'
;
import
Flash
from
'
../../flash
'
;
import
MonitoringService
from
'
../services/monitoring_service
'
;
import
MonitorAreaChart
from
'
./charts/area.vue
'
;
import
GraphGroup
from
'
./graph_group.vue
'
;
import
EmptyState
from
'
./empty_state.vue
'
;
import
MonitoringStore
from
'
../stores/monitoring_store
'
;
import
{
timeWindows
,
timeWindowsKeyNames
}
from
'
../constants
'
;
import
{
getTimeDiff
}
from
'
../utils
'
;
...
...
@@ -128,9 +126,7 @@ export default {
},
data
()
{
return
{
store
:
new
MonitoringStore
(),
state
:
'
gettingStarted
'
,
showEmptyState
:
true
,
elWidth
:
0
,
selectedTimeWindow
:
''
,
selectedTimeWindowKey
:
''
,
...
...
@@ -141,13 +137,21 @@ export default {
canAddMetrics
()
{
return
this
.
customMetricsAvailable
&&
this
.
customMetricsPath
.
length
;
},
...
mapState
(
'
monitoringDashboard
'
,
[
'
groups
'
,
'
emptyState
'
,
'
showEmptyState
'
,
'
environments
'
,
'
deploymentData
'
,
]),
},
created
()
{
this
.
se
rvice
=
new
MonitoringService
({
this
.
se
tEndpoints
({
metricsEndpoint
:
this
.
metricsEndpoint
,
deploymentEndpoint
:
this
.
deploymentEndpoint
,
environmentsEndpoint
:
this
.
environmentsEndpoint
,
deploymentsEndpoint
:
this
.
deploymentEndpoint
,
});
this
.
timeWindows
=
timeWindows
;
this
.
selectedTimeWindowKey
=
_
.
escape
(
getParameterValues
(
'
time_window
'
)[
0
])
||
timeWindowsKeyNames
.
eightHours
;
...
...
@@ -165,31 +169,11 @@ export default {
}
},
mounted
()
{
const
startEndWindow
=
getTimeDiff
(
this
.
timeWindows
[
this
.
selectedTimeWindowKey
]);
this
.
servicePromises
=
[
this
.
service
.
getGraphsData
(
startEndWindow
)
.
then
(
data
=>
this
.
store
.
storeMetrics
(
data
))
.
catch
(()
=>
Flash
(
s__
(
'
Metrics|There was an error while retrieving metrics
'
))),
this
.
service
.
getDeploymentData
()
.
then
(
data
=>
this
.
store
.
storeDeploymentData
(
data
))
.
catch
(()
=>
Flash
(
s__
(
'
Metrics|There was an error getting deployment information.
'
))),
];
if
(
!
this
.
hasMetrics
)
{
this
.
s
tate
=
'
gettingStarted
'
;
this
.
s
etGettingStartedEmptyState
()
;
}
else
{
if
(
this
.
environmentsEndpoint
)
{
this
.
servicePromises
.
push
(
this
.
service
.
getEnvironmentsData
()
.
then
(
data
=>
this
.
store
.
storeEnvironmentsData
(
data
))
.
catch
(()
=>
Flash
(
s__
(
'
Metrics|There was an error getting environments information.
'
)),
),
);
}
this
.
getGraphsData
();
this
.
fetchData
(
getTimeDiff
(
this
.
timeWindows
.
eightHours
));
sidebarMutationObserver
=
new
MutationObserver
(
this
.
onSidebarMutation
);
sidebarMutationObserver
.
observe
(
document
.
querySelector
(
'
.layout-page
'
),
{
attributes
:
true
,
...
...
@@ -199,6 +183,11 @@ export default {
}
},
methods
:
{
...
mapActions
(
'
monitoringDashboard
'
,
[
'
fetchData
'
,
'
setGettingStartedEmptyState
'
,
'
setEndpoints
'
,
]),
getGraphAlerts
(
queries
)
{
if
(
!
this
.
allAlerts
)
return
{};
const
metricIdsForChart
=
queries
.
map
(
q
=>
q
.
metricId
);
...
...
@@ -207,21 +196,6 @@ export default {
getGraphAlertValues
(
queries
)
{
return
Object
.
values
(
this
.
getGraphAlerts
(
queries
));
},
getGraphsData
()
{
this
.
state
=
'
loading
'
;
Promise
.
all
(
this
.
servicePromises
)
.
then
(()
=>
{
if
(
this
.
store
.
groups
.
length
<
1
)
{
this
.
state
=
'
noData
'
;
return
;
}
this
.
showEmptyState
=
false
;
})
.
catch
(()
=>
{
this
.
state
=
'
unableToConnect
'
;
});
},
hideAddMetricModal
()
{
this
.
$refs
.
addMetricModal
.
hide
();
},
...
...
@@ -263,10 +237,10 @@ export default {
class=
"prepend-left-10 js-environments-dropdown"
toggle-class=
"dropdown-menu-toggle"
:text=
"currentEnvironmentName"
:disabled=
"
store.environmentsData
.length === 0"
:disabled=
"
environments
.length === 0"
>
<gl-dropdown-item
v-for=
"environment in
store.environmentsData
"
v-for=
"environment in
environments
"
:key=
"environment.id"
:active=
"environment.name === currentEnvironmentName"
active-class=
"is-active"
...
...
@@ -336,7 +310,7 @@ export default {
</div>
</div>
<graph-group
v-for=
"(groupData, index) in
store.
groups"
v-for=
"(groupData, index) in groups"
:key=
"index"
:name=
"groupData.group"
:show-panels=
"showPanels"
...
...
@@ -345,7 +319,7 @@ export default {
v-for=
"(graphData, graphIndex) in groupData.metrics"
:key=
"graphIndex"
:graph-data=
"graphData"
:deployment-data=
"
store.
deploymentData"
:deployment-data=
"deploymentData"
:thresholds=
"getGraphAlertValues(graphData.queries)"
:container-width=
"elWidth"
group-id=
"monitor-area-chart"
...
...
@@ -362,7 +336,7 @@ export default {
</div>
<empty-state
v-else
:selected-state=
"
s
tate"
:selected-state=
"
emptyS
tate"
:documentation-path=
"documentationPath"
:settings-path=
"settingsPath"
:clusters-path=
"clustersPath"
...
...
app/assets/javascripts/monitoring/monitoring_bundle.js
View file @
840b6f01
import
Vue
from
'
vue
'
;
import
{
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
Dashboard
from
'
ee_else_ce/monitoring/components/dashboard.vue
'
;
import
store
from
'
./stores
'
;
export
default
(
props
=
{})
=>
{
const
el
=
document
.
getElementById
(
'
prometheus-graphs
'
);
...
...
@@ -9,6 +10,7 @@ export default (props = {}) => {
// eslint-disable-next-line no-new
new
Vue
({
el
,
store
,
render
(
createElement
)
{
return
createElement
(
Dashboard
,
{
props
:
{
...
...
app/assets/javascripts/monitoring/services/monitoring_service.js
deleted
100644 → 0
View file @
1fb99d7c
import
axios
from
'
../../lib/utils/axios_utils
'
;
import
statusCodes
from
'
../../lib/utils/http_status
'
;
import
{
backOff
}
from
'
../../lib/utils/common_utils
'
;
import
{
s__
,
__
}
from
'
../../locale
'
;
const
MAX_REQUESTS
=
3
;
function
backOffRequest
(
makeRequestCallback
)
{
let
requestCounter
=
0
;
return
backOff
((
next
,
stop
)
=>
{
makeRequestCallback
()
.
then
(
resp
=>
{
if
(
resp
.
status
===
statusCodes
.
NO_CONTENT
)
{
requestCounter
+=
1
;
if
(
requestCounter
<
MAX_REQUESTS
)
{
next
();
}
else
{
stop
(
new
Error
(
__
(
'
Failed to connect to the prometheus server
'
)));
}
}
else
{
stop
(
resp
);
}
})
.
catch
(
stop
);
});
}
export
default
class
MonitoringService
{
constructor
({
metricsEndpoint
,
deploymentEndpoint
,
environmentsEndpoint
})
{
this
.
metricsEndpoint
=
metricsEndpoint
;
this
.
deploymentEndpoint
=
deploymentEndpoint
;
this
.
environmentsEndpoint
=
environmentsEndpoint
;
}
getGraphsData
(
params
=
{})
{
return
backOffRequest
(()
=>
axios
.
get
(
this
.
metricsEndpoint
,
{
params
}))
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
data
||
!
response
.
success
)
{
throw
new
Error
(
s__
(
'
Metrics|Unexpected metrics data response from prometheus endpoint
'
));
}
return
response
.
data
;
});
}
getDeploymentData
()
{
if
(
!
this
.
deploymentEndpoint
)
{
return
Promise
.
resolve
([]);
}
return
backOffRequest
(()
=>
axios
.
get
(
this
.
deploymentEndpoint
))
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
deployments
)
{
throw
new
Error
(
s__
(
'
Metrics|Unexpected deployment data response from prometheus endpoint
'
),
);
}
return
response
.
deployments
;
});
}
getEnvironmentsData
()
{
return
axios
.
get
(
this
.
environmentsEndpoint
)
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
environments
)
{
throw
new
Error
(
s__
(
'
Metrics|There was an error fetching the environments data, please try again
'
),
);
}
return
response
.
environments
;
});
}
}
app/assets/javascripts/monitoring/stores/actions.js
0 → 100644
View file @
840b6f01
import
*
as
types
from
'
./mutation_types
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
createFlash
from
'
~/flash
'
;
import
statusCodes
from
'
../../lib/utils/http_status
'
;
import
{
backOff
}
from
'
../../lib/utils/common_utils
'
;
import
{
s__
,
__
}
from
'
../../locale
'
;
const
MAX_REQUESTS
=
3
;
function
backOffRequest
(
makeRequestCallback
)
{
let
requestCounter
=
0
;
return
backOff
((
next
,
stop
)
=>
{
makeRequestCallback
()
.
then
(
resp
=>
{
if
(
resp
.
status
===
statusCodes
.
NO_CONTENT
)
{
requestCounter
+=
1
;
if
(
requestCounter
<
MAX_REQUESTS
)
{
next
();
}
else
{
stop
(
new
Error
(
__
(
'
Failed to connect to the prometheus server
'
)));
}
}
else
{
stop
(
resp
);
}
})
.
catch
(
stop
);
});
}
export
const
setGettingStartedEmptyState
=
({
commit
})
=>
{
commit
(
types
.
SET_GETTING_STARTED_EMPTY_STATE
);
};
export
const
setEndpoints
=
({
commit
},
endpoints
)
=>
{
commit
(
types
.
SET_ENDPOINTS
,
endpoints
);
};
export
const
requestMetricsData
=
({
commit
})
=>
commit
(
types
.
REQUEST_METRICS_DATA
);
export
const
receiveMetricsDataSuccess
=
({
commit
},
data
)
=>
commit
(
types
.
RECEIVE_METRICS_DATA_SUCCESS
,
data
);
export
const
receiveMetricsDataFailure
=
({
commit
},
error
)
=>
commit
(
types
.
RECEIVE_METRICS_DATA_FAILURE
,
error
);
export
const
receiveDeploymentsDataSuccess
=
({
commit
},
data
)
=>
commit
(
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
,
data
);
export
const
receiveDeploymentsDataFailure
=
({
commit
})
=>
commit
(
types
.
RECEIVE_DEPLOYMENTS_DATA_FAILURE
);
export
const
receiveEnvironmentsDataSuccess
=
({
commit
},
data
)
=>
commit
(
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
,
data
);
export
const
receiveEnvironmentsDataFailure
=
({
commit
})
=>
commit
(
types
.
RECEIVE_ENVIRONMENTS_DATA_FAILURE
);
export
const
fetchData
=
({
dispatch
},
params
)
=>
{
dispatch
(
'
fetchMetricsData
'
,
params
);
dispatch
(
'
fetchDeploymentsData
'
);
dispatch
(
'
fetchEnvironmentsData
'
);
};
export
const
fetchMetricsData
=
({
state
,
dispatch
},
params
)
=>
{
dispatch
(
'
requestMetricsData
'
);
return
backOffRequest
(()
=>
axios
.
get
(
state
.
metricsEndpoint
,
{
params
}))
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
data
||
!
response
.
success
)
{
dispatch
(
'
receiveMetricsDataFailure
'
,
null
);
createFlash
(
s__
(
'
Metrics|Unexpected metrics data response from prometheus endpoint
'
));
}
dispatch
(
'
receiveMetricsDataSuccess
'
,
response
.
data
);
})
.
catch
(
error
=>
{
dispatch
(
'
receiveMetricsDataFailure
'
,
error
);
createFlash
(
s__
(
'
Metrics|There was an error while retrieving metrics
'
));
});
};
export
const
fetchDeploymentsData
=
({
state
,
dispatch
})
=>
{
if
(
!
state
.
deploymentEndpoint
)
{
return
Promise
.
resolve
([]);
}
return
backOffRequest
(()
=>
axios
.
get
(
state
.
deploymentEndpoint
))
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
deployments
)
{
createFlash
(
s__
(
'
Metrics|Unexpected deployment data response from prometheus endpoint
'
));
}
dispatch
(
'
receiveDeploymentsDataSuccess
'
,
response
.
deployments
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveDeploymentsDataFailure
'
);
createFlash
(
s__
(
'
Metrics|There was an error getting deployment information.
'
));
});
};
export
const
fetchEnvironmentsData
=
({
state
,
dispatch
})
=>
{
if
(
!
state
.
environmentsEndpoint
)
{
return
Promise
.
resolve
([]);
}
return
axios
.
get
(
state
.
environmentsEndpoint
)
.
then
(
resp
=>
resp
.
data
)
.
then
(
response
=>
{
if
(
!
response
||
!
response
.
environments
)
{
createFlash
(
s__
(
'
Metrics|There was an error fetching the environments data, please try again
'
),
);
}
dispatch
(
'
receiveEnvironmentsDataSuccess
'
,
response
.
environments
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveEnvironmentsDataFailure
'
);
createFlash
(
s__
(
'
Metrics|There was an error getting environments information.
'
));
});
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export
default
()
=>
{};
app/assets/javascripts/monitoring/stores/index.js
0 → 100644
View file @
840b6f01
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
*
as
actions
from
'
./actions
'
;
import
mutations
from
'
./mutations
'
;
import
state
from
'
./state
'
;
Vue
.
use
(
Vuex
);
export
const
createStore
=
()
=>
new
Vuex
.
Store
({
modules
:
{
monitoringDashboard
:
{
namespaced
:
true
,
actions
,
mutations
,
state
,
},
},
});
export
default
createStore
();
app/assets/javascripts/monitoring/stores/mutation_types.js
0 → 100644
View file @
840b6f01
export
const
REQUEST_METRICS_DATA
=
'
REQUEST_METRICS_DATA
'
;
export
const
RECEIVE_METRICS_DATA_SUCCESS
=
'
RECEIVE_METRICS_DATA_SUCCESS
'
;
export
const
RECEIVE_METRICS_DATA_FAILURE
=
'
RECEIVE_METRICS_DATA_FAILURE
'
;
export
const
REQUEST_DEPLOYMENTS_DATA
=
'
REQUEST_DEPLOYMENTS_DATA
'
;
export
const
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
=
'
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
'
;
export
const
RECEIVE_DEPLOYMENTS_DATA_FAILURE
=
'
RECEIVE_DEPLOYMENTS_DATA_FAILURE
'
;
export
const
REQUEST_ENVIRONMENTS_DATA
=
'
REQUEST_ENVIRONMENTS_DATA
'
;
export
const
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
=
'
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
'
;
export
const
RECEIVE_ENVIRONMENTS_DATA_FAILURE
=
'
RECEIVE_ENVIRONMENTS_DATA_FAILURE
'
;
export
const
SET_TIME_WINDOW
=
'
SET_TIME_WINDOW
'
;
export
const
SET_METRICS_ENDPOINT
=
'
SET_METRICS_ENDPOINT
'
;
export
const
SET_ENVIRONMENTS_ENDPOINT
=
'
SET_ENVIRONMENTS_ENDPOINT
'
;
export
const
SET_DEPLOYMENTS_ENDPOINT
=
'
SET_DEPLOYMENTS_ENDPOINT
'
;
export
const
SET_ENDPOINTS
=
'
SET_ENDPOINTS
'
;
export
const
SET_GETTING_STARTED_EMPTY_STATE
=
'
SET_GETTING_STARTED_EMPTY_STATE
'
;
app/assets/javascripts/monitoring/stores/mutations.js
0 → 100644
View file @
840b6f01
import
*
as
types
from
'
./mutation_types
'
;
import
{
normalizeMetrics
,
sortMetrics
}
from
'
./utils
'
;
export
default
{
[
types
.
REQUEST_METRICS_DATA
](
state
)
{
state
.
emptyState
=
'
loading
'
;
state
.
showEmptyState
=
true
;
},
[
types
.
RECEIVE_METRICS_DATA_SUCCESS
](
state
,
groupData
)
{
state
.
groups
=
groupData
.
map
(
group
=>
({
...
group
,
metrics
:
normalizeMetrics
(
sortMetrics
(
group
.
metrics
)),
}));
if
(
!
state
.
groups
.
length
)
{
state
.
emptyState
=
'
noData
'
;
}
else
{
state
.
showEmptyState
=
false
;
}
},
[
types
.
RECEIVE_METRICS_DATA_FAILURE
](
state
,
error
)
{
state
.
emptyState
=
error
?
'
unableToConnect
'
:
'
noData
'
;
state
.
showEmptyState
=
true
;
},
[
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
](
state
,
deployments
)
{
state
.
deploymentData
=
deployments
;
},
[
types
.
RECEIVE_DEPLOYMENTS_DATA_FAILURE
](
state
)
{
state
.
deploymentData
=
[];
},
[
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
](
state
,
environments
)
{
state
.
environments
=
environments
;
},
[
types
.
RECEIVE_ENVIRONMENTS_DATA_FAILURE
](
state
)
{
state
.
environments
=
[];
},
[
types
.
SET_ENDPOINTS
](
state
,
endpoints
)
{
state
.
metricsEndpoint
=
endpoints
.
metricsEndpoint
;
state
.
environmentsEndpoint
=
endpoints
.
environmentsEndpoint
;
state
.
deploymentsEndpoint
=
endpoints
.
deploymentsEndpoint
;
},
[
types
.
SET_GETTING_STARTED_EMPTY_STATE
](
state
)
{
state
.
emptyState
=
'
gettingStarted
'
;
},
};
app/assets/javascripts/monitoring/stores/state.js
0 → 100644
View file @
840b6f01
export
default
()
=>
({
hasMetrics
:
false
,
showPanels
:
true
,
metricsEndpoint
:
null
,
environmentsEndpoint
:
null
,
deploymentsEndpoint
:
null
,
emptyState
:
'
gettingStarted
'
,
showEmptyState
:
true
,
groups
:
[],
deploymentData
:
[],
environments
:
[],
});
app/assets/javascripts/monitoring/stores/
monitoring_store
.js
→
app/assets/javascripts/monitoring/stores/
utils
.js
View file @
840b6f01
import
_
from
'
underscore
'
;
function
sortMetrics
(
metrics
)
{
return
_
.
chain
(
metrics
)
.
sortBy
(
'
title
'
)
.
sortBy
(
'
weight
'
)
.
value
();
}
function
checkQueryEmptyData
(
query
)
{
return
{
...
query
,
...
...
@@ -59,7 +52,13 @@ function groupQueriesByChartInfo(metrics) {
return
Object
.
values
(
metricsByChart
);
}
function
normalizeMetrics
(
metrics
)
{
export
const
sortMetrics
=
metrics
=>
_
.
chain
(
metrics
)
.
sortBy
(
'
title
'
)
.
sortBy
(
'
weight
'
)
.
value
();
export
const
normalizeMetrics
=
metrics
=>
{
const
groupedMetrics
=
groupQueriesByChartInfo
(
metrics
);
return
groupedMetrics
.
map
(
metric
=>
{
...
...
@@ -81,31 +80,4 @@ function normalizeMetrics(metrics) {
queries
:
removeTimeSeriesNoData
(
queries
),
};
});
}
export
default
class
MonitoringStore
{
constructor
()
{
this
.
groups
=
[];
this
.
deploymentData
=
[];
this
.
environmentsData
=
[];
}
storeMetrics
(
groups
=
[])
{
this
.
groups
=
groups
.
map
(
group
=>
({
...
group
,
metrics
:
normalizeMetrics
(
sortMetrics
(
group
.
metrics
)),
}));
}
storeDeploymentData
(
deploymentData
=
[])
{
this
.
deploymentData
=
deploymentData
;
}
storeEnvironmentsData
(
environmentsData
=
[])
{
this
.
environmentsData
=
environmentsData
.
filter
(
environment
=>
!!
environment
.
last_deployment
);
}
getMetricsCount
()
{
return
this
.
groups
.
reduce
((
count
,
group
)
=>
count
+
group
.
metrics
.
length
,
0
);
}
}
};
changelogs/unreleased/jivl-migrate-dashboard-store-vuex.yml
0 → 100644
View file @
840b6f01
---
title
:
Migrate the monitoring dashboard store to vuex
merge_request
:
28555
author
:
type
:
other
spec/javascripts/monitoring/charts/area_spec.js
View file @
840b6f01
...
...
@@ -2,7 +2,8 @@ import { shallowMount } from '@vue/test-utils';
import
{
GlAreaChart
,
GlChartSeriesLabel
}
from
'
@gitlab/ui/dist/charts
'
;
import
{
shallowWrapperContainsSlotText
}
from
'
spec/helpers/vue_test_utils_helper
'
;
import
Area
from
'
~/monitoring/components/charts/area.vue
'
;
import
MonitoringStore
from
'
~/monitoring/stores/monitoring_store
'
;
import
{
createStore
}
from
'
~/monitoring/stores
'
;
import
*
as
types
from
'
~/monitoring/stores/mutation_types
'
;
import
MonitoringMock
,
{
deploymentData
}
from
'
../mock_data
'
;
describe
(
'
Area component
'
,
()
=>
{
...
...
@@ -13,17 +14,18 @@ describe('Area component', () => {
let
spriteSpy
;
beforeEach
(()
=>
{
const
store
=
new
MonitoringStore
();
store
.
storeMetrics
(
MonitoringMock
.
data
);
store
.
storeDeploymentData
(
deploymentData
);
const
store
=
createStore
();
[
mockGraphData
]
=
store
.
groups
[
0
].
metrics
;
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_METRICS_DATA_SUCCESS
}
`
,
MonitoringMock
.
data
);
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
}
`
,
deploymentData
);
[
mockGraphData
]
=
store
.
state
.
monitoringDashboard
.
groups
[
0
].
metrics
;
areaChart
=
shallowMount
(
Area
,
{
propsData
:
{
graphData
:
mockGraphData
,
containerWidth
:
0
,
deploymentData
:
store
.
deploymentData
,
deploymentData
:
store
.
state
.
monitoringDashboard
.
deploymentData
,
},
slots
:
{
default
:
mockWidgets
,
...
...
spec/javascripts/monitoring/dashboard_spec.js
View file @
840b6f01
...
...
@@ -2,8 +2,15 @@ import Vue from 'vue';
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Dashboard
from
'
~/monitoring/components/dashboard.vue
'
;
import
{
timeWindows
,
timeWindowsKeyNames
}
from
'
~/monitoring/constants
'
;
import
*
as
types
from
'
~/monitoring/stores/mutation_types
'
;
import
{
createStore
}
from
'
~/monitoring/stores
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
metricsGroupsAPIResponse
,
mockApiEndpoint
,
environmentData
}
from
'
./mock_data
'
;
import
{
metricsGroupsAPIResponse
,
mockApiEndpoint
,
environmentData
,
singleGroupResponse
,
}
from
'
./mock_data
'
;
const
propsData
=
{
hasMetrics
:
false
,
...
...
@@ -30,6 +37,7 @@ export default propsData;
describe
(
'
Dashboard
'
,
()
=>
{
let
DashboardComponent
;
let
mock
;
let
store
;
beforeEach
(()
=>
{
setFixtures
(
`
...
...
@@ -45,6 +53,7 @@ describe('Dashboard', () => {
},
};
store
=
createStore
();
mock
=
new
MockAdapter
(
axios
);
DashboardComponent
=
Vue
.
extend
(
Dashboard
);
});
...
...
@@ -58,10 +67,11 @@ describe('Dashboard', () => {
const
component
=
new
DashboardComponent
({
el
:
document
.
querySelector
(
'
.prometheus-graphs
'
),
propsData
:
{
...
propsData
,
showTimeWindowDropdown
:
false
},
store
,
});
expect
(
component
.
$el
.
querySelector
(
'
.prometheus-graphs
'
)).
toBe
(
null
);
expect
(
component
.
s
tate
).
toEqual
(
'
gettingStarted
'
);
expect
(
component
.
emptyS
tate
).
toEqual
(
'
gettingStarted
'
);
});
});
...
...
@@ -74,10 +84,11 @@ describe('Dashboard', () => {
const
component
=
new
DashboardComponent
({
el
:
document
.
querySelector
(
'
.prometheus-graphs
'
),
propsData
:
{
...
propsData
,
hasMetrics
:
true
,
showTimeWindowDropdown
:
false
},
store
,
});
Vue
.
nextTick
(()
=>
{
expect
(
component
.
s
tate
).
toEqual
(
'
loading
'
);
expect
(
component
.
emptyS
tate
).
toEqual
(
'
loading
'
);
done
();
});
});
...
...
@@ -91,6 +102,7 @@ describe('Dashboard', () => {
showLegend
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
setTimeout
(()
=>
{
...
...
@@ -110,6 +122,7 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
setTimeout
(()
=>
{
...
...
@@ -129,16 +142,24 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
component
.
store
.
storeEnvironmentsData
(
environmentData
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
}
`
,
environmentData
,
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_METRICS_DATA_SUCCESS
}
`
,
singleGroupResponse
,
);
setTimeout
(()
=>
{
const
dropdownMenuEnvironments
=
component
.
$el
.
querySelectorAll
(
'
.js-environments-dropdown .dropdown-item
'
,
);
expect
(
dropdownMenuEnvironments
.
length
).
toEqual
(
component
.
store
.
environmentsData
.
length
);
expect
(
dropdownMenuEnvironments
.
length
).
toEqual
(
component
.
environments
.
length
);
done
();
});
});
...
...
@@ -152,18 +173,29 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
component
.
store
.
storeEnvironmentsData
([]);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
SET_ENVIRONMENTS_ENDPOINT
}
`
,
'
/environments
'
,
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
}
`
,
[]);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_METRICS_DATA_SUCCESS
}
`
,
singleGroupResponse
,
);
setTimeout
(()
=>
{
const
dropdownMenuEnvironments
=
component
.
$el
.
querySelectorAll
(
'
.js-environments-dropdown .dropdown-item
'
,
);
Vue
.
nextTick
()
.
then
(()
=>
{
const
dropdownMenuEnvironments
=
component
.
$el
.
querySelectorAll
(
'
.js-environments-dropdown .dropdown-item
'
,
);
expect
(
dropdownMenuEnvironments
.
length
).
toEqual
(
0
);
done
();
});
expect
(
dropdownMenuEnvironments
.
length
).
toEqual
(
0
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
renders the environments dropdown with a single active element
'
,
done
=>
{
...
...
@@ -175,19 +207,32 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
component
.
store
.
storeEnvironmentsData
(
environmentData
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
SET_ENVIRONMENTS_ENDPOINT
}
`
,
'
/environments
'
,
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
}
`
,
environmentData
,
);
component
.
$store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_METRICS_DATA_SUCCESS
}
`
,
singleGroupResponse
,
);
setTimeout
(()
=>
{
const
dropdownItems
=
component
.
$el
.
querySelectorAll
(
'
.js-environments-dropdown .dropdown-item[active="true"]
'
,
);
Vue
.
nextTick
()
.
then
(()
=>
{
const
dropdownItems
=
component
.
$el
.
querySelectorAll
(
'
.js-environments-dropdown .dropdown-item[active="true"]
'
,
);
expect
(
dropdownItems
.
length
).
toEqual
(
1
);
expect
(
dropdownItems
[
0
].
textContent
.
trim
()).
toEqual
(
component
.
currentEnvironmentName
);
done
();
}
);
expect
(
dropdownItems
.
length
).
toEqual
(
1
);
done
(
);
})
.
catch
(
done
.
fail
);
});
it
(
'
hides the dropdown
'
,
done
=>
{
...
...
@@ -200,6 +245,7 @@ describe('Dashboard', () => {
environmentsEndpoint
:
''
,
showTimeWindowDropdown
:
false
,
},
store
,
});
Vue
.
nextTick
(()
=>
{
...
...
@@ -219,6 +265,7 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
setTimeout
(()
=>
{
...
...
@@ -239,6 +286,7 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
true
,
},
store
,
});
const
numberOfTimeWindows
=
Object
.
keys
(
timeWindows
).
length
;
...
...
@@ -261,6 +309,7 @@ describe('Dashboard', () => {
const
component
=
new
DashboardComponent
({
el
:
document
.
querySelector
(
'
.prometheus-graphs
'
),
propsData
:
{
...
propsData
,
hasMetrics
:
true
,
showTimeWindowDropdown
:
true
},
store
,
});
setTimeout
(()
=>
{
...
...
@@ -281,6 +330,7 @@ describe('Dashboard', () => {
const
component
=
new
DashboardComponent
({
el
:
document
.
querySelector
(
'
.prometheus-graphs
'
),
propsData
:
{
...
propsData
,
hasMetrics
:
true
,
showTimeWindowDropdown
:
true
},
store
,
});
Vue
.
nextTick
(()
=>
{
...
...
@@ -310,6 +360,7 @@ describe('Dashboard', () => {
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
},
store
,
});
expect
(
component
.
elWidth
).
toEqual
(
0
);
...
...
@@ -352,6 +403,7 @@ describe('Dashboard', () => {
showTimeWindowDropdown
:
false
,
externalDashboardPath
:
'
/mockPath
'
,
},
store
,
});
});
...
...
@@ -377,6 +429,7 @@ describe('Dashboard', () => {
showTimeWindowDropdown
:
false
,
externalDashboardPath
:
''
,
},
store
,
});
});
...
...
spec/javascripts/monitoring/helpers.js
0 → 100644
View file @
840b6f01
// eslint-disable-next-line import/prefer-default-export
export
const
resetStore
=
store
=>
{
store
.
replaceState
({
showEmptyState
:
true
,
emptyState
:
'
loading
'
,
groups
:
[],
});
};
spec/javascripts/monitoring/mock_data.js
View file @
840b6f01
This diff is collapsed.
Click to expand it.
spec/javascripts/monitoring/monitoring_store_spec.js
deleted
100644 → 0
View file @
1fb99d7c
import
MonitoringStore
from
'
~/monitoring/stores/monitoring_store
'
;
import
MonitoringMock
,
{
deploymentData
,
environmentData
}
from
'
./mock_data
'
;
describe
(
'
MonitoringStore
'
,
()
=>
{
const
store
=
new
MonitoringStore
();
store
.
storeMetrics
(
MonitoringMock
.
data
);
it
(
'
contains two groups that contains, one of which has two queries sorted by priority
'
,
()
=>
{
expect
(
store
.
groups
).
toBeDefined
();
expect
(
store
.
groups
.
length
).
toEqual
(
2
);
expect
(
store
.
groups
[
0
].
metrics
.
length
).
toEqual
(
2
);
});
it
(
'
gets the metrics count for every group
'
,
()
=>
{
expect
(
store
.
getMetricsCount
()).
toEqual
(
3
);
});
it
(
'
contains deployment data
'
,
()
=>
{
store
.
storeDeploymentData
(
deploymentData
);
expect
(
store
.
deploymentData
).
toBeDefined
();
expect
(
store
.
deploymentData
.
length
).
toEqual
(
3
);
expect
(
typeof
store
.
deploymentData
[
0
]).
toEqual
(
'
object
'
);
});
it
(
'
only stores environment data that contains deployments
'
,
()
=>
{
store
.
storeEnvironmentsData
(
environmentData
);
expect
(
store
.
environmentsData
.
length
).
toEqual
(
2
);
});
it
(
'
removes the data if all the values from a query are not defined
'
,
()
=>
{
expect
(
store
.
groups
[
1
].
metrics
[
0
].
queries
[
0
].
result
.
length
).
toEqual
(
0
);
});
it
(
'
assigns queries a metric id
'
,
()
=>
{
expect
(
store
.
groups
[
1
].
metrics
[
0
].
queries
[
0
].
metricId
).
toEqual
(
'
100
'
);
});
it
(
'
assigns metric id of null if metric has no id
'
,
()
=>
{
const
noId
=
MonitoringMock
.
data
.
map
(
group
=>
({
...
group
,
...{
metrics
:
group
.
metrics
.
map
(
metric
=>
{
const
{
id
,
...
metricWithoutId
}
=
metric
;
return
metricWithoutId
;
}),
},
}));
store
.
storeMetrics
(
noId
);
store
.
groups
.
forEach
(
group
=>
{
group
.
metrics
.
forEach
(
metric
=>
{
expect
(
metric
.
queries
.
every
(
query
=>
query
.
metricId
===
null
)).
toBe
(
true
);
});
});
});
});
spec/javascripts/monitoring/store/actions_spec.js
0 → 100644
View file @
840b6f01
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
store
from
'
~/monitoring/stores
'
;
import
*
as
types
from
'
~/monitoring/stores/mutation_types
'
;
import
{
fetchDeploymentsData
,
fetchEnvironmentsData
,
requestMetricsData
,
setEndpoints
,
setGettingStartedEmptyState
,
}
from
'
~/monitoring/stores/actions
'
;
import
storeState
from
'
~/monitoring/stores/state
'
;
import
testAction
from
'
spec/helpers/vuex_action_helper
'
;
import
{
resetStore
}
from
'
../helpers
'
;
import
{
deploymentData
,
environmentData
}
from
'
../mock_data
'
;
describe
(
'
Monitoring store actions
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
resetStore
(
store
);
mock
.
restore
();
});
describe
(
'
requestMetricsData
'
,
()
=>
{
it
(
'
sets emptyState to loading
'
,
()
=>
{
const
commit
=
jasmine
.
createSpy
();
const
{
state
}
=
store
;
requestMetricsData
({
state
,
commit
});
expect
(
commit
).
toHaveBeenCalledWith
(
types
.
REQUEST_METRICS_DATA
);
});
});
describe
(
'
fetchDeploymentsData
'
,
()
=>
{
it
(
'
commits RECEIVE_DEPLOYMENTS_DATA_SUCCESS on error
'
,
done
=>
{
const
dispatch
=
jasmine
.
createSpy
();
const
{
state
}
=
store
;
state
.
deploymentEndpoint
=
'
/success
'
;
mock
.
onGet
(
state
.
deploymentEndpoint
).
reply
(
200
,
{
deployments
:
deploymentData
,
});
fetchDeploymentsData
({
state
,
dispatch
})
.
then
(()
=>
{
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
receiveDeploymentsDataSuccess
'
,
deploymentData
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
commits RECEIVE_DEPLOYMENTS_DATA_FAILURE on error
'
,
done
=>
{
const
dispatch
=
jasmine
.
createSpy
();
const
{
state
}
=
store
;
state
.
deploymentEndpoint
=
'
/error
'
;
mock
.
onGet
(
state
.
deploymentEndpoint
).
reply
(
500
);
fetchDeploymentsData
({
state
,
dispatch
})
.
then
(()
=>
{
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
receiveDeploymentsDataFailure
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
fetchEnvironmentsData
'
,
()
=>
{
it
(
'
commits RECEIVE_ENVIRONMENTS_DATA_SUCCESS on error
'
,
done
=>
{
const
dispatch
=
jasmine
.
createSpy
();
const
{
state
}
=
store
;
state
.
environmentsEndpoint
=
'
/success
'
;
mock
.
onGet
(
state
.
environmentsEndpoint
).
reply
(
200
,
{
environments
:
environmentData
,
});
fetchEnvironmentsData
({
state
,
dispatch
})
.
then
(()
=>
{
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
receiveEnvironmentsDataSuccess
'
,
environmentData
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
commits RECEIVE_ENVIRONMENTS_DATA_FAILURE on error
'
,
done
=>
{
const
dispatch
=
jasmine
.
createSpy
();
const
{
state
}
=
store
;
state
.
environmentsEndpoint
=
'
/error
'
;
mock
.
onGet
(
state
.
environmentsEndpoint
).
reply
(
500
);
fetchEnvironmentsData
({
state
,
dispatch
})
.
then
(()
=>
{
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
receiveEnvironmentsDataFailure
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
Set endpoints
'
,
()
=>
{
let
mockedState
;
beforeEach
(()
=>
{
mockedState
=
storeState
();
});
it
(
'
should commit SET_ENDPOINTS mutation
'
,
done
=>
{
testAction
(
setEndpoints
,
{
metricsEndpoint
:
'
additional_metrics.json
'
,
deploymentsEndpoint
:
'
deployments.json
'
,
environmentsEndpoint
:
'
deployments.json
'
,
},
mockedState
,
[
{
type
:
types
.
SET_ENDPOINTS
,
payload
:
{
metricsEndpoint
:
'
additional_metrics.json
'
,
deploymentsEndpoint
:
'
deployments.json
'
,
environmentsEndpoint
:
'
deployments.json
'
,
},
},
],
[],
done
,
);
});
});
describe
(
'
Set empty states
'
,
()
=>
{
let
mockedState
;
beforeEach
(()
=>
{
mockedState
=
storeState
();
});
it
(
'
should commit SET_METRICS_ENDPOINT mutation
'
,
done
=>
{
testAction
(
setGettingStartedEmptyState
,
null
,
mockedState
,
[{
type
:
types
.
SET_GETTING_STARTED_EMPTY_STATE
}],
[],
done
,
);
});
});
});
spec/javascripts/monitoring/store/mutations_spec.js
0 → 100644
View file @
840b6f01
import
mutations
from
'
~/monitoring/stores/mutations
'
;
import
*
as
types
from
'
~/monitoring/stores/mutation_types
'
;
import
state
from
'
~/monitoring/stores/state
'
;
import
{
metricsGroupsAPIResponse
,
deploymentData
}
from
'
../mock_data
'
;
describe
(
'
Monitoring mutations
'
,
()
=>
{
let
stateCopy
;
beforeEach
(()
=>
{
stateCopy
=
state
();
});
describe
(
types
.
RECEIVE_METRICS_DATA_SUCCESS
,
()
=>
{
beforeEach
(()
=>
{
stateCopy
.
groups
=
[];
const
groups
=
metricsGroupsAPIResponse
.
data
;
mutations
[
types
.
RECEIVE_METRICS_DATA_SUCCESS
](
stateCopy
,
groups
);
});
it
(
'
normalizes values
'
,
()
=>
{
const
expectedTimestamp
=
'
2017-05-25T08:22:34.925Z
'
;
const
expectedValue
=
0.0010794445585559514
;
const
[
timestamp
,
value
]
=
stateCopy
.
groups
[
0
].
metrics
[
0
].
queries
[
0
].
result
[
0
].
values
[
0
];
expect
(
timestamp
).
toEqual
(
expectedTimestamp
);
expect
(
value
).
toEqual
(
expectedValue
);
});
it
(
'
contains two groups that contains, one of which has two queries sorted by priority
'
,
()
=>
{
expect
(
stateCopy
.
groups
).
toBeDefined
();
expect
(
stateCopy
.
groups
.
length
).
toEqual
(
2
);
expect
(
stateCopy
.
groups
[
0
].
metrics
.
length
).
toEqual
(
2
);
});
it
(
'
assigns queries a metric id
'
,
()
=>
{
expect
(
stateCopy
.
groups
[
1
].
metrics
[
0
].
queries
[
0
].
metricId
).
toEqual
(
'
100
'
);
});
it
(
'
removes the data if all the values from a query are not defined
'
,
()
=>
{
expect
(
stateCopy
.
groups
[
1
].
metrics
[
0
].
queries
[
0
].
result
.
length
).
toEqual
(
0
);
});
it
(
'
assigns metric id of null if metric has no id
'
,
()
=>
{
stateCopy
.
groups
=
[];
const
groups
=
metricsGroupsAPIResponse
.
data
;
const
noId
=
groups
.
map
(
group
=>
({
...
group
,
...{
metrics
:
group
.
metrics
.
map
(
metric
=>
{
const
{
id
,
...
metricWithoutId
}
=
metric
;
return
metricWithoutId
;
}),
},
}));
mutations
[
types
.
RECEIVE_METRICS_DATA_SUCCESS
](
stateCopy
,
noId
);
stateCopy
.
groups
.
forEach
(
group
=>
{
group
.
metrics
.
forEach
(
metric
=>
{
expect
(
metric
.
queries
.
every
(
query
=>
query
.
metricId
===
null
)).
toBe
(
true
);
});
});
});
});
describe
(
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
,
()
=>
{
it
(
'
stores the deployment data
'
,
()
=>
{
stateCopy
.
deploymentData
=
[];
mutations
[
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
](
stateCopy
,
deploymentData
);
expect
(
stateCopy
.
deploymentData
).
toBeDefined
();
expect
(
stateCopy
.
deploymentData
.
length
).
toEqual
(
3
);
expect
(
typeof
stateCopy
.
deploymentData
[
0
]).
toEqual
(
'
object
'
);
});
});
describe
(
'
SET_ENDPOINTS
'
,
()
=>
{
it
(
'
should set all the endpoints
'
,
()
=>
{
mutations
[
types
.
SET_ENDPOINTS
](
stateCopy
,
{
metricsEndpoint
:
'
additional_metrics.json
'
,
environmentsEndpoint
:
'
environments.json
'
,
deploymentsEndpoint
:
'
deployments.json
'
,
});
expect
(
stateCopy
.
metricsEndpoint
).
toEqual
(
'
additional_metrics.json
'
);
expect
(
stateCopy
.
environmentsEndpoint
).
toEqual
(
'
environments.json
'
);
expect
(
stateCopy
.
deploymentsEndpoint
).
toEqual
(
'
deployments.json
'
);
});
});
});
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