diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/actions.js b/app/assets/javascripts/ci/reports/codequality_report/store/actions.js deleted file mode 100644 index 5247faef363acafddcc41857bbba005b1d33ab67..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/actions.js +++ /dev/null @@ -1,30 +0,0 @@ -import pollUntilComplete from '~/lib/utils/poll_until_complete'; -import { STATUS_NOT_FOUND } from '../../constants'; -import { parseCodeclimateMetrics } from '../utils/codequality_parser'; -import * as types from './mutation_types'; - -export const setPaths = ({ commit }, paths) => commit(types.SET_PATHS, paths); - -export const fetchReports = ({ state, dispatch, commit }) => { - commit(types.REQUEST_REPORTS); - - return pollUntilComplete(state.reportsPath) - .then(({ data }) => { - if (data.status === STATUS_NOT_FOUND) { - return dispatch('receiveReportsError', data); - } - return dispatch('receiveReportsSuccess', { - newIssues: parseCodeclimateMetrics(data.new_errors, state.headBlobPath), - resolvedIssues: parseCodeclimateMetrics(data.resolved_errors, state.baseBlobPath), - }); - }) - .catch((error) => dispatch('receiveReportsError', error)); -}; - -export const receiveReportsSuccess = ({ commit }, data) => { - commit(types.RECEIVE_REPORTS_SUCCESS, data); -}; - -export const receiveReportsError = ({ commit }, error) => { - commit(types.RECEIVE_REPORTS_ERROR, error); -}; diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/getters.js b/app/assets/javascripts/ci/reports/codequality_report/store/getters.js deleted file mode 100644 index 70d11e96a54974f4347ce7aabf3790a10842d2e8..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/getters.js +++ /dev/null @@ -1,63 +0,0 @@ -import { spriteIcon } from '~/lib/utils/common_utils'; -import { sprintf, s__, n__ } from '~/locale'; -import { LOADING, ERROR, SUCCESS, STATUS_NOT_FOUND } from '../../constants'; - -export const hasCodequalityIssues = (state) => - Boolean(state.newIssues?.length || state.resolvedIssues?.length); - -export const codequalityStatus = (state) => { - if (state.isLoading) { - return LOADING; - } - if (state.hasError) { - return ERROR; - } - - return SUCCESS; -}; - -export const codequalityText = (state) => { - const { newIssues, resolvedIssues } = state; - let text; - if (!newIssues.length && !resolvedIssues.length) { - text = s__('ciReport|No changes to code quality'); - } else if (newIssues.length && resolvedIssues.length) { - text = sprintf( - s__(`ciReport|Code quality scanning detected %{issueCount} changes in merged results`), - { - issueCount: newIssues.length + resolvedIssues.length, - }, - ); - } else if (resolvedIssues.length) { - text = n__( - `ciReport|Code quality improved due to 1 resolved issue`, - `ciReport|Code quality improved due to %d resolved issues`, - resolvedIssues.length, - ); - } else if (newIssues.length) { - text = n__( - `ciReport|Code quality degraded due to 1 new issue`, - `ciReport|Code quality degraded due to %d new issues`, - newIssues.length, - ); - } - - return text; -}; - -export const codequalityPopover = (state) => { - if (state.status === STATUS_NOT_FOUND) { - return { - title: s__('ciReport|Base pipeline codequality artifact not found'), - content: sprintf( - s__('ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}'), - { - linkStartTag: `<a href="${state.helpPath}" target="_blank" rel="noopener noreferrer">`, - linkEndTag: `${spriteIcon('external-link', 's16')}</a>`, - }, - false, - ), - }; - } - return {}; -}; diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/index.js b/app/assets/javascripts/ci/reports/codequality_report/store/index.js deleted file mode 100644 index c2f706e56e66ae32371cf0486cd96b8cae297744..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import Vue from 'vue'; -// eslint-disable-next-line no-restricted-imports -import Vuex from 'vuex'; -import * as actions from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; -import state from './state'; - -Vue.use(Vuex); - -export const getStoreConfig = (initialState) => ({ - actions, - getters, - mutations, - state: state(initialState), -}); - -export default (initialState) => new Vuex.Store(getStoreConfig(initialState)); diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/mutation_types.js b/app/assets/javascripts/ci/reports/codequality_report/store/mutation_types.js deleted file mode 100644 index c362c973ae112b1c78553a37bf33202e8d1550cd..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/mutation_types.js +++ /dev/null @@ -1,5 +0,0 @@ -export const SET_PATHS = 'SET_PATHS'; - -export const REQUEST_REPORTS = 'REQUEST_REPORTS'; -export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS'; -export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR'; diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/mutations.js b/app/assets/javascripts/ci/reports/codequality_report/store/mutations.js deleted file mode 100644 index 249c2f35c0ba09de113dff84749bcfdacfe2629d..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/mutations.js +++ /dev/null @@ -1,27 +0,0 @@ -import * as types from './mutation_types'; - -export default { - [types.SET_PATHS](state, paths) { - state.baseBlobPath = paths.baseBlobPath; - state.headBlobPath = paths.headBlobPath; - state.reportsPath = paths.reportsPath; - state.helpPath = paths.helpPath; - }, - [types.REQUEST_REPORTS](state) { - state.isLoading = true; - }, - [types.RECEIVE_REPORTS_SUCCESS](state, data) { - state.hasError = false; - state.status = ''; - state.statusReason = ''; - state.isLoading = false; - state.newIssues = data.newIssues; - state.resolvedIssues = data.resolvedIssues; - }, - [types.RECEIVE_REPORTS_ERROR](state, error) { - state.isLoading = false; - state.hasError = true; - state.status = error?.status || ''; - state.statusReason = error?.response?.data?.status_reason; - }, -}; diff --git a/app/assets/javascripts/ci/reports/codequality_report/store/state.js b/app/assets/javascripts/ci/reports/codequality_report/store/state.js deleted file mode 100644 index f68dbc2a5fa227d967559af38b3871961252ef66..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/ci/reports/codequality_report/store/state.js +++ /dev/null @@ -1,16 +0,0 @@ -export default () => ({ - reportsPath: null, - - baseBlobPath: null, - headBlobPath: null, - - isLoading: false, - hasError: false, - status: '', - statusReason: '', - - newIssues: [], - resolvedIssues: [], - - helpPath: null, -}); diff --git a/ee/app/assets/javascripts/codequality_report/store/actions.js b/ee/app/assets/javascripts/codequality_report/store/actions.js deleted file mode 100644 index 29081b7a8656782e8a52b09f0156eb2c1792646e..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/actions.js +++ /dev/null @@ -1,38 +0,0 @@ -import Api from '~/api'; -import { createAlert } from '~/alert'; -import axios from '~/lib/utils/axios_utils'; -import { s__ } from '~/locale'; - -import { parseCodeclimateMetrics } from '~/ci/reports/codequality_report/utils/codequality_parser'; -import { VIEW_EVENT_NAME } from './constants'; -import * as types from './mutation_types'; - -export const setPage = ({ commit }, page) => commit(types.SET_PAGE, page); - -export const requestReport = ({ commit }) => { - commit(types.REQUEST_REPORT); - - Api.trackRedisHllUserEvent(VIEW_EVENT_NAME); -}; -export const receiveReportSuccess = ({ state, commit }, data) => { - const parsedIssues = parseCodeclimateMetrics(data, state.blobPath); - commit(types.RECEIVE_REPORT_SUCCESS, parsedIssues); -}; -export const receiveReportError = ({ commit }, error) => commit(types.RECEIVE_REPORT_ERROR, error); - -export const fetchReport = ({ state, dispatch }) => { - dispatch('requestReport'); - - axios - .get(state.endpoint) - .then(({ data }) => { - if (!state.blobPath) throw new Error(); - dispatch('receiveReportSuccess', data); - }) - .catch((error) => { - dispatch('receiveReportError', error); - createAlert({ - message: s__('ciReport|There was an error fetching the codequality report.'), - }); - }); -}; diff --git a/ee/app/assets/javascripts/codequality_report/store/constants.js b/ee/app/assets/javascripts/codequality_report/store/constants.js deleted file mode 100644 index 9776302a3eed8697981b48468800cbad8cd47627..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -export const VIEW_EVENT_NAME = 'i_testing_full_code_quality_report_total'; - -export const PAGE_SIZE = 25; - -export const SEVERITY_SORT_ORDER = { - unknown: 0, - blocker: 1, - critical: 2, - major: 3, - minor: 4, - info: 5, -}; diff --git a/ee/app/assets/javascripts/codequality_report/store/getters.js b/ee/app/assets/javascripts/codequality_report/store/getters.js deleted file mode 100644 index a7f3f1eb2a661d485eb44e8a7c2fcdd7bd04d032..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/getters.js +++ /dev/null @@ -1,7 +0,0 @@ -export const codequalityIssues = (state) => { - const { page, perPage } = state.pageInfo; - const start = (page - 1) * perPage; - return state.allCodequalityIssues.slice(start, start + perPage); -}; - -export const codequalityIssueTotal = (state) => state.allCodequalityIssues.length; diff --git a/ee/app/assets/javascripts/codequality_report/store/index.js b/ee/app/assets/javascripts/codequality_report/store/index.js deleted file mode 100644 index f7e752a55793fb2a4c7bb43b0a76578d7edc7842..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import * as actions from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; -import state from './state'; - -export const setupStore = (store, initialState) => { - store.registerModule('codeQualityReport', { - namespaced: true, - actions, - getters, - mutations, - state: { - ...state(), - ...initialState, - }, - }); -}; diff --git a/ee/app/assets/javascripts/codequality_report/store/mutation_types.js b/ee/app/assets/javascripts/codequality_report/store/mutation_types.js deleted file mode 100644 index d66afa5e95c6dc51b32d66bdcad8d4c3c4711f9a..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/mutation_types.js +++ /dev/null @@ -1,4 +0,0 @@ -export const SET_PAGE = 'SET_PAGE'; -export const REQUEST_REPORT = 'REQUEST_REPORT'; -export const RECEIVE_REPORT_SUCCESS = 'RECEIVE_REPORT_SUCCESS'; -export const RECEIVE_REPORT_ERROR = 'RECEIVE_REPORT_ERROR'; diff --git a/ee/app/assets/javascripts/codequality_report/store/mutations.js b/ee/app/assets/javascripts/codequality_report/store/mutations.js deleted file mode 100644 index 5949082fbc6f84a7a05f9ce1b7ea4e38528b18c5..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/mutations.js +++ /dev/null @@ -1,39 +0,0 @@ -import { SEVERITY_SORT_ORDER } from './constants'; -import * as types from './mutation_types'; - -export default { - [types.SET_PAGE](state, page) { - Object.assign(state, { - pageInfo: Object.assign(state.pageInfo, { - page, - }), - }); - }, - [types.REQUEST_REPORT](state) { - Object.assign(state, { isLoadingCodequality: true }); - }, - [types.RECEIVE_REPORT_SUCCESS](state, allCodequalityIssues) { - Object.assign(state, { - isLoadingCodequality: false, - allCodequalityIssues: Object.freeze( - allCodequalityIssues.sort( - (a, b) => SEVERITY_SORT_ORDER[a.severity] - SEVERITY_SORT_ORDER[b.severity], - ), - ), - pageInfo: Object.assign(state.pageInfo, { - total: allCodequalityIssues.length, - }), - }); - }, - [types.RECEIVE_REPORT_ERROR](state, codeQualityError) { - Object.assign(state, { - isLoadingCodequality: false, - allCodequalityIssues: [], - loadingCodequalityFailed: true, - codeQualityError, - pageInfo: Object.assign(state.pageInfo, { - total: 0, - }), - }); - }, -}; diff --git a/ee/app/assets/javascripts/codequality_report/store/state.js b/ee/app/assets/javascripts/codequality_report/store/state.js deleted file mode 100644 index b07cf8dd448dd4f22240721109f4f0b22d6eb564..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/codequality_report/store/state.js +++ /dev/null @@ -1,14 +0,0 @@ -import { PAGE_SIZE } from './constants'; - -export default () => ({ - endpoint: '', - allCodequalityIssues: [], - isLoadingCodequality: false, - loadingCodequalityFailed: false, - codeQualityError: null, - pageInfo: { - page: 1, - perPage: PAGE_SIZE, - total: 0, - }, -}); diff --git a/ee/spec/frontend/codequality_report/store/actions_spec.js b/ee/spec/frontend/codequality_report/store/actions_spec.js deleted file mode 100644 index 1dad8c44f4cf66c317dd3ab9ea79dec17ca6959c..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/codequality_report/store/actions_spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import MockAdapter from 'axios-mock-adapter'; -import * as actions from 'ee/codequality_report/store/actions'; -import initialState from 'ee/codequality_report/store/state'; -import { VIEW_EVENT_NAME } from 'ee/codequality_report/store/constants'; -import * as types from 'ee/codequality_report/store/mutation_types'; -import { TEST_HOST } from 'helpers/test_constants'; -import testAction from 'helpers/vuex_action_helper'; -import Api from '~/api'; -import { createAlert } from '~/alert'; -import axios from '~/lib/utils/axios_utils'; -import { HTTP_STATUS_OK } from '~/lib/utils/http_status'; -import { unparsedIssues, parsedIssues } from '../mock_data'; - -jest.mock('~/api.js'); -jest.mock('~/alert'); - -describe('Codequality report actions', () => { - let mock; - let state; - - const endpoint = `${TEST_HOST}/codequality_report.json`; - const defaultState = { - ...initialState(), - endpoint, - }; - - beforeEach(() => { - mock = new MockAdapter(axios); - state = defaultState; - window.gon = { features: {} }; - }); - - afterEach(() => { - mock.restore(); - }); - - describe('setPage', () => { - it('sets the page number', async () => { - await testAction(actions.setPage, 12, state, [{ type: types.SET_PAGE, payload: 12 }], []); - }); - }); - - describe('requestReport', () => { - it('sets the loading flag', async () => { - await testAction(actions.requestReport, null, state, [{ type: types.REQUEST_REPORT }], []); - }); - - it('tracks a service ping event', () => { - actions.requestReport({ commit: jest.fn() }); - - expect(Api.trackRedisHllUserEvent).toHaveBeenCalledWith(VIEW_EVENT_NAME); - }); - }); - - describe('receiveReportSuccess', () => { - it('parses the list of issues from the report', async () => { - await testAction( - actions.receiveReportSuccess, - unparsedIssues, - { blobPath: '/root/test-codequality/blob/feature-branch', ...state }, - [{ type: types.RECEIVE_REPORT_SUCCESS, payload: parsedIssues }], - [], - ); - }); - }); - - describe('receiveReportError', () => { - it('accepts a report error', async () => { - await testAction( - actions.receiveReportError, - 'error', - state, - [{ type: types.RECEIVE_REPORT_ERROR, payload: 'error' }], - [], - ); - }); - }); - - describe('fetchReport', () => { - beforeEach(() => { - mock.onGet(endpoint).replyOnce(HTTP_STATUS_OK, unparsedIssues); - }); - - it('fetches the report', async () => { - await testAction( - actions.fetchReport, - null, - { blobPath: 'blah', ...state }, - [], - [{ type: 'requestReport' }, { type: 'receiveReportSuccess', payload: unparsedIssues }], - ); - }); - - it('shows an alert message when there is an error', async () => { - await testAction( - actions.fetchReport, - 'error', - state, - [], - [{ type: 'requestReport' }, { type: 'receiveReportError', payload: expect.any(Error) }], - ); - expect(createAlert).toHaveBeenCalledWith({ - message: 'There was an error fetching the codequality report.', - }); - }); - - it('shows an error when blob path is missing', async () => { - await testAction( - actions.fetchReport, - null, - state, - [], - [{ type: 'requestReport' }, { type: 'receiveReportError', payload: expect.any(Error) }], - ); - expect(createAlert).toHaveBeenCalledWith({ - message: 'There was an error fetching the codequality report.', - }); - }); - }); -}); diff --git a/ee/spec/frontend/codequality_report/store/getters_spec.js b/ee/spec/frontend/codequality_report/store/getters_spec.js deleted file mode 100644 index bf4b815e14fbb8be92a993723502e54ab85aa8f9..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/codequality_report/store/getters_spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as getters from 'ee/codequality_report/store/getters'; -import { parsedIssues } from '../mock_data'; - -describe('Codequality report getters', () => { - let state; - - const defaultState = { - allCodequalityIssues: parsedIssues, - }; - - beforeEach(() => { - state = defaultState; - }); - - describe('codequalityIssues', () => { - it('gets the current page of issues', () => { - expect( - getters.codequalityIssues({ pageInfo: { page: 1, perPage: 2, total: 3 }, ...state }), - ).toEqual(parsedIssues.slice(0, 2)); - expect( - getters.codequalityIssues({ pageInfo: { page: 2, perPage: 2, total: 3 }, ...state }), - ).toEqual(parsedIssues.slice(2, 3)); - }); - }); - - describe('codequalityIssueTotal', () => { - it('gets the total number of codequality issues', () => { - expect(getters.codequalityIssueTotal(state)).toBe(parsedIssues.length); - }); - }); -}); diff --git a/ee/spec/frontend/codequality_report/store/mutations_spec.js b/ee/spec/frontend/codequality_report/store/mutations_spec.js deleted file mode 100644 index f31317d025bbfe1d6ac788ff7d1a0fca6bedf28e..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/codequality_report/store/mutations_spec.js +++ /dev/null @@ -1,69 +0,0 @@ -import * as types from 'ee/codequality_report/store/mutation_types'; -import mutations from 'ee/codequality_report/store/mutations'; -import { parsedIssues } from '../mock_data'; - -describe('Codequality report mutations', () => { - let state; - - const defaultState = { - pageInfo: {}, - }; - - beforeEach(() => { - state = defaultState; - }); - - describe('set page', () => { - it('should set page', () => { - mutations[types.SET_PAGE](state, 4); - expect(state.pageInfo.page).toBe(4); - }); - }); - - describe('request report', () => { - it('should set the loading flag', () => { - mutations[types.REQUEST_REPORT](state); - expect(state.isLoadingCodequality).toBe(true); - }); - }); - - describe('receive report success', () => { - it('should set issue info and clear the loading flag', () => { - mutations[types.RECEIVE_REPORT_SUCCESS](state, parsedIssues); - - expect(state.isLoadingCodequality).toBe(false); - expect(state.allCodequalityIssues).toBe(parsedIssues); - expect(state.pageInfo.total).toBe(parsedIssues.length); - }); - - it('should sort issues by severity', () => { - mutations[types.RECEIVE_REPORT_SUCCESS](state, [ - { severity: 'critical' }, - { severity: 'blocker' }, - { severity: 'info' }, - { severity: 'minor' }, - { severity: 'unknown' }, - { severity: 'major' }, - ]); - - expect(state.allCodequalityIssues[0].severity).toBe('unknown'); - expect(state.allCodequalityIssues[1].severity).toBe('blocker'); - expect(state.allCodequalityIssues[2].severity).toBe('critical'); - expect(state.allCodequalityIssues[3].severity).toBe('major'); - expect(state.allCodequalityIssues[4].severity).toBe('minor'); - expect(state.allCodequalityIssues[5].severity).toBe('info'); - }); - }); - - describe('receive report error', () => { - it('should set error info and clear the loading flag', () => { - mutations[types.RECEIVE_REPORT_ERROR](state, new Error()); - - expect(state.isLoadingCodequality).toBe(false); - expect(state.loadingCodequalityFailed).toBe(true); - expect(state.allCodequalityIssues).toEqual([]); - expect(state.codeQualityError).toEqual(new Error()); - expect(state.pageInfo.total).toBe(0); - }); - }); -}); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 737d28501f06dce00f337c5cf321835346b821cf..67b5d53a254b8c37ed090ee8c02adc8d8cbd4d6b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -56683,9 +56683,6 @@ msgstr "" msgid "ciReport|%{improvedNum} improved" msgstr "" -msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}" -msgstr "" - msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}" msgstr "" @@ -56731,9 +56728,6 @@ msgstr "" msgid "ciReport|Automatically opens a merge request with a solution generated by AI" msgstr "" -msgid "ciReport|Base pipeline codequality artifact not found" -msgstr "" - msgid "ciReport|Browser Performance" msgstr "" @@ -56769,19 +56763,6 @@ msgstr "" msgid "ciReport|Code Quality is loading" msgstr "" -msgid "ciReport|Code quality degraded due to 1 new issue" -msgid_plural "ciReport|Code quality degraded due to %d new issues" -msgstr[0] "" -msgstr[1] "" - -msgid "ciReport|Code quality improved due to 1 resolved issue" -msgid_plural "ciReport|Code quality improved due to %d resolved issues" -msgstr[0] "" -msgstr[1] "" - -msgid "ciReport|Code quality scanning detected %{issueCount} changes in merged results" -msgstr "" - msgid "ciReport|Container Scanning" msgstr "" @@ -56901,9 +56882,6 @@ msgstr "" msgid "ciReport|New vulnerabilities are vulnerabilities that the security scan detects in the merge request that are different to existing vulnerabilities in the default branch." msgstr "" -msgid "ciReport|No changes to code quality" -msgstr "" - msgid "ciReport|No code quality issues found" msgstr "" @@ -56973,9 +56951,6 @@ msgstr "" msgid "ciReport|There was an error dismissing the vulnerability: %{error}" msgstr "" -msgid "ciReport|There was an error fetching the codequality report." -msgstr "" - msgid "ciReport|There was an error reverting the dismissal. Please try again." msgstr "" diff --git a/spec/frontend/ci/reports/codequality_report/store/actions_spec.js b/spec/frontend/ci/reports/codequality_report/store/actions_spec.js deleted file mode 100644 index a606bce3d78faa25c45d2bbdaec201cc6289b885..0000000000000000000000000000000000000000 --- a/spec/frontend/ci/reports/codequality_report/store/actions_spec.js +++ /dev/null @@ -1,190 +0,0 @@ -import MockAdapter from 'axios-mock-adapter'; -import testAction from 'helpers/vuex_action_helper'; -import { TEST_HOST } from 'spec/test_constants'; -import axios from '~/lib/utils/axios_utils'; -import { - HTTP_STATUS_INTERNAL_SERVER_ERROR, - HTTP_STATUS_NO_CONTENT, - HTTP_STATUS_OK, -} from '~/lib/utils/http_status'; -import createStore from '~/ci/reports/codequality_report/store'; -import * as actions from '~/ci/reports/codequality_report/store/actions'; -import * as types from '~/ci/reports/codequality_report/store/mutation_types'; -import { STATUS_NOT_FOUND } from '~/ci/reports/constants'; -import { reportIssues, parsedReportIssues } from '../mock_data'; - -const pollInterval = 123; -const pollIntervalHeader = { - 'Poll-Interval': pollInterval, -}; - -describe('Codequality Reports actions', () => { - let localState; - let localStore; - - beforeEach(() => { - localStore = createStore(); - localState = localStore.state; - }); - - describe('setPaths', () => { - it('should commit SET_PATHS mutation', () => { - const paths = { - baseBlobPath: 'baseBlobPath', - headBlobPath: 'headBlobPath', - reportsPath: 'reportsPath', - }; - - return testAction( - actions.setPaths, - paths, - localState, - [{ type: types.SET_PATHS, payload: paths }], - [], - ); - }); - }); - - describe('fetchReports', () => { - const endpoint = `${TEST_HOST}/codequality_reports.json`; - let mock; - - beforeEach(() => { - localState.reportsPath = endpoint; - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - - describe('on success', () => { - it('commits REQUEST_REPORTS and dispatches receiveReportsSuccess', () => { - mock.onGet(endpoint).reply(HTTP_STATUS_OK, reportIssues); - - return testAction( - actions.fetchReports, - null, - localState, - [{ type: types.REQUEST_REPORTS }], - [ - { - payload: parsedReportIssues, - type: 'receiveReportsSuccess', - }, - ], - ); - }); - }); - - describe('on error', () => { - it('commits REQUEST_REPORTS and dispatches receiveReportsError', () => { - mock.onGet(endpoint).reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); - - return testAction( - actions.fetchReports, - null, - localState, - [{ type: types.REQUEST_REPORTS }], - [{ type: 'receiveReportsError', payload: expect.any(Error) }], - ); - }); - }); - - describe('when base report is not found', () => { - it('commits REQUEST_REPORTS and dispatches receiveReportsError', () => { - const data = { status: STATUS_NOT_FOUND }; - mock.onGet(`${TEST_HOST}/codequality_reports.json`).reply(HTTP_STATUS_OK, data); - - return testAction( - actions.fetchReports, - null, - localState, - [{ type: types.REQUEST_REPORTS }], - [{ type: 'receiveReportsError', payload: data }], - ); - }); - }); - - describe('while waiting for report results', () => { - it('continues polling until it receives data', () => { - mock - .onGet(endpoint) - .replyOnce(HTTP_STATUS_NO_CONTENT, undefined, pollIntervalHeader) - .onGet(endpoint) - .reply(HTTP_STATUS_OK, reportIssues); - - return Promise.all([ - testAction( - actions.fetchReports, - null, - localState, - [{ type: types.REQUEST_REPORTS }], - [ - { - payload: parsedReportIssues, - type: 'receiveReportsSuccess', - }, - ], - ), - axios - // wait for initial NO_CONTENT response to be fulfilled - .waitForAll() - .then(() => { - jest.advanceTimersByTime(pollInterval); - }), - ]); - }); - - it('continues polling until it receives an error', () => { - mock - .onGet(endpoint) - .replyOnce(HTTP_STATUS_NO_CONTENT, undefined, pollIntervalHeader) - .onGet(endpoint) - .reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); - - return Promise.all([ - testAction( - actions.fetchReports, - null, - localState, - [{ type: types.REQUEST_REPORTS }], - [{ type: 'receiveReportsError', payload: expect.any(Error) }], - ), - axios - // wait for initial NO_CONTENT response to be fulfilled - .waitForAll() - .then(() => { - jest.advanceTimersByTime(pollInterval); - }), - ]); - }); - }); - }); - - describe('receiveReportsSuccess', () => { - it('commits RECEIVE_REPORTS_SUCCESS', () => { - const data = { issues: [] }; - - return testAction( - actions.receiveReportsSuccess, - data, - localState, - [{ type: types.RECEIVE_REPORTS_SUCCESS, payload: data }], - [], - ); - }); - }); - - describe('receiveReportsError', () => { - it('commits RECEIVE_REPORTS_ERROR', () => { - return testAction( - actions.receiveReportsError, - null, - localState, - [{ type: types.RECEIVE_REPORTS_ERROR, payload: null }], - [], - ); - }); - }); -}); diff --git a/spec/frontend/ci/reports/codequality_report/store/getters_spec.js b/spec/frontend/ci/reports/codequality_report/store/getters_spec.js deleted file mode 100644 index f4505204f678f0788030ffa399debec2b1b61746..0000000000000000000000000000000000000000 --- a/spec/frontend/ci/reports/codequality_report/store/getters_spec.js +++ /dev/null @@ -1,94 +0,0 @@ -import createStore from '~/ci/reports/codequality_report/store'; -import * as getters from '~/ci/reports/codequality_report/store/getters'; -import { LOADING, ERROR, SUCCESS, STATUS_NOT_FOUND } from '~/ci/reports/constants'; - -describe('Codequality reports store getters', () => { - let localState; - let localStore; - - beforeEach(() => { - localStore = createStore(); - localState = localStore.state; - }); - - describe('hasCodequalityIssues', () => { - describe('when there are issues', () => { - it('returns true', () => { - localState.newIssues = [{ reason: 'repetitive code' }]; - localState.resolvedIssues = []; - - expect(getters.hasCodequalityIssues(localState)).toEqual(true); - - localState.newIssues = []; - localState.resolvedIssues = [{ reason: 'repetitive code' }]; - - expect(getters.hasCodequalityIssues(localState)).toEqual(true); - }); - }); - - describe('when there are no issues', () => { - it('returns false when there are no issues', () => { - expect(getters.hasCodequalityIssues(localState)).toEqual(false); - }); - }); - }); - - describe('codequalityStatus', () => { - describe('when loading', () => { - it('returns loading status', () => { - localState.isLoading = true; - - expect(getters.codequalityStatus(localState)).toEqual(LOADING); - }); - }); - - describe('on error', () => { - it('returns error status', () => { - localState.hasError = true; - - expect(getters.codequalityStatus(localState)).toEqual(ERROR); - }); - }); - - describe('when successfully loaded', () => { - it('returns error status', () => { - expect(getters.codequalityStatus(localState)).toEqual(SUCCESS); - }); - }); - }); - - describe('codequalityText', () => { - it.each` - resolvedIssues | newIssues | expectedText - ${0} | ${0} | ${'No changes to code quality'} - ${0} | ${1} | ${'Code quality degraded due to 1 new issue'} - ${2} | ${0} | ${'Code quality improved due to 2 resolved issues'} - ${1} | ${2} | ${'Code quality scanning detected 3 changes in merged results'} - `( - 'returns a summary containing $resolvedIssues resolved issues and $newIssues new issues', - ({ newIssues, resolvedIssues, expectedText }) => { - localState.newIssues = new Array(newIssues).fill({ reason: 'Repetitive code' }); - localState.resolvedIssues = new Array(resolvedIssues).fill({ reason: 'Repetitive code' }); - - expect(getters.codequalityText(localState)).toEqual(expectedText); - }, - ); - }); - - describe('codequalityPopover', () => { - describe('when base report is not available', () => { - it('returns a popover with a documentation link', () => { - localState.status = STATUS_NOT_FOUND; - localState.helpPath = 'codequality_help.html'; - - expect(getters.codequalityPopover(localState).title).toEqual( - 'Base pipeline codequality artifact not found', - ); - expect(getters.codequalityPopover(localState).content).toContain( - 'Learn more about codequality reports', - 'href="codequality_help.html"', - ); - }); - }); - }); -}); diff --git a/spec/frontend/ci/reports/codequality_report/store/mutations_spec.js b/spec/frontend/ci/reports/codequality_report/store/mutations_spec.js deleted file mode 100644 index 22ff86b1040c5d5910624560b0c403fb436b62d2..0000000000000000000000000000000000000000 --- a/spec/frontend/ci/reports/codequality_report/store/mutations_spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import createStore from '~/ci/reports/codequality_report/store'; -import mutations from '~/ci/reports/codequality_report/store/mutations'; -import { STATUS_NOT_FOUND } from '~/ci/reports/constants'; - -describe('Codequality Reports mutations', () => { - let localState; - let localStore; - - beforeEach(() => { - localStore = createStore(); - localState = localStore.state; - }); - - describe('SET_PATHS', () => { - it('sets paths to given values', () => { - const baseBlobPath = 'base/blob/path/'; - const headBlobPath = 'head/blob/path/'; - const reportsPath = 'reports.json'; - const helpPath = 'help.html'; - - mutations.SET_PATHS(localState, { - baseBlobPath, - headBlobPath, - reportsPath, - helpPath, - }); - - expect(localState.baseBlobPath).toEqual(baseBlobPath); - expect(localState.headBlobPath).toEqual(headBlobPath); - expect(localState.reportsPath).toEqual(reportsPath); - expect(localState.helpPath).toEqual(helpPath); - }); - }); - - describe('REQUEST_REPORTS', () => { - it('sets isLoading to true', () => { - mutations.REQUEST_REPORTS(localState); - - expect(localState.isLoading).toEqual(true); - }); - }); - - describe('RECEIVE_REPORTS_SUCCESS', () => { - it('sets isLoading to false', () => { - mutations.RECEIVE_REPORTS_SUCCESS(localState, {}); - - expect(localState.isLoading).toEqual(false); - }); - - it('sets hasError to false', () => { - mutations.RECEIVE_REPORTS_SUCCESS(localState, {}); - - expect(localState.hasError).toEqual(false); - }); - - it('clears status and statusReason', () => { - mutations.RECEIVE_REPORTS_SUCCESS(localState, {}); - - expect(localState.status).toEqual(''); - expect(localState.statusReason).toEqual(''); - }); - - it('sets newIssues and resolvedIssues from response data', () => { - const data = { newIssues: [{ id: 1 }], resolvedIssues: [{ id: 2 }] }; - mutations.RECEIVE_REPORTS_SUCCESS(localState, data); - - expect(localState.newIssues).toEqual(data.newIssues); - expect(localState.resolvedIssues).toEqual(data.resolvedIssues); - }); - }); - - describe('RECEIVE_REPORTS_ERROR', () => { - it('sets isLoading to false', () => { - mutations.RECEIVE_REPORTS_ERROR(localState); - - expect(localState.isLoading).toEqual(false); - }); - - it('sets hasError to true', () => { - mutations.RECEIVE_REPORTS_ERROR(localState); - - expect(localState.hasError).toEqual(true); - }); - - it('sets status based on error object', () => { - const error = { status: STATUS_NOT_FOUND }; - mutations.RECEIVE_REPORTS_ERROR(localState, error); - - expect(localState.status).toEqual(error.status); - }); - - it('sets statusReason to string from error response data', () => { - const data = { status_reason: 'This merge request does not have codequality reports' }; - const error = { response: { data } }; - mutations.RECEIVE_REPORTS_ERROR(localState, error); - - expect(localState.statusReason).toEqual(data.status_reason); - }); - }); -});