Commit 079d4b89 authored by Zack Cuddy's avatar Zack Cuddy Committed by Phil Hughes

Cleanup styles for Geo Node Items

Remove unneeded class

Fix geo node status colors

Node warning styles

Cleanup geo-node-item

Cleanup node section items

Mobile friendly node actions

Tweak margins

Remove unneeded class

Starting to fix tests

Another fix

Lots of tests

Final lint and tests

Fix backend tests
parent c7fc256d
......@@ -79,53 +79,49 @@ export default {
</script>
<template>
<div class="geo-node-actions">
<div v-if="isSecondaryNode" class="node-action-container">
<a :href="node.geoProjectsUrl" class="btn btn-sm btn-node-action" target="_blank">
<icon v-if="!node.current" name="external-link" /> {{ __('Open projects') }}
</a>
</div>
<div class="d-flex align-items-center justify-content-end geo-node-actions">
<a v-if="isSecondaryNode" :href="node.geoProjectsUrl" class="btn btn-sm mx-1 " target="_blank">
<icon v-if="!node.current" name="external-link" /> {{ __('Open projects') }}
</a>
<template v-if="nodeActionsAllowed">
<div v-if="nodeMissingOauth" class="node-action-container">
<button type="button" class="btn btn-default btn-sm btn-node-action" @click="onRepairNode">
{{ s__('Repair authentication') }}
</button>
</div>
<div v-if="isToggleAllowed" class="node-action-container">
<button
:class="{
'btn-warning': node.enabled,
'btn-success': !node.enabled,
}"
type="button"
class="btn btn-sm btn-node-action"
@click="onToggleNode"
>
<icon :name="nodeToggleIcon" />
{{ nodeToggleLabel }}
</button>
</div>
<div v-if="nodeEditAllowed" class="node-action-container">
<a :href="node.editPath" class="btn btn-sm btn-node-action"> {{ __('Edit') }} </a>
</div>
<div class="node-action-container">
<button
v-if="isSecondaryNode"
type="button"
class="btn btn-sm btn-node-action btn-danger"
@click="onRemoveSecondaryNode"
>
{{ __('Remove') }}
</button>
<button
v-else
type="button"
class="btn btn-sm btn-node-action btn-danger"
@click="onRemovePrimaryNode"
>
{{ __('Remove') }}
</button>
</div>
<button
v-if="nodeMissingOauth"
type="button"
class="btn btn-sm btn-default mx-1"
@click="onRepairNode"
>
{{ s__('Repair authentication') }}
</button>
<button
v-if="isToggleAllowed"
:class="{
'btn-warning': node.enabled,
'btn-success': !node.enabled,
}"
type="button"
class="btn btn-sm mx-1"
@click="onToggleNode"
>
<icon :name="nodeToggleIcon" />
{{ nodeToggleLabel }}
</button>
<a v-if="nodeEditAllowed" :href="node.editPath" class="btn btn-sm mx-1"> {{ __('Edit') }} </a>
<button
v-if="isSecondaryNode"
type="button"
class="btn btn-sm btn-danger mx-1"
@click="onRemoveSecondaryNode"
>
{{ __('Remove') }}
</button>
<button
v-if="!isSecondaryNode"
type="button"
class="btn btn-sm btn-danger mx-1"
@click="onRemovePrimaryNode"
>
{{ __('Remove') }}
</button>
</template>
</div>
</template>
......@@ -126,19 +126,21 @@ export default {
</script>
<template>
<div v-if="!featureDisabled" class="prepend-top-15 prepend-left-10 node-detail-item">
<div class="node-detail-title">
<span>{{ itemTitle }}</span>
<div v-if="!featureDisabled" class="mt-2 ml-2 node-detail-item">
<div class="d-flex align-items-center text-secondary-700">
<span class="node-detail-title">{{ itemTitle }}</span>
<icon
v-if="hasHelpInfo"
v-popover="popoverConfig"
:size="12"
class="node-detail-help-text prepend-left-5"
class="text-primary-600 ml-1 node-detail-help-text"
name="question"
/>
</div>
<div v-if="isValueTypePlain" :class="cssClass" class="node-detail-value">{{ itemValue }}</div>
<div v-if="isValueTypeGraph" :class="{ 'd-flex': itemValueStale }" class="node-detail-value">
<div v-if="isValueTypePlain" :class="cssClass" class="mt-1 node-detail-value">
{{ itemValue }}
</div>
<div v-if="isValueTypeGraph" :class="{ 'd-flex': itemValueStale }" class="mt-1">
<stacked-progress-bar
:css-class="itemValueStale ? 'flex-fill' : ''"
:success-label="successLabel"
......@@ -153,7 +155,7 @@ export default {
v-tooltip
:title="itemValueStaleTooltip"
name="time-out"
class="prepend-left-10 detail-value-stale-icon"
class="ml-2 text-warning-500"
data-container="body"
/>
</div>
......
......@@ -66,7 +66,7 @@ export default {
</script>
<template>
<div class="card-body">
<div class="card-body p-0">
<node-details-section-main
:node="node"
:node-details="nodeDetails"
......@@ -85,8 +85,8 @@ export default {
:node-details="nodeDetails"
:node-type-primary="node.primary"
/>
<div v-if="hasError || hasVersionMismatch" class="node-health-message-container">
<p class="node-health-message">
<div v-if="hasError || hasVersionMismatch">
<p class="p-3 mb-0 bg-danger-100 text-danger-500">
{{ errorMessage }}
<gl-link :href="geoTroubleshootingHelpPath">{{
s__('Geo|Please refer to Geo Troubleshooting.')
......
......@@ -39,7 +39,7 @@ export default {
</script>
<template>
<div class="node-detail-value">
<div class="mt-1 node-detail-value">
<template v-if="eventTimeStamp">
<strong> {{ eventString }} </strong>
<span
......
......@@ -42,11 +42,10 @@ export default {
return this.isNodeHTTP || this.nodeDetailsFailed;
},
nodeStatusIconClass() {
const iconClasses = 'prepend-left-10 node-status-icon';
if (this.nodeDetailsFailed) {
return `${iconClasses} status-icon-failure`;
}
return `${iconClasses} status-icon-warning`;
return [
'ml-2',
{ 'text-danger-500': this.nodeDetailsFailed, 'text-warning-500': !this.nodeDetailsFailed },
];
},
nodeStatusIconName() {
if (this.nodeDetailsFailed) {
......@@ -70,7 +69,7 @@ export default {
<div class="card-header">
<div class="row">
<div class="col-md-8 clearfix">
<span class="d-flex float-left append-right-10">
<span class="d-flex align-items-center float-left append-right-10">
<strong class="node-url"> {{ node.url }} </strong>
<gl-loading-icon
v-if="nodeDetailsLoading || node.nodeActionActive"
......@@ -87,11 +86,17 @@ export default {
data-placement="bottom"
/>
</span>
<span class="inline node-type-badges">
<span v-if="node.current" class="node-badge current-node">
<span class="inline">
<span
v-if="node.current"
class="rounded-pill gl-font-size-12 p-1 text-white bg-success-400"
>
{{ s__('Current node') }}
</span>
<span v-if="node.primary" class="prepend-left-5 node-badge primary-node">
<span
v-if="node.primary"
class="ml-1 rounded-pill gl-font-size-12 p-1 text-white bg-primary-600"
>
{{ s__('Primary') }}
</span>
</span>
......
<script>
import icon from '~/vue_shared/components/icon.vue';
import { HEALTH_STATUS_ICON } from '../constants';
import { HEALTH_STATUS_ICON, HEALTH_STATUS_CLASS } from '../constants';
export default {
components: {
......@@ -14,7 +14,7 @@ export default {
},
computed: {
healthCssClass() {
return `geo-node-${this.status.toLowerCase()}`;
return HEALTH_STATUS_CLASS[this.status.toLowerCase()];
},
statusIconName() {
return HEALTH_STATUS_ICON[this.status.toLowerCase()];
......@@ -24,11 +24,11 @@ export default {
</script>
<template>
<div class="prepend-top-15 detail-section-item">
<div class="node-detail-title">{{ s__('GeoNodes|Health status') }}</div>
<div :class="healthCssClass" class="node-detail-value node-health-status">
<div class="mt-2 detail-section-item">
<div class="text-secondary-700 node-detail-title">{{ s__('GeoNodes|Health status') }}</div>
<div :class="healthCssClass" class="mt-1 d-flex align-items-center node-health-status">
<icon :size="16" :name="statusIconName" />
<span class="status-text prepend-left-5"> {{ status }} </span>
<span class="status-text ml-2"> {{ status }} </span>
</div>
</div>
</template>
......@@ -78,7 +78,7 @@ export default {
</script>
<template>
<div :class="{ 'node-action-active': node.nodeActionActive }" class="card geo-node-item">
<div :class="{ 'node-action-active': node.nodeActionActive }" class="card">
<geo-node-header
:node="node"
:node-details="nodeDetails"
......@@ -93,8 +93,8 @@ export default {
:node-actions-allowed="nodeActionsAllowed"
:geo-troubleshooting-help-path="geoTroubleshootingHelpPath"
/>
<div v-if="isNodeDetailsFailed" class="node-health-message-container">
<p class="node-health-message">
<div v-if="isNodeDetailsFailed">
<p class="p-3 mb-0 bg-danger-100 text-danger-500">
{{ errorMessage
}}<gl-link :href="geoTroubleshootingHelpPath">{{
s__('Geo|Please refer to Geo Troubleshooting.')
......
......@@ -108,18 +108,18 @@ export default {
</script>
<template>
<div class="node-detail-value">
<span v-if="syncStatusUnavailable" class="node-detail-value-bold"> {{ __('Unknown') }} </span>
<div class="mt-1 node-sync-settings">
<strong v-if="syncStatusUnavailable"> {{ __('Unknown') }} </strong>
<span
v-else
v-tooltip
:title="syncStatusTooltip"
class="node-sync-settings"
class="d-flex align-items-center"
data-placement="bottom"
>
<strong>{{ syncType }}</strong>
<icon name="retry" class="sync-status-icon prepend-left-5" />
<span v-if="!eventTimestampEmpty" class="sync-status-event-info prepend-left-5">
<icon name="retry" class="ml-2" />
<span v-if="!eventTimestampEmpty" class="ml-2">
{{ syncStatusEventInfo }}
</span>
</span>
......
......@@ -46,13 +46,13 @@ export default {
</script>
<template>
<div class="row-fluid clearfix node-detail-section primary-section">
<div class="col-md-8 section-items-container">
<div class="detail-section-item node-version">
<div class="node-detail-title">{{ s__('GeoNodes|GitLab version') }}</div>
<div class="row-fluid clearfix py-3 primary-section">
<div class="col-md-8">
<div>
<div class="text-secondary-700 node-detail-title">{{ s__('GeoNodes|GitLab version') }}</div>
<div
:class="{ 'node-detail-value-error': versionMismatch }"
class="node-detail-value node-detail-value-bold"
:class="{ 'text-danger-500': versionMismatch }"
class="mt-1 font-weight-bold node-detail-value"
>
{{ nodeVersion }}
</div>
......
......@@ -54,7 +54,7 @@ export default {
itemTitle: s__('GeoNodes|Replication slot WAL'),
itemValue: numberToHumanSize(this.nodeDetails.replicationSlotWAL),
itemValueType: VALUE_TYPE.PLAIN,
cssClass: 'node-detail-value-bold',
cssClass: 'font-weight-bold',
});
}
......@@ -63,7 +63,7 @@ export default {
itemTitle: s__('GeoNodes|Internal URL'),
itemValue: this.node.internalUrl,
itemValueType: VALUE_TYPE.PLAIN,
cssClass: 'node-detail-value-bold',
cssClass: 'font-weight-bold',
});
}
......@@ -76,7 +76,7 @@ export default {
itemTitle: s__('GeoNodes|Storage config'),
itemValue: this.storageShardsStatus,
itemValueType: VALUE_TYPE.PLAIN,
cssClass: this.storageShardsCssClass,
cssClass: this.storageShardsCssClass.join(' '),
},
];
},
......@@ -89,10 +89,7 @@ export default {
: s__('GeoNodes|Does not match the primary storage configuration');
},
storageShardsCssClass() {
const cssClass = 'node-detail-value-bold';
return !this.nodeDetails.storageShardsMatch
? `${cssClass} node-detail-value-error`
: cssClass;
return ['font-weight-bold', { 'text-danger-500': !this.nodeDetails.storageShardsMatch }];
},
},
methods: {
......@@ -104,17 +101,14 @@ export default {
</script>
<template>
<div class="row-fluid clearfix node-detail-section other-section">
<div class="row-fluid clearfix py-3 border-top border-color-default other-section">
<div class="col-md-12">
<section-reveal-button
:button-title="__('Other information')"
@toggleButton="handleSectionToggle"
/>
</div>
<div
v-show="showSectionItems"
class="col-md-6 prepend-left-15 prepend-top-10 section-items-container"
>
<div v-if="showSectionItems" class="col-md-6 ml-2 mt-2 section-items-container">
<geo-node-detail-item
v-for="(nodeDetailItem, index) in nodeDetailItems"
:key="index"
......
......@@ -130,17 +130,14 @@ export default {
</script>
<template>
<div class="row-fluid clearfix node-detail-section sync-section">
<div class="row-fluid clearfix py-3 border-top border-color-default sync-section">
<div class="col-md-12">
<section-reveal-button
:button-title="__('Sync information')"
@toggleButton="handleSectionToggle"
/>
</div>
<div
v-show="showSectionItems"
class="col-md-6 prepend-left-15 prepend-top-10 section-items-container"
>
<div v-if="showSectionItems" class="col-md-6 ml-2 mt-2 section-items-container">
<geo-node-detail-item
v-for="(nodeDetailItem, index) in nodeDetailItems"
:key="index"
......
......@@ -113,7 +113,7 @@ export default {
</script>
<template>
<div class="row-fluid clearfix node-detail-section verification-section">
<div class="row-fluid clearfix py-3 border-top border-color-default verification-section">
<div class="col-md-12">
<section-reveal-button
:button-title="__('Verification information')"
......@@ -121,7 +121,7 @@ export default {
/>
</div>
<template v-if="showSectionItems">
<div class="col-md-6 prepend-left-15 prepend-top-10 section-items-container">
<div class="col-md-6 ml-2 mt-2 section-items-container">
<geo-node-detail-item
v-for="(nodeDetailItem, index) in nodeDetailItems"
:key="index"
......
......@@ -31,7 +31,7 @@ export default {
</script>
<template>
<button class="btn-link btn-show-section" type="button" @click="onClickButton">
<button class="btn-link d-flex align-items-center" type="button" @click="onClickButton">
<icon :size="16" :name="toggleButtonIcon" />
<span class="prepend-left-8">{{ buttonTitle }}</span>
</button>
......
......@@ -23,6 +23,14 @@ export const HEALTH_STATUS_ICON = {
offline: 'status_canceled',
};
export const HEALTH_STATUS_CLASS = {
healthy: 'text-success-500',
unhealthy: 'text-danger-500',
disabled: 'text-secondary-950',
unknown: 'cdark',
offline: 'cdark',
};
export const TIME_DIFF = {
FIVE_MINS: 300,
HOUR: 3600,
......
.node-badge {
color: $white-light;
padding: 1px $gl-padding-8;
font-size: $label-font-size;
border-radius: $label-border-radius;
@media (max-width: map-get($grid-breakpoints, sm)) {
.geo-node-actions {
flex-direction: column;
margin: 0 1rem;
&.primary-node {
background-color: $blue-600;
}
&.current-node {
background-color: $green-400;
}
}
.geo-node-healthy {
color: $green-500;
}
.geo-node-unhealthy {
color: $red-500;
}
.geo-node-offline {
color: $gray-950;
}
.geo-node-disabled {
color: $gray-darkest;
}
.geo-node-unknown {
color: $gray-darkest;
}
.geo-node-item {
.node-status-icon {
height: 35px;
}
.status-icon-warning {
fill: $orange-500;
}
.status-icon-failure {
fill: $red-500;
}
.card-body {
padding: 0;
.node-detail-section {
padding: $gl-padding 0;
&.sync-section,
&.verification-section,
&.other-section {
border-top: 1px solid $border-color;
}
.btn-show-section {
padding: 0;
}
}
}
.node-health-message-container {
max-height: $dropdown-max-height;
overflow-y: auto;
.node-health-message {
margin-bottom: 0;
padding: $gl-padding;
background-color: $red-100;
color: $red-500;
}
}
}
.node-detail-section {
.detail-section-item,
.section-items-container {
.node-detail-title {
color: $gray-700;
.node-detail-help-text {
color: $blue-600;
}
.tooltip .tooltip-inner {
text-align: left;
}
}
.node-detail-value {
margin-top: 4px;
}
.detail-value-stale-icon {
color: $orange-500;
}
.node-detail-value-bold {
font-weight: $gl-font-weight-bold;
}
.node-detail-value-error {
color: $red-500;
}
}
.section-items-container {
display: inline-block;
.node-detail-item {
&:first-child {
margin-top: 0;
}
}
@include media-breakpoint-down(sm) {
width: 95%;
}
}
}
.node-detail-title,
.node-health-status,
.node-sync-settings,
.node-detail-section .btn-show-section {
display: flex;
align-items: center;
}
.geo-node-actions {
display: inline-flex;
justify-content: center;
float: right;
.node-action-container {
margin: 0 5px;
&:last-child {
margin-right: $gl-padding;
}
}
@include media-breakpoint-down(sm) {
display: block;
width: 100%;
.node-action-container {
width: 100%;
margin: 0;
margin-top: 10px;
padding: 0 10px;
}
.btn-node-action {
.btn-sm {
width: 100%;
margin-top: 1rem;
}
}
}
......
......@@ -16,7 +16,7 @@ describe 'admin Geo Nodes', :js, :geo do
wait_for_requests
expect(page).to have_link('New node', href: new_admin_geo_node_path)
page.within(find('.geo-node-item', match: :first)) do
page.within(find('.card', match: :first)) do
expect(page).to have_content(geo_node.url)
end
end
......@@ -86,7 +86,7 @@ describe 'admin Geo Nodes', :js, :geo do
expect(current_path).to eq admin_geo_nodes_path
wait_for_requests
page.within(find('.geo-node-item', match: :first)) do
page.within(find('.card', match: :first)) do
expect(page).to have_content(geo_node.url)
end
end
......@@ -167,7 +167,7 @@ describe 'admin Geo Nodes', :js, :geo do
expect(current_path).to eq admin_geo_nodes_path
wait_for_requests
page.within(find('.geo-node-item', match: :first)) do
page.within(find('.card', match: :first)) do
expect(page).to have_content('http://newsite.com')
expect(page).to have_content('Primary')
......@@ -196,7 +196,7 @@ describe 'admin Geo Nodes', :js, :geo do
expect(current_path).to eq admin_geo_nodes_path
wait_for_requests
expect(page).not_to have_css('.geo-node-item')
expect(page).not_to have_css('.card')
end
end
end
......@@ -125,8 +125,7 @@ describe('GeoNodeActionsComponent', () => {
describe('template', () => {
it('renders container elements correctly', () => {
expect(vm.$el.classList.contains('geo-node-actions')).toBe(true);
expect(vm.$el.querySelectorAll('.node-action-container').length).not.toBe(0);
expect(vm.$el.querySelectorAll('.btn-node-action').length).not.toBe(0);
expect(vm.$el.querySelectorAll('.btn-sm').length).not.toBe(0);
});
});
});
......@@ -75,7 +75,7 @@ describe('GeoNodeDetailItemComponent', () => {
itemValueStaleTooltip,
});
const iconEl = vm.$el.querySelector('.detail-value-stale-icon');
const iconEl = vm.$el.querySelector('.text-warning-500');
expect(iconEl).not.toBeNull();
expect(iconEl.dataset.originalTitle).toBe(itemValueStaleTooltip);
......
......@@ -87,9 +87,7 @@ describe('GeoNodeDetailsComponent', () => {
vm.errorMessage = 'Foobar';
vm.$nextTick(() => {
expect(vm.$el.querySelector('.node-health-message-container a').getAttribute('href')).toBe(
'/foo/bar',
);
expect(vm.$el.querySelector('.bg-danger-100 a').getAttribute('href')).toBe('/foo/bar');
done();
});
});
......
import Vue from 'vue';
import geoNodeHealthStatusComponent from 'ee/geo_nodes/components/geo_node_health_status.vue';
import { HEALTH_STATUS_ICON, HEALTH_STATUS_CLASS } from 'ee/geo_nodes/constants';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { mockNodeDetails } from '../mock_data';
......@@ -16,38 +17,38 @@ describe('GeoNodeHealthStatusComponent', () => {
describe('computed', () => {
describe('healthCssClass', () => {
it('returns CSS class representing `status` prop value', () => {
const vm = createComponent('Healthy');
const vm = createComponent('healthy');
expect(vm.healthCssClass).toBe('geo-node-healthy');
expect(vm.healthCssClass).toBe(HEALTH_STATUS_CLASS.healthy);
vm.$destroy();
});
});
describe('statusIconName', () => {
it('returns icon name representing `status` prop value', () => {
let vm = createComponent('Healthy');
let vm = createComponent('healthy');
expect(vm.statusIconName).toBe('status_success');
expect(vm.statusIconName).toBe(HEALTH_STATUS_ICON.healthy);
vm.$destroy();
vm = createComponent('Unhealthy');
vm = createComponent('unhealthy');
expect(vm.statusIconName).toBe('status_failed');
expect(vm.statusIconName).toBe(HEALTH_STATUS_ICON.unhealthy);
vm.$destroy();
vm = createComponent('Disabled');
vm = createComponent('disabled');
expect(vm.statusIconName).toBe('status_canceled');
expect(vm.statusIconName).toBe(HEALTH_STATUS_ICON.disabled);
vm.$destroy();
vm = createComponent('Unknown');
vm = createComponent('unknown');
expect(vm.statusIconName).toBe('status_warning');
expect(vm.statusIconName).toBe(HEALTH_STATUS_ICON.unknown);
vm.$destroy();
vm = createComponent('Offline');
vm = createComponent('offline');
expect(vm.statusIconName).toBe('status_canceled');
expect(vm.statusIconName).toBe(HEALTH_STATUS_ICON.offline);
vm.$destroy();
});
});
......@@ -60,7 +61,7 @@ describe('GeoNodeHealthStatusComponent', () => {
expect(vm.$el.classList.contains('detail-section-item')).toBe(true);
expect(vm.$el.querySelector('.node-detail-title').innerText.trim()).toBe('Health status');
const iconContainerEl = vm.$el.querySelector('.node-detail-value.node-health-status');
const iconContainerEl = vm.$el.querySelector('.node-health-status');
expect(iconContainerEl).not.toBeNull();
expect(iconContainerEl.querySelector('svg use').getAttribute('xlink:href')).toContain(
......
......@@ -148,11 +148,9 @@ describe('GeoNodeItemComponent', () => {
vm.isNodeDetailsFailed = true;
vm.errorMessage = err;
Vue.nextTick(() => {
expect(vm.$el.querySelectorAll('p.node-health-message').length).not.toBe(0);
expect(vm.$el.querySelector('p.node-health-message').innerText.trim()).toContain(err);
expect(vm.$el.querySelector('p.node-health-message a').getAttribute('href')).toBe(
'/foo/bar',
);
expect(vm.$el.querySelectorAll('p.bg-danger-100').length).not.toBe(0);
expect(vm.$el.querySelector('p.bg-danger-100').innerText.trim()).toContain(err);
expect(vm.$el.querySelector('p.bg-danger-100 a').getAttribute('href')).toBe('/foo/bar');
done();
});
});
......
......@@ -89,18 +89,20 @@ describe('NodeDetailsSectionOther', () => {
});
describe('storageShardsCssClass', () => {
it('returns CSS class `node-detail-value-bold` when `nodeDetails.storageShardsMatch` is true', done => {
it('returns CSS class `font-weight-bold` when `nodeDetails.storageShardsMatch` is true', done => {
vm.nodeDetails.storageShardsMatch = true;
Vue.nextTick()
.then(() => {
expect(vm.storageShardsCssClass).toBe('node-detail-value-bold');
expect(vm.storageShardsCssClass[0]).toBe('font-weight-bold');
expect(vm.storageShardsCssClass[1]['text-danger-500']).toBeFalsy();
})
.then(done)
.catch(done.fail);
});
it('returns CSS class `node-detail-value-bold node-detail-value-error` when `nodeDetails.storageShardsMatch` is false', () => {
expect(vm.storageShardsCssClass).toBe('node-detail-value-bold node-detail-value-error');
it('returns CSS class `font-weight-bold text-danger-500` when `nodeDetails.storageShardsMatch` is false', () => {
expect(vm.storageShardsCssClass[0]).toBe('font-weight-bold');
expect(vm.storageShardsCssClass[1]['text-danger-500']).toBeTruthy();
});
});
});
......@@ -111,14 +113,16 @@ describe('NodeDetailsSectionOther', () => {
});
it('renders show section button element', () => {
expect(vm.$el.querySelector('.btn-show-section')).not.toBeNull();
expect(vm.$el.querySelector('.btn-show-section > span').innerText.trim()).toBe(
'Other information',
);
expect(vm.$el.querySelector('.btn-link')).not.toBeNull();
expect(vm.$el.querySelector('.btn-link > span').innerText.trim()).toBe('Other information');
});
it('renders section items container element', () => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull();
it('renders section items container element', done => {
vm.showSectionItems = true;
Vue.nextTick(() => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull();
done();
});
});
});
});
......@@ -89,14 +89,16 @@ describe('NodeDetailsSectionSync', () => {
});
it('renders show section button element', () => {
expect(vm.$el.querySelector('.btn-show-section')).not.toBeNull();
expect(vm.$el.querySelector('.btn-show-section > span').innerText.trim()).toBe(
'Sync information',
);
expect(vm.$el.querySelector('.btn-link')).not.toBeNull();
expect(vm.$el.querySelector('.btn-link > span').innerText.trim()).toBe('Sync information');
});
it('renders section items container element', () => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull();
it('renders section items container element', done => {
vm.showSectionItems = true;
Vue.nextTick(() => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull();
done();
});
});
});
});
......@@ -83,6 +83,13 @@ describe('NodeDetailsSectionVerification', () => {
expect(vm.$el.classList.contains('verification-section')).toBe(true);
});
it('renders show section button element', () => {
expect(vm.$el.querySelector('.btn-link')).not.toBeNull();
expect(vm.$el.querySelector('.btn-link > span').innerText.trim()).toBe(
'Verification information',
);
});
it('renders section items container element', done => {
vm.showSectionItems = true;
Vue.nextTick(() => {
......
......@@ -62,7 +62,7 @@ describe('SectionRevealButton', () => {
describe('template', () => {
it('renders button element', () => {
expect(vm.$el.classList.contains('btn-show-section')).toBe(true);
expect(vm.$el.classList.contains('btn-link')).toBe(true);
expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('#angle-down');
expect(vm.$el.querySelector('span').innerText.trim()).toBe('Foo button');
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment