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';
}
interface DispatchToProps {
+ fetchBranchStatus: (branchLike: T.BranchLike, projectKey: string) => Promise<void>;
fetchMetrics: () => void;
}
export class App extends React.PureComponent<Props, State> {
mounted = false;
-
state: State = {
breadcrumbs: [],
loading: true,
this.setState({ highlighted });
};
+ handleIssueChange = (_: T.Issue) => {
+ this.refreshBranchStatus();
+ };
+
handleSearchClear = () => {
this.setState({ searchResults: undefined });
};
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 {
isFile={true}
location={location}
onGoToParent={this.handleGoToParent}
+ onIssueChange={this.handleIssueChange}
/>
</div>
)}
metrics: getMetrics(state)
});
-const mapDispatchToProps: DispatchToProps = { fetchMetrics };
+const mapDispatchToProps: DispatchToProps = {
+ fetchBranchStatus: fetchBranchStatus as any,
+ fetchMetrics
+};
export default connect<StateToProps, DispatchToProps, Props>(
mapStateToProps,
branchLike?: T.BranchLike;
component: string;
location: Pick<Location, 'query'>;
+ onIssueChange?: (issue: T.Issue) => void;
}
export class SourceViewerWrapper extends React.PureComponent<Props> {
branchLike={branchLike}
component={component}
highlightedLine={finalLine}
+ onIssueChange={this.props.onIssueChange}
onLoaded={this.scrollToLine}
showMeasures={true}
/>
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', () => ({
});
it('should have correct title for APP based component', async () => {
- const wrapper = getWrapper();
+ const wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.find('HelmetWrapper')).toMatchSnapshot();
});
page: 0,
total: 1
});
- const wrapper = getWrapper();
+ const wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.find('HelmetWrapper')).toMatchSnapshot();
});
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: [],
organization: 'foo',
qualifier: 'FOO'
}}
+ fetchBranchStatus={jest.fn()}
fetchMetrics={jest.fn()}
location={{ query: { branch: 'b', id: 'foo', line: '7' } }}
metrics={METRICS}
router={mockRouter()}
+ {...props}
/>
);
-};
+}