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
f653dd5d
Commit
f653dd5d
authored
Jan 11, 2018
by
Kushal Pandya
Committed by
Clement Ho
Jan 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle node details load failure gracefully on UI
parent
35b6b354
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
286 additions
and
106 deletions
+286
-106
app/assets/stylesheets/pages/geo_nodes.scss
app/assets/stylesheets/pages/geo_nodes.scss
+5
-1
changelogs/unreleased-ee/4511-handle-node-error-gracefully.yml
...elogs/unreleased-ee/4511-handle-node-error-gracefully.yml
+5
-0
ee/app/assets/javascripts/geo_nodes/components/app.vue
ee/app/assets/javascripts/geo_nodes/components/app.vue
+1
-2
ee/app/assets/javascripts/geo_nodes/components/geo_node_item.vue
...assets/javascripts/geo_nodes/components/geo_node_item.vue
+119
-66
ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js
ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js
+17
-17
spec/javascripts/geo_nodes/components/app_spec.js
spec/javascripts/geo_nodes/components/app_spec.js
+3
-3
spec/javascripts/geo_nodes/components/geo_node_item_spec.js
spec/javascripts/geo_nodes/components/geo_node_item_spec.js
+135
-16
spec/javascripts/geo_nodes/mock_data.js
spec/javascripts/geo_nodes/mock_data.js
+1
-1
No files found.
app/assets/stylesheets/pages/geo_nodes.scss
View file @
f653dd5d
...
...
@@ -73,9 +73,13 @@
}
.geo-nodes
{
.node-
url
-warning
{
.node-
status-icon
-warning
{
fill
:
$gl-warning
;
}
.node-status-icon-failure
{
fill
:
$gl-danger
;
}
}
.node-details-list
{
...
...
changelogs/unreleased-ee/4511-handle-node-error-gracefully.yml
0 → 100644
View file @
f653dd5d
---
title
:
Handle node details load failure gracefully on UI
merge_request
:
3992
author
:
type
:
fixed
ee/app/assets/javascripts/geo_nodes/components/app.vue
View file @
f653dd5d
...
...
@@ -80,8 +80,7 @@
eventHub
.
$emit
(
'
nodeDetailsLoaded
'
,
this
.
store
.
getNodeDetails
(
nodeId
));
})
.
catch
((
err
)
=>
{
this
.
hasError
=
true
;
this
.
errorMessage
=
err
;
eventHub
.
$emit
(
'
nodeDetailsLoadFailed
'
,
nodeId
,
err
);
});
},
initNodeDetailsPolling
(
nodeId
)
{
...
...
ee/app/assets/javascripts/geo_nodes/components/geo_node_item.vue
View file @
f653dd5d
<
script
>
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
loadingIcon
from
'
~/vue_shared/components/loading_icon.vue
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
{
s__
}
from
'
~/locale
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
loadingIcon
from
'
~/vue_shared/components/loading_icon.vue
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
eventHub
from
'
../event_hub
'
;
import
eventHub
from
'
../event_hub
'
;
import
geoNodeActions
from
'
./geo_node_actions.vue
'
;
import
geoNodeDetails
from
'
./geo_node_details.vue
'
;
import
geoNodeActions
from
'
./geo_node_actions.vue
'
;
import
geoNodeDetails
from
'
./geo_node_details.vue
'
;
export
default
{
components
:
{
icon
,
loadingIcon
,
geoNodeActions
,
geoNodeDetails
,
export
default
{
components
:
{
icon
,
loadingIcon
,
geoNodeActions
,
geoNodeDetails
,
},
directives
:
{
tooltip
,
},
props
:
{
node
:
{
type
:
Object
,
required
:
true
,
},
directives
:
{
tooltip
,
primaryNode
:
{
type
:
Boolean
,
required
:
true
,
},
props
:
{
node
:
{
type
:
Object
,
required
:
true
,
},
primaryNode
:
{
type
:
Boolean
,
required
:
true
,
},
nodeActionsAllowed
:
{
type
:
Boolean
,
required
:
true
,
},
nodeEditAllowed
:
{
type
:
Boolean
,
required
:
true
,
},
nodeActionsAllowed
:
{
type
:
Boolean
,
required
:
true
,
},
data
()
{
return
{
isNodeDetailsLoading
:
true
,
nodeHealthStatus
:
''
,
nodeDetails
:
{},
};
nodeEditAllowed
:
{
type
:
Boolean
,
required
:
true
,
},
computed
:
{
showInsecureUrlWarning
()
{
return
this
.
node
.
url
.
startsWith
(
'
http://
'
);
},
},
data
()
{
return
{
isNodeDetailsLoading
:
true
,
isNodeDetailsFailed
:
false
,
nodeHealthStatus
:
''
,
errorMessage
:
''
,
nodeDetails
:
{},
};
},
computed
:
{
isNodeNonHTTPS
()
{
return
this
.
node
.
url
.
startsWith
(
'
http://
'
);
},
created
()
{
eventHub
.
$on
(
'
nodeDetailsLoaded
'
,
this
.
handleNodeDetails
);
showNodeStatusIcon
()
{
if
(
this
.
isNodeDetailsLoading
)
{
return
false
;
}
return
this
.
isNodeNonHTTPS
||
this
.
isNodeDetailsFailed
;
},
showNodeDetails
()
{
if
(
!
this
.
isNodeDetailsLoading
)
{
return
!
this
.
isNodeDetailsFailed
;
}
return
false
;
},
nodeStatusIconClass
()
{
const
iconClasses
=
'
prepend-left-10 pull-left
'
;
if
(
this
.
isNodeDetailsFailed
)
{
return
`
${
iconClasses
}
node-status-icon-failure`
;
}
return
`
${
iconClasses
}
node-status-icon-warning`
;
},
mounted
()
{
this
.
handleMounted
();
nodeStatusIconName
()
{
if
(
this
.
isNodeDetailsFailed
)
{
return
'
status_failed_borderless
'
;
}
return
'
warning
'
;
},
beforeDestroy
()
{
eventHub
.
$off
(
'
nodeDetailsLoaded
'
,
this
.
handleNodeDetails
);
nodeStatusIconTooltip
()
{
if
(
this
.
isNodeDetailsFailed
)
{
return
''
;
}
return
s__
(
'
GeoNodes|You have configured Geo nodes using an insecure HTTP connection. We recommend the use of HTTPS.
'
);
},
methods
:
{
handleNodeDetails
(
nodeDetails
)
{
if
(
this
.
node
.
id
===
nodeDetails
.
id
)
{
this
.
isNodeDetailsLoading
=
false
;
this
.
nodeDetails
=
nodeDetails
;
this
.
nodeHealthStatus
=
nodeDetails
.
health
;
}
},
handleMounted
()
{
eventHub
.
$emit
(
'
pollNodeDetails
'
,
this
.
node
.
id
);
},
},
created
()
{
eventHub
.
$on
(
'
nodeDetailsLoaded
'
,
this
.
handleNodeDetails
);
eventHub
.
$on
(
'
nodeDetailsLoadFailed
'
,
this
.
handleNodeDetailsFailure
);
},
mounted
()
{
this
.
handleMounted
();
},
beforeDestroy
()
{
eventHub
.
$off
(
'
nodeDetailsLoaded
'
,
this
.
handleNodeDetails
);
eventHub
.
$off
(
'
nodeDetailsLoadFailed
'
,
this
.
handleNodeDetailsFailure
);
},
methods
:
{
handleNodeDetails
(
nodeDetails
)
{
if
(
this
.
node
.
id
===
nodeDetails
.
id
)
{
this
.
isNodeDetailsLoading
=
false
;
this
.
isNodeDetailsFailed
=
false
;
this
.
errorMessage
=
''
;
this
.
nodeDetails
=
nodeDetails
;
this
.
nodeHealthStatus
=
nodeDetails
.
health
;
}
},
};
handleNodeDetailsFailure
(
nodeId
,
err
)
{
if
(
this
.
node
.
id
===
nodeId
)
{
this
.
isNodeDetailsLoading
=
false
;
this
.
isNodeDetailsFailed
=
true
;
this
.
errorMessage
=
err
.
message
;
}
},
handleMounted
()
{
eventHub
.
$emit
(
'
pollNodeDetails
'
,
this
.
node
.
id
);
},
},
};
</
script
>
<
template
>
...
...
@@ -88,14 +134,13 @@
/>
<icon
v-tooltip
v-if=
"!isNodeDetailsLoading && showInsecureUrlWarning"
css-classes=
"prepend-left-10 pull-left node-url-warning"
name=
"warning"
v-if=
"showNodeStatusIcon"
data-container=
"body"
data-placement=
"bottom"
:title=
"s__(`GeoNodes|You have configured Geo nodes using
an insecure HTTP connection. We recommend the use of HTTPS.`)"
:name=
"nodeStatusIconName"
:size=
"18"
:css-classes=
"nodeStatusIconClass"
:title=
"nodeStatusIconTooltip"
/>
<span
class=
"inline pull-left prepend-left-10"
>
<span
...
...
@@ -115,16 +160,24 @@ an insecure HTTP connection. We recommend the use of HTTPS.`)"
</div>
</div>
<geo-node-actions
v-if=
"
!isNodeDetailsLoading
&& nodeActionsAllowed"
v-if=
"
showNodeDetails
&& nodeActionsAllowed"
:node=
"node"
:node-edit-allowed=
"nodeEditAllowed"
:node-missing-oauth=
"nodeDetails.missingOAuthApplication"
/>
</div>
<geo-node-details
v-if=
"
!isNodeDetailsLoading
"
v-if=
"
showNodeDetails
"
:node=
"node"
:node-details=
"nodeDetails"
/>
<div
v-if=
"isNodeDetailsFailed"
class=
"prepend-top-10"
>
<p
class=
"health-message"
>
{{
errorMessage
}}
</p>
</div>
</li>
</
template
>
ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js
View file @
f653dd5d
...
...
@@ -44,34 +44,34 @@ export default class GeoNodesStore {
missingOAuthApplication
:
rawNodeDetails
.
missing_oauth_application
,
storageShardsMatch
:
rawNodeDetails
.
storage_shards_match
,
replicationSlots
:
{
totalCount
:
rawNodeDetails
.
replication_slots_count
,
successCount
:
rawNodeDetails
.
replication_slots_used_count
,
totalCount
:
rawNodeDetails
.
replication_slots_count
||
0
,
successCount
:
rawNodeDetails
.
replication_slots_used_count
||
0
,
failureCount
:
0
,
},
repositories
:
{
totalCount
:
rawNodeDetails
.
repositories_count
,
successCount
:
rawNodeDetails
.
repositories_synced_count
,
failureCount
:
rawNodeDetails
.
repositories_failed_count
,
totalCount
:
rawNodeDetails
.
repositories_count
||
0
,
successCount
:
rawNodeDetails
.
repositories_synced_count
||
0
,
failureCount
:
rawNodeDetails
.
repositories_failed_count
||
0
,
},
wikis
:
{
totalCount
:
rawNodeDetails
.
wikis_count
,
successCount
:
rawNodeDetails
.
wikis_synced_count
,
failureCount
:
rawNodeDetails
.
wikis_failed_count
,
totalCount
:
rawNodeDetails
.
wikis_count
||
0
,
successCount
:
rawNodeDetails
.
wikis_synced_count
||
0
,
failureCount
:
rawNodeDetails
.
wikis_failed_count
||
0
,
},
lfs
:
{
totalCount
:
rawNodeDetails
.
lfs_objects_count
,
successCount
:
rawNodeDetails
.
lfs_objects_synced_count
,
failureCount
:
rawNodeDetails
.
lfs_objects_failed_count
,
totalCount
:
rawNodeDetails
.
lfs_objects_count
||
0
,
successCount
:
rawNodeDetails
.
lfs_objects_synced_count
||
0
,
failureCount
:
rawNodeDetails
.
lfs_objects_failed_count
||
0
,
},
jobArtifacts
:
{
totalCount
:
rawNodeDetails
.
job_artifacts_count
,
successCount
:
rawNodeDetails
.
job_artifacts_synced_count
,
failureCount
:
rawNodeDetails
.
job_artifacts_failed_count
,
totalCount
:
rawNodeDetails
.
job_artifacts_count
||
0
,
successCount
:
rawNodeDetails
.
job_artifacts_synced_count
||
0
,
failureCount
:
rawNodeDetails
.
job_artifacts_failed_count
||
0
,
},
attachments
:
{
totalCount
:
rawNodeDetails
.
attachments_count
,
successCount
:
rawNodeDetails
.
attachments_synced_count
,
failureCount
:
rawNodeDetails
.
attachments_failed_count
,
totalCount
:
rawNodeDetails
.
attachments_count
||
0
,
successCount
:
rawNodeDetails
.
attachments_synced_count
||
0
,
failureCount
:
rawNodeDetails
.
attachments_failed_count
||
0
,
},
lastEvent
:
{
id
:
rawNodeDetails
.
last_event_id
,
...
...
spec/javascripts/geo_nodes/components/app_spec.js
View file @
f653dd5d
...
...
@@ -94,15 +94,15 @@ describe('AppComponent', () => {
},
0
);
});
it
(
'
sets error flag and message
on failure
'
,
(
done
)
=>
{
it
(
'
emits `nodeDetailsLoadFailed` event
on failure
'
,
(
done
)
=>
{
const
err
=
'
Something went wrong
'
;
const
mock
=
new
MockAdapter
(
axios
);
spyOn
(
eventHub
,
'
$emit
'
);
mock
.
onGet
(
`
${
vm
.
service
.
geoNodeDetailsBasePath
}
/2/status.json`
).
reply
(
500
,
err
);
vm
.
fetchNodeDetails
(
2
);
setTimeout
(()
=>
{
expect
(
vm
.
hasError
).
toBeTruthy
();
expect
(
vm
.
errorMessage
.
response
.
data
).
toBe
(
err
);
expect
(
eventHub
.
$emit
).
toHaveBeenCalledWith
(
'
nodeDetailsLoadFailed
'
,
2
,
jasmine
.
any
(
Object
));
done
();
},
0
);
});
...
...
spec/javascripts/geo_nodes/components/geo_node_item_spec.js
View file @
f653dd5d
...
...
@@ -31,24 +31,118 @@ describe('GeoNodeItemComponent', () => {
describe
(
'
data
'
,
()
=>
{
it
(
'
returns default data props
'
,
()
=>
{
expect
(
vm
.
isNodeDetailsLoading
).
toBeTruthy
();
expect
(
vm
.
isNodeDetailsFailed
).
toBeFalsy
();
expect
(
vm
.
nodeHealthStatus
).
toBe
(
''
);
expect
(
vm
.
errorMessage
).
toBe
(
''
);
expect
(
typeof
vm
.
nodeDetails
).
toBe
(
'
object
'
);
});
});
describe
(
'
computed
'
,
()
=>
{
describe
(
'
showInsecureUrlWarning
'
,
()
=>
{
it
(
'
returns boolean value representing URL protocol security
'
,
()
=>
{
// With altered mock data for secure URL
const
mockNode
=
Object
.
assign
({},
mockNodes
[
0
],
{
url
:
'
https://127.0.0.1:3001/
'
,
});
const
vmX
=
createComponent
(
mockNode
);
expect
(
vmX
.
showInsecureUrlWarning
).
toBeFalsy
();
vmX
.
$destroy
();
let
vmHttps
;
let
mockNode
;
beforeEach
(()
=>
{
// Altered mock data for secure URL
mockNode
=
Object
.
assign
({},
mockNodes
[
0
],
{
url
:
'
https://127.0.0.1:3001/
'
,
});
vmHttps
=
createComponent
(
mockNode
);
});
afterEach
(()
=>
{
vmHttps
.
$destroy
();
});
describe
(
'
isNodeNonHTTPS
'
,
()
=>
{
it
(
'
returns `true` if Node URL protocol is non-HTTPS
'
,
()
=>
{
// With default mock data
expect
(
vm
.
showInsecureUrlWarning
).
toBeTruthy
();
expect
(
vm
.
isNodeNonHTTPS
).
toBeTruthy
();
});
it
(
'
returns `false` is Node URL protocol is HTTPS
'
,
()
=>
{
// With altered mock data
expect
(
vmHttps
.
isNodeNonHTTPS
).
toBeFalsy
();
});
});
describe
(
'
showNodeStatusIcon
'
,
()
=>
{
it
(
'
returns `false` if Node details are still loading
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
true
;
expect
(
vm
.
showNodeStatusIcon
).
toBeFalsy
();
});
it
(
'
returns `true` if Node details failed to load
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
false
;
vm
.
isNodeDetailsFailed
=
true
;
expect
(
vm
.
showNodeStatusIcon
).
toBeTruthy
();
});
it
(
'
returns `true` if Node details loaded and Node URL is non-HTTPS
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
false
;
vm
.
isNodeDetailsFailed
=
false
;
expect
(
vm
.
showNodeStatusIcon
).
toBeTruthy
();
});
it
(
'
returns `false` if Node details loaded and Node URL is HTTPS
'
,
()
=>
{
vmHttps
.
isNodeDetailsLoading
=
false
;
vmHttps
.
isNodeDetailsFailed
=
false
;
expect
(
vmHttps
.
showNodeStatusIcon
).
toBeFalsy
();
});
});
describe
(
'
showNodeDetails
'
,
()
=>
{
it
(
'
returns `false` if Node details are still loading
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
true
;
expect
(
vm
.
showNodeDetails
).
toBeFalsy
();
});
it
(
'
returns `false` if Node details failed to load
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
false
;
vm
.
isNodeDetailsFailed
=
true
;
expect
(
vm
.
showNodeDetails
).
toBeFalsy
();
});
it
(
'
returns `true` if Node details loaded
'
,
()
=>
{
vm
.
isNodeDetailsLoading
=
false
;
vm
.
isNodeDetailsFailed
=
false
;
expect
(
vm
.
showNodeDetails
).
toBeTruthy
();
});
});
describe
(
'
nodeStatusIconClass
'
,
()
=>
{
it
(
'
returns `node-status-icon-failure` along with default classes if Node details failed to load
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
true
;
expect
(
vm
.
nodeStatusIconClass
).
toBe
(
'
prepend-left-10 pull-left node-status-icon-failure
'
);
});
it
(
'
returns `node-status-icon-warning` along with default classes if Node details loaded and Node URL is non-HTTPS
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
false
;
expect
(
vm
.
nodeStatusIconClass
).
toBe
(
'
prepend-left-10 pull-left node-status-icon-warning
'
);
});
});
describe
(
'
nodeStatusIconName
'
,
()
=>
{
it
(
'
returns `warning` if Node details loaded and Node URL is non-HTTPS
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
false
;
expect
(
vm
.
nodeStatusIconName
).
toBe
(
'
warning
'
);
});
it
(
'
returns `status_failed_borderless` if Node details failed to load
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
true
;
expect
(
vm
.
nodeStatusIconName
).
toBe
(
'
status_failed_borderless
'
);
});
});
describe
(
'
nodeStatusIconTooltip
'
,
()
=>
{
it
(
'
returns empty string if Node details failed to load
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
true
;
expect
(
vm
.
nodeStatusIconTooltip
).
toBe
(
''
);
});
it
(
'
returns tooltip string if Node details loaded and Node URL is non-HTTPS
'
,
()
=>
{
vm
.
isNodeDetailsFailed
=
false
;
expect
(
vm
.
nodeStatusIconTooltip
).
toBe
(
'
You have configured Geo nodes using an insecure HTTP connection. We recommend the use of HTTPS.
'
);
});
});
});
...
...
@@ -58,13 +152,15 @@ describe('GeoNodeItemComponent', () => {
it
(
'
intializes props based on provided `nodeDetails`
'
,
()
=>
{
// With altered mock data with matching ID
const
mockNode
=
Object
.
assign
({},
mockNodes
[
1
]);
const
vm
X
=
createComponent
(
mockNode
);
const
vm
NodePrimary
=
createComponent
(
mockNode
);
vmX
.
handleNodeDetails
(
mockNodeDetails
);
expect
(
vmX
.
isNodeDetailsLoading
).
toBeFalsy
();
expect
(
vmX
.
nodeDetails
).
toBe
(
mockNodeDetails
);
expect
(
vmX
.
nodeHealthStatus
).
toBe
(
mockNodeDetails
.
health
);
vmX
.
$destroy
();
vmNodePrimary
.
handleNodeDetails
(
mockNodeDetails
);
expect
(
vmNodePrimary
.
isNodeDetailsLoading
).
toBeFalsy
();
expect
(
vmNodePrimary
.
isNodeDetailsFailed
).
toBeFalsy
();
expect
(
vmNodePrimary
.
errorMessage
).
toBe
(
''
);
expect
(
vmNodePrimary
.
nodeDetails
).
toBe
(
mockNodeDetails
);
expect
(
vmNodePrimary
.
nodeHealthStatus
).
toBe
(
mockNodeDetails
.
health
);
vmNodePrimary
.
$destroy
();
// With default mock data without matching ID
vm
.
handleNodeDetails
(
mockNodeDetails
);
...
...
@@ -74,6 +170,16 @@ describe('GeoNodeItemComponent', () => {
});
});
describe
(
'
handleNodeDetailsFailure
'
,
()
=>
{
it
(
'
initializes props for Node details failure
'
,
()
=>
{
const
err
=
'
Something went wrong
'
;
vm
.
handleNodeDetailsFailure
(
1
,
{
message
:
err
});
expect
(
vm
.
isNodeDetailsLoading
).
toBeFalsy
();
expect
(
vm
.
isNodeDetailsFailed
).
toBeTruthy
();
expect
(
vm
.
errorMessage
).
toBe
(
err
);
});
});
describe
(
'
handleMounted
'
,
()
=>
{
it
(
'
emits `pollNodeDetails` event and passes node ID
'
,
()
=>
{
spyOn
(
eventHub
,
'
$emit
'
);
...
...
@@ -90,6 +196,7 @@ describe('GeoNodeItemComponent', () => {
const
vmX
=
createComponent
();
expect
(
eventHub
.
$on
).
toHaveBeenCalledWith
(
'
nodeDetailsLoaded
'
,
jasmine
.
any
(
Function
));
expect
(
eventHub
.
$on
).
toHaveBeenCalledWith
(
'
nodeDetailsLoadFailed
'
,
jasmine
.
any
(
Function
));
vmX
.
$destroy
();
});
});
...
...
@@ -101,6 +208,7 @@ describe('GeoNodeItemComponent', () => {
const
vmX
=
createComponent
();
vmX
.
$destroy
();
expect
(
eventHub
.
$off
).
toHaveBeenCalledWith
(
'
nodeDetailsLoaded
'
,
jasmine
.
any
(
Function
));
expect
(
eventHub
.
$off
).
toHaveBeenCalledWith
(
'
nodeDetailsLoadFailed
'
,
jasmine
.
any
(
Function
));
});
});
...
...
@@ -121,5 +229,16 @@ describe('GeoNodeItemComponent', () => {
it
(
'
renders node badge `Primary`
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.node-badge.primary-node
'
).
length
).
not
.
toBe
(
0
);
});
it
(
'
renders node error message
'
,
(
done
)
=>
{
const
err
=
'
Something error message
'
;
vm
.
isNodeDetailsFailed
=
true
;
vm
.
errorMessage
=
err
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
p.health-message
'
).
length
).
not
.
toBe
(
0
);
expect
(
vm
.
$el
.
querySelector
(
'
p.health-message
'
).
innerText
.
trim
()).
toBe
(
err
);
done
();
});
});
});
});
spec/javascripts/geo_nodes/mock_data.js
View file @
f653dd5d
...
...
@@ -133,7 +133,7 @@ export const mockNodeDetails = {
successCount
:
0
,
failureCount
:
0
,
},
job
_a
rtifacts
:
{
job
A
rtifacts
:
{
totalCount
:
0
,
successCount
:
0
,
failureCount
:
0
,
...
...
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