Browse Source

SONAR-11875 Connect Code to the branch redux store, and refresh branch status when updating an issue

tags/7.8
Wouter Admiraal 5 years ago
parent
commit
0c1596629e

+ 19
- 4
server/sonar-web/src/main/js/apps/code/components/App.tsx View File

@@ -32,9 +32,9 @@ import { retrieveComponentChildren, retrieveComponent, loadMoreChildren } from '
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget';
import ListFooter from '../../../components/controls/ListFooter';
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import { fetchMetrics } from '../../../store/rootActions';
import { fetchMetrics, fetchBranchStatus } from '../../../store/rootActions';
import { getMetrics } from '../../../store/rootReducer';
import { isSameBranchLike } from '../../../helpers/branches';
import { isSameBranchLike, isPullRequest, isShortLivingBranch } from '../../../helpers/branches';
import { translate } from '../../../helpers/l10n';
import { getProjectUrl, getCodeUrl } from '../../../helpers/urls';
import '../code.css';
@@ -44,6 +44,7 @@ interface StateToProps {
}

interface DispatchToProps {
fetchBranchStatus: (branchLike: T.BranchLike, projectKey: string) => Promise<void>;
fetchMetrics: () => void;
}

@@ -70,7 +71,6 @@ interface State {

export class App extends React.PureComponent<Props, State> {
mounted = false;

state: State = {
breadcrumbs: [],
loading: true,
@@ -190,6 +190,10 @@ export class App extends React.PureComponent<Props, State> {
this.setState({ highlighted });
};

handleIssueChange = (_: T.Issue) => {
this.refreshBranchStatus();
};

handleSearchClear = () => {
this.setState({ searchResults: undefined });
};
@@ -218,6 +222,13 @@ export class App extends React.PureComponent<Props, State> {
this.loadComponent(finalKey);
};

refreshBranchStatus = () => {
const { branchLike, component } = this.props;
if (branchLike && component && (isPullRequest(branchLike) || isShortLivingBranch(branchLike))) {
this.props.fetchBranchStatus(branchLike, component.key);
}
};

render() {
const { branchLike, component, location } = this.props;
const {
@@ -312,6 +323,7 @@ export class App extends React.PureComponent<Props, State> {
isFile={true}
location={location}
onGoToParent={this.handleGoToParent}
onIssueChange={this.handleIssueChange}
/>
</div>
)}
@@ -325,7 +337,10 @@ const mapStateToProps = (state: any): StateToProps => ({
metrics: getMetrics(state)
});

const mapDispatchToProps: DispatchToProps = { fetchMetrics };
const mapDispatchToProps: DispatchToProps = {
fetchBranchStatus: fetchBranchStatus as any,
fetchMetrics
};

export default connect<StateToProps, DispatchToProps, Props>(
mapStateToProps,

+ 2
- 0
server/sonar-web/src/main/js/apps/code/components/SourceViewerWrapper.tsx View File

@@ -27,6 +27,7 @@ interface Props {
branchLike?: T.BranchLike;
component: string;
location: Pick<Location, 'query'>;
onIssueChange?: (issue: T.Issue) => void;
}

export class SourceViewerWrapper extends React.PureComponent<Props> {
@@ -53,6 +54,7 @@ export class SourceViewerWrapper extends React.PureComponent<Props> {
branchLike={branchLike}
component={component}
highlightedLine={finalLine}
onIssueChange={this.props.onIssueChange}
onLoaded={this.scrollToLine}
showMeasures={true}
/>

+ 20
- 7
server/sonar-web/src/main/js/apps/code/components/__tests__/App-test.tsx View File

@@ -21,7 +21,7 @@ import * as React from 'react';
import { shallow } from 'enzyme';
import { App } from '../App';
import { retrieveComponent } from '../../utils';
import { mockRouter } from '../../../../helpers/testMocks';
import { mockRouter, mockPullRequest, mockIssue } from '../../../../helpers/testMocks';
import { waitAndUpdate } from '../../../../helpers/testUtils';

jest.mock('../../utils', () => ({
@@ -45,7 +45,7 @@ beforeEach(() => {
});

it('should have correct title for APP based component', async () => {
const wrapper = getWrapper();
const wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.find('HelmetWrapper')).toMatchSnapshot();
});
@@ -58,7 +58,7 @@ it('should have correct title for portfolio base component', async () => {
page: 0,
total: 1
});
const wrapper = getWrapper();
const wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.find('HelmetWrapper')).toMatchSnapshot();
});
@@ -71,13 +71,24 @@ it('should have correct title for project component', async () => {
page: 0,
total: 1
});
const wrapper = getWrapper();
const wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.find('HelmetWrapper')).toMatchSnapshot();
});

const getWrapper = () => {
return shallow(
it('should refresh branch status if issues are updated', async () => {
const fetchBranchStatus = jest.fn();
const branchLike = mockPullRequest();
const wrapper = shallowRender({ branchLike, fetchBranchStatus });
const instance = wrapper.instance();
await waitAndUpdate(wrapper);

instance.handleIssueChange(mockIssue());
expect(fetchBranchStatus).toBeCalledWith(branchLike, 'foo');
});

function shallowRender(props: Partial<App['props']> = {}) {
return shallow<App>(
<App
component={{
breadcrumbs: [],
@@ -86,10 +97,12 @@ const getWrapper = () => {
organization: 'foo',
qualifier: 'FOO'
}}
fetchBranchStatus={jest.fn()}
fetchMetrics={jest.fn()}
location={{ query: { branch: 'b', id: 'foo', line: '7' } }}
metrics={METRICS}
router={mockRouter()}
{...props}
/>
);
};
}

Loading…
Cancel
Save