Uniformize code between both pipelines tables

This commit is contained in:
Filipa Lacerda 2017-06-20 14:54:55 +00:00 committed by Phil Hughes
parent 1d15ad02cb
commit 05cfba6f6d
16 changed files with 271 additions and 443 deletions

View File

@ -1,29 +1,25 @@
/* eslint-disable no-param-reassign */
import Vue from 'vue';
import VueResource from 'vue-resource';
import CommitPipelinesTable from './pipelines_table';
Vue.use(VueResource);
import commitPipelinesTable from './pipelines_table.vue';
/**
* Commits View > Pipelines Tab > Pipelines Table.
*
* Renders Pipelines table in pipelines tab in the commits show view.
* Used in:
* - Commit details View > Pipelines Tab > Pipelines Table.
* - Merge Request details View > Pipelines Tab > Pipelines Table.
* - New Merge Request View > Pipelines Tab > Pipelines Table.
*/
// export for use in merge_request_tabs.js (TODO: remove this hack)
window.gl = window.gl || {};
window.gl.CommitPipelinesTable = CommitPipelinesTable;
$(() => {
gl.commits = gl.commits || {};
gl.commits.pipelines = gl.commits.pipelines || {};
const CommitPipelinesTable = Vue.extend(commitPipelinesTable);
document.addEventListener('DOMContentLoaded', () => {
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
if (pipelineTableViewEl && pipelineTableViewEl.dataset.disableInitialization === undefined) {
gl.commits.pipelines.PipelinesTableBundle = new CommitPipelinesTable().$mount();
pipelineTableViewEl.appendChild(gl.commits.pipelines.PipelinesTableBundle.$el);
const table = new CommitPipelinesTable({
propsData: {
endpoint: pipelineTableViewEl.dataset.endpoint,
helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
},
}).$mount();
pipelineTableViewEl.appendChild(table.$el);
}
});

View File

@ -1,191 +0,0 @@
import Vue from 'vue';
import Visibility from 'visibilityjs';
import pipelinesTableComponent from '../../vue_shared/components/pipelines_table.vue';
import PipelinesService from '../../pipelines/services/pipelines_service';
import PipelineStore from '../../pipelines/stores/pipelines_store';
import eventHub from '../../pipelines/event_hub';
import emptyState from '../../pipelines/components/empty_state.vue';
import errorState from '../../pipelines/components/error_state.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import '../../lib/utils/common_utils';
import '../../vue_shared/vue_resource_interceptor';
import Poll from '../../lib/utils/poll';
/**
*
* Uses `pipelines-table-component` to render Pipelines table with an API call.
* Endpoint is provided in HTML and passed as `endpoint`.
* We need a store to store the received environemnts.
* We need a service to communicate with the server.
*
*/
export default Vue.component('pipelines-table', {
components: {
pipelinesTableComponent,
errorState,
emptyState,
loadingIcon,
},
/**
* Accesses the DOM to provide the needed data.
* Returns the necessary props to render `pipelines-table-component` component.
*
* @return {Object}
*/
data() {
const store = new PipelineStore();
return {
endpoint: null,
helpPagePath: null,
store,
state: store.state,
isLoading: false,
hasError: false,
isMakingRequest: false,
updateGraphDropdown: false,
hasMadeRequest: false,
};
},
computed: {
shouldRenderErrorState() {
return this.hasError && !this.isLoading;
},
/**
* Empty state is only rendered if after the first request we receive no pipelines.
*
* @return {Boolean}
*/
shouldRenderEmptyState() {
return !this.state.pipelines.length &&
!this.isLoading &&
this.hasMadeRequest &&
!this.hasError;
},
shouldRenderTable() {
return !this.isLoading &&
this.state.pipelines.length > 0 &&
!this.hasError;
},
},
/**
* When the component is about to be mounted, tell the service to fetch the data
*
* A request to fetch the pipelines will be made.
* In case of a successfull response we will store the data in the provided
* store, in case of a failed response we need to warn the user.
*
*/
beforeMount() {
const element = document.querySelector('#commit-pipeline-table-view');
this.endpoint = element.dataset.endpoint;
this.helpPagePath = element.dataset.helpPagePath;
this.service = new PipelinesService(this.endpoint);
this.poll = new Poll({
resource: this.service,
method: 'getPipelines',
successCallback: this.successCallback,
errorCallback: this.errorCallback,
notificationCallback: this.setIsMakingRequest,
});
if (!Visibility.hidden()) {
this.isLoading = true;
this.poll.makeRequest();
} else {
// If tab is not visible we need to make the first request so we don't show the empty
// state without knowing if there are any pipelines
this.fetchPipelines();
}
Visibility.change(() => {
if (!Visibility.hidden()) {
this.poll.restart();
} else {
this.poll.stop();
}
});
eventHub.$on('refreshPipelines', this.fetchPipelines);
},
beforeDestroy() {
eventHub.$off('refreshPipelines');
},
destroyed() {
this.poll.stop();
},
methods: {
fetchPipelines() {
this.isLoading = true;
return this.service.getPipelines()
.then(response => this.successCallback(response))
.catch(() => this.errorCallback());
},
successCallback(resp) {
const response = resp.json();
this.hasMadeRequest = true;
// depending of the endpoint the response can either bring a `pipelines` key or not.
const pipelines = response.pipelines || response;
this.store.storePipelines(pipelines);
this.isLoading = false;
this.updateGraphDropdown = true;
},
errorCallback() {
this.hasError = true;
this.isLoading = false;
this.updateGraphDropdown = false;
},
setIsMakingRequest(isMakingRequest) {
this.isMakingRequest = isMakingRequest;
if (isMakingRequest) {
this.updateGraphDropdown = false;
}
},
},
template: `
<div class="content-list pipelines">
<loading-icon
label="Loading pipelines"
size="3"
v-if="isLoading"
/>
<empty-state
v-if="shouldRenderEmptyState"
:help-page-path="helpPagePath" />
<error-state v-if="shouldRenderErrorState" />
<div
class="table-holder"
v-if="shouldRenderTable">
<pipelines-table-component
:pipelines="state.pipelines"
:service="service"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>
</div>
`,
});

View File

@ -0,0 +1,90 @@
<script>
import PipelinesService from '../../pipelines/services/pipelines_service';
import PipelineStore from '../../pipelines/stores/pipelines_store';
import pipelinesMixin from '../../pipelines/mixins/pipelines';
export default {
props: {
endpoint: {
type: String,
required: true,
},
helpPagePath: {
type: String,
required: true,
},
},
mixins: [
pipelinesMixin,
],
data() {
const store = new PipelineStore();
return {
store,
state: store.state,
};
},
computed: {
/**
* Empty state is only rendered if after the first request we receive no pipelines.
*
* @return {Boolean}
*/
shouldRenderEmptyState() {
return !this.state.pipelines.length &&
!this.isLoading &&
this.hasMadeRequest &&
!this.hasError;
},
shouldRenderTable() {
return !this.isLoading &&
this.state.pipelines.length > 0 &&
!this.hasError;
},
},
created() {
this.service = new PipelinesService(this.endpoint);
},
methods: {
successCallback(resp) {
const response = resp.json();
// depending of the endpoint the response can either bring a `pipelines` key or not.
const pipelines = response.pipelines || response;
this.setCommonData(pipelines);
},
},
};
</script>
<template>
<div class="content-list pipelines">
<loading-icon
label="Loading pipelines"
size="3"
v-if="isLoading"
/>
<empty-state
v-if="shouldRenderEmptyState"
:help-page-path="helpPagePath"
/>
<error-state
v-if="shouldRenderErrorState"
/>
<div
class="table-holder"
v-if="shouldRenderTable">
<pipelines-table-component
:pipelines="state.pipelines"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>
</div>
</template>

View File

@ -3,10 +3,12 @@
/* global Flash */
/* global notes */
import Vue from 'vue';
import Cookies from 'js-cookie';
import './breakpoints';
import './flash';
import BlobForkSuggestion from './blob/blob_fork_suggestion';
import commitPipelinesTable from './commit/pipelines/pipelines_table.vue';
/* eslint-disable max-len */
// MergeRequestTabs
@ -233,11 +235,18 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
}
mountPipelinesView() {
this.commitPipelinesTable = new gl.CommitPipelinesTable().$mount();
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
const CommitPipelinesTable = Vue.extend(commitPipelinesTable);
this.commitPipelinesTable = new CommitPipelinesTable({
propsData: {
endpoint: pipelineTableViewEl.dataset.endpoint,
helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
},
}).$mount();
// $mount(el) replaces the el with the new rendered component. We need it in order to mount
// it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
document.querySelector('#commit-pipeline-table-view')
.appendChild(this.commitPipelinesTable.$el);
pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
}
loadDiff(source) {

View File

@ -1,9 +1,9 @@
<script>
/* eslint-disable no-new, no-alert */
/* global Flash */
import '~/flash';
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import tooltipMixin from '../../vue_shared/mixins/tooltip';
export default {
props: {
@ -11,53 +11,42 @@ export default {
type: String,
required: true,
},
service: {
type: Object,
required: true,
},
title: {
type: String,
required: true,
},
icon: {
type: String,
required: true,
},
cssClass: {
type: String,
required: true,
},
confirmActionMessage: {
type: String,
required: false,
},
},
components: {
loadingIcon,
},
mixins: [
tooltipMixin,
],
data() {
return {
isLoading: false,
};
},
computed: {
iconClass() {
return `fa fa-${this.icon}`;
},
buttonClass() {
return `btn has-tooltip ${this.cssClass}`;
return `btn ${this.cssClass}`;
},
},
methods: {
onClick() {
if (this.confirmActionMessage && confirm(this.confirmActionMessage)) {
@ -66,21 +55,11 @@ export default {
this.makeRequest();
}
},
makeRequest() {
this.isLoading = true;
$(this.$el).tooltip('destroy');
this.service.postAction(this.endpoint)
.then(() => {
this.isLoading = false;
eventHub.$emit('refreshPipelines');
})
.catch(() => {
this.isLoading = false;
new Flash('An error occured while making the request.');
});
$(this.$refs.tooltip).tooltip('destroy');
eventHub.$emit('postAction', this.endpoint);
},
},
};
@ -95,10 +74,12 @@ export default {
:aria-label="title"
data-container="body"
data-placement="top"
ref="tooltip"
:disabled="isLoading">
<i
:class="iconClass"
aria-hidden="true" />
aria-hidden="true">
</i>
<loading-icon v-if="isLoading" />
</button>
</template>

View File

@ -1,15 +1,9 @@
<script>
import Visibility from 'visibilityjs';
import PipelinesService from '../services/pipelines_service';
import eventHub from '../event_hub';
import pipelinesTableComponent from '../../vue_shared/components/pipelines_table.vue';
import pipelinesMixin from '../mixins/pipelines';
import tablePagination from '../../vue_shared/components/table_pagination.vue';
import emptyState from './empty_state.vue';
import errorState from './error_state.vue';
import navigationTabs from './navigation_tabs.vue';
import navigationControls from './nav_controls.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import Poll from '../../lib/utils/poll';
export default {
props: {
@ -20,13 +14,12 @@
},
components: {
tablePagination,
pipelinesTableComponent,
emptyState,
errorState,
navigationTabs,
navigationControls,
loadingIcon,
},
mixins: [
pipelinesMixin,
],
data() {
const pipelinesData = document.querySelector('#pipelines-list-vue').dataset;
@ -47,11 +40,6 @@
state: this.store.state,
apiScope: 'all',
pagenum: 1,
isLoading: false,
hasError: false,
isMakingRequest: false,
updateGraphDropdown: false,
hasMadeRequest: false,
};
},
computed: {
@ -62,9 +50,6 @@
const scope = gl.utils.getParameterByName('scope');
return scope === null ? 'all' : scope;
},
shouldRenderErrorState() {
return this.hasError && !this.isLoading;
},
/**
* The empty state should only be rendered when the request is made to fetch all pipelines
@ -106,7 +91,6 @@
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage;
},
hasCiEnabled() {
return this.hasCi !== undefined;
},
@ -129,37 +113,7 @@
},
created() {
this.service = new PipelinesService(this.endpoint);
const poll = new Poll({
resource: this.service,
method: 'getPipelines',
data: { page: this.pageParameter, scope: this.scopeParameter },
successCallback: this.successCallback,
errorCallback: this.errorCallback,
notificationCallback: this.setIsMakingRequest,
});
if (!Visibility.hidden()) {
this.isLoading = true;
poll.makeRequest();
} else {
// If tab is not visible we need to make the first request so we don't show the empty
// state without knowing if there are any pipelines
this.fetchPipelines();
}
Visibility.change(() => {
if (!Visibility.hidden()) {
poll.restart();
} else {
poll.stop();
}
});
eventHub.$on('refreshPipelines', this.fetchPipelines);
},
beforeDestroy() {
eventHub.$off('refreshPipelines');
this.requestData = { page: this.pageParameter, scope: this.scopeParameter };
},
methods: {
/**
@ -174,15 +128,6 @@
return param;
},
fetchPipelines() {
if (!this.isMakingRequest) {
this.isLoading = true;
this.service.getPipelines({ scope: this.scopeParameter, page: this.pageParameter })
.then(response => this.successCallback(response))
.catch(() => this.errorCallback());
}
},
successCallback(resp) {
const response = {
headers: resp.headers,
@ -190,33 +135,14 @@
};
this.store.storeCount(response.body.count);
this.store.storePipelines(response.body.pipelines);
this.store.storePagination(response.headers);
this.isLoading = false;
this.updateGraphDropdown = true;
this.hasMadeRequest = true;
},
errorCallback() {
this.hasError = true;
this.isLoading = false;
this.updateGraphDropdown = false;
},
setIsMakingRequest(isMakingRequest) {
this.isMakingRequest = isMakingRequest;
if (isMakingRequest) {
this.updateGraphDropdown = false;
}
this.setCommonData(response.body.pipelines);
},
},
};
</script>
<template>
<div :class="cssClass">
<div
class="top-area scrolling-tabs-container inner-page-scroll-tabs"
v-if="!isLoading && !shouldRenderEmptyState">
@ -274,7 +200,6 @@
<pipelines-table-component
:pipelines="state.pipelines"
:service="service"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>

View File

@ -11,10 +11,6 @@
type: Array,
required: true,
},
service: {
type: Object,
required: true,
},
},
components: {
loadingIcon,
@ -31,17 +27,9 @@
$(this.$refs.tooltip).tooltip('destroy');
this.service.postAction(endpoint)
.then(() => {
this.isLoading = false;
eventHub.$emit('refreshPipelines');
})
.catch(() => {
this.isLoading = false;
// eslint-disable-next-line no-new
new Flash('An error occured while making the request.');
});
eventHub.$emit('postAction', endpoint);
},
isActionDisabled(action) {
if (action.playable === undefined) {
return false;

View File

@ -12,10 +12,6 @@
type: Array,
required: true,
},
service: {
type: Object,
required: true,
},
updateGraphDropdown: {
type: Boolean,
required: false,
@ -57,7 +53,6 @@
v-for="model in pipelines"
:key="model.id"
:pipeline="model"
:service="service"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>

View File

@ -1,13 +1,13 @@
<script>
/* eslint-disable no-param-reassign */
import asyncButtonComponent from '../../pipelines/components/async_button.vue';
import pipelinesActionsComponent from '../../pipelines/components/pipelines_actions.vue';
import pipelinesArtifactsComponent from '../../pipelines/components/pipelines_artifacts.vue';
import ciBadge from './ci_badge_link.vue';
import pipelineStage from '../../pipelines/components/stage.vue';
import pipelineUrl from '../../pipelines/components/pipeline_url.vue';
import pipelinesTimeago from '../../pipelines/components/time_ago.vue';
import commitComponent from './commit.vue';
import asyncButtonComponent from './async_button.vue';
import pipelinesActionsComponent from './pipelines_actions.vue';
import pipelinesArtifactsComponent from './pipelines_artifacts.vue';
import ciBadge from '../../vue_shared/components/ci_badge_link.vue';
import pipelineStage from './stage.vue';
import pipelineUrl from './pipeline_url.vue';
import pipelinesTimeago from './time_ago.vue';
import commitComponent from '../../vue_shared/components/commit.vue';
/**
* Pipeline table row.
@ -20,10 +20,6 @@ export default {
type: Object,
required: true,
},
service: {
type: Object,
required: true,
},
updateGraphDropdown: {
type: Boolean,
required: false,
@ -271,7 +267,6 @@ export default {
<pipelines-actions-component
v-if="pipeline.details.manual_actions.length"
:actions="pipeline.details.manual_actions"
:service="service"
/>
<pipelines-artifacts-component
@ -282,7 +277,6 @@ export default {
<async-button-component
v-if="pipeline.flags.retryable"
:service="service"
:endpoint="pipeline.retry_path"
css-class="js-pipelines-retry-button btn-default btn-retry"
title="Retry"
@ -291,7 +285,6 @@ export default {
<async-button-component
v-if="pipeline.flags.cancelable"
:service="service"
:endpoint="pipeline.cancel_path"
css-class="js-pipelines-cancel-button btn-remove"
title="Cancel"

View File

@ -0,0 +1,103 @@
/* global Flash */
import '~/flash';
import Visibility from 'visibilityjs';
import Poll from '../../lib/utils/poll';
import emptyState from '../components/empty_state.vue';
import errorState from '../components/error_state.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import pipelinesTableComponent from '../components/pipelines_table.vue';
import eventHub from '../event_hub';
export default {
components: {
pipelinesTableComponent,
errorState,
emptyState,
loadingIcon,
},
computed: {
shouldRenderErrorState() {
return this.hasError && !this.isLoading;
},
},
data() {
return {
isLoading: false,
hasError: false,
isMakingRequest: false,
updateGraphDropdown: false,
hasMadeRequest: false,
};
},
beforeMount() {
this.poll = new Poll({
resource: this.service,
method: 'getPipelines',
data: this.requestData ? this.requestData : undefined,
successCallback: this.successCallback,
errorCallback: this.errorCallback,
notificationCallback: this.setIsMakingRequest,
});
if (!Visibility.hidden()) {
this.isLoading = true;
this.poll.makeRequest();
} else {
// If tab is not visible we need to make the first request so we don't show the empty
// state without knowing if there are any pipelines
this.fetchPipelines();
}
Visibility.change(() => {
if (!Visibility.hidden()) {
this.poll.restart();
} else {
this.poll.stop();
}
});
eventHub.$on('refreshPipelines', this.fetchPipelines);
eventHub.$on('postAction', this.postAction);
},
beforeDestroy() {
eventHub.$off('refreshPipelines');
eventHub.$on('postAction', this.postAction);
},
destroyed() {
this.poll.stop();
},
methods: {
fetchPipelines() {
if (!this.isMakingRequest) {
this.isLoading = true;
this.service.getPipelines(this.requestData)
.then(response => this.successCallback(response))
.catch(() => this.errorCallback());
}
},
setCommonData(pipelines) {
this.store.storePipelines(pipelines);
this.isLoading = false;
this.updateGraphDropdown = true;
this.hasMadeRequest = true;
},
errorCallback() {
this.hasError = true;
this.isLoading = false;
this.updateGraphDropdown = false;
},
setIsMakingRequest(isMakingRequest) {
this.isMakingRequest = isMakingRequest;
if (isMakingRequest) {
this.updateGraphDropdown = false;
}
},
postAction(endpoint) {
this.service.postAction(endpoint)
.then(() => eventHub.$emit('refreshPipelines'))
.catch(() => new Flash('An error occured while making the request.'));
},
},
};

View File

@ -1,15 +1,15 @@
import Vue from 'vue';
import PipelinesTable from '~/commit/pipelines/pipelines_table';
import pipelinesTable from '~/commit/pipelines/pipelines_table.vue';
describe('Pipelines table in Commits and Merge requests', () => {
const jsonFixtureName = 'pipelines/pipelines.json';
let pipeline;
let PipelinesTable;
preloadFixtures('static/pipelines_table.html.raw');
preloadFixtures(jsonFixtureName);
beforeEach(() => {
loadFixtures('static/pipelines_table.html.raw');
PipelinesTable = Vue.extend(pipelinesTable);
const pipelines = getJSONFixture(jsonFixtureName).pipelines;
pipeline = pipelines.find(p => p.id === 1);
});
@ -26,8 +26,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesEmptyResponse);
this.component = new PipelinesTable({
el: document.querySelector('#commit-pipeline-table-view'),
});
propsData: {
endpoint: 'endpoint',
helpPagePath: 'foo',
},
}).$mount();
});
afterEach(function () {
@ -58,8 +61,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesResponse);
this.component = new PipelinesTable({
el: document.querySelector('#commit-pipeline-table-view'),
});
propsData: {
endpoint: 'endpoint',
helpPagePath: 'foo',
},
}).$mount();
});
afterEach(() => {
@ -92,8 +98,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesErrorResponse);
this.component = new PipelinesTable({
el: document.querySelector('#commit-pipeline-table-view'),
});
propsData: {
endpoint: 'endpoint',
helpPagePath: 'foo',
},
}).$mount();
});
afterEach(function () {

View File

@ -1 +0,0 @@
#commit-pipeline-table-view{ data: { endpoint: "endpoint", "help-page-path": "foo" } }

View File

@ -1,25 +1,20 @@
import Vue from 'vue';
import asyncButtonComp from '~/pipelines/components/async_button.vue';
import eventHub from '~/pipelines/event_hub';
describe('Pipelines Async Button', () => {
let component;
let spy;
let AsyncButtonComponent;
beforeEach(() => {
AsyncButtonComponent = Vue.extend(asyncButtonComp);
spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
component = new AsyncButtonComponent({
propsData: {
endpoint: '/foo',
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
service: {
postAction: spy,
},
},
}).$mount();
});
@ -33,7 +28,7 @@ describe('Pipelines Async Button', () => {
});
it('should render the provided title', () => {
expect(component.$el.getAttribute('title')).toContain('Foo');
expect(component.$el.getAttribute('data-original-title')).toContain('Foo');
expect(component.$el.getAttribute('aria-label')).toContain('Foo');
});
@ -41,37 +36,12 @@ describe('Pipelines Async Button', () => {
expect(component.$el.getAttribute('class')).toContain('bar');
});
it('should call the service when it is clicked with the provided endpoint', () => {
component.$el.click();
expect(spy).toHaveBeenCalledWith('/foo');
});
it('should hide loading if request fails', () => {
spy = jasmine.createSpy('spy').and.returnValue(Promise.reject());
component = new AsyncButtonComponent({
propsData: {
endpoint: '/foo',
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
dataAttributes: {
'data-foo': 'foo',
},
service: {
postAction: spy,
},
},
}).$mount();
component.$el.click();
expect(component.$el.querySelector('.fa-spinner')).toBe(null);
});
describe('With confirm dialog', () => {
it('should call the service when confimation is positive', () => {
spyOn(window, 'confirm').and.returnValue(true);
spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
eventHub.$on('postAction', (endpoint) => {
expect(endpoint).toEqual('/foo');
});
component = new AsyncButtonComponent({
propsData: {
@ -79,15 +49,11 @@ describe('Pipelines Async Button', () => {
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
service: {
postAction: spy,
},
confirmActionMessage: 'bar',
},
}).$mount();
component.$el.click();
expect(spy).toHaveBeenCalledWith('/foo');
});
});
});

View File

@ -3,7 +3,6 @@ import pipelinesActionsComp from '~/pipelines/components/pipelines_actions.vue';
describe('Pipelines Actions dropdown', () => {
let component;
let spy;
let actions;
let ActionsComponent;
@ -22,14 +21,9 @@ describe('Pipelines Actions dropdown', () => {
},
];
spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
component = new ActionsComponent({
propsData: {
actions,
service: {
postAction: spy,
},
},
}).$mount();
});
@ -40,31 +34,6 @@ describe('Pipelines Actions dropdown', () => {
).toEqual(actions.length);
});
it('should call the service when an action is clicked', () => {
component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click();
component.$el.querySelector('.js-pipeline-action-link').click();
expect(spy).toHaveBeenCalledWith(actions[0].path);
});
it('should hide loading if request fails', () => {
spy = jasmine.createSpy('spy').and.returnValue(Promise.reject());
component = new ActionsComponent({
propsData: {
actions,
service: {
postAction: spy,
},
},
}).$mount();
component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click();
component.$el.querySelector('.js-pipeline-action-link').click();
expect(component.$el.querySelector('.fa-spinner')).toEqual(null);
});
it('should render a disabled action when it\'s not playable', () => {
expect(
component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'),

View File

@ -1,5 +1,5 @@
import Vue from 'vue';
import tableRowComp from '~/vue_shared/components/pipelines_table_row.vue';
import tableRowComp from '~/pipelines/components/pipelines_table_row.vue';
describe('Pipelines Table Row', () => {
const jsonFixtureName = 'pipelines/pipelines.json';

View File

@ -1,5 +1,5 @@
import Vue from 'vue';
import pipelinesTableComp from '~/vue_shared/components/pipelines_table.vue';
import pipelinesTableComp from '~/pipelines/components/pipelines_table.vue';
import '~/lib/utils/datetime_utility';
describe('Pipelines Table', () => {
@ -22,7 +22,6 @@ describe('Pipelines Table', () => {
component = new PipelinesTableComponent({
propsData: {
pipelines: [],
service: {},
},
}).$mount();
});
@ -48,7 +47,6 @@ describe('Pipelines Table', () => {
const component = new PipelinesTableComponent({
propsData: {
pipelines: [],
service: {},
},
}).$mount();
expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0);
@ -58,10 +56,8 @@ describe('Pipelines Table', () => {
describe('with data', () => {
it('should render rows', () => {
const component = new PipelinesTableComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
pipelines: [pipeline],
service: {},
},
}).$mount();