@@ -0,0 +1,23 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
module.exports = { | |||
...require.requireActual('lodash'), | |||
debounce: (fn: Function) => (...args: any[]) => fn(...args) | |||
}; |
@@ -17,22 +17,63 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { registerBranchStatus } from '../rootActions'; | |||
import { mockLongLivingBranch } from '../../helpers/testMocks'; | |||
import { registerBranchStatus, fetchBranchStatus } from '../rootActions'; | |||
import { mockLongLivingBranch, mockQualityGateStatusCondition } from '../../helpers/testMocks'; | |||
import { registerBranchStatusAction } from '../branches'; | |||
jest.useFakeTimers(); | |||
jest.mock('../branches', () => ({ | |||
...require.requireActual('../branches'), | |||
registerBranchStatusAction: jest.fn() | |||
})); | |||
it('correctly dispatches actions for branches', () => { | |||
const dispatch = jest.fn(); | |||
jest.mock('../../api/quality-gates', () => { | |||
const { mockQualityGateProjectStatus } = require.requireActual('../../helpers/testMocks'); | |||
return { | |||
getQualityGateProjectStatus: jest.fn().mockResolvedValue( | |||
mockQualityGateProjectStatus({ | |||
conditions: [ | |||
{ | |||
actualValue: '10', | |||
comparator: 'GT', | |||
errorThreshold: '0', | |||
metricKey: 'foo', | |||
periodIndex: 1, | |||
status: 'ERROR' | |||
} | |||
] | |||
}) | |||
) | |||
}; | |||
}); | |||
describe('branch store actions', () => { | |||
const branchLike = mockLongLivingBranch(); | |||
const component = 'foo'; | |||
const status = 'OK'; | |||
registerBranchStatus(branchLike, component, status)(dispatch); | |||
expect(registerBranchStatusAction).toBeCalledWith(branchLike, component, status); | |||
expect(dispatch).toBeCalled(); | |||
it('correctly registers a new branch status', () => { | |||
const dispatch = jest.fn(); | |||
registerBranchStatus(branchLike, component, status)(dispatch); | |||
expect(registerBranchStatusAction).toBeCalledWith(branchLike, component, status); | |||
expect(dispatch).toBeCalled(); | |||
}); | |||
it('correctly fetches a branch status', async () => { | |||
const dispatch = jest.fn(); | |||
fetchBranchStatus(branchLike, component)(dispatch); | |||
jest.runAllTimers(); | |||
await new Promise(setImmediate); | |||
expect(registerBranchStatusAction).toBeCalledWith(branchLike, component, status, [ | |||
mockQualityGateStatusCondition({ | |||
period: 1 | |||
}) | |||
]); | |||
expect(dispatch).toBeCalled(); | |||
}); | |||
}); |
@@ -19,6 +19,7 @@ | |||
*/ | |||
import { Dispatch } from 'redux'; | |||
import { InjectedRouter } from 'react-router'; | |||
import { debounce } from 'lodash'; | |||
import { requireAuthorization as requireAuthorizationAction } from './appState'; | |||
import { registerBranchStatusAction } from './branches'; | |||
import { addGlobalErrorMessage } from './globalMessages'; | |||
@@ -29,6 +30,9 @@ import * as auth from '../api/auth'; | |||
import { getLanguages } from '../api/languages'; | |||
import { getAllMetrics } from '../api/metrics'; | |||
import { getOrganizations, getOrganization, getOrganizationNavigation } from '../api/organizations'; | |||
import { getQualityGateProjectStatus } from '../api/quality-gates'; | |||
import { getBranchLikeQuery } from '../helpers/branches'; | |||
import { extractStatusConditionsFromProjectStatus } from '../helpers/qualityGates'; | |||
export function fetchLanguages() { | |||
return (dispatch: Dispatch) => { | |||
@@ -62,6 +66,21 @@ export const fetchOrganization = (key: string) => (dispatch: Dispatch) => { | |||
); | |||
}; | |||
export function fetchBranchStatus(branchLike: T.BranchLike, projectKey: string) { | |||
return debounce((dispatch: Dispatch<any>) => { | |||
getQualityGateProjectStatus({ projectKey, ...getBranchLikeQuery(branchLike) }).then( | |||
projectStatus => { | |||
const { status } = projectStatus; | |||
const conditions = extractStatusConditionsFromProjectStatus(projectStatus); | |||
dispatch(registerBranchStatusAction(branchLike, projectKey, status, conditions)); | |||
}, | |||
() => { | |||
dispatch(addGlobalErrorMessage('Fetching Quality Gate status failed')); | |||
} | |||
); | |||
}, 1000); | |||
} | |||
export function doLogin(login: string, password: string) { | |||
return (dispatch: Dispatch<any>) => | |||
auth.login(login, password).then( |