Commit 39a2dbf2 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '282440-mlunoe-improve-graphql-local-resolver-tests-follow-up' into 'master'

Improve Apollo/GraphQL docs on fetchMore/pagination and tests

See merge request gitlab-org/gitlab!48245
parents c0e4f65d ca99b41b
This diff is collapsed.
...@@ -19,52 +19,53 @@ export default { ...@@ -19,52 +19,53 @@ export default {
}, },
data() { data() {
return { return {
requestCount: MAX_REQUEST_COUNT, requestCount: 0,
loadingError: false, loadingError: false,
isLoading: false,
selectedSegmentId: null, selectedSegmentId: null,
}; groups: {
}, nodes: [],
apollo: { pageInfo: null,
groups: {
query: getGroupsQuery,
loadingKey: 'loading',
result() {
this.requestCount -= 1;
if (this.requestCount > 0 && this.groups?.pageInfo?.nextPage) {
this.fetchNextPage();
}
}, },
error(error) { };
this.handleError(error);
},
},
}, },
computed: { computed: {
hasGroupData() { hasGroupData() {
return Boolean(this.groups?.nodes?.length); return Boolean(this.groups?.nodes?.length);
}, },
isLoading() { },
return this.$apollo.queries.groups.loading; created() {
}, this.fetchGroups();
}, },
methods: { methods: {
handleError(error) { handleError(error) {
this.loadingError = true; this.loadingError = true;
Sentry.captureException(error); Sentry.captureException(error);
}, },
fetchNextPage() { fetchGroups(nextPage) {
this.$apollo.queries.groups this.isLoading = true;
.fetchMore({ this.$apollo
.query({
query: getGroupsQuery,
variables: { variables: {
nextPage: this.groups.pageInfo.nextPage, nextPage,
}, },
updateQuery: (previousResult, { fetchMoreResult }) => { })
const { nodes, ...rest } = fetchMoreResult.groups; .then(({ data }) => {
const { nodes: previousNodes } = previousResult.groups; const { pageInfo, nodes } = data.groups;
return { groups: { ...rest, nodes: [...previousNodes, ...nodes] } }; // Update data
}, this.groups = {
pageInfo,
nodes: [...this.groups.nodes, ...nodes],
};
this.requestCount += 1;
if (this.requestCount < MAX_REQUEST_COUNT && pageInfo?.nextPage) {
this.fetchGroups(pageInfo.nextPage);
} else {
this.isLoading = false;
}
}) })
.catch(this.handleError); .catch(this.handleError);
}, },
......
...@@ -102,7 +102,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -102,7 +102,6 @@ describe('DevopsAdoptionApp', () => {
groupsSpy = jest.fn().mockResolvedValueOnce({ ...initialResponse, pageInfo: null }); groupsSpy = jest.fn().mockResolvedValueOnce({ ...initialResponse, pageInfo: null });
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
jest.spyOn(wrapper.vm.$apollo.queries.groups, 'fetchMore');
await waitForPromises(); await waitForPromises();
}); });
...@@ -117,21 +116,16 @@ describe('DevopsAdoptionApp', () => { ...@@ -117,21 +116,16 @@ describe('DevopsAdoptionApp', () => {
it('should fetch data once', () => { it('should fetch data once', () => {
expect(groupsSpy).toHaveBeenCalledTimes(1); expect(groupsSpy).toHaveBeenCalledTimes(1);
}); });
it('should not fetch more data', () => {
expect(wrapper.vm.$apollo.queries.groups.fetchMore).not.toHaveBeenCalled();
});
}); });
describe('when error is thrown in the initial request', () => { describe('when error is thrown in the initial request', () => {
const error = 'Error: foo!'; const error = new Error('foo!');
beforeEach(async () => { beforeEach(async () => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
groupsSpy = jest.fn().mockRejectedValueOnce(error); groupsSpy = jest.fn().mockRejectedValueOnce(error);
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
jest.spyOn(wrapper.vm.$apollo.queries.groups, 'fetchMore');
await waitForPromises(); await waitForPromises();
}); });
...@@ -147,10 +141,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -147,10 +141,6 @@ describe('DevopsAdoptionApp', () => {
expect(groupsSpy).toHaveBeenCalledTimes(1); expect(groupsSpy).toHaveBeenCalledTimes(1);
}); });
it('should not fetch more data', () => {
expect(wrapper.vm.$apollo.queries.groups.fetchMore).not.toHaveBeenCalled();
});
it('displays the error message and calls Sentry', () => { it('displays the error message and calls Sentry', () => {
const alert = wrapper.find(GlAlert); const alert = wrapper.find(GlAlert);
expect(alert.exists()).toBe(true); expect(alert.exists()).toBe(true);
...@@ -176,7 +166,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -176,7 +166,6 @@ describe('DevopsAdoptionApp', () => {
.mockResolvedValueOnce({ __typename: 'Groups', nodes: [nextGroupNode], nextPage: null }); .mockResolvedValueOnce({ __typename: 'Groups', nodes: [nextGroupNode], nextPage: null });
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
jest.spyOn(wrapper.vm.$apollo.queries.groups, 'fetchMore');
await waitForPromises(); await waitForPromises();
}); });
...@@ -193,12 +182,12 @@ describe('DevopsAdoptionApp', () => { ...@@ -193,12 +182,12 @@ describe('DevopsAdoptionApp', () => {
}); });
it('should fetch more data', () => { it('should fetch more data', () => {
expect(wrapper.vm.$apollo.queries.groups.fetchMore).toHaveBeenCalledTimes(1); expect(groupsSpy.mock.calls[0][1]).toMatchObject({
expect(wrapper.vm.$apollo.queries.groups.fetchMore).toHaveBeenCalledWith( nextPage: undefined,
expect.objectContaining({ });
variables: { nextPage: 2 }, expect(groupsSpy.mock.calls[1][1]).toMatchObject({
}), nextPage: 2,
); });
}); });
}); });
...@@ -208,7 +197,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -208,7 +197,6 @@ describe('DevopsAdoptionApp', () => {
groupsSpy = jest.fn().mockResolvedValue(initialResponse); groupsSpy = jest.fn().mockResolvedValue(initialResponse);
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo, data: { requestCount: 2 } }); wrapper = createComponent({ mockApollo, data: { requestCount: 2 } });
jest.spyOn(wrapper.vm.$apollo.queries.groups, 'fetchMore');
await waitForPromises(); await waitForPromises();
}); });
...@@ -219,10 +207,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -219,10 +207,6 @@ describe('DevopsAdoptionApp', () => {
it('should fetch data twice', () => { it('should fetch data twice', () => {
expect(groupsSpy).toHaveBeenCalledTimes(2); expect(groupsSpy).toHaveBeenCalledTimes(2);
}); });
it('should not fetch more than `requestCount`', () => {
expect(wrapper.vm.$apollo.queries.groups.fetchMore).toHaveBeenCalledTimes(1);
});
}); });
describe('when error is thrown in the fetchMore request', () => { describe('when error is thrown in the fetchMore request', () => {
...@@ -237,7 +221,6 @@ describe('DevopsAdoptionApp', () => { ...@@ -237,7 +221,6 @@ describe('DevopsAdoptionApp', () => {
.mockRejectedValue(error); .mockRejectedValue(error);
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
jest.spyOn(wrapper.vm.$apollo.queries.groups, 'fetchMore');
await waitForPromises(); await waitForPromises();
}); });
...@@ -254,11 +237,12 @@ describe('DevopsAdoptionApp', () => { ...@@ -254,11 +237,12 @@ describe('DevopsAdoptionApp', () => {
}); });
it('should fetch more data', () => { it('should fetch more data', () => {
expect(wrapper.vm.$apollo.queries.groups.fetchMore).toHaveBeenCalledWith( expect(groupsSpy.mock.calls[0][1]).toMatchObject({
expect.objectContaining({ nextPage: undefined,
variables: { nextPage: 2 }, });
}), expect(groupsSpy.mock.calls[1][1]).toMatchObject({
); nextPage: 2,
});
}); });
it('displays the error message and calls Sentry', () => { it('displays the error message and calls Sentry', () => {
......
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