From d651a1c806a18bf01f1cdab313f5f4ae518a3a61 Mon Sep 17 00:00:00 2001 From: robinsoc Date: Tue, 28 Jun 2022 11:01:01 +0200 Subject: [PATCH] feat: Retrieve the user's projets (#276) Part of [request #22618](https://tuleap.net/plugins/tracker/?aid=22618) Stop using the deprecated client in Jenkins plugin Co-authored-by: Clarck Robinson --- .../plugins/tuleap_api/client/ProjectApi.java | 1 + .../client/internals/TuleapApiClient.java | 44 +++++++++++++++++++ .../client/internals/TuleapApiClientTest.java | 40 ++++++++++++++++- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/jenkins/plugins/tuleap_api/client/ProjectApi.java b/src/main/java/io/jenkins/plugins/tuleap_api/client/ProjectApi.java index 93b1048..49ea245 100644 --- a/src/main/java/io/jenkins/plugins/tuleap_api/client/ProjectApi.java +++ b/src/main/java/io/jenkins/plugins/tuleap_api/client/ProjectApi.java @@ -18,4 +18,5 @@ public interface ProjectApi { Project getProjectById(String projectId, TuleapAccessToken token) ; List getProjectUserGroups(Integer projectId, AccessToken token); List getGitRepositories(Integer projectId, TuleapAccessToken token); + List getUserProjects(TuleapAccessToken token); } diff --git a/src/main/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClient.java b/src/main/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClient.java index 5c901b3..1b78c90 100644 --- a/src/main/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClient.java +++ b/src/main/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClient.java @@ -335,6 +335,50 @@ public List getGitRepositories(Integer projectId, TuleapAccessTok } while (offset < totalSize); return allRepositories; } + @Override + @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") // see https://github.com/spotbugs/spotbugs/issues/651 + public List getUserProjects(TuleapAccessToken token) { + int offset = 0; + int totalSize; + + List allProjects = new ArrayList<>(); + + do { + HttpUrl urlGetUserProjects = Objects.requireNonNull(HttpUrl.parse(this.tuleapConfiguration.getApiBaseUrl() + this.PROJECT_API)) + .newBuilder() + .addEncodedQueryParameter("limit", Integer.toString(PAGE_SIZE)) + .addEncodedQueryParameter("offset", Integer.toString(offset)) + .addEncodedQueryParameter("query", PROJECT_MEMBER_OF_QUERY) + .build(); + + Request request = new Request.Builder() + .url(urlGetUserProjects) + .addHeader(this.AUTHORIZATION_HEADER, token.getToken().getPlainText()) + .get() + .build(); + + try (Response response = this.client.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new InvalidTuleapResponseException(response); + } + + List projects = new ArrayList<>(this.objectMapper.readValue( + Objects.requireNonNull(response.body()).string(), + new TypeReference>() { + } + )); + + allProjects.addAll(projects); + + totalSize = Integer.parseInt(Objects.requireNonNull(response.header(COLLECTION_LENGTH_HEADER))); + offset = offset + PAGE_SIZE; + + } catch (InvalidTuleapResponseException | IOException e) { + throw new RuntimeException("Error while contacting Tuleap server", e); + } + } while (offset < totalSize); + return allProjects; + } @Override public void sendTTMResults(String campaignId, String buildUrl, List results, Secret secret) { diff --git a/src/test/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClientTest.java b/src/test/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClientTest.java index ee97e25..eec35ba 100644 --- a/src/test/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClientTest.java +++ b/src/test/java/io/jenkins/plugins/tuleap_api/client/internals/TuleapApiClientTest.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; -import java.util.Optional; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; @@ -801,4 +800,43 @@ public void itReturnsAllGitRepositories() throws IOException { assertEquals("alm/repo-Pouet.git", repositories.get(1).getPath()); } + + @Test(expected = RuntimeException.class) + public void itThrowsAnExceptionWhenUserProjectCannotBeRetrieved() throws IOException { + Call call = mock(Call.class); + Response response = mock(Response.class); + + when(client.newCall(any())).thenReturn(call); + when(call.execute()).thenReturn(response); + when(response.isSuccessful()).thenReturn(false); + + tuleapApiClient.getUserProjects(this.getTuleapAccessTokenStubClass()); + } + + @Test + public void itReturnsUserProjects() throws IOException { + TuleapAccessToken tuleapAccessToken = this.getTuleapAccessTokenStubClass(); + Call call = mock(Call.class); + Response response = mock(Response.class); + ResponseBody responseBody = mock(ResponseBody.class); + String payload = IOUtils.toString(TuleapApiClientTest.class.getResourceAsStream("project_payload.json"), UTF_8); + + when(client.newCall(any())).thenReturn(call); + when(call.execute()).thenReturn(response); + when(response.code()).thenReturn(200); + when(response.isSuccessful()).thenReturn(true); + when(response.body()).thenReturn(responseBody); + when(response.header("x-pagination-size")).thenReturn("1"); + when(responseBody.string()) + .thenReturn(payload); + + List projects = tuleapApiClient.getUserProjects( tuleapAccessToken); + + assertEquals("use-me", projects.get(0).getShortname()); + Integer expectedId = 118; + assertEquals(expectedId, projects.get(0).getId()); + assertEquals("Use Me", projects.get(0).getLabel()); + assertEquals("projects/118", projects.get(0).getUri()); + + } }