From d2aef03a3830823ae277ad935e01194bd99cb0df Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Tue, 11 Apr 2017 11:42:31 +0200 Subject: [PATCH] SONAR-9054 return org pages in WS api/navigation/organization --- .../server/ui/ws/OrganizationAction.java | 37 +++++++++++-- .../server/ui/ws/organization-example.json | 14 ++++- .../server/ui/ws/OrganizationActionTest.java | 53 +++++++++++++++++-- 3 files changed, 93 insertions(+), 11 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java index 277793109f3..dcecc5ef1db 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java @@ -19,17 +19,22 @@ */ package org.sonar.server.ui.ws; +import java.util.List; +import java.util.function.Consumer; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; +import org.sonar.api.web.page.Page; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.db.permission.OrganizationPermission; +import org.sonar.server.organization.DefaultOrganizationProvider; +import org.sonar.server.ui.PageRepository; import org.sonar.server.user.UserSession; +import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_001; import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; public class OrganizationAction implements NavigationWsAction { @@ -40,11 +45,13 @@ public class OrganizationAction implements NavigationWsAction { private final DbClient dbClient; private final DefaultOrganizationProvider defaultOrganizationProvider; private final UserSession userSession; + private final PageRepository pageRepository; - public OrganizationAction(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, UserSession userSession) { + public OrganizationAction(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, UserSession userSession, PageRepository pageRepository) { this.dbClient = dbClient; this.defaultOrganizationProvider = defaultOrganizationProvider; this.userSession = userSession; + this.pageRepository = pageRepository; } @Override @@ -59,7 +66,7 @@ public class OrganizationAction implements NavigationWsAction { projectNavigation.createParam(PARAM_ORGANIZATION) .setRequired(true) .setDescription("the organization key") - .setExampleValue("my-org"); + .setExampleValue(KEY_ORG_EXAMPLE_001); } @Override @@ -84,8 +91,28 @@ public class OrganizationAction implements NavigationWsAction { .prop("canAdmin", userSession.hasPermission(OrganizationPermission.ADMINISTER, organization)) .prop("canProvisionProjects", userSession.hasPermission(OrganizationPermission.PROVISION_PROJECTS, organization)) .prop("canDelete", organization.isGuarded() ? userSession.isSystemAdministrator() : userSession.hasPermission(OrganizationPermission.ADMINISTER, organization)) - .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey())) - .endObject(); + .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey())); + List pages = pageRepository.getOrganizationPages(false); + json.name("pages"); + writePages(json, pages); + if (userSession.hasPermission(OrganizationPermission.ADMINISTER, organization)) { + List adminPages = pageRepository.getOrganizationPages(true); + json.name("adminPages"); + writePages(json, adminPages); + } + json.endObject(); + } + + private static void writePages(JsonWriter json, List pages) { + json.beginArray(); + pages.forEach(writePage(json)); + json.endArray(); + } + private static Consumer writePage(JsonWriter json) { + return page -> json.beginObject() + .prop("key", page.getKey()) + .prop("name", page.getName()) + .endObject(); } } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/organization-example.json b/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/organization-example.json index 0c69c7e81f5..48642de61c5 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/organization-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/organization-example.json @@ -2,6 +2,18 @@ "organization": { "canAdmin": true, "canProvisionProjects": true, - "canDelete": false + "canDelete": false, + "pages": [ + { + "key": "my-plugin/org-page", + "name": "Organization page" + } + ], + "adminPages": [ + { + "key": "my-plugin/org-admin-page", + "name": "Organization admin page" + } + ] } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java index 09634d2ed54..46ab77d70f6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java @@ -25,17 +25,25 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; +import org.sonar.api.web.page.Page; +import org.sonar.api.web.page.PageDefinition; +import org.sonar.core.platform.PluginRepository; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ui.PageRepository; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.web.page.Page.Scope.ORGANIZATION; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; import static org.sonar.test.JsonAssert.assertJson; @@ -50,12 +58,13 @@ public class OrganizationActionTest { private DbClient dbClient = dbTester.getDbClient(); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); + private PageRepository pageRepository = mock(PageRepository.class); - private WsActionTester underTest = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession)); + private WsActionTester ws = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession, pageRepository)); @Test public void verify_definition() { - WebService.Action def = underTest.getDef(); + WebService.Action def = ws.getDef(); assertThat(def.isInternal()).isTrue(); assertThat(def.description()).isEqualTo("Get information concerning organization navigation for the current user"); @@ -77,7 +86,11 @@ public class OrganizationActionTest { } @Test - public void verify_example() { + public void json_example() { + initWithPages( + Page.builder("my-plugin/org-page").setName("Organization page").setScope(ORGANIZATION).build(), + Page.builder("my-plugin/org-admin-page").setName("Organization admin page").setScope(ORGANIZATION).setAdmin(true).build() + ); OrganizationDto organization = dbTester.organizations().insert(dto -> dto.setGuarded(true)); userSession.logIn() .addPermission(ADMINISTER, organization) @@ -86,7 +99,24 @@ public class OrganizationActionTest { TestResponse response = executeRequest(organization); assertJson(response.getInput()) - .isSimilarTo(underTest.getDef().responseExampleAsString()); + .isSimilarTo(ws.getDef().responseExampleAsString()); + } + + @Test + public void filter_out_admin_pages_when_user_is_not_admin() { + initWithPages( + Page.builder("my-plugin/org-page").setName("Organization page").setScope(ORGANIZATION).build(), + Page.builder("my-plugin/org-admin-page").setName("Organization admin page").setScope(ORGANIZATION).setAdmin(true).build() + ); + OrganizationDto organization = dbTester.organizations().insert(dto -> dto.setGuarded(true)); + userSession.logIn() + .addPermission(PROVISION_PROJECTS, organization); + + TestResponse response = executeRequest(organization); + + assertThat(response.getInput()) + .contains("my-plugin/org-page") + .doesNotContain("my-plugin/org-admin-page"); } @Test @@ -174,8 +204,20 @@ public class OrganizationActionTest { verifyResponse(executeRequest(org2), false, true, false); } + private void initWithPages(Page... pages) { + PluginRepository pluginRepository = mock(PluginRepository.class); + when(pluginRepository.hasPlugin(anyString())).thenReturn(true); + PageRepository pageRepository = new PageRepository(pluginRepository, new PageDefinition[] {context -> { + for (Page page : pages) { + context.addPage(page); + } + }}); + pageRepository.start(); + ws = new WsActionTester(new OrganizationAction(dbClient, defaultOrganizationProvider, userSession, pageRepository)); + } + private TestResponse executeRequest(@Nullable OrganizationDto organization) { - TestRequest request = underTest.newRequest(); + TestRequest request = ws.newRequest(); if (organization != null) { request.setParam("organization", organization.getKey()); } @@ -189,6 +231,7 @@ public class OrganizationActionTest { " \"canAdmin\": " + canAdmin + "," + " \"canProvisionProjects\": " + canProvisionProjects + "," + " \"canDelete\": " + canDelete + + " \"pages\": []" + " }" + "}"); } -- 2.39.5