aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2019-06-06 11:09:45 +0200
committersonartech <sonartech@sonarsource.com>2019-06-28 08:45:38 +0200
commit2ed3bdc4997ed05e5486940abc726dc008f6cd20 (patch)
treeebb39b5f14a17b14458d2ac750a72d2ae6c85f2d
parent9c3628f7f4d5745c010cb2f958129495fdcda632 (diff)
downloadsonarqube-2ed3bdc4997ed05e5486940abc726dc008f6cd20.tar.gz
sonarqube-2ed3bdc4997ed05e5486940abc726dc008f6cd20.zip
SONAR-11773 Make issues 'See Rules Details' accessible
-rw-r--r--server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx23
-rw-r--r--server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx29
-rw-r--r--server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap3
3 files changed, 52 insertions, 3 deletions
diff --git a/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx b/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx
index c30aa9279d8..e418177f965 100644
--- a/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx
+++ b/server/sonar-web/src/main/js/components/workspace/WorkspaceRuleViewer.tsx
@@ -30,17 +30,34 @@ export interface Props extends T.Omit<WorkspaceHeaderProps, 'children' | 'onClos
onLoad: (details: { key: string; name: string }) => void;
}
+interface State {
+ loading: boolean;
+}
+
export default class WorkspaceRuleViewer extends React.PureComponent<Props> {
+ state: State = { loading: true };
+
+ componentDidUpdate(prevProps: Props) {
+ if (prevProps.rule.key !== this.props.rule.key) {
+ this.setState({ loading: true });
+ }
+ }
+
handleClose = () => {
this.props.onClose(this.props.rule.key);
};
handleLoaded = (rule: { name: string }) => {
this.props.onLoad({ key: this.props.rule.key, name: rule.name });
+ // Allow time for the actual rendering, and the browser to pick it up.
+ setTimeout(() => {
+ this.setState({ loading: false });
+ }, 1000);
};
render() {
const { rule } = this.props;
+ const { loading } = this.state;
return (
<div className="workspace-viewer">
@@ -54,7 +71,11 @@ export default class WorkspaceRuleViewer extends React.PureComponent<Props> {
<WorkspaceRuleTitle rule={rule} />
</WorkspaceHeader>
- <div className="workspace-viewer-container" style={{ height: this.props.height }}>
+ <div
+ aria-busy={loading}
+ aria-live="polite"
+ className="workspace-viewer-container"
+ style={{ height: this.props.height }}>
<WorkspaceRuleDetails
onLoad={this.handleLoaded}
organizationKey={rule.organization}
diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx
index 9092b38f1ec..62d39d710e4 100644
--- a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx
+++ b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceRuleViewer-test.tsx
@@ -21,10 +21,35 @@ import * as React from 'react';
import { shallow } from 'enzyme';
import WorkspaceRuleViewer, { Props } from '../WorkspaceRuleViewer';
+jest.useFakeTimers();
+
it('should render', () => {
expect(shallowRender()).toMatchSnapshot();
});
+it('should correctly mark the content as busy loading (aria)', () => {
+ const rule = { key: 'foo', name: 'Foo', organization: 'org' };
+ const wrapper = shallowRender({ rule });
+ const instance = wrapper.instance();
+ const container = () => wrapper.find('.workspace-viewer-container');
+
+ expect(container().prop('aria-busy')).toBe(true);
+
+ instance.handleLoaded(rule);
+ jest.runAllTimers();
+ wrapper.update();
+ expect(container().prop('aria-busy')).toBe(false);
+
+ const newRule = { key: 'bar', name: 'Bar', organization: 'org' };
+ wrapper.setProps({ rule: newRule }).update();
+ expect(container().prop('aria-busy')).toBe(true);
+
+ instance.handleLoaded(newRule);
+ jest.runAllTimers();
+ wrapper.update();
+ expect(container().prop('aria-busy')).toBe(false);
+});
+
it('should close', () => {
const onClose = jest.fn();
const wrapper = shallowRender({ onClose });
@@ -41,8 +66,8 @@ it('should call back after load', () => {
});
function shallowRender(props?: Partial<Props>) {
- const rule = { key: 'foo', organization: 'org' };
- return shallow(
+ const rule = { key: 'foo', name: 'Foo', organization: 'org' };
+ return shallow<WorkspaceRuleViewer>(
<WorkspaceRuleViewer
height={300}
onClose={jest.fn()}
diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap
index 9af15132081..f2515a8cfca 100644
--- a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceRuleViewer-test.tsx.snap
@@ -15,12 +15,15 @@ exports[`should render 1`] = `
rule={
Object {
"key": "foo",
+ "name": "Foo",
"organization": "org",
}
}
/>
</WorkspaceHeader>
<div
+ aria-busy={true}
+ aria-live="polite"
className="workspace-viewer-container"
style={
Object {