aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-12-01 15:44:27 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-12-04 16:02:52 +0100
commit08be68fda3cfd859ab412bfa634409d211f79927 (patch)
treedf9db70e60787cf0cbcef503dc6c468478dba65c
parentf25ece8fe820b708f08aac652cdda94183bcb2df (diff)
downloadsonarqube-08be68fda3cfd859ab412bfa634409d211f79927.tar.gz
sonarqube-08be68fda3cfd859ab412bfa634409d211f79927.zip
SONAR-10074 Use new QP actions 'delete' and 'associateProjects'
-rw-r--r--server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java14
-rw-r--r--server/sonar-web/src/main/js/api/quality-profiles.ts4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx17
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/__snapshots__/ProfileActions-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx40
-rw-r--r--tests/src/test/java/org/sonarqube/tests/qualityProfile/OrganizationQualityProfilesUiTest.java11
8 files changed, 76 insertions, 43 deletions
diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java
index 88b009687b0..0541b1bd794 100644
--- a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java
+++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java
@@ -48,7 +48,19 @@ public class QualityProfilePage {
public QualityProfilePage shouldAllowToChangeProjects() {
Selenide.$(".js-change-projects").shouldBe(Condition.visible).click();
- Selenide.$("#profile-projects .select-list-list").shouldBe(Condition.visible);
+ Selenide.$("#profile-projects .select-list-list-container").shouldBe(Condition.visible);
+ return this;
+ }
+
+ public QualityProfilePage shouldNotAllowToChangeProjects() {
+ Selenide.$(".js-change-projects").shouldNot(Condition.exist);
+ return this;
+ }
+
+ public QualityProfilePage shouldNotAllowToEdit() {
+ Selenide.$("button.dropdown-toggle").should(Condition.exist).click();
+ Selenide.$("#quality-profile-rename").shouldNot(Condition.exist);
+ Selenide.$("#quality-profile-activate-more-rules").shouldNot(Condition.exist);
return this;
}
}
diff --git a/server/sonar-web/src/main/js/api/quality-profiles.ts b/server/sonar-web/src/main/js/api/quality-profiles.ts
index 77bc1868809..5488682fa16 100644
--- a/server/sonar-web/src/main/js/api/quality-profiles.ts
+++ b/server/sonar-web/src/main/js/api/quality-profiles.ts
@@ -30,7 +30,9 @@ import { Paging } from '../app/types';
import throwGlobalError from '../app/utils/throwGlobalError';
export interface ProfileActions {
+ associateProjects?: boolean;
copy?: boolean;
+ delete?: boolean;
edit?: boolean;
setAsDefault?: boolean;
}
@@ -104,7 +106,7 @@ export function restoreQualityProfile(data: RequestData): Promise<any> {
}
export function getProfileProjects(data: RequestData): Promise<any> {
- return getJSON('/api/qualityprofiles/projects', data);
+ return getJSON('/api/qualityprofiles/projects', data).catch(throwGlobalError);
}
export function getProfileInheritance(profileKey: string): Promise<any> {
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx
index f7e7d5f2679..9cda74cbfe1 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx
@@ -41,5 +41,11 @@ export default function BuiltInQualityProfileBadge({ className, tooltip = true }
</span>
);
- return tooltip ? <Tooltip overlay={overlay}>{badge}</Tooltip> : badge;
+ return tooltip ? (
+ <Tooltip overlay={overlay} placement="right">
+ {badge}
+ </Tooltip>
+ ) : (
+ badge
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx
index 0a2aff5cffb..0ed58dbb34c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx
@@ -137,15 +137,10 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
this.props.organization
);
- const canActivateRules = actions.edit && !profile.isBuiltIn;
- const canRename = actions.edit && !profile.isBuiltIn;
- const canSetAsDefault = actions.setAsDefault && !profile.isDefault;
- const canDelete = actions.edit && !profile.isDefault && !profile.isBuiltIn;
-
return (
<ActionsDropdown className={this.props.className}>
- {canActivateRules && (
- <ActionsDropdownItem to={activateMoreUrl}>
+ {actions.edit && (
+ <ActionsDropdownItem to={activateMoreUrl} id="quality-profile-activate-more-rules">
{translate('quality_profiles.activate_more_rules')}
</ActionsDropdownItem>
)}
@@ -171,13 +166,13 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
</ActionsDropdownItem>
)}
- {canRename && (
+ {actions.edit && (
<ActionsDropdownItem id="quality-profile-rename" onClick={this.handleRenameClick}>
{translate('rename')}
</ActionsDropdownItem>
)}
- {canSetAsDefault && (
+ {actions.setAsDefault && (
<ActionsDropdownItem
id="quality-profile-set-as-default"
onClick={this.handleSetDefaultClick}>
@@ -185,9 +180,9 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
</ActionsDropdownItem>
)}
- {canDelete && <ActionsDropdownDivider />}
+ {actions.delete && <ActionsDropdownDivider />}
- {canDelete && (
+ {actions.delete && (
<ActionsDropdownItem
destructive={true}
id="quality-profile-delete"
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx
index f54dde5ed08..ee33feb4d51 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx
@@ -50,7 +50,7 @@ it('renders with no permissions', () => {
).toMatchSnapshot();
});
-it('renders with permission to edit', () => {
+it('renders with permission to edit only', () => {
expect(
shallow(
<ProfileActions
@@ -69,7 +69,16 @@ it('renders with all permissions', () => {
<ProfileActions
onRequestFail={jest.fn()}
organization="org"
- profile={{ ...PROFILE, actions: { copy: true, edit: true, setAsDefault: true } }}
+ profile={{
+ ...PROFILE,
+ actions: {
+ copy: true,
+ edit: true,
+ delete: true,
+ setAsDefault: true,
+ associateProjects: true
+ }
+ }}
updateProfiles={jest.fn()}
/>
)
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/__snapshots__/ProfileActions-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/__snapshots__/ProfileActions-test.tsx.snap
index ba760e5cb62..7e53929904b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/__snapshots__/ProfileActions-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/__snapshots__/ProfileActions-test.tsx.snap
@@ -3,6 +3,7 @@
exports[`renders with all permissions 1`] = `
<ActionsDropdown>
<ActionsDropdownItem
+ id="quality-profile-activate-more-rules"
to="/organizations/org/rules#qprofile=foo|activation=false"
>
quality_profiles.activate_more_rules
@@ -83,9 +84,10 @@ exports[`renders with no permissions 1`] = `
</ActionsDropdown>
`;
-exports[`renders with permission to edit 1`] = `
+exports[`renders with permission to edit only 1`] = `
<ActionsDropdown>
<ActionsDropdownItem
+ id="quality-profile-activate-more-rules"
to="/organizations/org/rules#qprofile=foo|activation=false"
>
quality_profiles.activate_more_rules
@@ -117,13 +119,5 @@ exports[`renders with permission to edit 1`] = `
>
rename
</ActionsDropdownItem>
- <ActionsDropdownDivider />
- <ActionsDropdownItem
- destructive={true}
- id="quality-profile-delete"
- onClick={[Function]}
- >
- delete
- </ActionsDropdownItem>
</ActionsDropdown>
`;
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx
index 9b1acd46c8e..66476d8c966 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx
@@ -69,15 +69,18 @@ export default class ProfileProjects extends React.PureComponent<Props, State> {
}
const data = { key: this.props.profile.key };
- getProfileProjects(data).then((r: any) => {
- if (this.mounted) {
- this.setState({
- projects: r.results,
- more: r.more,
- loading: false
- });
- }
- });
+ getProfileProjects(data).then(
+ (r: any) => {
+ if (this.mounted) {
+ this.setState({
+ projects: r.results,
+ more: r.more,
+ loading: false
+ });
+ }
+ },
+ () => {}
+ );
}
handleChangeClick = (event: React.SyntheticEvent<HTMLElement>) => {
@@ -91,6 +94,10 @@ export default class ProfileProjects extends React.PureComponent<Props, State> {
};
renderDefault() {
+ if (this.state.loading) {
+ return <i className="spinner" />;
+ }
+
return (
<div>
<span className="badge spacer-right">{translate('default')}</span>
@@ -100,6 +107,10 @@ export default class ProfileProjects extends React.PureComponent<Props, State> {
}
renderProjects() {
+ if (this.state.loading) {
+ return <i className="spinner" />;
+ }
+
const { projects } = this.state;
if (projects == null) {
@@ -130,8 +141,7 @@ export default class ProfileProjects extends React.PureComponent<Props, State> {
return (
<div className="boxed-group quality-profile-projects">
{profile.actions &&
- profile.actions.edit &&
- !profile.isDefault && (
+ profile.actions.associateProjects && (
<div className="boxed-group-actions">
<button className="js-change-projects" onClick={this.handleChangeClick}>
{translate('quality_profiles.change_projects')}
@@ -144,13 +154,7 @@ export default class ProfileProjects extends React.PureComponent<Props, State> {
</header>
<div className="boxed-group-inner">
- {this.state.loading ? (
- <i className="spinner" />
- ) : profile.isDefault ? (
- this.renderDefault()
- ) : (
- this.renderProjects()
- )}
+ {profile.isDefault ? this.renderDefault() : this.renderProjects()}
</div>
{this.state.formOpen && (
diff --git a/tests/src/test/java/org/sonarqube/tests/qualityProfile/OrganizationQualityProfilesUiTest.java b/tests/src/test/java/org/sonarqube/tests/qualityProfile/OrganizationQualityProfilesUiTest.java
index 48470073a6b..d9445e5896d 100644
--- a/tests/src/test/java/org/sonarqube/tests/qualityProfile/OrganizationQualityProfilesUiTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/qualityProfile/OrganizationQualityProfilesUiTest.java
@@ -118,6 +118,17 @@ public class OrganizationQualityProfilesUiTest {
}
@Test
+ public void testBuiltIn() {
+ Navigation nav = tester.openBrowser().logIn().submitCredentials(user.getLogin());
+ nav.openQualityProfile("xoo", "Sonar way", "test-org")
+ .shouldNotAllowToEdit()
+ .shouldAllowToChangeProjects();
+ nav.openQualityProfile("xoo", "Basic", "test-org")
+ .shouldNotAllowToEdit()
+ .shouldNotAllowToChangeProjects();
+ }
+
+ @Test
public void testCreation() {
Selenese.runSelenese(orchestrator, "/organization/OrganizationQualityProfilesUiTest/should_create.html");
}