diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2018-07-04 10:50:32 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-07-11 20:21:21 +0200 |
commit | f675d5865684706e6943bf74bdb96a7e1b7e1549 (patch) | |
tree | 426f60b6297a13d94d24e6e5d0258c70630142a6 | |
parent | 6c7e6840822b0f4a8b65187f63dce4b55c2427f6 (diff) | |
download | sonarqube-f675d5865684706e6943bf74bdb96a7e1b7e1549.tar.gz sonarqube-f675d5865684706e6943bf74bdb96a7e1b7e1549.zip |
SONAR-10945 Add membership check for paid organization in api/qualityprofiles
* Add membership check for paid organization in api/qualityprofiles/search
* Add membership check for paid organization in api/qualityprofiles/backup
* Add membership check for paid organization in api/qualityprofiles/changelog, compare, export, inheritance
* Add membership check for paid organization in api/qualityprofiles/projects
* Add membership check for paid organization in api/qualityprofiles/show
27 files changed, 1039 insertions, 966 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java index ca1f86174be..aea1c6848a7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java @@ -93,7 +93,7 @@ public class ActivateRulesAction implements QProfileWsAction { QProfileDto profile = wsSupport.getProfile(dbSession, fromKey(qualityProfileKey)); OrganizationDto organization = wsSupport.getOrganization(dbSession, profile); wsSupport.checkCanEdit(dbSession, organization, profile); - wsSupport.checkNotBuiltInt(profile); + wsSupport.checkNotBuiltIn(profile); RuleQuery ruleQuery = ruleQueryFactory.createRuleQuery(dbSession, request); ruleQuery.setIncludeExternal(false); result = qProfileRules.bulkActivateAndCommit(dbSession, profile, ruleQuery, request.param(PARAM_TARGET_SEVERITY)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java index 0897d1b017e..73780aa7f95 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CompareAction.java @@ -72,11 +72,13 @@ public class CompareAction implements QProfileWsAction { private final DbClient dbClient; private final QProfileComparison comparator; private final Languages languages; + private final QProfileWsSupport wsSupport; - public CompareAction(DbClient dbClient, QProfileComparison comparator, Languages languages) { + public CompareAction(DbClient dbClient, QProfileComparison comparator, Languages languages, QProfileWsSupport wsSupport) { this.dbClient = dbClient; this.comparator = comparator; this.languages = languages; + this.wsSupport = wsSupport; } @Override @@ -112,7 +114,9 @@ public class CompareAction implements QProfileWsAction { checkArgument(Objects.equals(left.getOrganizationUuid(), right.getOrganizationUuid()), "Cannot compare quality profiles of different organizations. Quality profile left with key '%s' belongs to organization '%s', " + - "quality profile right with key '%s' belongs to organization '%s'.", leftKey, left.getOrganizationUuid(), rightKey, right.getOrganizationUuid()); + "quality profile right with key '%s' belongs to organization '%s'.", + leftKey, left.getOrganizationUuid(), rightKey, right.getOrganizationUuid()); + wsSupport.getOrganization(dbSession, left); QProfileComparisonResult result = comparator.compare(dbSession, left, right); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java index a75ce6198cc..489f08f52e0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java @@ -33,13 +33,14 @@ import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.user.UserSession; -import org.sonar.server.ws.WsUtils; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.WsUtils.checkFound; import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; @@ -71,16 +72,20 @@ public class QProfileWsSupport { public OrganizationDto getOrganization(DbSession dbSession, QProfileDto profile) { requireNonNull(profile); String organizationUuid = profile.getOrganizationUuid(); - return dbClient.organizationDao().selectByUuid(dbSession, organizationUuid) + OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid) .orElseThrow(() -> new IllegalStateException("Cannot load organization with uuid=" + organizationUuid)); + checkMembershipOnPaidOrganization(dbSession, organization); + return organization; } public OrganizationDto getOrganizationByKey(DbSession dbSession, @Nullable String organizationKey) { String organizationOrDefaultKey = Optional.ofNullable(organizationKey) .orElseGet(defaultOrganizationProvider.get()::getKey); - return WsUtils.checkFoundWithOptional( + OrganizationDto organization = checkFoundWithOptional( dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey), "No organization with key '%s'", organizationOrDefaultKey); + checkMembershipOnPaidOrganization(dbSession, organization); + return organization; } public RuleDefinitionDto getRule(DbSession dbSession, RuleKey ruleKey) { @@ -100,6 +105,8 @@ public class QProfileWsSupport { if (ref.hasKey()) { profile = dbClient.qualityProfileDao().selectByUuid(dbSession, ref.getKey()); checkFound(profile, "Quality Profile with key '%s' does not exist", ref.getKey()); + // Load organization to execute various checks (existence, membership if paid organization, etc.) + getOrganization(dbSession, profile); } else { OrganizationDto org = getOrganizationByKey(dbSession, ref.getOrganizationKey().orElse(null)); profile = dbClient.qualityProfileDao().selectByNameAndLanguage(dbSession, org, ref.getName(), ref.getLanguage()); @@ -122,7 +129,7 @@ public class QProfileWsSupport { return user; } - public GroupDto getGroup(DbSession dbSession, OrganizationDto organization, String groupName) { + GroupDto getGroup(DbSession dbSession, OrganizationDto organization, String groupName) { Optional<GroupDto> group = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), groupName); checkFoundWithOptional(group, "No group with name '%s' in organization '%s'", groupName, organization.getKey()); return group.get(); @@ -148,18 +155,34 @@ public class QProfileWsSupport { } public void checkCanEdit(DbSession dbSession, OrganizationDto organization, QProfileDto profile) { - checkNotBuiltInt(profile); + checkNotBuiltIn(profile); if (!canEdit(dbSession, organization, profile)) { throw insufficientPrivilegesException(); } } - public void checkNotBuiltInt(QProfileDto profile) { + void checkNotBuiltIn(QProfileDto profile) { checkRequest(!profile.isBuiltIn(), "Operation forbidden for built-in Quality Profile '%s' with language '%s'", profile.getName(), profile.getLanguage()); } - public void checkMembership(DbSession dbSession, OrganizationDto organization, UserDto user) { - checkArgument(dbClient.organizationMemberDao().select(dbSession, organization.getUuid(), user.getId()).isPresent(), + private void checkMembership(DbSession dbSession, OrganizationDto organization, UserDto user) { + checkArgument(isMember(dbSession, organization, user.getId()), "User '%s' is not member of organization '%s'", user.getLogin(), organization.getKey()); } + + private boolean isMember(DbSession dbSession, OrganizationDto organization, int userId) { + return dbClient.organizationMemberDao().select(dbSession, organization.getUuid(), userId).isPresent(); + } + + private void checkMembershipOnPaidOrganization(DbSession dbSession, OrganizationDto organization) { + if (!organization.getSubscription().equals(PAID)) { + return; + } + Integer userId = userSession.getUserId(); + if (userId != null && isMember(dbSession, organization, userId)) { + return; + } + throw new ForbiddenException(String.format("You're not member of organization '%s'", organization.getKey())); + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java index 971413ffcf4..0a6ce961f5f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java @@ -331,7 +331,7 @@ public class SearchAction implements QProfileWsAction { return organizationKey; } - public SearchRequest setOrganizationKey(String organizationKey) { + public SearchRequest setOrganizationKey(@Nullable String organizationKey) { this.organizationKey = organizationKey; return this; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java index df13491fd41..672d218c9fe 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/BackupActionTest.java @@ -28,7 +28,8 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.qualityprofile.QualityProfileTesting; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.language.LanguageTesting; import org.sonar.server.organization.DefaultOrganizationProvider; @@ -39,7 +40,10 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; +import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.organization.OrganizationDto.Subscription.FREE; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; public class BackupActionTest { @@ -60,27 +64,6 @@ public class BackupActionTest { private WsActionTester tester = new WsActionTester(new BackupAction(db.getDbClient(), backuper, wsSupport, languages)); @Test - public void test_definition() { - WebService.Action definition = tester.getDef(); - - assertThat(definition.key()).isEqualTo("backup"); - assertThat(definition.responseExampleAsString()).isNotEmpty(); - assertThat(definition.isInternal()).isFalse(); - assertThat(definition.isPost()).isFalse(); - - // parameters - assertThat(definition.params()).extracting(Param::key).containsExactlyInAnyOrder("key", "organization", "qualityProfile", "language"); - Param key = definition.param("key"); - assertThat(key.deprecatedKey()).isEqualTo("profileKey"); - assertThat(key.deprecatedSince()).isEqualTo("6.6"); - Param language = definition.param("language"); - assertThat(language.deprecatedSince()).isNullOrEmpty(); - Param profileName = definition.param("qualityProfile"); - Param orgParam = definition.param("organization"); - assertThat(orgParam.since()).isEqualTo("6.4"); - } - - @Test public void returns_backup_of_profile_with_specified_key() { QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization()); @@ -115,6 +98,37 @@ public class BackupActionTest { } @Test + public void returns_backup_of_profile_on_free_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(FREE)); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE)); + + TestResponse response = tester.newRequest() + .setParam("organization", organization.getKey()) + .setParam("language", profile.getLanguage()) + .setParam("qualityProfile", profile.getName()) + .execute(); + + assertThat(response.getInput()).isXmlEqualTo(xmlForProfileWithoutRules(profile)); + } + + @Test + public void returns_backup_of_profile_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + TestResponse response = tester.newRequest() + .setParam("organization", organization.getKey()) + .setParam("language", profile.getLanguage()) + .setParam("qualityProfile", profile.getName()) + .execute(); + + assertThat(response.getInput()).isXmlEqualTo(xmlForProfileWithoutRules(profile)); + } + + @Test public void throws_NotFoundException_if_profile_with_specified_key_does_not_exist() { expectedException.expect(NotFoundException.class); expectedException.expectMessage("Quality Profile with key 'missing' does not exist"); @@ -158,6 +172,57 @@ public class BackupActionTest { tester.newRequest().execute(); } + @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE)); + userSession.logIn(); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + tester.newRequest() + .setParam("organization", organization.getKey()) + .setParam("language", profile.getLanguage()) + .setParam("qualityProfile", profile.getName()) + .execute(); + } + + @Test + public void fail_on_paid_organization_when_not_member_using_deprecated_profile_key() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE)); + userSession.logIn(); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + tester.newRequest() + .setParam("key", profile.getKee()) + .execute(); + } + + @Test + public void test_definition() { + WebService.Action definition = tester.getDef(); + + assertThat(definition.key()).isEqualTo("backup"); + assertThat(definition.responseExampleAsString()).isNotEmpty(); + assertThat(definition.isInternal()).isFalse(); + assertThat(definition.isPost()).isFalse(); + + // parameters + assertThat(definition.params()).extracting(Param::key).containsExactlyInAnyOrder("key", "organization", "qualityProfile", "language"); + Param key = definition.param("key"); + assertThat(key.deprecatedKey()).isEqualTo("profileKey"); + assertThat(key.deprecatedSince()).isEqualTo("6.6"); + Param language = definition.param("language"); + assertThat(language.deprecatedSince()).isNullOrEmpty(); + Param profileName = definition.param("qualityProfile"); + Param orgParam = definition.param("organization"); + assertThat(orgParam.since()).isEqualTo("6.4"); + } + private static String xmlForProfileWithoutRules(QProfileDto profile) { return "<?xml version='1.0' encoding='UTF-8'?>" + "<profile>" + @@ -167,9 +232,4 @@ public class BackupActionTest { "</profile>"; } - private static QProfileDto newProfile(OrganizationDto org) { - return QualityProfileTesting.newQualityProfileDto() - .setLanguage(A_LANGUAGE) - .setOrganizationUuid(org.getUuid()); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java index 0a6de2cfecc..12498e06f90 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java @@ -38,6 +38,7 @@ import org.sonar.db.qualityprofile.QProfileChangeDto; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.qualityprofile.ActiveRuleChange; @@ -45,8 +46,10 @@ import org.sonar.server.qualityprofile.ActiveRuleInheritance; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; +import static java.lang.String.format; import static java.lang.String.valueOf; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; @@ -65,66 +68,13 @@ public class ChangelogActionTest { @Rule public UserSessionRule userSession = UserSessionRule.standalone(); @Rule - public ExpectedException thrown = ExpectedException.none(); + public ExpectedException expectedException = ExpectedException.none(); private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)); private WsActionTester ws = new WsActionTester( new ChangelogAction(wsSupport, new Languages(), db.getDbClient())); @Test - public void definition() { - WebService.Action definition = ws.getDef(); - - assertThat(definition.responseExampleAsString()).isNotEmpty(); - assertThat(definition.params()).extracting(WebService.Param::key) - .containsExactlyInAnyOrder("key", "qualityProfile", "language", "organization", "since", "to", "p", "ps"); - WebService.Param profileName = definition.param("qualityProfile"); - assertThat(profileName.deprecatedSince()).isNullOrEmpty(); - WebService.Param language = definition.param("language"); - assertThat(language.deprecatedSince()).isNullOrEmpty(); - } - - @Test - public void example() { - OrganizationDto organization = db.organizations().insert(); - QProfileDto profile = db.qualityProfiles().insert(organization); - String profileUuid = profile.getRulesProfileUuid(); - - system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:39+0100").getTime()); - RuleDefinitionDto rule1 = db.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected")); - UserDto user1 = db.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker")); - insertChange(c -> c.setRulesProfileUuid(profileUuid) - .setUserUuid(user1.getUuid()) - .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) - .setData(ImmutableMap.of("severity", "CRITICAL", "ruleId", valueOf(rule1.getId())))); - - system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:18+0100").getTime()); - RuleDefinitionDto rule2 = db.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses")); - UserDto user2 = db.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala")); - QProfileChangeDto change2 = insertChange(c -> c.setRulesProfileUuid(profileUuid) - .setUserUuid(user2.getUuid()) - .setChangeType(ActiveRuleChange.Type.DEACTIVATED.name()) - .setData(ImmutableMap.of("ruleId", valueOf(rule2.getId())))); - - system2.setNow(DateUtils.parseDateTime("2014-09-12T15:20:46+0200").getTime()); - RuleDefinitionDto rule3 = db.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention")); - UserDto user3 = db.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi")); - QProfileChangeDto change3 = insertChange(c -> c.setRulesProfileUuid(profileUuid) - .setUserUuid(user3.getUuid()) - .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) - .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleId", valueOf(rule3.getId())))); - - String response = ws.newRequest() - .setMethod("GET") - .setParam(PARAM_KEY, profile.getKee()) - .setParam("ps", "10") - .execute() - .getInput(); - - assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json")); - } - - @Test public void return_change_with_all_fields() { OrganizationDto organization = db.organizations().insert(); QProfileDto profile = db.qualityProfiles().insert(organization); @@ -138,7 +88,6 @@ public class ChangelogActionTest { "param_bar", "bar_value")); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, profile.getKee()) .execute() .getInput(); @@ -177,7 +126,6 @@ public class ChangelogActionTest { "severity", "MINOR")); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, profile.getKee()) .execute() .getInput(); @@ -209,7 +157,6 @@ public class ChangelogActionTest { "severity", "MINOR")); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .execute() @@ -243,7 +190,6 @@ public class ChangelogActionTest { "severity", "MINOR")); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .setParam(PARAM_ORGANIZATION, organization.getKey()) @@ -272,7 +218,6 @@ public class ChangelogActionTest { QProfileDto qualityProfile = db.qualityProfiles().insert(organization); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, qualityProfile.getKee()) .execute() .getInput(); @@ -293,7 +238,6 @@ public class ChangelogActionTest { "severity", "MINOR")); assertJson(ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, qualityProfile.getKee()) .setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100") .execute() @@ -310,7 +254,6 @@ public class ChangelogActionTest { "}"); assertJson(ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, qualityProfile.getKee()) .setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100") .execute() @@ -336,7 +279,6 @@ public class ChangelogActionTest { ImmutableMap.of("ruleId", valueOf(rule2.getId()))); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, profile.getKee()) .execute() .getInput(); @@ -373,7 +315,6 @@ public class ChangelogActionTest { ImmutableMap.of("ruleId", "123")); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .setParam(PARAM_ORGANIZATION, organization.getKey()) @@ -403,7 +344,6 @@ public class ChangelogActionTest { .setData(ImmutableMap.of("ruleId", rule.getId()))); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .setParam(PARAM_ORGANIZATION, organization.getKey()) @@ -425,6 +365,35 @@ public class ChangelogActionTest { } @Test + public void changelog_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + RuleDefinitionDto rule = db.rules().insert(); + insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, db.users().insertUser(), + ImmutableMap.of( + "ruleId", valueOf(rule.getId()), + "severity", "MINOR")); + + String response = ws.newRequest() + .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) + .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute() + .getInput(); + + assertJson(response).isSimilarTo("{\n" + + " \"events\": [\n" + + " {\n" + + " \"ruleKey\": \"" + rule.getKey() + "\",\n" + + " }\n" + + " ]\n" + + "}"); + } + + @Test public void do_not_find_changelog_by_wrong_organization_and_language_and_name() { OrganizationDto organization1 = db.organizations().insert(); OrganizationDto organization2 = db.organizations().insert(); @@ -436,16 +405,84 @@ public class ChangelogActionTest { "ruleId", valueOf(rule.getId()), "severity", "MINOR")); - thrown.expect(NotFoundException.class); + expectedException.expect(NotFoundException.class); ws.newRequest() - .setMethod("GET") .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) .setParam(PARAM_ORGANIZATION, organization2.getKey()) .execute(); } + @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + ws.newRequest() + .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) + .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void example() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization); + String profileUuid = profile.getRulesProfileUuid(); + + system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:39+0100").getTime()); + RuleDefinitionDto rule1 = db.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected")); + UserDto user1 = db.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker")); + insertChange(c -> c.setRulesProfileUuid(profileUuid) + .setUserUuid(user1.getUuid()) + .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) + .setData(ImmutableMap.of("severity", "CRITICAL", "ruleId", valueOf(rule1.getId())))); + + system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:18+0100").getTime()); + RuleDefinitionDto rule2 = db.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses")); + UserDto user2 = db.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala")); + QProfileChangeDto change2 = insertChange(c -> c.setRulesProfileUuid(profileUuid) + .setUserUuid(user2.getUuid()) + .setChangeType(ActiveRuleChange.Type.DEACTIVATED.name()) + .setData(ImmutableMap.of("ruleId", valueOf(rule2.getId())))); + + system2.setNow(DateUtils.parseDateTime("2014-09-12T15:20:46+0200").getTime()); + RuleDefinitionDto rule3 = db.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention")); + UserDto user3 = db.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi")); + QProfileChangeDto change3 = insertChange(c -> c.setRulesProfileUuid(profileUuid) + .setUserUuid(user3.getUuid()) + .setChangeType(ActiveRuleChange.Type.ACTIVATED.name()) + .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleId", valueOf(rule3.getId())))); + + String response = ws.newRequest() + .setMethod("GET") + .setParam(PARAM_KEY, profile.getKee()) + .setParam("ps", "10") + .execute() + .getInput(); + + assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json")); + } + + @Test + public void definition() { + WebService.Action definition = ws.getDef(); + + assertThat(definition.isPost()).isFalse(); + assertThat(definition.responseExampleAsString()).isNotEmpty(); + assertThat(definition.params()).extracting(WebService.Param::key) + .containsExactlyInAnyOrder("key", "qualityProfile", "language", "organization", "since", "to", "p", "ps"); + WebService.Param profileName = definition.param("qualityProfile"); + assertThat(profileName.deprecatedSince()).isNullOrEmpty(); + WebService.Param language = definition.param("language"); + assertThat(language.deprecatedSince()).isNullOrEmpty(); + } + private QProfileChangeDto insertChange(QProfileDto profile, ActiveRuleChange.Type type, @Nullable UserDto user, @Nullable Map<String, Object> data) { return insertChange(c -> c.setRulesProfileUuid(profile.getRulesProfileUuid()) .setUserUuid(user == null ? null : user.getUuid()) diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionTest.java index 0c64765e101..250b6c86686 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionTest.java @@ -20,7 +20,6 @@ package org.sonar.server.qualityprofile.ws; import org.apache.commons.lang.StringUtils; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -29,9 +28,11 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.server.rule.RuleParamType; +import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualityprofile.ActiveRuleDto; import org.sonar.db.qualityprofile.ActiveRuleParamDto; import org.sonar.db.qualityprofile.QProfileDto; @@ -41,52 +42,39 @@ import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleDto.Scope; import org.sonar.db.rule.RuleParamDto; import org.sonar.db.rule.RuleRepositoryDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.language.LanguageTesting; +import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.qualityprofile.QProfileComparison; -import org.sonar.server.qualityprofile.QProfileName; -import org.sonar.server.qualityprofile.QProfileTesting; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; +import static java.lang.String.format; import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; public class CompareActionTest { @Rule - public DbTester dbTester = DbTester.create(); + public DbTester db = DbTester.create(); @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @Rule - public ExpectedException thrown = ExpectedException.none(); - private WsActionTester wsTester; - private CompareAction underTest; - private DbClient db = dbTester.getDbClient(); - private DbSession session = dbTester.getSession(); - - @Before - public void before() { - underTest = new CompareAction(dbTester.getDbClient(), new QProfileComparison(dbTester.getDbClient()), new Languages(LanguageTesting.newLanguage("xoo", "Xoo"))); - wsTester = new WsActionTester(underTest); - } - - @Test - public void should_not_allow_to_compare_quality_profiles_from_different_organizations() { - QProfileDto left = QualityProfileTesting.newQualityProfileDto(); - QProfileDto right = QualityProfileTesting.newQualityProfileDto(); - dbTester.qualityProfiles().insert(left, right); + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); - TestRequest request = wsTester.newRequest().setMethod("POST") - .setParam("leftKey", left.getKee()) - .setParam("rightKey", right.getKee()); + private DbClient dbClient = db.getDbClient(); + private DbSession session = db.getSession(); - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Cannot compare quality profiles of different organizations."); - request.execute(); - } + private WsActionTester ws = new WsActionTester( + new CompareAction(db.getDbClient(), new QProfileComparison(db.getDbClient()), new Languages(LanguageTesting.newLanguage("xoo", "Xoo")), + new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)))); @Test - public void compare_nominal() throws Exception { + public void compare_nominal() { createRepository("blah", "xoo", "Blah"); RuleDefinitionDto rule1 = createRule("xoo", "rule1"); @@ -122,14 +110,14 @@ public class CompareActionTest { createActiveRuleWithSeverity(rule5, profile2, Severity.MAJOR); session.commit(); - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", profile1.getKee()) .setParam("rightKey", profile2.getKee()) .execute().assertJson(this.getClass(), "compare_nominal.json"); } @Test - public void compare_param_on_left() throws Exception { + public void compare_param_on_left() { RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1"); createRepository("blah", "xoo", "Blah"); QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); @@ -138,14 +126,14 @@ public class CompareActionTest { createActiveRule(rule1, profile2); session.commit(); - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", profile1.getKee()) .setParam("rightKey", profile2.getKee()) .execute().assertJson(this.getClass(), "compare_param_on_left.json"); } @Test - public void compare_param_on_right() throws Exception { + public void compare_param_on_right() { RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1"); createRepository("blah", "xoo", "Blah"); QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234"); @@ -154,22 +142,37 @@ public class CompareActionTest { createActiveRuleWithParam(rule1, profile2, "polop"); session.commit(); - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", profile1.getKee()) .setParam("rightKey", profile2.getKee()) .execute().assertJson(this.getClass(), "compare_param_on_right.json"); } + @Test + public void do_not_fail_to_compare_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto left = db.qualityProfiles().insert(organization); + QProfileDto right = db.qualityProfiles().insert(organization); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + ws.newRequest() + .setParam("leftKey", left.getKee()) + .setParam("rightKey", right.getKee()) + .execute(); + } + @Test(expected = IllegalArgumentException.class) public void fail_on_missing_left_param() { - wsTester.newRequest() + ws.newRequest() .setParam("rightKey", "polop") .execute(); } @Test(expected = IllegalArgumentException.class) public void fail_on_missing_right_param() { - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", "polop") .execute(); } @@ -177,7 +180,7 @@ public class CompareActionTest { @Test(expected = IllegalArgumentException.class) public void fail_on_left_profile_not_found() { createProfile("xoo", "Right", "xoo-right-12345"); - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", "polop") .setParam("rightKey", "xoo-right-12345") .execute(); @@ -186,17 +189,55 @@ public class CompareActionTest { @Test(expected = IllegalArgumentException.class) public void fail_on_right_profile_not_found() { createProfile("xoo", "Left", "xoo-left-12345"); - wsTester.newRequest() + ws.newRequest() .setParam("leftKey", "xoo-left-12345") .setParam("rightKey", "polop") .execute(); } + @Test + public void fail_to_compare_quality_profiles_from_different_organizations() { + QProfileDto left = QualityProfileTesting.newQualityProfileDto(); + QProfileDto right = QualityProfileTesting.newQualityProfileDto(); + db.qualityProfiles().insert(left, right); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Cannot compare quality profiles of different organizations."); + + ws.newRequest() + .setParam("leftKey", left.getKee()) + .setParam("rightKey", right.getKee()) + .execute(); + } + + @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto left = db.qualityProfiles().insert(organization); + QProfileDto right = db.qualityProfiles().insert(organization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + ws.newRequest() + .setParam("leftKey", left.getKee()) + .setParam("rightKey", right.getKee()) + .execute(); + } + + @Test + public void definition() { + WebService.Action definition = ws.getDef(); + assertThat(definition).isNotNull(); + assertThat(definition.isPost()).isFalse(); + assertThat(definition.isInternal()).isTrue(); + assertThat(definition.params()).hasSize(2).extracting("key").containsOnly( + "leftKey", "rightKey"); + assertThat(definition.responseExampleAsString()).isNotEmpty(); + } + private QProfileDto createProfile(String lang, String name, String key) { - QProfileDto profile = QProfileTesting.newQProfileDto("org-123", new QProfileName(lang, name), key); - db.qualityProfileDao().insert(session, profile); - session.commit(); - return profile; + return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setKee(key).setName(name).setLanguage(lang)); } private RuleDefinitionDto createRule(String lang, String id) { @@ -207,7 +248,7 @@ public class CompareActionTest { .setScope(Scope.MAIN) .setStatus(RuleStatus.READY); RuleDefinitionDto ruleDefinition = rule.getDefinition(); - db.ruleDao().insert(session, ruleDefinition); + dbClient.ruleDao().insert(session, ruleDefinition); return ruleDefinition; } @@ -216,35 +257,35 @@ public class CompareActionTest { RuleParamDto param = RuleParamDto.createFor(rule) .setName("param_" + id) .setType(RuleParamType.STRING.toString()); - db.ruleDao().insertRuleParam(session, rule, param); + dbClient.ruleDao().insertRuleParam(session, rule, param); return rule; } private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) { ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) .setSeverity(rule.getSeverityString()); - db.activeRuleDao().insert(session, activeRule); + dbClient.activeRuleDao().insert(session, activeRule); return activeRule; } private ActiveRuleDto createActiveRuleWithParam(RuleDefinitionDto rule, QProfileDto profile, String value) { ActiveRuleDto activeRule = createActiveRule(rule, profile); - RuleParamDto paramDto = db.ruleDao().selectRuleParamsByRuleKey(session, rule.getKey()).get(0); + RuleParamDto paramDto = dbClient.ruleDao().selectRuleParamsByRuleKey(session, rule.getKey()).get(0); ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(paramDto).setValue(value); - db.activeRuleDao().insertParam(session, activeRule, activeRuleParam); + dbClient.activeRuleDao().insertParam(session, activeRule, activeRuleParam); return activeRule; } private ActiveRuleDto createActiveRuleWithSeverity(RuleDefinitionDto rule, QProfileDto profile, String severity) { ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule) .setSeverity(severity); - db.activeRuleDao().insert(session, activeRule); + dbClient.activeRuleDao().insert(session, activeRule); return activeRule; } private void createRepository(String repositoryKey, String repositoryLanguage, String repositoryName) { RuleRepositoryDto dto = new RuleRepositoryDto(repositoryKey, repositoryLanguage, repositoryName); - db.ruleRepositoryDao().insertOrUpdate(session, singletonList(dto)); + dbClient.ruleRepositoryDao().insertOrUpdate(session, singletonList(dto)); session.commit(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java index a0b4aa3d96c..bf9d0261104 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java @@ -114,6 +114,7 @@ public class CreateActionTest { WebService.Action definition = ws.getDef(); assertThat(definition.responseExampleAsString()).isNotEmpty(); + assertThat(definition.isPost()).isTrue(); assertThat(definition.params()).extracting(Param::key) .containsExactlyInAnyOrder("language", "organization", "name", "backup_with_messages", "backup_with_errors", "backup_xoo_lint"); Param name = definition.param("name"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java index 29c71e69045..826bea3d8f5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java @@ -312,6 +312,7 @@ public class DeleteActionTest { public void definition() { WebService.Action definition = ws.getDef(); + assertThat(definition.isPost()).isTrue(); assertThat(definition.params()).extracting(Param::key).containsExactlyInAnyOrder("language", "organization", "key", "qualityProfile"); Param key = definition.param("key"); assertThat(key.deprecatedKey()).isEqualTo("profileKey"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java index ccb587493f7..85ae3a93525 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportActionTest.java @@ -36,7 +36,9 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualityprofile.QProfileDto; +import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.language.LanguageTesting; import org.sonar.server.organization.TestDefaultOrganizationProvider; @@ -48,8 +50,11 @@ import org.sonar.server.ws.WsActionTester; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE; public class ExportActionTest { @@ -57,95 +62,31 @@ public class ExportActionTest { private static final String JAVA_LANGUAGE = "java"; @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule public DbTester db = DbTester.create(System2.INSTANCE); @Rule public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); private DbClient dbClient = db.getDbClient(); private QProfileBackuper backuper = new TestBackuper(); private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(db)); @Test - public void definition_without_exporters() { - WebService.Action definition = newWsActionTester().getDef(); - - assertThat(definition.isPost()).isFalse(); - assertThat(definition.isInternal()).isFalse(); - assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("key", "language", "qualityProfile", "organization"); - - WebService.Param organizationParam = definition.param("organization"); - assertThat(organizationParam.since()).isEqualTo("6.4"); - assertThat(organizationParam.isInternal()).isTrue(); - - WebService.Param key = definition.param("key"); - assertThat(key.since()).isEqualTo("6.5"); - assertThat(key.deprecatedSince()).isEqualTo("6.6"); - - WebService.Param name = definition.param("qualityProfile"); - assertThat(name.deprecatedSince()).isNullOrEmpty(); - assertThat(name.deprecatedKey()).isEqualTo("name"); - - WebService.Param language = definition.param("language"); - assertThat(language.deprecatedSince()).isNullOrEmpty(); - } - - @Test - public void definition_with_exporters() { - WebService.Action definition = newWsActionTester(newExporter("polop"), newExporter("palap")).getDef(); - - assertThat(definition.isPost()).isFalse(); - assertThat(definition.isInternal()).isFalse(); - assertThat(definition.params()).extracting("key").containsExactlyInAnyOrder("key", "language", "qualityProfile", "organization", "exporterKey"); - WebService.Param exportersParam = definition.param("exporterKey"); - assertThat(exportersParam.possibleValues()).containsOnly("polop", "palap"); - assertThat(exportersParam.deprecatedKey()).isEqualTo("format"); - assertThat(exportersParam.deprecatedKeySince()).isEqualTo("6.3"); - assertThat(exportersParam.isInternal()).isFalse(); - } - - @Test public void export_profile_with_key() { QProfileDto profile = createProfile(db.getDefaultOrganization(), false); WsActionTester tester = newWsActionTester(newExporter("polop"), newExporter("palap")); String result = tester.newRequest() .setParam(PARAM_KEY, profile.getKee()) - .setParam("exporterKey", "polop").execute() + .setParam("exporterKey", "polop") + .execute() .getInput(); assertThat(result).isEqualTo("Profile " + profile.getLanguage() + "/" + profile.getName() + " exported by polop"); } @Test - public void fail_if_profile_key_is_unknown() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Could not find profile with key 'PROFILE-KEY-404'"); - - WsActionTester ws = newWsActionTester(newExporter("polop"), newExporter("palap")); - ws.newRequest() - .setParam(PARAM_KEY, "PROFILE-KEY-404") - .setParam("exporterKey", "polop").execute() - .getInput(); - } - - @Test - public void fail_if_profile_key_and_language_provided() { - QProfileDto profile = createProfile(db.getDefaultOrganization(), false); - - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Either 'key' or 'language' must be provided"); - - WsActionTester ws = newWsActionTester(newExporter("polop"), newExporter("palap")); - ws.newRequest() - .setParam(PARAM_KEY, profile.getKee()) - .setParam(PARAM_LANGUAGE, profile.getLanguage()) - .setParam("exporterKey", "polop").execute() - .getInput(); - } - - @Test public void export_profile_in_default_organization() { QProfileDto profile = createProfile(db.getDefaultOrganization(), false); @@ -176,21 +117,6 @@ public class ExportActionTest { } @Test - public void throw_NotFoundException_if_specified_organization_does_not_exist() { - WsActionTester tester = newWsActionTester(newExporter("foo")); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("No organization with key 'does_not_exist'"); - - tester.newRequest() - .setParam("organization", "does_not_exist") - .setParam("language", XOO_LANGUAGE) - .setParam("name", "bar") - .setParam("exporterKey", "foo") - .execute(); - } - - @Test public void export_default_profile() { QProfileDto nonDefaultProfile = createProfile(db.getDefaultOrganization(), false); QProfileDto defaultProfile = createProfile(db.getDefaultOrganization(), true); @@ -206,27 +132,6 @@ public class ExportActionTest { } @Test - public void throw_NotFoundException_if_profile_with_specified_name_does_not_exist_in_default_organization() { - expectedException.expect(NotFoundException.class); - - newWsActionTester().newRequest() - .setParam("language", XOO_LANGUAGE) - .setParam("exporterKey", "polop").execute(); - } - - @Test - public void throw_IAE_if_export_with_specified_key_does_not_exist() { - QProfileDto profile = createProfile(db.getDefaultOrganization(), true); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Value of parameter 'exporterKey' (unknown) must be one of: [polop, palap]"); - - newWsActionTester(newExporter("polop"), newExporter("palap")).newRequest() - .setParam("language", XOO_LANGUAGE) - .setParam("exporterKey", "unknown").execute(); - } - - @Test public void return_backup_when_exporter_is_not_specified() { OrganizationDto organization = db.getDefaultOrganization(); QProfileDto profile = createProfile(organization, false); @@ -275,6 +180,143 @@ public class ExportActionTest { .isEqualTo("Backup of java/" + defaultJavaInOrg1.getKee()); } + @Test + public void export_profile_in_paid_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto profile = createProfile(organization, false); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + WsActionTester tester = newWsActionTester(newExporter("polop")); + String result = tester.newRequest() + .setParam("organization", organization.getKey()) + .setParam("language", profile.getLanguage()) + .setParam("qualityProfile", profile.getName()) + .setParam("exporterKey", "polop").execute() + .getInput(); + + assertThat(result).isEqualTo("Profile " + profile.getLanguage() + "/" + profile.getName() + " exported by polop"); + } + + @Test + public void throw_NotFoundException_if_profile_with_specified_name_does_not_exist_in_default_organization() { + expectedException.expect(NotFoundException.class); + + newWsActionTester().newRequest() + .setParam("language", XOO_LANGUAGE) + .setParam("exporterKey", "polop").execute(); + } + + @Test + public void throw_IAE_if_export_with_specified_key_does_not_exist() { + QProfileDto profile = createProfile(db.getDefaultOrganization(), true); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Value of parameter 'exporterKey' (unknown) must be one of: [polop, palap]"); + + newWsActionTester(newExporter("polop"), newExporter("palap")).newRequest() + .setParam("language", XOO_LANGUAGE) + .setParam("exporterKey", "unknown").execute(); + } + + @Test + public void throw_NotFoundException_if_specified_organization_does_not_exist() { + WsActionTester tester = newWsActionTester(newExporter("foo")); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("No organization with key 'does_not_exist'"); + + tester.newRequest() + .setParam("organization", "does_not_exist") + .setParam("language", XOO_LANGUAGE) + .setParam("name", "bar") + .setParam("exporterKey", "foo") + .execute(); + } + + @Test + public void fail_if_profile_key_is_unknown() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Could not find profile with key 'PROFILE-KEY-404'"); + + WsActionTester ws = newWsActionTester(newExporter("polop"), newExporter("palap")); + ws.newRequest() + .setParam(PARAM_KEY, "PROFILE-KEY-404") + .setParam("exporterKey", "polop").execute() + .getInput(); + } + + @Test + public void fail_if_profile_key_and_language_provided() { + QProfileDto profile = createProfile(db.getDefaultOrganization(), false); + + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("Either 'key' or 'language' must be provided"); + + WsActionTester ws = newWsActionTester(newExporter("polop"), newExporter("palap")); + ws.newRequest() + .setParam(PARAM_KEY, profile.getKee()) + .setParam(PARAM_LANGUAGE, profile.getLanguage()) + .setParam("exporterKey", "polop").execute() + .getInput(); + } + + @Test + public void fail_on_paid_organization_when_not_member() { + WsActionTester tester = newWsActionTester(newExporter("foo")); + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO_LANGUAGE)); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + tester.newRequest() + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) + .setParam(PARAM_LANGUAGE, XOO_LANGUAGE) + .setParam("exporterKey", "foo") + .execute(); + } + + @Test + public void definition_without_exporters() { + WebService.Action definition = newWsActionTester().getDef(); + + assertThat(definition.isPost()).isFalse(); + assertThat(definition.isInternal()).isFalse(); + assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("key", "language", "qualityProfile", "organization"); + + WebService.Param organizationParam = definition.param("organization"); + assertThat(organizationParam.since()).isEqualTo("6.4"); + assertThat(organizationParam.isInternal()).isTrue(); + + WebService.Param key = definition.param("key"); + assertThat(key.since()).isEqualTo("6.5"); + assertThat(key.deprecatedSince()).isEqualTo("6.6"); + + WebService.Param name = definition.param("qualityProfile"); + assertThat(name.deprecatedSince()).isNullOrEmpty(); + assertThat(name.deprecatedKey()).isEqualTo("name"); + + WebService.Param language = definition.param("language"); + assertThat(language.deprecatedSince()).isNullOrEmpty(); + } + + @Test + public void definition_with_exporters() { + WebService.Action definition = newWsActionTester(newExporter("polop"), newExporter("palap")).getDef(); + + assertThat(definition.isPost()).isFalse(); + assertThat(definition.isInternal()).isFalse(); + assertThat(definition.params()).extracting("key").containsExactlyInAnyOrder("key", "language", "qualityProfile", "organization", "exporterKey"); + WebService.Param exportersParam = definition.param("exporterKey"); + assertThat(exportersParam.possibleValues()).containsOnly("polop", "palap"); + assertThat(exportersParam.deprecatedKey()).isEqualTo("format"); + assertThat(exportersParam.deprecatedKeySince()).isEqualTo("6.3"); + assertThat(exportersParam.isInternal()).isFalse(); + } + private QProfileDto createProfile(OrganizationDto organization, boolean isDefault) { QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO_LANGUAGE)); if (isDefault) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java index 1b500eb42e1..d686bf6600e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java @@ -23,8 +23,10 @@ import java.io.Writer; import org.junit.Test; import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.server.ws.WebService; import org.sonar.server.ws.WsActionTester; +import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.test.JsonAssert.assertJson; public class ExportersActionTest { @@ -37,6 +39,15 @@ public class ExportersActionTest { assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); } + @Test + public void define_exporters_action() { + WebService.Action exporters = ws.getDef(); + assertThat(exporters).isNotNull(); + assertThat(exporters.isPost()).isFalse(); + assertThat(exporters.params()).isEmpty(); + assertThat(exporters.responseExampleAsString()).isNotEmpty(); + } + private ProfileExporter[] createExporters() { class NoopImporter extends ProfileExporter { private NoopImporter(String key, String name, String... languages) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java index d5c65a4bf0e..202f02e4a16 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java @@ -23,9 +23,11 @@ import java.io.Reader; import org.junit.Test; import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.ValidationMessages; import org.sonar.server.ws.WsActionTester; +import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.test.JsonAssert.assertJson; public class ImportersActionTest { @@ -33,19 +35,28 @@ public class ImportersActionTest { private WsActionTester ws = new WsActionTester(new ImportersAction(createImporters())); @Test - public void json_example() { + public void empty_importers() { + ws = new WsActionTester(new ImportersAction()); + String result = ws.newRequest().execute().getInput(); - assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); + assertJson(result).isSimilarTo("{ \"importers\": [] }"); } @Test - public void empty_importers() { - ws = new WsActionTester(new ImportersAction()); - + public void json_example() { String result = ws.newRequest().execute().getInput(); - assertJson(result).isSimilarTo("{ \"importers\": [] }"); + assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); + } + + @Test + public void define_importers_action() { + WebService.Action importers = ws.getDef(); + assertThat(importers).isNotNull(); + assertThat(importers.isPost()).isFalse(); + assertThat(importers.params()).isEmpty(); + assertThat(importers.responseExampleAsString()).isNotEmpty(); } private ProfileImporter[] createImporters() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java index ad587ab496f..25b501a72bd 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java @@ -22,9 +22,9 @@ package org.sonar.server.qualityprofile.ws; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; @@ -40,11 +40,12 @@ import org.sonar.db.qualityprofile.ActiveRuleDto; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleTesting; +import org.sonar.db.user.UserDto; import org.sonar.server.es.EsClient; import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualityprofile.QProfileName; import org.sonar.server.qualityprofile.QProfileRules; import org.sonar.server.qualityprofile.QProfileRulesImpl; import org.sonar.server.qualityprofile.QProfileTree; @@ -59,58 +60,48 @@ import org.sonar.server.util.TypeValidations; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualityprofiles.InheritanceWsResponse; +import static java.lang.String.format; import static java.util.Arrays.asList; import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.MediaTypes.PROTOBUF; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE; public class InheritanceActionTest { @Rule - public DbTester dbTester = DbTester.create(); + public DbTester db = DbTester.create(); @Rule public EsTester es = EsTester.create(); @Rule public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); - private DbClient dbClient; - private DbSession dbSession; - private EsClient esClient; - private RuleIndexer ruleIndexer; - private ActiveRuleIndexer activeRuleIndexer; - private QProfileRules qProfileRules; - private QProfileTree qProfileTree; - private OrganizationDto organization; - - private InheritanceAction underTest; - private WsActionTester ws; - - @Before - public void setUp() { - dbClient = dbTester.getDbClient(); - dbSession = dbTester.getSession(); - esClient = es.client(); - ruleIndexer = new RuleIndexer(esClient, dbClient); - activeRuleIndexer = new ActiveRuleIndexer(dbClient, esClient); - TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); - underTest = new InheritanceAction( - dbClient, - new QProfileWsSupport(dbClient, userSession, defaultOrganizationProvider), - new Languages()); - - ws = new WsActionTester(underTest); - RuleIndex ruleIndex = new RuleIndex(esClient, System2.INSTANCE); - RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, new TypeValidations(new ArrayList<>()), userSession); - qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer); - qProfileTree = new QProfileTreeImpl(dbClient, ruleActivator, System2.INSTANCE, activeRuleIndexer); - organization = dbTester.organizations().insert(); - } + private DbClient dbClient = db.getDbClient(); + private DbSession dbSession = db.getSession(); + private EsClient esClient = es.client(); + private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient); + private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, esClient); + + private RuleIndex ruleIndex = new RuleIndex(esClient, System2.INSTANCE); + private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, new TypeValidations(new ArrayList<>()), userSession); + private QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer); + private QProfileTree qProfileTree = new QProfileTreeImpl(dbClient, ruleActivator, System2.INSTANCE, activeRuleIndexer); + + private WsActionTester ws = new WsActionTester(new InheritanceAction( + dbClient, + new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(db)), + new Languages())); @Test public void inheritance_nominal() { + OrganizationDto organization = db.organizations().insert(); RuleDefinitionDto rule1 = createRule("xoo", "rule1"); RuleDefinitionDto rule2 = createRule("xoo", "rule2"); RuleDefinitionDto rule3 = createRule("xoo", "rule3"); @@ -118,32 +109,31 @@ public class InheritanceActionTest { /* * sonar way (2) <- companyWide (2) <- buWide (2, 1 overriding) <- (forProject1 (2), forProject2 (2)) */ - QProfileDto sonarway = dbTester.qualityProfiles().insert(organization, p -> p.setKee("xoo-sonar-way").setLanguage("xoo").setName("Sonar way").setIsBuiltIn(true)); - ActiveRuleDto activeRule1 = createActiveRule(rule1, sonarway); - ActiveRuleDto activeRule2 = createActiveRule(rule2, sonarway); + QProfileDto sonarway = db.qualityProfiles().insert(organization, p -> p.setKee("xoo-sonar-way").setLanguage("xoo").setName("Sonar way").setIsBuiltIn(true)); + createActiveRule(rule1, sonarway); + createActiveRule(rule2, sonarway); dbSession.commit(); activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); - QProfileDto companyWide = createProfile("xoo", "My Company Profile", "xoo-my-company-profile-12345"); + QProfileDto companyWide = createProfile(organization, "xoo", "My Company Profile", "xoo-my-company-profile-12345"); setParent(sonarway, companyWide); - QProfileDto buWide = createProfile("xoo", "My BU Profile", "xoo-my-bu-profile-23456"); + QProfileDto buWide = createProfile(organization, "xoo", "My BU Profile", "xoo-my-bu-profile-23456"); setParent(companyWide, buWide); overrideActiveRuleSeverity(rule1, buWide, Severity.CRITICAL); - QProfileDto forProject1 = createProfile("xoo", "For Project One", "xoo-for-project-one-34567"); + QProfileDto forProject1 = createProfile(organization, "xoo", "For Project One", "xoo-for-project-one-34567"); setParent(buWide, forProject1); createActiveRule(rule3, forProject1); dbSession.commit(); activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); - QProfileDto forProject2 = createProfile("xoo", "For Project Two", "xoo-for-project-two-45678"); + QProfileDto forProject2 = createProfile(organization, "xoo", "For Project Two", "xoo-for-project-two-45678"); setParent(buWide, forProject2); overrideActiveRuleSeverity(rule2, forProject2, Severity.CRITICAL); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, buWide.getKee()) .execute() .getInput(); @@ -153,24 +143,24 @@ public class InheritanceActionTest { @Test public void inheritance_parent_child() throws Exception { - RuleDefinitionDto rule1 = dbTester.rules().insert(); - RuleDefinitionDto rule2 = dbTester.rules().insert(); - RuleDefinitionDto rule3 = dbTester.rules().insert(); - ruleIndexer.commitAndIndex(dbTester.getSession(), asList(rule1.getId(), rule2.getId(), rule3.getId())); - - QProfileDto parent = dbTester.qualityProfiles().insert(organization); - dbTester.qualityProfiles().activateRule(parent, rule1); - dbTester.qualityProfiles().activateRule(parent, rule2); + OrganizationDto organization = db.organizations().insert(); + RuleDefinitionDto rule1 = db.rules().insert(); + RuleDefinitionDto rule2 = db.rules().insert(); + RuleDefinitionDto rule3 = db.rules().insert(); + ruleIndexer.commitAndIndex(db.getSession(), asList(rule1.getId(), rule2.getId(), rule3.getId())); + + QProfileDto parent = db.qualityProfiles().insert(organization); + db.qualityProfiles().activateRule(parent, rule1); + db.qualityProfiles().activateRule(parent, rule2); long parentRules = 2; - QProfileDto child = dbTester.qualityProfiles().insert(organization, q -> q.setParentKee(parent.getKee())); - dbTester.qualityProfiles().activateRule(child, rule3); + QProfileDto child = db.qualityProfiles().insert(organization, q -> q.setParentKee(parent.getKee())); + db.qualityProfiles().activateRule(child, rule3); long childRules = 1; activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); InputStream response = ws.newRequest() - .setMethod("GET") .setMediaType(PROTOBUF) .setParam(PARAM_KEY, child.getKee()) .execute() @@ -187,17 +177,17 @@ public class InheritanceActionTest { @Test public void inheritance_ignores_removed_rules() throws Exception { - RuleDefinitionDto rule = dbTester.rules().insert(r -> r.setStatus(RuleStatus.REMOVED)); - ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId()); + OrganizationDto organization = db.organizations().insert(); + RuleDefinitionDto rule = db.rules().insert(r -> r.setStatus(RuleStatus.REMOVED)); + ruleIndexer.commitAndIndex(db.getSession(), rule.getId()); - QProfileDto profile = dbTester.qualityProfiles().insert(organization); - dbTester.qualityProfiles().activateRule(profile, rule); + QProfileDto profile = db.qualityProfiles().insert(organization); + db.qualityProfiles().activateRule(profile, rule); long activeRules = 0; activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); InputStream response = ws.newRequest() - .setMethod("GET") .setMediaType(PROTOBUF) .setParam(PARAM_KEY, profile.getKee()) .execute() @@ -211,10 +201,10 @@ public class InheritanceActionTest { @Test public void inheritance_no_family() { // Simple profile, no parent, no child - QProfileDto remi = createProfile("xoo", "Nobodys Boy", "xoo-nobody-s-boy-01234"); + OrganizationDto organization = db.organizations().insert(); + QProfileDto remi = createProfile(organization,"xoo", "Nobodys Boy", "xoo-nobody-s-boy-01234"); String response = ws.newRequest() - .setMethod("GET") .setParam(PARAM_KEY, remi.getKee()) .execute() .getInput(); @@ -222,10 +212,39 @@ public class InheritanceActionTest { assertJson(response).isSimilarTo(getClass().getResource("InheritanceActionTest/inheritance-simple.json")); } + @Test + public void inheritance_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + ws.newRequest() + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) + .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) + .execute(); + } + @Test(expected = NotFoundException.class) public void fail_if_not_found() { + ws.newRequest().setParam(PARAM_KEY, "polop").execute(); + } + + @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + ws.newRequest() - .setMethod("GET").setParam(PARAM_KEY, "polop").execute(); + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName()) + .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage()) + .execute(); } @Test @@ -243,11 +262,8 @@ public class InheritanceActionTest { assertThat(language.deprecatedSince()).isNullOrEmpty(); } - private QProfileDto createProfile(String lang, String name, String key) { - QProfileDto profile = newQProfileDto(organization, new QProfileName(lang, name), key); - dbClient.qualityProfileDao().insert(dbSession, profile); - dbSession.commit(); - return profile; + private QProfileDto createProfile(OrganizationDto organization, String lang, String name, String key) { + return db.qualityProfiles().insert(organization, qp -> qp.setKee(key).setName(name).setLanguage(lang)); } private void setParent(QProfileDto profile, QProfileDto parent) { @@ -279,7 +295,5 @@ public class InheritanceActionTest { private void overrideActiveRuleSeverity(RuleDefinitionDto rule, QProfileDto profile, String severity) { qProfileRules.activateAndCommit(dbSession, profile, singleton(RuleActivation.create(rule.getId(), severity, null))); -// dbSession.commit(); -// activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java index 231851e2d31..b9cf0f4fc2a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ProjectsActionTest.java @@ -19,31 +19,30 @@ */ package org.sonar.server.qualityprofile.ws; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.user.UserDto; -import org.sonar.db.user.UserTesting; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.qualityprofile.QProfileTesting; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; -import org.sonar.server.ws.WsTester.TestRequest; +import org.sonar.server.ws.WsActionTester; +import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.server.ws.WebService.Param.PAGE; +import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; +import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; +import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; public class ProjectsActionTest { @@ -53,161 +52,303 @@ public class ProjectsActionTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); + public UserSessionRule userSession = UserSessionRule.standalone(); - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - - private OrganizationDto organizationDto; - private UserDto user; - private QProfileDto xooP1; - private QProfileDto xooP2; - private ComponentDto project1; - private ComponentDto project2; - private ComponentDto project3; - private ComponentDto project4; - - private WsTester wsTester = new WsTester(new QProfilesWs( - new ProjectsAction(dbClient, userSessionRule, new QProfileWsSupport(dbClient, userSessionRule, TestDefaultOrganizationProvider.from(db))))); - - @Before - public void setUp() { - organizationDto = db.organizations().insert(); - user = db.users().insertUser(UserTesting.newUserDto().setLogin("obiwan")); - userSessionRule.logIn("obiwan").setUserId(user.getId()); - - createProfiles(); - - dbSession.commit(); - } + private WsActionTester ws = new WsActionTester( + new ProjectsAction(db.getDbClient(), userSession, new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)))); @Test - public void should_list_authorized_projects_only() throws Exception { - project1 = newPrivateProject("ABCD", "Project One"); - project2 = newPrivateProject("BCDE", "Project Two"); - db.components().insertComponents(project1, project2); - + public void list_authorized_projects_only() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project1 = db.components().insertPrivateProject(organization); + ComponentDto project2 = db.components().insertPrivateProject(organization); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project1, project2); // user only sees project1 - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project1); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2); - - dbSession.commit(); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").execute().assertJson(this.getClass(), "authorized_selected.json"); + UserDto user = db.users().insertUser(); + db.users().insertProjectPermissionOnUser(user, USER, project1); + userSession.logIn(user); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .execute() + .assertJson("{\"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project1.getKey() + "\",\n" + + " \"name\": \"" + project1.name() + "\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]}"); } @Test - public void should_paginate() throws Exception { - project1 = newPublicProject("ABCD", "Project One"); - project2 = newPublicProject("BCDE", "Project Two"); - project3 = newPublicProject("CDEF", "Project Three"); - project4 = newPublicProject("DEFA", "Project Four"); - dbClient.componentDao().insert(dbSession, project1, project2, project3, project4); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2, project3, project4); - - dbSession.commit(); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "2") - .execute().assertJson(this.getClass(), "selected_page1.json"); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "2").setParam(Param.PAGE, "2") - .execute().assertJson(this.getClass(), "selected_page2.json"); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "2").setParam(Param.PAGE, "3") - .execute().assertJson(this.getClass(), "empty.json"); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "2").setParam(Param.PAGE, "4") - .execute().assertJson(this.getClass(), "empty.json"); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "3").setParam(Param.PAGE, "1") - .execute().assertJson(this.getClass(), "selected_ps3_page1.json"); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "3").setParam(Param.PAGE, "2") - .execute().assertJson(this.getClass(), "selected_ps3_page2.json"); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "selected").setParam(Param.PAGE_SIZE, "3").setParam(Param.PAGE, "3") - .execute().assertJson(this.getClass(), "empty.json"); + public void paginate() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project1 = db.components().insertPublicProject(organization, p -> p.setName("Project One")); + ComponentDto project2 = db.components().insertPublicProject(organization, p -> p.setName("Project Two")); + ComponentDto project3 = db.components().insertPublicProject(organization, p -> p.setName("Project Three")); + ComponentDto project4 = db.components().insertPublicProject(organization, p -> p.setName("Project Four")); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project1, project2, project3, project4); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "2") + .execute() + .assertJson("{\n" + + " \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project4.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project1.getKey() + "\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]\n" + + "}\n"); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "2") + .setParam(PAGE, "2") + .execute() + .assertJson("{\n" + + " \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project3.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project2.getKey() + "\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]\n" + + "}\n"); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "2") + .setParam(PAGE, "3") + .execute() + .assertJson("{\"results\":[]}"); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "2") + .setParam(PAGE, "4") + .execute() + .assertJson("{\"results\":[]}"); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "3") + .setParam(PAGE, "1") + .execute() + .assertJson("{\n" + + " \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project4.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project1.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project3.getKey() + "\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]\n" + + "}\n"); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "3") + .setParam(PAGE, "2") + .execute() + .assertJson("{\n" + + " \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project2.getKey() + "\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]\n" + + "}\n"); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "selected") + .setParam(PAGE_SIZE, "3") + .setParam(PAGE, "3") + .execute() + .assertJson("{\"results\":[]}"); } @Test - public void should_show_unselected() throws Exception { - project1 = newPublicProject("ABCD", "Project One"); - project2 = newPublicProject("BCDE", "Project Two"); - project3 = newPublicProject("CDEF", "Project Three"); - project4 = newPublicProject("DEFA", "Project Four"); - dbClient.componentDao().insert(dbSession, project1, project2, project3, project4); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2); - - dbSession.commit(); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "deselected").execute().assertJson(this.getClass(), "deselected.json"); + public void show_unselected() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project1 = db.components().insertPublicProject(organization); + ComponentDto project2 = db.components().insertPublicProject(organization); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project1); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "deselected") + .execute() + .assertJson("{ \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project2.getKey() + "\",\n" + + " \"selected\": false\n" + + " }\n" + + " ]}"); } @Test - public void should_show_all() throws Exception { - project1 = newPublicProject("ABCD", "Project One"); - project2 = newPublicProject("BCDE", "Project Two"); - project3 = newPublicProject("CDEF", "Project Three"); - project4 = newPublicProject("DEFA", "Project Four"); - dbClient.componentDao().insert(dbSession, project1, project2, project3, project4); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2); + public void show_all() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project1 = db.components().insertPublicProject(organization, p -> p.setName("Project 1")); + ComponentDto project2 = db.components().insertPublicProject(organization, p -> p.setName("Project 2")); + ComponentDto project3 = db.components().insertPublicProject(organization, p -> p.setName("Project 3")); + ComponentDto project4 = db.components().insertPublicProject(organization, p -> p.setName("Project 4")); + QProfileDto qualityProfile1 = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile1, project1, project2); + QProfileDto qualityProfile2 = db.qualityProfiles().insert(organization); // project3 is associated with P2, must appear as not associated with xooP1 - associateProjectsWithProfile(dbSession, xooP2, project3); - - dbSession.commit(); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "all").execute().assertJson(this.getClass(), "all.json"); + associateProjectsWithProfile(qualityProfile2, project3); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile1.getKee()) + .setParam("selected", "all") + .execute() + .assertJson("{\n" + + " \"results\": [\n" + + " {\n" + + " \"key\": \"" + project1.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project2.getKey() + "\",\n" + + " \"selected\": true\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project3.getKey() + "\",\n" + + " \"selected\": false\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project4.getKey() + "\",\n" + + " \"selected\": false\n" + + " }\n" + + " ]}\n"); } @Test - public void should_filter_on_name() throws Exception { - project1 = newPublicProject("ABCD", "Project One"); - project2 = newPublicProject("BCDE", "Project Two"); - project3 = newPublicProject("CDEF", "Project Three"); - project4 = newPublicProject("DEFA", "Project Four"); - dbClient.componentDao().insert(dbSession, project1, project2, project3, project4); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2); - - dbSession.commit(); - - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "all").setParam(Param.TEXT_QUERY, "project t").execute().assertJson(this.getClass(), "all_filtered.json"); + public void filter_on_name() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project1 = db.components().insertPublicProject(organization, p -> p.setName("Project One")); + ComponentDto project2 = db.components().insertPublicProject(organization, p -> p.setName("Project Two")); + ComponentDto project3 = db.components().insertPublicProject(organization, p -> p.setName("Project Three")); + ComponentDto project4 = db.components().insertPublicProject(organization, p -> p.setName("Project Four")); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project1, project2); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "all") + .setParam(TEXT_QUERY, "project t") + .execute() + .assertJson("{\n" + + " \"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project3.getKey() + "\",\n" + + " \"name\": \"Project Three\",\n" + + " \"selected\": false\n" + + " },\n" + + " {\n" + + " \"key\": \"" + project2.getKey() + "\",\n" + + " \"name\": \"Project Two\",\n" + + " \"selected\": true\n" + + " }\n" + + " ]}\n"); } @Test - public void should_fail_on_nonexistent_profile() throws Exception { - expectedException.expect(NotFoundException.class); - - newRequest().setParam(PARAM_KEY, "unknown").setParam("selected", "all").execute(); + public void return_deprecated_uuid_field() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project = db.components().insertPublicProject(organization); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "all") + .execute() + .assertJson("{\"results\":\n" + + " [\n" + + " {\n" + + " \"id\": \"" + project.uuid() + "\",\n" + + " \"key\": \"" + project.getKey() + "\",\n" + + " }\n" + + " ]}"); } @Test - public void return_deprecated_uuid_field() throws Exception { - project1 = newPublicProject("ABCD", "Project One"); - project2 = newPublicProject("BCDE", "Project Two"); - project3 = newPublicProject("CDEF", "Project Three"); - project4 = newPublicProject("DEFA", "Project Four"); - dbClient.componentDao().insert(dbSession, project1, project2, project3, project4); - - associateProjectsWithProfile(dbSession, xooP1, project1, project2); - // project3 is associated with P2, must appear as not associated with xooP1 - associateProjectsWithProfile(dbSession, xooP2, project3); + public void projects_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto project = db.components().insertPublicProject(organization); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + associateProjectsWithProfile(qualityProfile, project); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .setParam("selected", "all") + .execute() + .assertJson("{\"results\":\n" + + " [\n" + + " {\n" + + " \"key\": \"" + project.getKey() + "\",\n" + + " }\n" + + " ]}"); + } - dbSession.commit(); + @Test + public void fail_on_nonexistent_profile() { + expectedException.expect(NotFoundException.class); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam("selected", "all").execute().assertJson(this.getClass(), "return_deprecated_uuid_field.json"); + ws.newRequest() + .setParam(PARAM_KEY, "unknown") + .execute(); } @Test - public void fail_if_page_size_greater_than_500() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("'ps' value (501) must be less than 500"); + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); - newRequest().setParam(PARAM_KEY, xooP1.getKee()).setParam(Param.PAGE_SIZE, "501").execute(); + ws.newRequest() + .setParam(PARAM_KEY, qualityProfile.getKee()) + .execute(); } @Test public void definition() { - WebService.Action definition = wsTester.action("api/qualityprofiles", "projects"); + WebService.Action definition = ws.getDef(); assertThat(definition.key()).isEqualTo("projects"); assertThat(definition.responseExampleAsString()).isNotEmpty(); @@ -222,27 +363,10 @@ public class ProjectsActionTest { assertThat(query.deprecatedKey()).isEqualTo("query"); } - private void createProfiles() { - xooP1 = QProfileTesting.newXooP1(organizationDto); - xooP2 = QProfileTesting.newXooP2(organizationDto); - dbClient.qualityProfileDao().insert(dbSession, xooP1, xooP2); - } - - private TestRequest newRequest() { - return wsTester.newGetRequest("api/qualityprofiles", "projects"); - } - - private ComponentDto newPublicProject(String uuid, String name) { - return ComponentTesting.newPublicProjectDto(organizationDto, uuid).setName(name); - } - - private ComponentDto newPrivateProject(String uuid, String name) { - return ComponentTesting.newPrivateProjectDto(organizationDto, uuid).setName(name); - } - - private void associateProjectsWithProfile(DbSession dbSession, QProfileDto profile, ComponentDto... projects) { + private void associateProjectsWithProfile(QProfileDto profile, ComponentDto... projects) { for (ComponentDto project : projects) { - dbClient.qualityProfileDao().insertProjectProfileAssociation(dbSession, project, profile); + db.getDbClient().qualityProfileDao().insertProjectProfileAssociation(db.getSession(), project, profile); } + db.commit(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java deleted file mode 100644 index 0707679e0d8..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.qualityprofile.ws; - -import java.io.Reader; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.db.DbClient; -import org.sonar.server.language.LanguageTesting; -import org.sonar.server.organization.DefaultOrganizationProvider; -import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class QProfilesWsTest { - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - private WebService.Controller controller; - private String xoo1Key = "xoo1"; - private String xoo2Key = "xoo2"; - private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); - private QProfileWsSupport wsSupport = new QProfileWsSupport(mock(DbClient.class), userSession, defaultOrganizationProvider); - - @Before - public void setUp() { - DbClient dbClient = mock(DbClient.class); - - Languages languages = LanguageTesting.newLanguages(xoo1Key, xoo2Key); - - ProfileImporter[] importers = createImporters(languages); - - controller = new WsTester(new QProfilesWs( - new CreateAction(null, null, null, languages, wsSupport, userSession, null, importers), - new ImportersAction(importers), - new SearchAction(userSession, languages, dbClient, wsSupport, null), - new SetDefaultAction(languages, null, null, wsSupport), - new ProjectsAction(null, userSession, wsSupport), - new ChangelogAction(wsSupport, languages, dbClient), - new ChangeParentAction(dbClient, null, languages, wsSupport, userSession), - new CompareAction(null, null, languages), - new DeleteAction(languages, null, null, userSession, wsSupport), - new ExportersAction(), - new InheritanceAction(null, null, languages), - new RenameAction(dbClient, userSession, wsSupport))).controller(QProfilesWs.API_ENDPOINT); - } - - private ProfileImporter[] createImporters(Languages languages) { - class NoopImporter extends ProfileImporter { - public NoopImporter(Language language) { - super(language.getKey(), language.getName()); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - return null; - } - } - return new ProfileImporter[] { - new NoopImporter(languages.get(xoo1Key)), - new NoopImporter(languages.get(xoo2Key)) - }; - } - - @Test - public void define_controller() { - assertThat(controller).isNotNull(); - assertThat(controller.path()).isEqualTo(QProfilesWs.API_ENDPOINT); - assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).isNotEmpty(); - } - - @Test - public void define_create_action() { - WebService.Action create = controller.action("create"); - assertThat(create).isNotNull(); - assertThat(create.isPost()).isTrue(); - assertThat(create.params()).hasSize(5); - assertThat(create.param("organization")).isNotNull(); - assertThat(create.param("organization").isRequired()).isFalse(); - assertThat(create.param("organization").isInternal()).isTrue(); - assertThat(create.param("name")).isNotNull(); - assertThat(create.param("name").isRequired()).isTrue(); - assertThat(create.param("language").possibleValues()).containsOnly(xoo1Key, xoo2Key); - assertThat(create.param("language").isRequired()).isTrue(); - assertThat(create.param("backup_" + xoo1Key)).isNotNull(); - assertThat(create.param("backup_" + xoo1Key).isRequired()).isFalse(); - assertThat(create.param("backup_" + xoo2Key)).isNotNull(); - assertThat(create.param("backup_" + xoo2Key).isRequired()).isFalse(); - } - - @Test - public void define_importers_action() { - WebService.Action importers = controller.action("importers"); - assertThat(importers).isNotNull(); - assertThat(importers.isPost()).isFalse(); - assertThat(importers.params()).isEmpty(); - assertThat(importers.responseExampleAsString()).isNotEmpty(); - } - - @Test - public void define_changelog_action() { - WebService.Action changelog = controller.action("changelog"); - assertThat(changelog).isNotNull(); - assertThat(changelog.isPost()).isFalse(); - assertThat(changelog.params().size()).isPositive(); - assertThat(changelog.responseExampleAsString()).isNotEmpty(); - assertThat(changelog.param("organization").since()).isEqualTo("6.4"); - assertThat(changelog.param("organization").isInternal()).isTrue(); - } - - @Test - public void define_compare_action() { - WebService.Action compare = controller.action("compare"); - assertThat(compare).isNotNull(); - assertThat(compare.isPost()).isFalse(); - assertThat(compare.isInternal()).isTrue(); - assertThat(compare.params()).hasSize(2).extracting("key").containsOnly( - "leftKey", "rightKey"); - assertThat(compare.responseExampleAsString()).isNotEmpty(); - } - - @Test - public void define_delete_action() { - WebService.Action delete = controller.action("delete"); - assertThat(delete).isNotNull(); - assertThat(delete.isPost()).isTrue(); - assertThat(delete.params()).hasSize(4).extracting(Param::key).containsOnly( - "organization", "key", "language", "qualityProfile"); - } - - @Test - public void define_exporters_action() { - WebService.Action exporters = controller.action("exporters"); - assertThat(exporters).isNotNull(); - assertThat(exporters.isPost()).isFalse(); - assertThat(exporters.params()).isEmpty(); - assertThat(exporters.responseExampleAsString()).isNotEmpty(); - } - - @Test - public void define_inheritance_action() { - WebService.Action inheritance = controller.action("inheritance"); - assertThat(inheritance).isNotNull(); - assertThat(inheritance.isPost()).isFalse(); - assertThat(inheritance.params()).hasSize(4).extracting(Param::key).containsExactlyInAnyOrder( - "organization", "key", "language", "qualityProfile"); - assertThat(inheritance.responseExampleAsString()).isNotEmpty(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java index a84e3b2831a..506f769c7ee 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java @@ -41,6 +41,7 @@ import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; @@ -58,6 +59,8 @@ import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.rule.RuleStatus.DEPRECATED; import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.db.component.ComponentTesting.newModuleDto; +import static org.sonar.db.organization.OrganizationDto.Subscription.FREE; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto; import static org.sonar.server.language.LanguageTesting.newLanguage; import static org.sonar.test.JsonAssert.assertJson; @@ -88,46 +91,6 @@ public class SearchActionTest { private WsActionTester ws = new WsActionTester(underTest); @Test - public void definition() { - WebService.Action definition = ws.getDef(); - - assertThat(definition.key()).isEqualTo("search"); - assertThat(definition.responseExampleAsString()).isNotEmpty(); - assertThat(definition.isPost()).isFalse(); - - assertThat(definition.changelog()) - .extracting(Change::getVersion, Change::getDescription) - .containsExactlyInAnyOrder( - tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"), - tuple("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"), - tuple("7.0", "Add available actions 'delete' and 'associateProjects'")); - - WebService.Param organization = definition.param("organization"); - assertThat(organization).isNotNull(); - assertThat(organization.isRequired()).isFalse(); - assertThat(organization.isInternal()).isTrue(); - assertThat(organization.description()).isNotEmpty(); - assertThat(organization.since()).isEqualTo("6.4"); - - WebService.Param defaults = definition.param("defaults"); - assertThat(defaults.defaultValue()).isEqualTo("false"); - assertThat(defaults.description()).isEqualTo("If set to true, return only the quality profiles marked as default for each language"); - - WebService.Param projectKey = definition.param("project"); - assertThat(projectKey.description()).isEqualTo("Project key"); - assertThat(projectKey.deprecatedKey()).isEqualTo("projectKey"); - - WebService.Param language = definition.param("language"); - assertThat(language.possibleValues()).containsExactly("xoo1", "xoo2"); - assertThat(language.deprecatedSince()).isNull(); - assertThat(language.description()).isEqualTo("Language key. If provided, only profiles for the given language are returned."); - - WebService.Param profileName = definition.param("qualityProfile"); - assertThat(profileName.deprecatedSince()).isNull(); - assertThat(profileName.description()).isEqualTo("Quality profile name"); - } - - @Test public void no_profile() { SearchWsResponse result = call(ws.newRequest()); @@ -393,39 +356,6 @@ public class SearchActionTest { } @Test - public void fail_if_project_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Component key 'unknown-project' not found"); - - call(ws.newRequest().setParam(PARAM_PROJECT_KEY, "unknown-project")); - } - - @Test - public void fail_if_project_of_module_does_not_exist() { - ComponentDto project = db.components().insertPrivateProject(); - ComponentDto module = db.components().insertComponent(newModuleDto(project).setProjectUuid("unknown")); - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage(format("Project uuid of component uuid '%s' does not exist", module.uuid())); - - call(ws.newRequest().setParam(PARAM_PROJECT_KEY, module.getDbKey())); - } - - @Test - public void fail_if_project_is_on_another_organization() { - OrganizationDto organization = db.organizations().insert(); - OrganizationDto anotherOrganization = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(anotherOrganization); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component key '%s' not found", project.getDbKey())); - - call(ws.newRequest() - .setParam(PARAM_ORGANIZATION, organization.getKey()) - .setParam(PARAM_PROJECT_KEY, project.getDbKey())); - } - - @Test public void statistics_on_active_rules() { QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey())); RuleDefinitionDto rule = db.rules().insertRule(r -> r.setLanguage(XOO1.getKey())).getDefinition(); @@ -479,6 +409,83 @@ public class SearchActionTest { } @Test + public void return_qprofile_on_free_organization() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(FREE)); + QProfileDto qProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey())); + + SearchWsResponse result = call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey())); + + assertThat(result.getProfilesList()).extracting(QualityProfile::getKey) + .containsExactlyInAnyOrder(qProfile.getKee()); + } + + @Test + public void return_qprofile_on_paid_organization_when_user_is_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey())); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + SearchWsResponse result = call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey())); + + assertThat(result.getProfilesList()).extracting(QualityProfile::getKey) + .containsExactlyInAnyOrder(qProfile.getKee()); + } + + @Test + public void fail_if_project_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Component key 'unknown-project' not found"); + + call(ws.newRequest().setParam(PARAM_PROJECT_KEY, "unknown-project")); + } + + @Test + public void fail_if_project_of_module_does_not_exist() { + ComponentDto project = db.components().insertPrivateProject(); + ComponentDto module = db.components().insertComponent(newModuleDto(project).setProjectUuid("unknown")); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage(format("Project uuid of component uuid '%s' does not exist", module.uuid())); + + call(ws.newRequest().setParam(PARAM_PROJECT_KEY, module.getDbKey())); + } + + @Test + public void fail_if_project_is_on_another_organization() { + OrganizationDto organization = db.organizations().insert(); + OrganizationDto anotherOrganization = db.organizations().insert(); + ComponentDto project = db.components().insertPrivateProject(anotherOrganization); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage(format("Component key '%s' not found", project.getDbKey())); + + call(ws.newRequest() + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .setParam(PARAM_PROJECT_KEY, project.getDbKey())); + } + + @Test + public void fail_if_organization_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("No organization with key 'unknown-organization'"); + + call(ws.newRequest().setParam(PARAM_ORGANIZATION, "unknown-organization")); + } + + @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + userSession.logIn(); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey())); + } + + @Test public void json_example() { OrganizationDto organization = db.organizations().insertForKey("My Organization"); // languages @@ -528,6 +535,46 @@ public class SearchActionTest { .isSimilarTo(ws.getDef().responseExampleAsString()); } + @Test + public void definition() { + WebService.Action definition = ws.getDef(); + + assertThat(definition.key()).isEqualTo("search"); + assertThat(definition.responseExampleAsString()).isNotEmpty(); + assertThat(definition.isPost()).isFalse(); + + assertThat(definition.changelog()) + .extracting(Change::getVersion, Change::getDescription) + .containsExactlyInAnyOrder( + tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"), + tuple("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"), + tuple("7.0", "Add available actions 'delete' and 'associateProjects'")); + + WebService.Param organization = definition.param("organization"); + assertThat(organization).isNotNull(); + assertThat(organization.isRequired()).isFalse(); + assertThat(organization.isInternal()).isTrue(); + assertThat(organization.description()).isNotEmpty(); + assertThat(organization.since()).isEqualTo("6.4"); + + WebService.Param defaults = definition.param("defaults"); + assertThat(defaults.defaultValue()).isEqualTo("false"); + assertThat(defaults.description()).isEqualTo("If set to true, return only the quality profiles marked as default for each language"); + + WebService.Param projectKey = definition.param("project"); + assertThat(projectKey.description()).isEqualTo("Project key"); + assertThat(projectKey.deprecatedKey()).isEqualTo("projectKey"); + + WebService.Param language = definition.param("language"); + assertThat(language.possibleValues()).containsExactly("xoo1", "xoo2"); + assertThat(language.deprecatedSince()).isNull(); + assertThat(language.description()).isEqualTo("Language key. If provided, only profiles for the given language are returned."); + + WebService.Param profileName = definition.param("qualityProfile"); + assertThat(profileName.deprecatedSince()).isNull(); + assertThat(profileName.description()).isEqualTo("Quality profile name"); + } + private SearchWsResponse call(TestRequest request) { TestRequest wsRequest = request.setMediaType(MediaTypes.PROTOBUF); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ShowActionTest.java index 5e3e09572dc..dbb9b617ead 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ShowActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ShowActionTest.java @@ -28,9 +28,12 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDefinitionDto; +import org.sonar.db.user.UserDto; import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; @@ -40,15 +43,16 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.MediaTypes; -import org.sonarqube.ws.Qualityprofiles; import org.sonarqube.ws.Qualityprofiles.ShowResponse; import org.sonarqube.ws.Qualityprofiles.ShowResponse.CompareToSonarWay; import org.sonarqube.ws.Qualityprofiles.ShowResponse.QualityProfile; +import static java.lang.String.format; import static java.util.stream.IntStream.range; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.rule.RuleStatus.DEPRECATED; import static org.sonar.api.utils.DateUtils.parseDateTime; +import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.server.language.LanguageTesting.newLanguage; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_COMPARE_TO_SONAR_WAY; @@ -77,31 +81,10 @@ public class ShowActionTest { new ShowAction(db.getDbClient(), new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)), LANGUAGES, ruleIndex)); @Test - public void test_definition() { - WebService.Action action = ws.getDef(); - assertThat(action.key()).isEqualTo("show"); - assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.isPost()).isFalse(); - assertThat(action.since()).isEqualTo("6.5"); - - WebService.Param profile = action.param("key"); - assertThat(profile.isRequired()).isTrue(); - assertThat(profile.isInternal()).isFalse(); - assertThat(profile.description()).isNotEmpty(); - - WebService.Param compareToSonarWay = action.param("compareToSonarWay"); - assertThat(compareToSonarWay.isRequired()).isFalse(); - assertThat(compareToSonarWay.isInternal()).isTrue(); - assertThat(compareToSonarWay.description()).isNotEmpty(); - assertThat(compareToSonarWay.defaultValue()).isEqualTo("false"); - assertThat(compareToSonarWay.possibleValues()).contains("true", "false"); - } - - @Test public void profile_info() { QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey())); - Qualityprofiles.ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); + ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); assertThat(result.getProfile()) .extracting(QualityProfile::getKey, QualityProfile::getName, QualityProfile::getIsBuiltIn, QualityProfile::getLanguage, QualityProfile::getLanguageName, @@ -114,7 +97,7 @@ public class ShowActionTest { QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey())); db.qualityProfiles().setAsDefault(profile); - Qualityprofiles.ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); + ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); assertThat(result.getProfile().getIsDefault()).isTrue(); } @@ -139,7 +122,7 @@ public class ShowActionTest { .setLastUsed(time) .setUserUpdatedAt(time)); - Qualityprofiles.ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); + ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); assertThat(result.getProfile().getRulesUpdatedAt()).isEqualTo("2016-12-21T19:10:03+0100"); assertThat(parseDateTime(result.getProfile().getLastUsed()).getTime()).isEqualTo(time); @@ -162,7 +145,7 @@ public class ShowActionTest { .mapToObj(i -> db.components().insertPrivateProject()) .forEach(project -> db.qualityProfiles().associateWithProject(project, profile)); - Qualityprofiles.ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); + ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, profile.getKee())); assertThat(result.getProfile()) .extracting(QualityProfile::getActiveRuleCount, QualityProfile::getActiveDeprecatedRuleCount, QualityProfile::getProjectCount) @@ -192,7 +175,7 @@ public class ShowActionTest { CompareToSonarWay result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")) - .getCompareToSonarWay(); + .getCompareToSonarWay(); assertThat(result) .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName, CompareToSonarWay::getMissingRuleCount) @@ -212,7 +195,7 @@ public class ShowActionTest { CompareToSonarWay result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")) - .getCompareToSonarWay(); + .getCompareToSonarWay(); assertThat(result) .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName, CompareToSonarWay::getMissingRuleCount) @@ -237,7 +220,7 @@ public class ShowActionTest { QProfileDto sonarWayProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setIsBuiltIn(true).setName("Sonar way").setLanguage(XOO1.getKey())); QProfileDto anotherBuiltInProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setIsBuiltIn(true).setLanguage(XOO1.getKey())); - Qualityprofiles.ShowResponse result = call(ws.newRequest() + ShowResponse result = call(ws.newRequest() .setParam(PARAM_KEY, anotherBuiltInProfile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")); @@ -249,7 +232,7 @@ public class ShowActionTest { QProfileDto sonarWayProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setIsBuiltIn(false).setName("Sonar way").setLanguage(XOO1.getKey())); QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey())); - Qualityprofiles.ShowResponse result = call(ws.newRequest() + ShowResponse result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")); @@ -261,7 +244,7 @@ public class ShowActionTest { QProfileDto sonarWayProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setIsBuiltIn(true).setName("Sonar way").setLanguage(XOO1.getKey())); QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey())); - Qualityprofiles.ShowResponse result = call(ws.newRequest() + ShowResponse result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "false")); @@ -276,7 +259,7 @@ public class ShowActionTest { CompareToSonarWay result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")) - .getCompareToSonarWay(); + .getCompareToSonarWay(); assertThat(result) .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName) @@ -292,7 +275,7 @@ public class ShowActionTest { CompareToSonarWay result = call(ws.newRequest() .setParam(PARAM_KEY, profile.getKee()) .setParam(PARAM_COMPARE_TO_SONAR_WAY, "true")) - .getCompareToSonarWay(); + .getCompareToSonarWay(); assertThat(result) .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName) @@ -300,6 +283,21 @@ public class ShowActionTest { } @Test + public void show_on_paid_organization() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey())); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + userSession.logIn(user); + + ShowResponse result = call(ws.newRequest().setParam(PARAM_KEY, qualityProfile.getKee())); + + assertThat(result.getProfile()) + .extracting(QualityProfile::getKey) + .containsExactly(qualityProfile.getKee()); + } + + @Test public void fail_if_profile_language_is_not_supported() { QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setKee("unknown-profile").setLanguage("kotlin")); @@ -318,6 +316,17 @@ public class ShowActionTest { } @Test + public void fail_on_paid_organization_when_not_member() { + OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID)); + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey())); + + call(ws.newRequest().setParam(PARAM_KEY, qualityProfile.getKee())); + } + + @Test public void json_example() { Language cs = newLanguage("cs", "C#"); QProfileDto parentProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), @@ -347,8 +356,29 @@ public class ShowActionTest { assertJson(result).ignoreFields("rulesUpdatedAt", "lastUsed", "userUpdatedAt").isSimilarTo(ws.getDef().responseExampleAsString()); } + @Test + public void test_definition() { + WebService.Action action = ws.getDef(); + assertThat(action.key()).isEqualTo("show"); + assertThat(action.responseExampleAsString()).isNotEmpty(); + assertThat(action.isPost()).isFalse(); + assertThat(action.since()).isEqualTo("6.5"); + + WebService.Param profile = action.param("key"); + assertThat(profile.isRequired()).isTrue(); + assertThat(profile.isInternal()).isFalse(); + assertThat(profile.description()).isNotEmpty(); + + WebService.Param compareToSonarWay = action.param("compareToSonarWay"); + assertThat(compareToSonarWay.isRequired()).isFalse(); + assertThat(compareToSonarWay.isInternal()).isTrue(); + assertThat(compareToSonarWay.description()).isNotEmpty(); + assertThat(compareToSonarWay.defaultValue()).isEqualTo("false"); + assertThat(compareToSonarWay.possibleValues()).contains("true", "false"); + } + private ShowResponse call(TestRequest request) { TestRequest wsRequest = request.setMediaType(MediaTypes.PROTOBUF); - return wsRequest.executeProtobuf(Qualityprofiles.ShowResponse.class); + return wsRequest.executeProtobuf(ShowResponse.class); } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json deleted file mode 100644 index c5af6b1dd32..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "results": [ - { - "id": "DEFA", - "key": "KEY_DEFA", - "name": "Project Four", - "selected": false - }, - { - "id": "ABCD", - "key": "KEY_ABCD", - "name": "Project One", - "selected": true - }, - { - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": false - }, - { - "id": "BCDE", - "key": "KEY_BCDE", - "name": "Project Two", - "selected": true - } - ], - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json deleted file mode 100644 index 76ef1f18a49..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/all_filtered.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "results": - [ - { - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": false - }, - { - "id": "BCDE", - "key": "KEY_BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json deleted file mode 100644 index 786617f8b92..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/authorized_selected.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "results": - [ - { - "id": "ABCD", - "key": "KEY_ABCD", - "name": "Project One", - "selected": true - } - ], - - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json deleted file mode 100644 index f4a11d0044a..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/deselected.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "results": - [ - { - "id": "DEFA", - "key": "KEY_DEFA", - "name": "Project Four", - "selected": false - }, - { - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": false - } - ], - - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json deleted file mode 100644 index cea4e2ee3c4..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/empty.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "results": - [], - - "more": false -}
\ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/return_deprecated_uuid_field.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/return_deprecated_uuid_field.json deleted file mode 100644 index 698b409356d..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/return_deprecated_uuid_field.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "results": [ - { - "uuid": "DEFA", - "id": "DEFA", - "key": "KEY_DEFA", - "name": "Project Four", - "selected": false - }, - { - "uuid": "ABCD", - "id": "ABCD", - "key": "KEY_ABCD", - "name": "Project One", - "selected": true - }, - { - "uuid": "CDEF", - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": false - }, - { - "uuid": "BCDE", - "id": "BCDE", - "key": "KEY_BCDE", - "name": "Project Two", - "selected": true - } - ], - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json deleted file mode 100644 index 0633017aece..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page1.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "results": - [ - { - "id": "DEFA", - "key": "KEY_DEFA", - "name": "Project Four", - "selected": true - }, - { - "uuid": "ABCD", - "key": "KEY_ABCD", - "name": "Project One", - "selected": true - } - ], - - "more": true -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json deleted file mode 100644 index f32c97b7946..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_page2.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "results": - [ - { - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": true - }, - { - "id": "BCDE", - "key": "KEY_BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json deleted file mode 100644 index adc3dfb5657..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page1.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "results": - [ - { - "id": "DEFA", - "key": "KEY_DEFA", - "name": "Project Four", - "selected": true - }, - { - "id": "ABCD", - "key": "KEY_ABCD", - "name": "Project One", - "selected": true - }, - { - "id": "CDEF", - "key": "KEY_CDEF", - "name": "Project Three", - "selected": true - } - ], - - "more": true -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json deleted file mode 100644 index 51941a6cbce..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/ProjectsActionTest/selected_ps3_page2.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "results": - [ - { - "id": "BCDE", - "key": "KEY_BCDE", - "name": "Project Two", - "selected": true - } - ], - - "more": false -} |