summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/ide/components/jobs/list.vue6
-rw-r--r--app/assets/javascripts/ide/components/jobs/stage.vue12
-rw-r--r--app/assets/javascripts/ide/stores/modules/pipelines/mutations.js26
-rw-r--r--spec/javascripts/ide/components/jobs/list_spec.js24
-rw-r--r--spec/javascripts/ide/components/jobs/stage_spec.js62
5 files changed, 81 insertions, 49 deletions
diff --git a/app/assets/javascripts/ide/components/jobs/list.vue b/app/assets/javascripts/ide/components/jobs/list.vue
index fd6bfdf86d0..bdd0364c9b9 100644
--- a/app/assets/javascripts/ide/components/jobs/list.vue
+++ b/app/assets/javascripts/ide/components/jobs/list.vue
@@ -1,4 +1,5 @@
<script>
+import { mapActions } from 'vuex';
import LoadingIcon from '../../../vue_shared/components/loading_icon.vue';
import Stage from './stage.vue';
@@ -17,6 +18,9 @@ export default {
required: true,
},
},
+ methods: {
+ ...mapActions('pipelines', ['fetchJobs', 'toggleStageCollapsed']),
+ },
};
</script>
@@ -32,6 +36,8 @@ export default {
v-for="stage in stages"
:key="stage.id"
:stage="stage"
+ @fetch="fetchJobs"
+ @toggleCollapsed="toggleStageCollapsed"
/>
</template>
</div>
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue
index 370bb61bae8..5b24bb1f5a7 100644
--- a/app/assets/javascripts/ide/components/jobs/stage.vue
+++ b/app/assets/javascripts/ide/components/jobs/stage.vue
@@ -1,5 +1,4 @@
<script>
-import { mapActions } from 'vuex';
import tooltip from '../../../vue_shared/directives/tooltip';
import Icon from '../../../vue_shared/components/icon.vue';
import CiIcon from '../../../vue_shared/components/ci_icon.vue';
@@ -38,16 +37,17 @@ export default {
return this.stage.jobs.length;
},
},
- created() {
- this.fetchJobs(this.stage);
- },
mounted() {
const { stageTitle } = this.$refs;
this.showTooltip = stageTitle.scrollWidth > stageTitle.offsetWidth;
+
+ this.$emit('fetch', this.stage);
},
methods: {
- ...mapActions('pipelines', ['fetchJobs', 'toggleStageCollapsed']),
+ toggleCollapsed() {
+ this.$emit('toggleCollapsed', this.stage.id);
+ },
},
};
</script>
@@ -61,7 +61,7 @@ export default {
:class="{
'border-bottom-0': stage.isCollapsed
}"
- @click="toggleStageCollapsed(stage.id)"
+ @click="toggleCollapsed"
>
<ci-icon
:status="stage.status"
diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/mutations.js b/app/assets/javascripts/ide/stores/modules/pipelines/mutations.js
index 38459dfbe77..3c50279642b 100644
--- a/app/assets/javascripts/ide/stores/modules/pipelines/mutations.js
+++ b/app/assets/javascripts/ide/stores/modules/pipelines/mutations.js
@@ -39,20 +39,28 @@ export default {
}
},
[types.REQUEST_JOBS](state, id) {
- const stage = state.stages.find(s => s.id === id);
- stage.isLoading = true;
+ state.stages = state.stages.map(stage => ({
+ ...stage,
+ isLoading: stage.id === id ? true : stage.isLoading,
+ }));
},
[types.RECEIVE_JOBS_ERROR](state, id) {
- const stage = state.stages.find(s => s.id === id);
- stage.isLoading = false;
+ state.stages = state.stages.map(stage => ({
+ ...stage,
+ isLoading: stage.id === id ? false : stage.isLoading,
+ }));
},
[types.RECEIVE_JOBS_SUCCESS](state, { id, data }) {
- const stage = state.stages.find(s => s.id === id);
- stage.isLoading = false;
- stage.jobs = data.latest_statuses.map(normalizeJob);
+ state.stages = state.stages.map(stage => ({
+ ...stage,
+ isLoading: stage.id === id ? false : stage.isLoading,
+ jobs: data.latest_statuses.map(normalizeJob),
+ }));
},
[types.TOGGLE_STAGE_COLLAPSE](state, id) {
- const stage = state.stages.find(s => s.id === id);
- stage.isCollapsed = !stage.isCollapsed;
+ state.stages = state.stages.map(stage => ({
+ ...stage,
+ isCollapsed: stage.id === id ? !stage.isCollapsed : stage.isCollapsed,
+ }));
},
};
diff --git a/spec/javascripts/ide/components/jobs/list_spec.js b/spec/javascripts/ide/components/jobs/list_spec.js
index 484cab3c135..b24853c56fa 100644
--- a/spec/javascripts/ide/components/jobs/list_spec.js
+++ b/spec/javascripts/ide/components/jobs/list_spec.js
@@ -21,7 +21,12 @@ describe('IDE stages list', () => {
isCollapsed: false,
})),
loading: false,
- }).$mount();
+ });
+
+ spyOn(vm, 'fetchJobs');
+ spyOn(vm, 'toggleStageCollapsed');
+
+ vm.$mount();
});
afterEach(() => {
@@ -42,4 +47,21 @@ describe('IDE stages list', () => {
done();
});
});
+
+ it('calls toggleStageCollapsed when clicking stage header', done => {
+ vm.$el.querySelector('.card-header').click();
+
+ vm.$nextTick(() => {
+ expect(vm.toggleStageCollapsed).toHaveBeenCalledWith(0);
+
+ done();
+ });
+ });
+
+ it('calls fetchJobs when stage is mounted', () => {
+ expect(vm.fetchJobs.calls.count()).toBe(stages.length);
+
+ expect(vm.fetchJobs.calls.argsFor(0)).toEqual([vm.stages[0]]);
+ expect(vm.fetchJobs.calls.argsFor(1)).toEqual([vm.stages[1]]);
+ });
});
diff --git a/spec/javascripts/ide/components/jobs/stage_spec.js b/spec/javascripts/ide/components/jobs/stage_spec.js
index 5496c57bbb7..fc3831f2d05 100644
--- a/spec/javascripts/ide/components/jobs/stage_spec.js
+++ b/spec/javascripts/ide/components/jobs/stage_spec.js
@@ -1,51 +1,37 @@
import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import { createStore } from '~/ide/stores';
import Stage from '~/ide/components/jobs/stage.vue';
-import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
import { stages, jobs } from '../../mock_data';
describe('IDE pipeline stage', () => {
const Component = Vue.extend(Stage);
let vm;
- let mock;
let stage;
- beforeEach(done => {
- const store = createStore();
- mock = new MockAdapter(axios);
-
- Vue.set(
- store.state.pipelines,
- 'stages',
- stages.map((mappedState, i) => ({
- ...mappedState,
- id: i,
- dropdownPath: mappedState.dropdown_path,
- jobs: [],
- isLoading: false,
- isCollapsed: false,
- })),
- );
-
- stage = store.state.pipelines.stages[0];
-
- mock.onGet(stage.dropdownPath).reply(200, {
- latest_statuses: jobs,
+ beforeEach(() => {
+ stage = {
+ ...stages[0],
+ id: 0,
+ dropdownPath: stages[0].dropdown_path,
+ jobs: [...jobs],
+ isLoading: false,
+ isCollapsed: false,
+ };
+
+ vm = new Component({
+ propsData: { stage },
});
- vm = createComponentWithStore(Component, store, {
- stage,
- }).$mount();
+ spyOn(vm, '$emit');
- setTimeout(done, 500);
+ vm.$mount();
});
afterEach(() => {
vm.$destroy();
+ });
- mock.restore();
+ it('emits fetch event when mounted', () => {
+ expect(vm.$emit).toHaveBeenCalledWith('fetch', vm.stage);
});
it('renders stages details', () => {
@@ -57,10 +43,20 @@ describe('IDE pipeline stage', () => {
});
describe('collapsed', () => {
- it('toggles collapse status when clicking header', done => {
+ it('emits event when clicking header', done => {
vm.$el.querySelector('.card-header').click();
vm.$nextTick(() => {
+ expect(vm.$emit).toHaveBeenCalledWith('toggleCollapsed', vm.stage.id);
+
+ done();
+ });
+ });
+
+ it('toggles collapse status when collapsed', done => {
+ vm.stage.isCollapsed = true;
+
+ vm.$nextTick(() => {
expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
done();
@@ -68,7 +64,7 @@ describe('IDE pipeline stage', () => {
});
it('sets border bottom class when collapsed', done => {
- vm.$el.querySelector('.card-header').click();
+ vm.stage.isCollapsed = true;
vm.$nextTick(() => {
expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');