RuleDetails.test.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { render } from '@testing-library/react';
  2. import React from 'react';
  3. import { Provider } from 'react-redux';
  4. import { MemoryRouter } from 'react-router-dom';
  5. import { byRole } from 'testing-library-selector';
  6. import { contextSrv } from 'app/core/services/context_srv';
  7. import { configureStore } from 'app/store/configureStore';
  8. import { AccessControlAction } from 'app/types';
  9. import { CombinedRule } from 'app/types/unified-alerting';
  10. import { useIsRuleEditable } from '../../hooks/useIsRuleEditable';
  11. import { mockCombinedRule, mockDataSource, mockPromAlertingRule, mockRulerAlertingRule } from '../../mocks';
  12. import { RuleDetails } from './RuleDetails';
  13. jest.mock('../../hooks/useIsRuleEditable');
  14. const mocks = {
  15. useIsRuleEditable: jest.mocked(useIsRuleEditable),
  16. };
  17. const ui = {
  18. actionButtons: {
  19. edit: byRole('link', { name: 'Edit' }),
  20. delete: byRole('button', { name: 'Delete' }),
  21. silence: byRole('link', { name: 'Silence' }),
  22. },
  23. };
  24. jest.spyOn(contextSrv, 'accessControlEnabled').mockReturnValue(true);
  25. describe('RuleDetails RBAC', () => {
  26. describe('Grafana rules action buttons', () => {
  27. const grafanaRule = getGrafanaRule({ name: 'Grafana' });
  28. it('Should not render Edit button for users without the update permission', () => {
  29. // Arrange
  30. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isEditable: false });
  31. // Act
  32. renderRuleDetails(grafanaRule);
  33. // Assert
  34. expect(ui.actionButtons.edit.query()).not.toBeInTheDocument();
  35. });
  36. it('Should not render Delete button for users without the delete permission', () => {
  37. // Arrange
  38. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isRemovable: false });
  39. // Act
  40. renderRuleDetails(grafanaRule);
  41. // Assert
  42. expect(ui.actionButtons.delete.query()).not.toBeInTheDocument();
  43. });
  44. it('Should render Edit button for users with the update permission', () => {
  45. // Arrange
  46. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isEditable: true });
  47. // Act
  48. renderRuleDetails(grafanaRule);
  49. // Assert
  50. expect(ui.actionButtons.edit.query()).toBeInTheDocument();
  51. });
  52. it('Should render Delete button for users with the delete permission', () => {
  53. // Arrange
  54. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isRemovable: true });
  55. // Act
  56. renderRuleDetails(grafanaRule);
  57. // Assert
  58. expect(ui.actionButtons.delete.query()).toBeInTheDocument();
  59. });
  60. it('Should not render Silence button for users wihout the instance create permission', () => {
  61. // Arrange
  62. jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(false);
  63. // Act
  64. renderRuleDetails(grafanaRule);
  65. // Assert
  66. expect(ui.actionButtons.silence.query()).not.toBeInTheDocument();
  67. });
  68. it('Should render Silence button for users with the instance create permissions', () => {
  69. // Arrange
  70. jest
  71. .spyOn(contextSrv, 'hasPermission')
  72. .mockImplementation((action) => action === AccessControlAction.AlertingInstanceCreate);
  73. // Act
  74. renderRuleDetails(grafanaRule);
  75. // Assert
  76. expect(ui.actionButtons.silence.query()).toBeInTheDocument();
  77. });
  78. });
  79. describe('Cloud rules action buttons', () => {
  80. const cloudRule = getCloudRule({ name: 'Cloud' });
  81. it('Should not render Edit button for users without the update permission', () => {
  82. // Arrange
  83. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isEditable: false });
  84. // Act
  85. renderRuleDetails(cloudRule);
  86. // Assert
  87. expect(ui.actionButtons.edit.query()).not.toBeInTheDocument();
  88. });
  89. it('Should not render Delete button for users without the delete permission', () => {
  90. // Arrange
  91. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isRemovable: false });
  92. // Act
  93. renderRuleDetails(cloudRule);
  94. // Assert
  95. expect(ui.actionButtons.delete.query()).not.toBeInTheDocument();
  96. });
  97. it('Should render Edit button for users with the update permission', () => {
  98. // Arrange
  99. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isEditable: true });
  100. // Act
  101. renderRuleDetails(cloudRule);
  102. // Assert
  103. expect(ui.actionButtons.edit.query()).toBeInTheDocument();
  104. });
  105. it('Should render Delete button for users with the delete permission', () => {
  106. // Arrange
  107. mocks.useIsRuleEditable.mockReturnValue({ loading: false, isRemovable: true });
  108. // Act
  109. renderRuleDetails(cloudRule);
  110. // Assert
  111. expect(ui.actionButtons.delete.query()).toBeInTheDocument();
  112. });
  113. });
  114. });
  115. function renderRuleDetails(rule: CombinedRule) {
  116. const store = configureStore();
  117. render(
  118. <Provider store={store}>
  119. <MemoryRouter>
  120. <RuleDetails rule={rule} />
  121. </MemoryRouter>
  122. </Provider>
  123. );
  124. }
  125. function getGrafanaRule(override?: Partial<CombinedRule>) {
  126. return mockCombinedRule({
  127. namespace: {
  128. groups: [],
  129. name: 'Grafana',
  130. rulesSource: 'grafana',
  131. },
  132. ...override,
  133. });
  134. }
  135. function getCloudRule(override?: Partial<CombinedRule>) {
  136. return mockCombinedRule({
  137. namespace: {
  138. groups: [],
  139. name: 'Cortex',
  140. rulesSource: mockDataSource(),
  141. },
  142. promRule: mockPromAlertingRule(),
  143. rulerRule: mockRulerAlertingRule(),
  144. ...override,
  145. });
  146. }