|
|
|
|
|
|
|
|
import { act, fireEvent, screen } from '@testing-library/react'; |
|
|
import { act, fireEvent, screen } from '@testing-library/react'; |
|
|
import selectEvent from 'react-select-event'; |
|
|
import selectEvent from 'react-select-event'; |
|
|
import CodingRulesServiceMock, { RULE_TAGS_MOCK } from '../../../api/mocks/CodingRulesServiceMock'; |
|
|
import CodingRulesServiceMock, { RULE_TAGS_MOCK } from '../../../api/mocks/CodingRulesServiceMock'; |
|
|
|
|
|
import SettingsServiceMock from '../../../api/mocks/SettingsServiceMock'; |
|
|
|
|
|
import { QP_2 } from '../../../api/mocks/data/ids'; |
|
|
import { CLEAN_CODE_CATEGORIES, SOFTWARE_QUALITIES } from '../../../helpers/constants'; |
|
|
import { CLEAN_CODE_CATEGORIES, SOFTWARE_QUALITIES } from '../../../helpers/constants'; |
|
|
import { parseDate } from '../../../helpers/dates'; |
|
|
import { parseDate } from '../../../helpers/dates'; |
|
|
import { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks'; |
|
|
import { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks'; |
|
|
|
|
|
|
|
|
CleanCodeAttributeCategory, |
|
|
CleanCodeAttributeCategory, |
|
|
SoftwareQuality, |
|
|
SoftwareQuality, |
|
|
} from '../../../types/clean-code-taxonomy'; |
|
|
} from '../../../types/clean-code-taxonomy'; |
|
|
|
|
|
import { SettingsKey } from '../../../types/settings'; |
|
|
import { CurrentUser } from '../../../types/users'; |
|
|
import { CurrentUser } from '../../../types/users'; |
|
|
import routes from '../routes'; |
|
|
import routes from '../routes'; |
|
|
import { getPageObjects } from '../utils-tests'; |
|
|
import { getPageObjects } from '../utils-tests'; |
|
|
|
|
|
|
|
|
const handler: CodingRulesServiceMock = new CodingRulesServiceMock(); |
|
|
|
|
|
|
|
|
const rulesHandler = new CodingRulesServiceMock(); |
|
|
|
|
|
const settingsHandler = new SettingsServiceMock(); |
|
|
|
|
|
|
|
|
afterEach(() => handler.reset()); |
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
|
rulesHandler.reset(); |
|
|
|
|
|
settingsHandler.reset(); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
describe('Rules app list', () => { |
|
|
describe('Rules app list', () => { |
|
|
it('renders correctly', async () => { |
|
|
it('renders correctly', async () => { |
|
|
|
|
|
|
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
// Renders list |
|
|
// Renders list |
|
|
handler |
|
|
|
|
|
|
|
|
rulesHandler |
|
|
.allRulesName() |
|
|
.allRulesName() |
|
|
.forEach((name) => expect(ui.ruleListItemLink(name).get()).toBeInTheDocument()); |
|
|
.forEach((name) => expect(ui.ruleListItemLink(name).get()).toBeInTheDocument()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('bulk change', () => { |
|
|
describe('bulk change', () => { |
|
|
it('no quality profile for bulk change based on language search', async () => { |
|
|
it('no quality profile for bulk change based on language search', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should be able to bulk activate quality profile', async () => { |
|
|
it('should be able to bulk activate quality profile', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
const [selectQPSuccess, selectQPWarning] = handler.allQualityProfile('java'); |
|
|
|
|
|
|
|
|
const [selectQPSuccess, selectQPWarning] = rulesHandler.allQualityProfile('java'); |
|
|
|
|
|
|
|
|
const rulesCount = handler.allRulesCount(); |
|
|
|
|
|
|
|
|
const rulesCount = rulesHandler.allRulesCount(); |
|
|
|
|
|
|
|
|
await ui.bulkActivate(rulesCount, selectQPSuccess); |
|
|
await ui.bulkActivate(rulesCount, selectQPSuccess); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await user.click(ui.bulkClose.get()); |
|
|
await user.click(ui.bulkClose.get()); |
|
|
|
|
|
|
|
|
// Try bulk change when quality profile has warnning. |
|
|
// Try bulk change when quality profile has warnning. |
|
|
handler.activateWithWarning(); |
|
|
|
|
|
|
|
|
rulesHandler.activateWithWarning(); |
|
|
|
|
|
|
|
|
await ui.bulkActivate(rulesCount, selectQPWarning); |
|
|
await ui.bulkActivate(rulesCount, selectQPWarning); |
|
|
expect( |
|
|
expect( |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should be able to bulk deactivate quality profile', async () => { |
|
|
it('should be able to bulk deactivate quality profile', async () => { |
|
|
const { ui } = getPageObjects(); |
|
|
const { ui } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
const [selectQP] = handler.allQualityProfile('java'); |
|
|
|
|
|
const rulesCount = handler.allRulesCount(); |
|
|
|
|
|
|
|
|
const [selectQP] = rulesHandler.allQualityProfile('java'); |
|
|
|
|
|
const rulesCount = rulesHandler.allRulesCount(); |
|
|
|
|
|
|
|
|
await ui.bulkDeactivate(rulesCount, selectQP); |
|
|
await ui.bulkDeactivate(rulesCount, selectQP); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can activate/deactivate specific rule for quality profile', async () => { |
|
|
it('can activate/deactivate specific rule for quality profile', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
await act(async () => { |
|
|
await act(async () => { |
|
|
await user.click(ui.qpFacet.get()); |
|
|
await user.click(ui.qpFacet.get()); |
|
|
await user.click(ui.facetItem('QP Foo Java').get()); |
|
|
|
|
|
|
|
|
await user.click(ui.facetItem('QP Bar Python').get()); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Only one rule is activated in selected QP |
|
|
|
|
|
expect(ui.ruleListItem.getAll(ui.rulesList.get())).toHaveLength(1); |
|
|
|
|
|
|
|
|
// Only 4 rules are activated in selected QP |
|
|
|
|
|
expect(ui.ruleListItem.getAll(ui.rulesList.get())).toHaveLength(4); |
|
|
|
|
|
|
|
|
// Switch to inactive rules |
|
|
// Switch to inactive rules |
|
|
await act(async () => { |
|
|
await act(async () => { |
|
|
await user.click(ui.qpInactiveRadio.get(ui.facetItem('QP Foo Java').get())); |
|
|
|
|
|
|
|
|
await user.click(ui.qpInactiveRadio.get(ui.facetItem('QP Bar Python').get())); |
|
|
}); |
|
|
}); |
|
|
expect(ui.ruleListItem.getAll(ui.rulesList.get())).toHaveLength(1); |
|
|
|
|
|
|
|
|
expect(ui.ruleListItem.getAll(ui.rulesList.get())).toHaveLength(2); |
|
|
|
|
|
expect(ui.activateButton.getAll()).toHaveLength(2); |
|
|
|
|
|
|
|
|
// Activate Rule for qp |
|
|
// Activate Rule for qp |
|
|
await user.click(ui.activateButton.get()); |
|
|
|
|
|
|
|
|
await user.click(ui.activateButton.getAll()[0]); |
|
|
await user.click(ui.activateButton.get(ui.activateQPDialog.get())); |
|
|
await user.click(ui.activateButton.get(ui.activateQPDialog.get())); |
|
|
expect(ui.activateButton.query()).not.toBeInTheDocument(); |
|
|
|
|
|
expect(ui.deactivateButton.get()).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
expect(ui.activateButton.getAll()).toHaveLength(1); |
|
|
|
|
|
expect(ui.deactivateButton.getAll()).toHaveLength(1); |
|
|
|
|
|
|
|
|
// Deactivate activated rule |
|
|
// Deactivate activated rule |
|
|
await user.click(ui.deactivateButton.get()); |
|
|
await user.click(ui.deactivateButton.get()); |
|
|
await user.click(ui.yesButton.get()); |
|
|
await user.click(ui.yesButton.get()); |
|
|
expect(ui.deactivateButton.query()).not.toBeInTheDocument(); |
|
|
expect(ui.deactivateButton.query()).not.toBeInTheDocument(); |
|
|
expect(ui.activateButton.get()).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
expect(ui.activateButton.getAll()).toHaveLength(2); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('can not deactivate rules for quality profile if setting is false', async () => { |
|
|
|
|
|
const { ui } = getPageObjects(); |
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
|
|
|
settingsHandler.set(SettingsKey.QPAdminCanDisableInheritedRules, 'false'); |
|
|
|
|
|
renderCodingRulesApp( |
|
|
|
|
|
mockLoggedInUser(), |
|
|
|
|
|
'coding_rules?activation=true&tags=cute&qprofile=' + QP_2, |
|
|
|
|
|
); |
|
|
|
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
// Only rule 9 is shown (inherited, activated) |
|
|
|
|
|
expect(ui.ruleListItem.getAll(ui.rulesList.get())).toHaveLength(1); |
|
|
|
|
|
expect(ui.deactivateButton.get()).toBeDisabled(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
it('navigates by keyboard', async () => { |
|
|
it('navigates by keyboard', async () => { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can activate/change/deactivate rule in quality profile', async () => { |
|
|
it('can activate/change/deactivate rule in quality profile', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule1'); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule1'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
expect(ui.qpLink('QP Foo').get()).toBeInTheDocument(); |
|
|
expect(ui.qpLink('QP Foo').get()).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can extend the rule description', async () => { |
|
|
it('can extend the rule description', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(undefined, 'coding_rules?open=rule5'); |
|
|
renderCodingRulesApp(undefined, 'coding_rules?open=rule5'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
expect(ui.ruleTitle('Awsome Python rule').get()).toBeInTheDocument(); |
|
|
expect(ui.ruleTitle('Awsome Python rule').get()).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can set tags', async () => { |
|
|
it('can set tags', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(undefined, 'coding_rules?open=rule10'); |
|
|
renderCodingRulesApp(undefined, 'coding_rules?open=rule10'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('custom rule', () => { |
|
|
describe('custom rule', () => { |
|
|
it('can create custom rule', async () => { |
|
|
it('can create custom rule', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
renderCodingRulesApp(mockLoggedInUser()); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can edit custom rule', async () => { |
|
|
it('can edit custom rule', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule9'); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule9'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can delete custom rule', async () => { |
|
|
it('can delete custom rule', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule9'); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule9'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can delete custom rule from template page', async () => { |
|
|
it('can delete custom rule from template page', async () => { |
|
|
const { ui, user } = getPageObjects(); |
|
|
const { ui, user } = getPageObjects(); |
|
|
handler.setIsAdmin(); |
|
|
|
|
|
|
|
|
rulesHandler.setIsAdmin(); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule8'); |
|
|
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule8'); |
|
|
await ui.appLoaded(); |
|
|
await ui.appLoaded(); |
|
|
|
|
|
|