Commit 710a95f5 authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '327751-code-quality-widget-status-keep-polling-while-parsing' into 'master'

Continue code quality widget polling on 204 response (when pipeline is still running or results are being parsed)

See merge request gitlab-org/gitlab!67176
parents b6258b3c 0ba54b5f
import axios from '~/lib/utils/axios_utils'; import pollUntilComplete from '~/lib/utils/poll_until_complete';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { parseCodeclimateMetrics } from './utils/codequality_parser'; import { parseCodeclimateMetrics } from './utils/codequality_parser';
...@@ -10,8 +10,7 @@ export const fetchReports = ({ state, dispatch, commit }) => { ...@@ -10,8 +10,7 @@ export const fetchReports = ({ state, dispatch, commit }) => {
if (!state.basePath) { if (!state.basePath) {
return dispatch('receiveReportsError'); return dispatch('receiveReportsError');
} }
return axios return pollUntilComplete(state.reportsPath)
.get(state.reportsPath)
.then(({ data }) => { .then(({ data }) => {
return dispatch('receiveReportsSuccess', { return dispatch('receiveReportsSuccess', {
newIssues: parseCodeclimateMetrics(data.new_errors, state.headBlobPath), newIssues: parseCodeclimateMetrics(data.new_errors, state.headBlobPath),
......
...@@ -7,6 +7,11 @@ import * as actions from '~/reports/codequality_report/store/actions'; ...@@ -7,6 +7,11 @@ import * as actions from '~/reports/codequality_report/store/actions';
import * as types from '~/reports/codequality_report/store/mutation_types'; import * as types from '~/reports/codequality_report/store/mutation_types';
import { reportIssues, parsedReportIssues } from '../mock_data'; import { reportIssues, parsedReportIssues } from '../mock_data';
const pollInterval = 123;
const pollIntervalHeader = {
'Poll-Interval': pollInterval,
};
describe('Codequality Reports actions', () => { describe('Codequality Reports actions', () => {
let localState; let localState;
let localStore; let localStore;
...@@ -39,10 +44,11 @@ describe('Codequality Reports actions', () => { ...@@ -39,10 +44,11 @@ describe('Codequality Reports actions', () => {
}); });
describe('fetchReports', () => { describe('fetchReports', () => {
const endpoint = `${TEST_HOST}/codequality_reports.json`;
let mock; let mock;
beforeEach(() => { beforeEach(() => {
localState.reportsPath = `${TEST_HOST}/codequality_reports.json`; localState.reportsPath = endpoint;
localState.basePath = '/base/path'; localState.basePath = '/base/path';
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
}); });
...@@ -53,7 +59,7 @@ describe('Codequality Reports actions', () => { ...@@ -53,7 +59,7 @@ describe('Codequality Reports actions', () => {
describe('on success', () => { describe('on success', () => {
it('commits REQUEST_REPORTS and dispatches receiveReportsSuccess', (done) => { it('commits REQUEST_REPORTS and dispatches receiveReportsSuccess', (done) => {
mock.onGet(`${TEST_HOST}/codequality_reports.json`).reply(200, reportIssues); mock.onGet(endpoint).reply(200, reportIssues);
testAction( testAction(
actions.fetchReports, actions.fetchReports,
...@@ -73,7 +79,7 @@ describe('Codequality Reports actions', () => { ...@@ -73,7 +79,7 @@ describe('Codequality Reports actions', () => {
describe('on error', () => { describe('on error', () => {
it('commits REQUEST_REPORTS and dispatches receiveReportsError', (done) => { it('commits REQUEST_REPORTS and dispatches receiveReportsError', (done) => {
mock.onGet(`${TEST_HOST}/codequality_reports.json`).reply(500); mock.onGet(endpoint).reply(500);
testAction( testAction(
actions.fetchReports, actions.fetchReports,
...@@ -100,6 +106,63 @@ describe('Codequality Reports actions', () => { ...@@ -100,6 +106,63 @@ describe('Codequality Reports actions', () => {
); );
}); });
}); });
describe('while waiting for report results', () => {
it('continues polling until it receives data', (done) => {
mock
.onGet(endpoint)
.replyOnce(204, undefined, pollIntervalHeader)
.onGet(endpoint)
.reply(200, reportIssues);
Promise.all([
testAction(
actions.fetchReports,
null,
localState,
[{ type: types.REQUEST_REPORTS }],
[
{
payload: parsedReportIssues,
type: 'receiveReportsSuccess',
},
],
done,
),
axios
// wait for initial NO_CONTENT response to be fulfilled
.waitForAll()
.then(() => {
jest.advanceTimersByTime(pollInterval);
}),
]).catch(done.fail);
});
it('continues polling until it receives an error', (done) => {
mock
.onGet(endpoint)
.replyOnce(204, undefined, pollIntervalHeader)
.onGet(endpoint)
.reply(500);
Promise.all([
testAction(
actions.fetchReports,
null,
localState,
[{ type: types.REQUEST_REPORTS }],
[{ type: 'receiveReportsError', payload: expect.any(Error) }],
done,
),
axios
// wait for initial NO_CONTENT response to be fulfilled
.waitForAll()
.then(() => {
jest.advanceTimersByTime(pollInterval);
}),
]).catch(done.fail);
});
});
}); });
describe('receiveReportsSuccess', () => { describe('receiveReportsSuccess', () => {
......
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