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