Commit a2955b97 authored by Filipa Lacerda's avatar Filipa Lacerda

Adds loading state to linked pipeline

Renders a loading spinner for the isLoading
state.
Updates tests
parent f1c10b7f
<script>
import ciStatus from '~/vue_shared/components/ci_icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import { GlLoadingIcon, GlTooltipDirective, GlLink } from '@gitlab/ui';
import CiStatus from '~/vue_shared/components/ci_icon.vue';
export default {
directives: {
tooltip,
GlTooltip: GlTooltipDirective,
},
components: {
ciStatus,
CiStatus,
GlLoadingIcon,
GlLink,
},
props: {
pipelineId: {
......@@ -26,6 +28,11 @@ export default {
type: String,
required: true,
},
isLoading: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
tooltipText() {
......@@ -39,20 +46,20 @@ export default {
<li class="linked-pipeline build">
<div class="curve"></div>
<div>
<a
v-tooltip
<gl-link
v-gl-tooltip
:href="pipelinePath"
:title="tooltipText"
class="linked-pipeline-content"
data-container="body"
class="js-linked-pipeline-content linked-pipeline-content"
>
<span class="linked-pipeline-status ci-status-text">
<ci-status :status="pipelineStatus" />
<span class="js-linked-pipeline-status ci-status-text">
<gl-loading-icon v-if="isLoading" class="js-linked-pipeline-loading" />
<ci-status v-else :status="pipelineStatus" class="js-linked-pipeline-status" />
</span>
<span class="linked-pipeline-project-name">{{ projectName }}</span>
<span class="project-name-pipeline-id-separator">&#8226;</span>
<span class="linked-pipeline-id">#{{ pipelineId }}</span>
</a>
<span class="js-linked-pipeline-id">#{{ pipelineId }}</span>
</gl-link>
</div>
</li>
</template>
import Vue from 'vue';
import LinkedPipelineComponent from 'ee/pipelines/components/graph/linked_pipeline.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mockData from './linked_pipelines_mock_data';
const LinkedPipeline = Vue.extend(LinkedPipelineComponent);
const mockPipeline = mockData.triggered[0];
describe('Linked pipeline', function() {
beforeEach(() => {
this.propsData = {
describe('Linked pipeline', () => {
const Component = Vue.extend(LinkedPipelineComponent);
let vm;
afterEach(() => {
vm.$destroy();
});
describe('while is loading', () => {
const props = {
pipelineId: mockPipeline.id,
pipelinePath: mockPipeline.path,
pipelineStatus: mockPipeline.details.status,
projectName: mockPipeline.project.name,
isLoading: true,
};
this.linkedPipeline = new LinkedPipeline({
propsData: this.propsData,
}).$mount();
});
beforeEach(() => {
vm = mountComponent(Component, props);
});
it('should return a defined Vue component', () => {
expect(this.linkedPipeline).toBeDefined();
it('renders loading icon', () => {
expect(vm.$el.querySelector('.js-linked-pipeline-loading')).not.toBeNull();
});
});
it('should render a list item as the containing element', () => {
expect(this.linkedPipeline.$el.tagName).toBe('LI');
});
describe('when it is not loading', () => {
const props = {
pipelineId: mockPipeline.id,
pipelinePath: mockPipeline.path,
pipelineStatus: mockPipeline.details.status,
projectName: mockPipeline.project.name,
isLoading: false,
};
it('should render a link', () => {
const linkElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-content');
beforeEach(() => {
vm = mountComponent(Component, props);
});
expect(linkElement).not.toBeNull();
});
it('should render a list item as the containing element', () => {
expect(vm.$el.tagName).toBe('LI');
});
it('should link to the correct path', () => {
const linkElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-content');
it('should render a link', () => {
const linkElement = vm.$el.querySelector('.js-linked-pipeline-content');
expect(linkElement.getAttribute('href')).toBe(this.propsData.pipelinePath);
});
expect(linkElement).not.toBeNull();
});
it('should render the project name', () => {
const projectNameElement = this.linkedPipeline.$el.querySelector(
'.linked-pipeline-project-name',
);
it('should link to the correct path', () => {
const linkElement = vm.$el.querySelector('.js-linked-pipeline-content');
expect(projectNameElement.innerText).toContain(this.propsData.projectName);
});
expect(linkElement.getAttribute('href')).toBe(props.pipelinePath);
});
it('should render an svg within the status container', () => {
const pipelineStatusElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-status');
it('should render the project name', () => {
const projectNameElement = vm.$el.querySelector('.linked-pipeline-project-name');
expect(pipelineStatusElement.querySelector('svg')).not.toBeNull();
});
expect(projectNameElement.innerText).toContain(props.projectName);
});
it('should render the pipeline status icon svg', () => {
const pipelineStatusElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-status');
it('should render an svg within the status container', () => {
const pipelineStatusElement = vm.$el.querySelector('.js-linked-pipeline-status');
expect(pipelineStatusElement.querySelector('.ci-status-icon-running')).not.toBeNull();
expect(pipelineStatusElement.innerHTML).toContain('<svg');
});
expect(pipelineStatusElement.querySelector('svg')).not.toBeNull();
});
it('should render the correct pipeline status icon style selector', () => {
const pipelineStatusElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-status');
it('should render the pipeline status icon svg', () => {
const pipelineStatusElement = vm.$el.querySelector('.js-linked-pipeline-status');
expect(pipelineStatusElement.firstChild.classList.contains('ci-status-icon-running')).toBe(
true,
);
});
expect(pipelineStatusElement.querySelector('.ci-status-icon-running')).not.toBeNull();
expect(pipelineStatusElement.innerHTML).toContain('<svg');
});
it('should have a ci-status child component', () => {
const ciStatusComponent = this.linkedPipeline.$children[0];
it('should render the correct pipeline status icon style selector', () => {
const pipelineStatusElement = vm.$el.querySelector('.js-linked-pipeline-status');
expect(ciStatusComponent).toBeDefined();
expect(ciStatusComponent.$el.classList.contains('ci-status-icon')).toBe(true);
});
expect(pipelineStatusElement.firstChild.classList.contains('ci-status-icon-running')).toBe(
true,
);
});
it('should render the pipeline id', () => {
const pipelineIdElement = this.linkedPipeline.$el.querySelector('.linked-pipeline-id');
it('should have a ci-status child component', () => {
expect(vm.$el.querySelector('.js-linked-pipeline-status')).not.toBeNull();
});
expect(pipelineIdElement.innerText).toContain(`#${this.propsData.pipelineId}`);
});
it('should render the pipeline id', () => {
const pipelineIdElement = vm.$el.querySelector('.js-linked-pipeline-id');
it('should correctly compute the tooltip text', () => {
expect(this.linkedPipeline.tooltipText).toContain(mockPipeline.project.name);
expect(this.linkedPipeline.tooltipText).toContain(mockPipeline.details.status.label);
});
expect(pipelineIdElement.innerText).toContain(`#${props.pipelineId}`);
});
it('should correctly compute the tooltip text', () => {
expect(vm.tooltipText).toContain(mockPipeline.project.name);
expect(vm.tooltipText).toContain(mockPipeline.details.status.label);
});
it('should render the tooltip text as the title attribute', () => {
const tooltipRef = this.linkedPipeline.$el.querySelector('.linked-pipeline-content');
const titleAttr = tooltipRef.getAttribute('data-original-title');
it('should render the tooltip text as the title attribute', () => {
const tooltipRef = vm.$el.querySelector('.js-linked-pipeline-content');
const titleAttr = tooltipRef.getAttribute('data-original-title');
expect(titleAttr).toContain(mockPipeline.project.name);
expect(titleAttr).toContain(mockPipeline.details.status.label);
expect(titleAttr).toContain(mockPipeline.project.name);
expect(titleAttr).toContain(mockPipeline.details.status.label);
});
});
});
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