Commit e378fd28 authored by Winnie Hellmann's avatar Winnie Hellmann Committed by Mike Greiling

Fix transient failure of group_member_contributions/components/app_spec.js

parent 033f523c
<script>
import { __ } from '~/locale';
import Flash from '~/flash';
import { GlLoadingIcon } from '@gitlab-org/gitlab-ui';
import COLUMNS from '../constants';
import TableHeader from './table_header.vue';
import TableBody from './table_body.vue';
import { GlLoadingIcon } from '@gitlab-org/gitlab-ui';
export default {
columns: COLUMNS,
......@@ -20,17 +17,11 @@ export default {
type: Object,
required: true,
},
service: {
type: Object,
required: true,
},
},
data() {
return {
isLoading: true,
};
},
computed: {
isLoading() {
return this.store.isLoading;
},
members() {
return this.store.members;
},
......@@ -38,24 +29,7 @@ export default {
return this.store.sortOrders;
},
},
mounted() {
this.fetchContributedMembers();
},
methods: {
fetchContributedMembers() {
this.service
.getContributedMembers()
.then(res => res.data)
.then(members => {
this.store.setColumns(this.$options.columns);
this.store.setMembers(members);
this.isLoading = false;
})
.catch(() => {
this.isLoading = false;
Flash(__('Something went wrong while fetching group member contributions'));
});
},
handleColumnClick(columnName) {
this.store.sortMembers(columnName);
},
......
......@@ -3,7 +3,6 @@ import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import GroupMemberStore from './store/group_member_store';
import GroupMemberService from './service/group_member_service';
import GroupMemberContributionsApp from './components/app.vue';
......@@ -16,19 +15,19 @@ export default () => {
return false;
}
const { memberContributionsPath } = el.dataset;
const store = new GroupMemberStore(memberContributionsPath);
store.fetchContributedMembers();
return new Vue({
el,
components: {
GroupMemberContributionsApp,
},
data() {
const { memberContributionsPath } = el.dataset;
const store = new GroupMemberStore();
const service = new GroupMemberService(memberContributionsPath);
return {
store,
service,
};
},
render(createElement) {
......
import axios from '~/lib/utils/axios_utils';
export default class GroupMemberService {
constructor(memberContributionsPath) {
this.memberContributionsPath = memberContributionsPath;
}
getContributedMembers() {
return axios.get(this.memberContributionsPath);
}
}
import axios from '~/lib/utils/axios_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import Flash from '~/flash';
import COLUMNS from '../constants';
export default class GroupMemberStore {
constructor() {
constructor(memberContributionsPath) {
this.memberContributionsPath = memberContributionsPath;
this.state = {};
this.state.isLoading = true;
this.state.members = [];
this.state.columns = [];
this.state.sortOrders = {};
this.state.currentSortedColumn = '';
}
get isLoading() {
return this.state.isLoading;
}
get members() {
return this.state.members;
}
......@@ -53,6 +64,22 @@ export default class GroupMemberStore {
}
}
fetchContributedMembers() {
return axios
.get(this.memberContributionsPath)
.then(res => res.data)
.then(members => {
this.setColumns(COLUMNS);
this.setMembers(members);
this.state.isLoading = false;
})
.catch(e => {
this.state.isLoading = false;
Flash(__('Something went wrong while fetching group member contributions'));
throw e;
});
}
static formatMember(rawMember) {
return convertObjectPropsToCamelCase(rawMember);
}
......
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import AppComponent from 'ee/group_member_contributions/components/app.vue';
import GroupMemberStore from 'ee/group_member_contributions/store/group_member_store';
import GroupMemberService from 'ee/group_member_contributions/service/group_member_service';
import { contributionsPath, rawMembers } from '../mock_data';
import { contributionsPath } from '../mock_data';
const createComponent = () => {
const Component = Vue.extend(AppComponent);
const store = new GroupMemberStore();
const service = new GroupMemberService(contributionsPath);
const store = new GroupMemberStore(contributionsPath);
return mountComponent(Component, {
store,
service,
});
};
......@@ -34,51 +28,6 @@ describe('AppComponent', () => {
});
describe('methods', () => {
describe('fetchContributedMembers', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
document.body.innerHTML += '<div class="flash-container"></div>';
});
afterEach(() => {
mock.restore();
document.querySelector('.flash-container').remove();
});
it('calls service.getContributedMembers and sets response to the store on success', done => {
mock.onGet(vm.service.memberContributionsPath).reply(200, rawMembers);
spyOn(vm.store, 'setColumns');
spyOn(vm.store, 'setMembers');
vm.fetchContributedMembers();
expect(vm.isLoading).toBe(true);
setTimeout(() => {
expect(vm.isLoading).toBe(false);
expect(vm.store.setColumns).toHaveBeenCalledWith(jasmine.any(Object));
expect(vm.store.setMembers).toHaveBeenCalledWith(rawMembers);
done();
}, 0);
});
it('calls service.getContributedMembers and sets `isLoading` to false and shows flash message if request failed', done => {
mock.onGet(vm.service.memberContributionsPath).reply(500, {});
vm.fetchContributedMembers();
expect(vm.isLoading).toBe(true);
setTimeout(() => {
expect(vm.isLoading).toBe(false);
expect(document.querySelector('.flash-text').innerText.trim()).toBe(
'Something went wrong while fetching group member contributions',
);
done();
}, 0);
});
});
describe('handleColumnClick', () => {
it('calls store.sortMembers with columnName param', () => {
spyOn(vm.store, 'sortMembers');
......@@ -101,7 +50,7 @@ describe('AppComponent', () => {
});
it('shows loading icon when isLoading prop is true', done => {
vm.isLoading = true;
vm.store.state.isLoading = true;
vm.$nextTick()
.then(() => {
const loadingEl = vm.$el.querySelector('.loading-animation');
......@@ -116,7 +65,7 @@ describe('AppComponent', () => {
});
it('renders table container element', done => {
vm.isLoading = false;
vm.store.state.isLoading = false;
vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('table.table.gl-sortable')).not.toBeNull();
......
import axios from '~/lib/utils/axios_utils';
import GroupMemberService from 'ee/group_member_contributions/service/group_member_service';
import { contributionsPath } from '../mock_data';
describe('GroupMemberService', () => {
let service;
beforeEach(() => {
service = new GroupMemberService(contributionsPath);
});
describe('constructor', () => {
it('initializes default properties', () => {
expect(service.memberContributionsPath).toBe(contributionsPath);
});
});
describe('getContributedMembers', () => {
it('returns axios instance for memberContributionsPath', () => {
spyOn(axios, 'get').and.stub();
service.getContributedMembers();
expect(axios.get).toHaveBeenCalledWith(service.memberContributionsPath);
});
});
});
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
import GroupMemberStore from 'ee/group_member_contributions/store/group_member_store';
import defaultColumns from 'ee/group_member_contributions/constants';
import { rawMembers } from '../mock_data';
import { rawMembers, contributionsPath } from '../mock_data';
describe('GroupMemberStore', () => {
let store;
beforeEach(() => {
store = new GroupMemberStore();
store = new GroupMemberStore(contributionsPath);
});
describe('setColumns', () => {
......@@ -49,4 +52,54 @@ describe('GroupMemberStore', () => {
expect(firstMember.fullname).toBe('Terrell Graham');
});
});
describe('fetchContributedMembers', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
setFixtures('<div class="flash-container"></div>');
});
afterEach(() => {
mock.restore();
});
it('calls service.getContributedMembers and sets response to the store on success', done => {
mock.onGet(contributionsPath).reply(200, rawMembers);
spyOn(store, 'setColumns');
spyOn(store, 'setMembers');
store
.fetchContributedMembers()
.then(() => {
expect(store.isLoading).toBe(false);
expect(store.setColumns).toHaveBeenCalledWith(jasmine.any(Object));
expect(store.setMembers).toHaveBeenCalledWith(rawMembers);
done();
})
.catch(done.fail);
expect(store.isLoading).toBe(true);
});
it('calls service.getContributedMembers and sets `isLoading` to false and shows flash message if request failed', done => {
mock.onGet(contributionsPath).reply(500, {});
store
.fetchContributedMembers()
.then(() => done.fail('Expected error to be thrown!'))
.catch(e => {
expect(e.message).toBe('Request failed with status code 500');
expect(store.isLoading).toBe(false);
expect(document.querySelector('.flash-text').innerText.trim()).toBe(
'Something went wrong while fetching group member contributions',
);
})
.then(done)
.catch(done.fail);
expect(store.isLoading).toBe(true);
});
});
});
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