Resolve "Show CI pipeline status in Web IDE"
This commit is contained in:
parent
de12348ee8
commit
c53890548e
|
@ -21,6 +21,7 @@ const Api = {
|
||||||
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
|
||||||
usersPath: '/api/:version/users.json',
|
usersPath: '/api/:version/users.json',
|
||||||
commitPath: '/api/:version/projects/:id/repository/commits',
|
commitPath: '/api/:version/projects/:id/repository/commits',
|
||||||
|
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
|
||||||
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
|
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
|
||||||
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
createBranchPath: '/api/:version/projects/:id/repository/branches',
|
||||||
pipelinesPath: '/api/:version/projects/:id/pipelines',
|
pipelinesPath: '/api/:version/projects/:id/pipelines',
|
||||||
|
@ -166,6 +167,19 @@ const Api = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
commitPipelines(projectId, sha) {
|
||||||
|
const encodedProjectId = projectId
|
||||||
|
.split('/')
|
||||||
|
.map(fragment => encodeURIComponent(fragment))
|
||||||
|
.join('/');
|
||||||
|
|
||||||
|
const url = Api.buildUrl(Api.commitPipelinesPath)
|
||||||
|
.replace(':project_id', encodedProjectId)
|
||||||
|
.replace(':sha', encodeURIComponent(sha));
|
||||||
|
|
||||||
|
return axios.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
branchSingle(id, branch) {
|
branchSingle(id, branch) {
|
||||||
const url = Api.buildUrl(Api.branchSinglePath)
|
const url = Api.buildUrl(Api.branchSinglePath)
|
||||||
.replace(':id', encodeURIComponent(id))
|
.replace(':id', encodeURIComponent(id))
|
||||||
|
|
|
@ -123,8 +123,6 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ide-status-bar
|
<ide-status-bar :file="activeFile"/>
|
||||||
:file="activeFile"
|
|
||||||
/>
|
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapActions, mapState, mapGetters } from 'vuex';
|
||||||
import icon from '~/vue_shared/components/icon.vue';
|
import icon from '~/vue_shared/components/icon.vue';
|
||||||
import tooltip from '~/vue_shared/directives/tooltip';
|
import tooltip from '~/vue_shared/directives/tooltip';
|
||||||
import timeAgoMixin from '~/vue_shared/mixins/timeago';
|
import timeAgoMixin from '~/vue_shared/mixins/timeago';
|
||||||
|
import CiIcon from '../../vue_shared/components/ci_icon.vue';
|
||||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
icon,
|
icon,
|
||||||
userAvatarImage,
|
userAvatarImage,
|
||||||
|
CiIcon,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
tooltip,
|
tooltip,
|
||||||
|
@ -27,8 +29,16 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState(['currentBranchId', 'currentProjectId']),
|
||||||
...mapGetters(['currentProject', 'lastCommit']),
|
...mapGetters(['currentProject', 'lastCommit']),
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
lastCommit() {
|
||||||
|
if (!this.isPollingInitialized) {
|
||||||
|
this.initPipelinePolling();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
},
|
},
|
||||||
|
@ -36,13 +46,21 @@ export default {
|
||||||
if (this.intervalId) {
|
if (this.intervalId) {
|
||||||
clearInterval(this.intervalId);
|
clearInterval(this.intervalId);
|
||||||
}
|
}
|
||||||
|
if (this.isPollingInitialized) {
|
||||||
|
this.stopPipelinePolling();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions(['pipelinePoll', 'stopPipelinePolling']),
|
||||||
startTimer() {
|
startTimer() {
|
||||||
this.intervalId = setInterval(() => {
|
this.intervalId = setInterval(() => {
|
||||||
this.commitAgeUpdate();
|
this.commitAgeUpdate();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
},
|
},
|
||||||
|
initPipelinePolling() {
|
||||||
|
this.pipelinePoll();
|
||||||
|
this.isPollingInitialized = true;
|
||||||
|
},
|
||||||
commitAgeUpdate() {
|
commitAgeUpdate() {
|
||||||
if (this.lastCommit) {
|
if (this.lastCommit) {
|
||||||
this.lastCommitFormatedAge = this.timeFormated(this.lastCommit.committed_date);
|
this.lastCommitFormatedAge = this.timeFormated(this.lastCommit.committed_date);
|
||||||
|
@ -61,6 +79,23 @@ export default {
|
||||||
class="ide-status-branch"
|
class="ide-status-branch"
|
||||||
v-if="lastCommit && lastCommitFormatedAge"
|
v-if="lastCommit && lastCommitFormatedAge"
|
||||||
>
|
>
|
||||||
|
<span
|
||||||
|
class="ide-status-pipeline"
|
||||||
|
v-if="lastCommit.pipeline && lastCommit.pipeline.details"
|
||||||
|
>
|
||||||
|
<ci-icon
|
||||||
|
:status="lastCommit.pipeline.details.status"
|
||||||
|
v-tooltip
|
||||||
|
:title="lastCommit.pipeline.details.status.text"
|
||||||
|
/>
|
||||||
|
Pipeline
|
||||||
|
<a
|
||||||
|
class="monospace"
|
||||||
|
:href="lastCommit.pipeline.details.status.details_path">#{{ lastCommit.pipeline.id }}</a>
|
||||||
|
{{ lastCommit.pipeline.details.status.text }}
|
||||||
|
for
|
||||||
|
</span>
|
||||||
|
|
||||||
<icon
|
<icon
|
||||||
name="commit"
|
name="commit"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -75,4 +75,8 @@ export default {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
lastCommitPipelines({ getters }) {
|
||||||
|
const commitSha = getters.lastCommit.id;
|
||||||
|
return Api.commitPipelines(getters.currentProject.path_with_namespace, commitSha);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
import Visibility from 'visibilityjs';
|
||||||
import flash from '~/flash';
|
import flash from '~/flash';
|
||||||
|
import { __ } from '~/locale';
|
||||||
import service from '../../services';
|
import service from '../../services';
|
||||||
import * as types from '../mutation_types';
|
import * as types from '../mutation_types';
|
||||||
|
import Poll from '../../../lib/utils/poll';
|
||||||
|
|
||||||
|
let eTagPoll;
|
||||||
|
|
||||||
export const getProjectData = (
|
export const getProjectData = (
|
||||||
{ commit, state, dispatch },
|
{ commit, state, dispatch },
|
||||||
|
@ -21,7 +26,7 @@ export const getProjectData = (
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
flash(
|
flash(
|
||||||
'Error loading project data. Please try again.',
|
__('Error loading project data. Please try again.'),
|
||||||
'alert',
|
'alert',
|
||||||
document,
|
document,
|
||||||
null,
|
null,
|
||||||
|
@ -59,7 +64,7 @@ export const getBranchData = (
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
flash(
|
flash(
|
||||||
'Error loading branch data. Please try again.',
|
__('Error loading branch data. Please try again.'),
|
||||||
'alert',
|
'alert',
|
||||||
document,
|
document,
|
||||||
null,
|
null,
|
||||||
|
@ -73,10 +78,8 @@ export const getBranchData = (
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const refreshLastCommitData = (
|
export const refreshLastCommitData = ({ commit, state, dispatch }, { projectId, branchId } = {}) =>
|
||||||
{ commit, state, dispatch },
|
service
|
||||||
{ projectId, branchId } = {},
|
|
||||||
) => service
|
|
||||||
.getBranchData(projectId, branchId)
|
.getBranchData(projectId, branchId)
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
commit(types.SET_BRANCH_COMMIT, {
|
commit(types.SET_BRANCH_COMMIT, {
|
||||||
|
@ -86,12 +89,63 @@ export const refreshLastCommitData = (
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
flash(__('Error loading last commit.'), 'alert', document, null, false, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const pollSuccessCallBack = ({ commit, state, dispatch }, { data }) => {
|
||||||
|
if (data.pipelines && data.pipelines.length) {
|
||||||
|
const lastCommitHash =
|
||||||
|
state.projects[state.currentProjectId].branches[state.currentBranchId].commit.id;
|
||||||
|
const lastCommitPipeline = data.pipelines.find(
|
||||||
|
pipeline => pipeline.commit.id === lastCommitHash,
|
||||||
|
);
|
||||||
|
commit(types.SET_LAST_COMMIT_PIPELINE, {
|
||||||
|
projectId: state.currentProjectId,
|
||||||
|
branchId: state.currentBranchId,
|
||||||
|
pipeline: lastCommitPipeline || {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pipelinePoll = ({ getters, dispatch }) => {
|
||||||
|
eTagPoll = new Poll({
|
||||||
|
resource: service,
|
||||||
|
method: 'lastCommitPipelines',
|
||||||
|
data: {
|
||||||
|
getters,
|
||||||
|
},
|
||||||
|
successCallback: ({ data }) => dispatch('pollSuccessCallBack', { data }),
|
||||||
|
errorCallback: () => {
|
||||||
flash(
|
flash(
|
||||||
'Error loading last commit.',
|
__('Something went wrong while fetching the latest pipeline status.'),
|
||||||
'alert',
|
'alert',
|
||||||
document,
|
document,
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!Visibility.hidden()) {
|
||||||
|
eTagPoll.makeRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
Visibility.change(() => {
|
||||||
|
if (!Visibility.hidden()) {
|
||||||
|
eTagPoll.restart();
|
||||||
|
} else {
|
||||||
|
eTagPoll.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stopPipelinePolling = () => {
|
||||||
|
eTagPoll.stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const restartPipelinePolling = () => {
|
||||||
|
eTagPoll.restart();
|
||||||
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ export const SET_BRANCH = 'SET_BRANCH';
|
||||||
export const SET_BRANCH_COMMIT = 'SET_BRANCH_COMMIT';
|
export const SET_BRANCH_COMMIT = 'SET_BRANCH_COMMIT';
|
||||||
export const SET_BRANCH_WORKING_REFERENCE = 'SET_BRANCH_WORKING_REFERENCE';
|
export const SET_BRANCH_WORKING_REFERENCE = 'SET_BRANCH_WORKING_REFERENCE';
|
||||||
export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN';
|
export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN';
|
||||||
|
export const SET_LAST_COMMIT_PIPELINE = 'SET_LAST_COMMIT_PIPELINE';
|
||||||
|
|
||||||
// Tree mutation types
|
// Tree mutation types
|
||||||
export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
|
export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
|
||||||
|
|
|
@ -14,6 +14,10 @@ export default {
|
||||||
treeId: `${projectPath}/${branchName}`,
|
treeId: `${projectPath}/${branchName}`,
|
||||||
active: true,
|
active: true,
|
||||||
workingReference: '',
|
workingReference: '',
|
||||||
|
commit: {
|
||||||
|
...branch.commit,
|
||||||
|
pipeline: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -28,4 +32,9 @@ export default {
|
||||||
commit,
|
commit,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
[types.SET_LAST_COMMIT_PIPELINE](state, { projectId, branchId, pipeline }) {
|
||||||
|
Object.assign(state.projects[projectId].branches[branchId].commit, {
|
||||||
|
pipeline,
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -230,7 +230,7 @@ $row-hover: $blue-50;
|
||||||
$row-hover-border: $blue-200;
|
$row-hover-border: $blue-200;
|
||||||
$progress-color: #c0392b;
|
$progress-color: #c0392b;
|
||||||
$header-height: 40px;
|
$header-height: 40px;
|
||||||
$ide-statusbar-height: 27px;
|
$ide-statusbar-height: 25px;
|
||||||
$fixed-layout-width: 1280px;
|
$fixed-layout-width: 1280px;
|
||||||
$limited-layout-width: 990px;
|
$limited-layout-width: 990px;
|
||||||
$limited-layout-width-sm: 790px;
|
$limited-layout-width-sm: 790px;
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
height: calc(100vh - #{$header-height});
|
height: calc(100vh - #{$header-height});
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
border-top: 1px solid $white-dark;
|
border-top: 1px solid $white-dark;
|
||||||
border-bottom: 1px solid $white-dark;
|
|
||||||
padding-bottom: $ide-statusbar-height;
|
padding-bottom: $ide-statusbar-height;
|
||||||
|
|
||||||
&.is-collapsed {
|
&.is-collapsed {
|
||||||
|
@ -380,7 +379,7 @@
|
||||||
|
|
||||||
.ide-status-bar {
|
.ide-status-bar {
|
||||||
border-top: 1px solid $white-dark;
|
border-top: 1px solid $white-dark;
|
||||||
padding: $gl-bar-padding $gl-padding;
|
padding: 2px $gl-padding-8 0;
|
||||||
background: $white-light;
|
background: $white-light;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -391,12 +390,19 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
> div + div {
|
> div + div {
|
||||||
padding-left: $gl-padding;
|
padding-left: $gl-padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
vertical-align: middle;
|
vertical-align: sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add pipeline status to the status bar of the Web IDE
|
||||||
|
merge_request:
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -341,4 +341,25 @@ describe('Api', () => {
|
||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('commitPipelines', () => {
|
||||||
|
it('fetches pipelines for a given commit', done => {
|
||||||
|
const projectId = 'example/foobar';
|
||||||
|
const commitSha = 'abc123def';
|
||||||
|
const expectedUrl = `${dummyUrlRoot}/${projectId}/commit/${commitSha}/pipelines`;
|
||||||
|
mock.onGet(expectedUrl).reply(200, [
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
Api.commitPipelines(projectId, commitSha)
|
||||||
|
.then(({ data }) => {
|
||||||
|
expect(data.length).toBe(1);
|
||||||
|
expect(data[0].name).toBe('test');
|
||||||
|
})
|
||||||
|
.then(done)
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,3 +59,37 @@ export const jobs = [
|
||||||
duration: 1,
|
duration: 1,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const fullPipelinesResponse = {
|
||||||
|
data: {
|
||||||
|
count: {
|
||||||
|
all: 2,
|
||||||
|
},
|
||||||
|
pipelines: [
|
||||||
|
{
|
||||||
|
id: '51',
|
||||||
|
commit: {
|
||||||
|
id: 'xxxxxxxxxxxxxxxxxxxx',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
status: {
|
||||||
|
icon: 'status_failed',
|
||||||
|
text: 'failed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '50',
|
||||||
|
commit: {
|
||||||
|
id: 'abc123def456ghi789jkl',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
status: {
|
||||||
|
icon: 'status_passed',
|
||||||
|
text: 'passed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -1,14 +1,33 @@
|
||||||
import {
|
import Visibility from 'visibilityjs';
|
||||||
refreshLastCommitData,
|
import MockAdapter from 'axios-mock-adapter';
|
||||||
} from '~/ide/stores/actions';
|
import { refreshLastCommitData, pollSuccessCallBack } from '~/ide/stores/actions';
|
||||||
import store from '~/ide/stores';
|
import store from '~/ide/stores';
|
||||||
import service from '~/ide/services';
|
import service from '~/ide/services';
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import { fullPipelinesResponse } from '../../mock_data';
|
||||||
import { resetStore } from '../../helpers';
|
import { resetStore } from '../../helpers';
|
||||||
import testAction from '../../../helpers/vuex_action_helper';
|
import testAction from '../../../helpers/vuex_action_helper';
|
||||||
|
|
||||||
describe('IDE store project actions', () => {
|
describe('IDE store project actions', () => {
|
||||||
|
const setProjectState = () => {
|
||||||
|
store.state.currentProjectId = 'abc/def';
|
||||||
|
store.state.currentBranchId = 'master';
|
||||||
|
store.state.projects['abc/def'] = {
|
||||||
|
id: 4,
|
||||||
|
path_with_namespace: 'abc/def',
|
||||||
|
branches: {
|
||||||
|
master: {
|
||||||
|
commit: {
|
||||||
|
id: 'abc123def456ghi789jkl',
|
||||||
|
title: 'example',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store.state.projects.abcproject = {};
|
store.state.projects['abc/def'] = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -17,18 +36,16 @@ describe('IDE store project actions', () => {
|
||||||
|
|
||||||
describe('refreshLastCommitData', () => {
|
describe('refreshLastCommitData', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store.state.currentProjectId = 'abcproject';
|
store.state.currentProjectId = 'abc/def';
|
||||||
store.state.currentBranchId = 'master';
|
store.state.currentBranchId = 'master';
|
||||||
store.state.projects.abcproject = {
|
store.state.projects['abc/def'] = {
|
||||||
|
id: 4,
|
||||||
branches: {
|
branches: {
|
||||||
master: {
|
master: {
|
||||||
commit: null,
|
commit: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
it('calls the service', done => {
|
|
||||||
spyOn(service, 'getBranchData').and.returnValue(
|
spyOn(service, 'getBranchData').and.returnValue(
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
data: {
|
data: {
|
||||||
|
@ -36,14 +53,16 @@ describe('IDE store project actions', () => {
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls the service', done => {
|
||||||
store
|
store
|
||||||
.dispatch('refreshLastCommitData', {
|
.dispatch('refreshLastCommitData', {
|
||||||
projectId: store.state.currentProjectId,
|
projectId: store.state.currentProjectId,
|
||||||
branchId: store.state.currentBranchId,
|
branchId: store.state.currentBranchId,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(service.getBranchData).toHaveBeenCalledWith('abcproject', 'master');
|
expect(service.getBranchData).toHaveBeenCalledWith('abc/def', 'master');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
|
@ -53,16 +72,118 @@ describe('IDE store project actions', () => {
|
||||||
it('commits getBranchData', done => {
|
it('commits getBranchData', done => {
|
||||||
testAction(
|
testAction(
|
||||||
refreshLastCommitData,
|
refreshLastCommitData,
|
||||||
{},
|
{
|
||||||
{},
|
projectId: store.state.currentProjectId,
|
||||||
[{
|
branchId: store.state.currentBranchId,
|
||||||
|
},
|
||||||
|
store.state,
|
||||||
|
[
|
||||||
|
{
|
||||||
type: 'SET_BRANCH_COMMIT',
|
type: 'SET_BRANCH_COMMIT',
|
||||||
payload: {
|
payload: {
|
||||||
projectId: 'abcproject',
|
projectId: 'abc/def',
|
||||||
branchId: 'master',
|
branchId: 'master',
|
||||||
commit: { id: '123' },
|
commit: { id: '123' },
|
||||||
},
|
},
|
||||||
}], // mutations
|
},
|
||||||
|
], // mutations
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: 'getLastCommitPipeline',
|
||||||
|
payload: {
|
||||||
|
projectId: 'abc/def',
|
||||||
|
projectIdNumber: store.state.projects['abc/def'].id,
|
||||||
|
branchId: 'master',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
], // action
|
||||||
|
done,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pipelinePoll', () => {
|
||||||
|
let mock;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setProjectState();
|
||||||
|
jasmine.clock().install();
|
||||||
|
mock = new MockAdapter(axios);
|
||||||
|
mock
|
||||||
|
.onGet('/abc/def/commit/abc123def456ghi789jkl/pipelines')
|
||||||
|
.reply(200, { data: { foo: 'bar' } }, { 'poll-interval': '10000' });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jasmine.clock().uninstall();
|
||||||
|
mock.restore();
|
||||||
|
store.dispatch('stopPipelinePolling');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls service periodically', done => {
|
||||||
|
spyOn(axios, 'get').and.callThrough();
|
||||||
|
spyOn(Visibility, 'hidden').and.returnValue(false);
|
||||||
|
|
||||||
|
store
|
||||||
|
.dispatch('pipelinePoll')
|
||||||
|
.then(() => {
|
||||||
|
jasmine.clock().tick(1000);
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalled();
|
||||||
|
expect(axios.get.calls.count()).toBe(1);
|
||||||
|
})
|
||||||
|
.then(() => new Promise(resolve => requestAnimationFrame(resolve)))
|
||||||
|
.then(() => {
|
||||||
|
jasmine.clock().tick(10000);
|
||||||
|
expect(axios.get.calls.count()).toBe(2);
|
||||||
|
})
|
||||||
|
.then(() => new Promise(resolve => requestAnimationFrame(resolve)))
|
||||||
|
.then(() => {
|
||||||
|
jasmine.clock().tick(10000);
|
||||||
|
expect(axios.get.calls.count()).toBe(3);
|
||||||
|
})
|
||||||
|
.then(() => new Promise(resolve => requestAnimationFrame(resolve)))
|
||||||
|
.then(() => {
|
||||||
|
jasmine.clock().tick(10000);
|
||||||
|
expect(axios.get.calls.count()).toBe(4);
|
||||||
|
})
|
||||||
|
|
||||||
|
.then(done)
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pollSuccessCallBack', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setProjectState();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('commits correct pipeline', done => {
|
||||||
|
testAction(
|
||||||
|
pollSuccessCallBack,
|
||||||
|
fullPipelinesResponse,
|
||||||
|
store.state,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: 'SET_LAST_COMMIT_PIPELINE',
|
||||||
|
payload: {
|
||||||
|
projectId: 'abc/def',
|
||||||
|
branchId: 'master',
|
||||||
|
pipeline: {
|
||||||
|
id: '50',
|
||||||
|
commit: {
|
||||||
|
id: 'abc123def456ghi789jkl',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
status: {
|
||||||
|
icon: 'status_passed',
|
||||||
|
text: 'passed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
], // mutations
|
||||||
[], // action
|
[], // action
|
||||||
done,
|
done,
|
||||||
);
|
);
|
||||||
|
|
|
@ -37,4 +37,40 @@ describe('Multi-file store branch mutations', () => {
|
||||||
expect(localState.projects.Example.branches.master.commit.title).toBe('Example commit');
|
expect(localState.projects.Example.branches.master.commit.title).toBe('Example commit');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('SET_LAST_COMMIT_PIPELINE', () => {
|
||||||
|
it('sets the pipeline for the last commit on current project', () => {
|
||||||
|
localState.projects = {
|
||||||
|
Example: {
|
||||||
|
branches: {
|
||||||
|
master: {
|
||||||
|
commit: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mutations.SET_LAST_COMMIT_PIPELINE(localState, {
|
||||||
|
projectId: 'Example',
|
||||||
|
branchId: 'master',
|
||||||
|
pipeline: {
|
||||||
|
id: '50',
|
||||||
|
details: {
|
||||||
|
status: {
|
||||||
|
icon: 'status_passed',
|
||||||
|
text: 'passed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(localState.projects.Example.branches.master.commit.pipeline.id).toBe('50');
|
||||||
|
expect(localState.projects.Example.branches.master.commit.pipeline.details.status.text).toBe(
|
||||||
|
'passed',
|
||||||
|
);
|
||||||
|
expect(localState.projects.Example.branches.master.commit.pipeline.details.status.icon).toBe(
|
||||||
|
'status_passed',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue