@@ -19,7 +19,7 @@ | |||
*/ | |||
import React from 'react'; | |||
import Checkbox from '../../../components/controls/Checkbox'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { translate, hasMessage } from '../../../helpers/l10n'; | |||
/*:: import type { | |||
Notification, | |||
NotificationsState, | |||
@@ -33,6 +33,7 @@ export default class NotificationsList extends React.PureComponent { | |||
onRemove: (n: Notification) => void, | |||
channels: ChannelsState, | |||
checkboxId: (string, string) => string, | |||
project?: boolean, | |||
types: TypesState, | |||
notifications: NotificationsState | |||
}; | |||
@@ -52,6 +53,15 @@ export default class NotificationsList extends React.PureComponent { | |||
} | |||
} | |||
getDispatcherLabel(dispatcher /*: string */) { | |||
const globalMessageKey = ['notification.dispatcher', dispatcher]; | |||
const projectMessageKey = [...globalMessageKey, 'project']; | |||
const shouldUseProjectMessage = this.props.project && hasMessage(...projectMessageKey); | |||
return shouldUseProjectMessage | |||
? translate(...projectMessageKey) | |||
: translate(...globalMessageKey); | |||
} | |||
render() { | |||
const { channels, checkboxId, types } = this.props; | |||
@@ -59,7 +69,7 @@ export default class NotificationsList extends React.PureComponent { | |||
<tbody> | |||
{types.map(type => ( | |||
<tr key={type}> | |||
<td>{translate('notification.dispatcher', type)}</td> | |||
<td>{this.getDispatcherLabel(type)}</td> | |||
{channels.map(channel => ( | |||
<td key={channel} className="text-center"> | |||
<Checkbox |
@@ -99,6 +99,7 @@ class ProjectNotifications extends React.PureComponent { | |||
checkboxId={(d, c) => `project-notification-${project.key}-${d}-${c}`} | |||
onAdd={n => this.handleAddNotification(n)} | |||
onRemove={n => this.handleRemoveNotification(n)} | |||
project={true} | |||
/> | |||
</table> | |||
); |
@@ -17,10 +17,18 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
/* eslint-disable import/first */ | |||
jest.mock('../../../../helpers/l10n', () => { | |||
const l10n = require.requireActual('../../../../helpers/l10n'); | |||
l10n.hasMessage = jest.fn(); | |||
return l10n; | |||
}); | |||
import React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import NotificationsList from '../NotificationsList'; | |||
import Checkbox from '../../../../components/controls/Checkbox'; | |||
import { hasMessage } from '../../../../helpers/l10n'; | |||
const channels = ['channel1', 'channel2']; | |||
const types = ['type1', 'type2']; | |||
@@ -31,6 +39,10 @@ const notifications = [ | |||
]; | |||
const checkboxId = (t, c) => `checkbox-io-${t}-${c}`; | |||
beforeEach(() => { | |||
hasMessage.mockImplementation(() => false).mockClear(); | |||
}); | |||
it('should match snapshot', () => { | |||
expect( | |||
shallow( | |||
@@ -46,6 +58,25 @@ it('should match snapshot', () => { | |||
).toMatchSnapshot(); | |||
}); | |||
it('renders project-specific labels', () => { | |||
hasMessage.mockImplementation(() => true); | |||
expect( | |||
shallow( | |||
<NotificationsList | |||
onAdd={jest.fn()} | |||
onRemove={jest.fn()} | |||
channels={channels} | |||
checkboxId={checkboxId} | |||
project={true} | |||
types={types} | |||
notifications={notifications} | |||
/> | |||
) | |||
).toMatchSnapshot(); | |||
expect(hasMessage).toBeCalledWith('notification.dispatcher', 'type1', 'project'); | |||
expect(hasMessage).toBeCalledWith('notification.dispatcher', 'type2', 'project'); | |||
}); | |||
it('should call `onAdd` and `onRemove`', () => { | |||
const onAdd = jest.fn(); | |||
const onRemove = jest.fn(); |
@@ -1,5 +1,60 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`renders project-specific labels 1`] = ` | |||
<tbody> | |||
<tr> | |||
<td> | |||
notification.dispatcher.type1.project | |||
</td> | |||
<td | |||
className="text-center" | |||
> | |||
<Checkbox | |||
checked={true} | |||
id="checkbox-io-type1-channel1" | |||
onCheck={[Function]} | |||
thirdState={false} | |||
/> | |||
</td> | |||
<td | |||
className="text-center" | |||
> | |||
<Checkbox | |||
checked={false} | |||
id="checkbox-io-type1-channel2" | |||
onCheck={[Function]} | |||
thirdState={false} | |||
/> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td> | |||
notification.dispatcher.type2.project | |||
</td> | |||
<td | |||
className="text-center" | |||
> | |||
<Checkbox | |||
checked={true} | |||
id="checkbox-io-type2-channel1" | |||
onCheck={[Function]} | |||
thirdState={false} | |||
/> | |||
</td> | |||
<td | |||
className="text-center" | |||
> | |||
<Checkbox | |||
checked={true} | |||
id="checkbox-io-type2-channel2" | |||
onCheck={[Function]} | |||
thirdState={false} | |||
/> | |||
</td> | |||
</tr> | |||
</tbody> | |||
`; | |||
exports[`should match snapshot 1`] = ` | |||
<tbody> | |||
<tr> |
@@ -74,6 +74,7 @@ exports[`should match snapshot 1`] = ` | |||
} | |||
onAdd={[Function]} | |||
onRemove={[Function]} | |||
project={true} | |||
types={ | |||
Array [ | |||
"type1", |
@@ -1862,7 +1862,8 @@ notification.dispatcher.NewIssues=New issues | |||
notification.dispatcher.NewAlerts=New quality gate status | |||
notification.dispatcher.NewFalsePositiveIssue=Issues resolved as false positive or won't fix | |||
notification.dispatcher.SQ-MyNewIssues=My new issues | |||
notification.dispatcher.CeReportTaskFailure=Report processing failure | |||
notification.dispatcher.CeReportTaskFailure=Background tasks in failure on my administered projects | |||
notification.dispatcher.CeReportTaskFailure.project=Background tasks in failure | |||
#------------------------------------------------------------------------------ |