Commit e8aced51 authored by Kushal Pandya's avatar Kushal Pandya

GeoNode NodeDetailsSectionSync Component

parent 3a8b9fbf
<script>
import { s__, __ } from '~/locale';
import { parseSeconds, stringifyTime } from '~/lib/utils/pretty_time';
import { VALUE_TYPE, CUSTOM_TYPE } from '../../constants';
import GeoNodeDetailItem from '../geo_node_detail_item.vue';
import SectionRevealButton from './section_reveal_button.vue';
export default {
components: {
SectionRevealButton,
GeoNodeDetailItem,
},
props: {
nodeDetails: {
type: Object,
required: true,
},
},
data() {
return {
showSectionItems: false,
nodeDetailItems: [
{
itemTitle: s__('GeoNodes|Sync settings:'),
itemValue: this.syncSettings(),
itemValueType: VALUE_TYPE.CUSTOM,
customType: CUSTOM_TYPE.SYNC,
},
{
itemTitle: s__('GeoNodes|Repositories:'),
itemValue: this.nodeDetails.repositories,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Wikis:'),
itemValue: this.nodeDetails.wikis,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Local LFS objects:'),
itemValue: this.nodeDetails.lfs,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Local attachments:'),
itemValue: this.nodeDetails.attachments,
itemValueType: VALUE_TYPE.GRAPH,
},
{
itemTitle: s__('GeoNodes|Data replication lag:'),
itemValue: this.dbReplicationLag(),
itemValueType: VALUE_TYPE.PLAIN,
},
{
itemTitle: s__('GeoNodes|Last event ID seen from primary:'),
itemValue: this.lastEventStatus(),
itemValueType: VALUE_TYPE.CUSTOM,
customType: CUSTOM_TYPE.EVENT,
},
{
itemTitle: s__('GeoNodes|Latest event log status:'),
itemValue: this.cursorLastEventStatus(),
itemValueType: VALUE_TYPE.CUSTOM,
customType: CUSTOM_TYPE.EVENT,
eventTypeLogStatus: true,
},
],
};
},
methods: {
syncSettings() {
return {
syncStatusUnavailable: this.nodeDetails.syncStatusUnavailable,
selectiveSyncType: this.nodeDetails.selectiveSyncType,
lastEvent: this.nodeDetails.lastEvent,
cursorLastEvent: this.nodeDetails.cursorLastEvent,
};
},
dbReplicationLag() {
// Replication lag can be nil if the secondary isn't actually streaming
if (this.nodeDetails.dbReplicationLag !== null &&
this.nodeDetails.dbReplicationLag >= 0) {
const parsedTime = parseSeconds(this.nodeDetails.dbReplicationLag, {
hoursPerDay: 24,
daysPerWeek: 7,
});
return stringifyTime(parsedTime);
}
return __('Unknown');
},
lastEventStatus() {
return {
eventId: this.nodeDetails.lastEvent.id,
eventTimeStamp: this.nodeDetails.lastEvent.timeStamp,
};
},
cursorLastEventStatus() {
return {
eventId: this.nodeDetails.cursorLastEvent.id,
eventTimeStamp: this.nodeDetails.cursorLastEvent.timeStamp,
};
},
handleSectionToggle(toggleState) {
this.showSectionItems = toggleState;
},
},
};
</script>
<template>
<div class="row-fluid clearfix node-detail-section 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"
>
<geo-node-detail-item
v-for="(nodeDetailItem, index) in nodeDetailItems"
:key="index"
:css-class="nodeDetailItem.cssClass"
:item-title="nodeDetailItem.itemTitle"
:item-value="nodeDetailItem.itemValue"
:item-value-type="nodeDetailItem.itemValueType"
:custom-type="nodeDetailItem.customType"
:event-type-log-status="nodeDetailItem.eventTypeLogStatus"
/>
</div>
</div>
</template>
import Vue from 'vue';
import NodeDetailsSectionSyncComponent from 'ee/geo_nodes/components/node_detail_sections/node_details_section_sync.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { mockNodeDetails } from '../../mock_data';
const createComponent = (
nodeDetails = Object.assign({}, mockNodeDetails),
) => {
const Component = Vue.extend(NodeDetailsSectionSyncComponent);
return mountComponent(Component, {
nodeDetails,
});
};
describe('NodeDetailsSectionSync', () => {
let vm;
beforeEach(() => {
vm = createComponent();
});
afterEach(() => {
vm.$destroy();
});
describe('data', () => {
it('returns default data props', () => {
expect(vm.showSectionItems).toBe(false);
expect(Array.isArray(vm.nodeDetailItems)).toBe(true);
expect(vm.nodeDetailItems.length > 0).toBe(true);
});
});
describe('methods', () => {
describe('syncSettings', () => {
it('returns sync settings object', (done) => {
vm.nodeDetails.syncStatusUnavailable = true;
Vue.nextTick()
.then(() => {
const syncSettings = vm.syncSettings();
expect(syncSettings.syncStatusUnavailable).toBe(true);
expect(syncSettings.namespaces).toBe(mockNodeDetails.namespaces);
expect(syncSettings.lastEvent).toBe(mockNodeDetails.lastEvent);
expect(syncSettings.cursorLastEvent).toBe(mockNodeDetails.cursorLastEvent);
})
.then(done)
.catch(done.fail);
});
});
describe('dbReplicationLag', () => {
it('returns DB replication lag time duration', () => {
expect(vm.dbReplicationLag()).toBe('0m');
});
it('returns `Unknown` when `dbReplicationLag` is null', (done) => {
vm.nodeDetails.dbReplicationLag = null;
Vue.nextTick()
.then(() => {
expect(vm.dbReplicationLag()).toBe('Unknown');
})
.then(done)
.catch(done.fail);
});
});
describe('lastEventStatus', () => {
it('returns event status object', () => {
expect(vm.lastEventStatus().eventId).toBe(mockNodeDetails.lastEvent.id);
expect(vm.lastEventStatus().eventTimeStamp).toBe(mockNodeDetails.lastEvent.timeStamp);
});
});
describe('cursorLastEventStatus', () => {
it('returns event status object', () => {
expect(vm.cursorLastEventStatus().eventId).toBe(mockNodeDetails.cursorLastEvent.id);
expect(vm.cursorLastEventStatus().eventTimeStamp)
.toBe(mockNodeDetails.cursorLastEvent.timeStamp);
});
});
});
describe('template', () => {
it('renders component container element', () => {
expect(vm.$el.classList.contains('sync-section')).toBe(true);
});
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');
});
it('renders section items container element', () => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull();
});
});
});
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