From 4fff4271f5b1cce5d416c76eb9f71efec4964e33 Mon Sep 17 00:00:00 2001 From: Oleg Kopysov Date: Fri, 20 Sep 2024 09:52:59 +0300 Subject: [PATCH] feat: Display link to the hub in pull request message when available (#616) * feat: Display link to the hub in pull request message when available Signed-off-by: Oleg Kopysov * fix: Apply changes after code review Signed-off-by: Oleg Kopysov --------- Signed-off-by: Oleg Kopysov --- .../com/lpvs/service/LPVSGitHubService.java | 17 +- .../lpvs/service/LPVSGitHubServiceTest.java | 232 +++++++++++++++--- 2 files changed, 217 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/lpvs/service/LPVSGitHubService.java b/src/main/java/com/lpvs/service/LPVSGitHubService.java index 5ced000d..80ce36e0 100644 --- a/src/main/java/com/lpvs/service/LPVSGitHubService.java +++ b/src/main/java/com/lpvs/service/LPVSGitHubService.java @@ -17,6 +17,7 @@ import com.lpvs.repository.LPVSPullRequestRepository; import com.lpvs.util.LPVSFileUtil; import com.lpvs.util.LPVSPayloadUtil; +import io.micrometer.common.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.kohsuke.github.GitHub; import org.kohsuke.github.GHRepository; @@ -316,11 +317,22 @@ public void commentResults( } } + // Generate hub link + String hubLink = ""; + if (!StringUtils.isBlank(webhookConfig.getHubLink())) { + hubLink = + "\n\n######

Check the validation details on the [website](" + + webhookConfig.getHubLink() + + ")

"; + } + if (hasProhibitedOrRestricted || hasConflicts) { lpvsPullRequest.setStatus(LPVSPullRequestStatus.ISSUES_DETECTED.toString()); pullRequestRepository.save(lpvsPullRequest); pullRequest.comment( - "**\\[LPVS\\]** Potential license issues detected \n\n" + commitComment); + "**\\[LPVS\\]** Potential license issues detected \n\n" + + commitComment + + hubLink); repository.createCommitStatus( webhookConfig.getHeadCommitSHA(), GHCommitState.FAILURE, @@ -330,7 +342,8 @@ public void commentResults( } else { lpvsPullRequest.setStatus(LPVSPullRequestStatus.COMPLETED.toString()); pullRequestRepository.save(lpvsPullRequest); - pullRequest.comment("**\\[LPVS\\]** No license issue detected \n\n" + commitComment); + pullRequest.comment( + "**\\[LPVS\\]** No license issue detected \n\n" + commitComment + hubLink); repository.createCommitStatus( webhookConfig.getHeadCommitSHA(), GHCommitState.SUCCESS, diff --git a/src/test/java/com/lpvs/service/LPVSGitHubServiceTest.java b/src/test/java/com/lpvs/service/LPVSGitHubServiceTest.java index ea6d77a9..8336664d 100644 --- a/src/test/java/com/lpvs/service/LPVSGitHubServiceTest.java +++ b/src/test/java/com/lpvs/service/LPVSGitHubServiceTest.java @@ -2264,8 +2264,23 @@ void setUp() { } @Test - public void testCommentResults__ProhibitedPresentConflictsPresent() throws Exception { + public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() + throws Exception { // main test + webhookConfig.setRepositoryLicense(spdx_id_1); + when(mocked_lpvsLicenseRepository.findFirstBySpdxIdOrderByLicenseIdDesc(spdx_id_1)) + .thenReturn( + new LPVSLicense( + 1L, + license_name_1, + spdx_id_1, + access_1, + alternativeName_1, + checklist_url_1)); + + when(mocked_lpvsLicenseRepository.saveAndFlush(Mockito.any(LPVSLicense.class))) + .thenAnswer(i -> i.getArguments()[0]); + gh_service.commentResults( webhookConfig, List.of(lpvs_file_1), List.of(conflict_1), lpvsPullRequest); @@ -2278,7 +2293,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresent() throws Excep + LPVSPayloadUtil.getRepositoryName(webhookConfig)); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresent() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() error " + e); fail(); } @@ -2296,7 +2311,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresent() throws Excep "[LPVS]"); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresent() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() error " + e); fail(); } @@ -2308,16 +2323,18 @@ public void testCommentResults__ProhibitedPresentConflictsPresent() throws Excep } @Test - public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() + public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() throws Exception { // main test - webhookConfig.setRepositoryLicense(spdx_id_1); - when(mocked_lpvsLicenseRepository.findFirstBySpdxIdOrderByLicenseIdDesc(spdx_id_1)) + webhookConfig.setRepositoryLicense(spdx_id_2); + when(mocked_lpvsLicenseRepository.findFirstBySpdxIdOrderByLicenseIdDesc(spdx_id_2)) + .thenReturn(null); + when(mocked_lpvsLicenseRepository.searchByAlternativeLicenseNames(spdx_id_2)) .thenReturn( new LPVSLicense( 1L, license_name_1, - spdx_id_1, + spdx_id_2, access_1, alternativeName_1, checklist_url_1)); @@ -2337,7 +2354,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresent( + LPVSPayloadUtil.getRepositoryName(webhookConfig)); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() error " + e); fail(); } @@ -2355,7 +2372,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresent( "[LPVS]"); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresent() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() error " + e); fail(); } @@ -2365,27 +2382,180 @@ public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresent( ((GHPullRequestOurMock) mocked_pr_2).verifyCommentCall(expected_comment); ((GHPullRequestOurMock) mocked_pr_2).verifyNoMoreCommentCalls(); } + } - @Test - public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() - throws Exception { - // main test - webhookConfig.setRepositoryLicense(spdx_id_2); - when(mocked_lpvsLicenseRepository.findFirstBySpdxIdOrderByLicenseIdDesc(spdx_id_2)) - .thenReturn(null); - when(mocked_lpvsLicenseRepository.searchByAlternativeLicenseNames(spdx_id_2)) - .thenReturn( - new LPVSLicense( - 1L, - license_name_1, - spdx_id_2, - access_1, - alternativeName_1, - checklist_url_1)); + @Nested + class TestCommentResults__ProhibitedPresentConflictsPresentWithHubLink { + LPVSPullRequestRepository mocked_pullRequestRepository = + mock(LPVSPullRequestRepository.class); + LPVSDetectedLicenseRepository mocked_lpvsDetectedLicenseRepository = + mock(LPVSDetectedLicenseRepository.class); + LPVSLicenseRepository mocked_lpvsLicenseRepository = mock(LPVSLicenseRepository.class); + LPVSLicenseConflictRepository mocked_lpvsLicenseConflictRepository = + mock(LPVSLicenseConflictRepository.class); - when(mocked_lpvsLicenseRepository.saveAndFlush(Mockito.any(LPVSLicense.class))) - .thenAnswer(i -> i.getArguments()[0]); + final String GH_LOGIN = "test_login"; + final String GH_AUTH_TOKEN = "test_auth_token"; + final String GH_API_URL = ""; + final LPVSGitHubService gh_service = + new LPVSGitHubService( + mocked_pullRequestRepository, + mocked_lpvsDetectedLicenseRepository, + mocked_lpvsLicenseRepository, + mocked_lpvsLicenseConflictRepository, + new LPVSGitHubConnectionService( + GH_LOGIN, GH_AUTH_TOKEN, GH_API_URL, exitHandler)); + + GitHub mocked_instance_gh = mock(GitHub.class); + GHRepository mocked_repo = mock(GHRepository.class); + GHPullRequest mocked_pr_1; + GHPullRequest mocked_pr_2; + final String url_pr_1 = "https://github.com/Samsung/LPVS/pull/18"; + final String url_pr_2 = "https://github.com/Samsung/LPVS/pull/19"; + final String repo_url = "https://github.com/Samsung/LPVS"; + + LPVSPullRequest lpvsPullRequest; + // `webhookConfig` + LPVSQueue webhookConfig; + final String commit_sha = "895337e89ae103ff2d18c9e0d93709f743226afa"; + + // `lpvs_file_1` + LPVSFile lpvs_file_1; + final String file_url_1 = + "https://github.com/Samsung/LPVS/tree/main/src/main/java/com/lpvs/service/LPVSGitHubService.java"; + final String file_path_1 = "src/main/java/com/lpvs/service/LPVSGitHubService.java"; + + final String absolute_file_path_1 = "src/main/java/com/lpvs/service/LPVSGitHubService.java"; + final String snippet_type_1 = "snippet"; + final String snippet_match_1 = "15%"; + final String matched_lines_1 = "1-6"; + final String component_1 = "LPVS::Services"; + final String component_file_path_1 = + "src/main/java/com/lpvs/service/LPVSGitHubService.java"; + final String component_file_url_1 = "src/main/java/com/lpvs/service/LPVSGitHubService.java"; + + // `lpvs_license_1` + LPVSLicense lpvs_license_1; + final String license_name_1 = "MIT License"; + final String spdx_id_1 = "MIT"; + final String access_1 = "PROHIBITED"; + final String alternativeName_1 = ""; + final String checklist_url_1 = "https://opensource.org/licenses/MIT"; + // `conflict_1` + LPVSConflict conflict_1; + final String conflict_1_l1 = "MIT"; + final String conflict_1_l2 = "Apache-1.0"; + + final String expected_comment = + "**\\[LPVS\\]** Potential license issues detected \n\n" + + "**Detected Licenses:**\n" + + "\n" + + "Potential license issues detected:\n" + + " - Prohibited license(s): 1\n" + + "\n" + + "
\n" + + "Detailed description of detected licenses\n" + + "\n" + + "
License Type / ExplanationLicense SPDX IDVendor / ComponentVersionRepository File PathComponent File PathMatched LinesMatch Value
PROHIBITED / This license prohibits the use of the licensed code in certain contexts, such as commercial software development.MITnull / LPVS::Servicesnullsrc/main/java/com/lpvs/service/LPVSGitHubService.javasrc/main/java/com/lpvs/service/LPVSGitHubService.java1-6 15%
\n" + + "
\n" + + "\n" + + "**Detected License Conflicts:**\n" + + "\n" + + "Potential license conflict(s) detected: 1\n" + + "\n" + + "
\n" + + "Detailed description of detected license conflicts\n" + + "\n" + + "
ConflictExplanation
MIT and Apache-1.0These two licenses are incompatible due to their conflicting terms and conditions. It is recommended to resolve this conflict by choosing either MIT or Apache-1.0 for the affected components.
\n" + + "
\n" + + "\n\n\n" + + "######

Check the validation details on the [website](http://test.com)

"; + + @BeforeEach + void setUp() { + // set `private static GitHub gitHub;` value + try { + Field staticPrivateGithub = LPVSGitHubService.class.getDeclaredField("gitHub"); + staticPrivateGithub.setAccessible(true); + staticPrivateGithub.set(null, mocked_instance_gh); + } catch (NoSuchFieldException | IllegalAccessException e) { + log.error( + "TestCommentResults__ProhibitedPresentConflictsPresent.setUp() error " + e); + fail(); + } + + lpvsPullRequest = new LPVSPullRequest(); + webhookConfig = new LPVSQueue(); + webhookConfig.setPullRequestAPIUrl(url_pr_2); + webhookConfig.setHeadCommitSHA(commit_sha); + webhookConfig.setPullRequestUrl(url_pr_2); + webhookConfig.setAttempts(0); + webhookConfig.setAction(LPVSPullRequestAction.OPEN); + webhookConfig.setUserId("user"); + webhookConfig.setRepositoryUrl(repo_url); + webhookConfig.setHubLink(""); + + try { + when(mocked_instance_gh.getRepository( + LPVSPayloadUtil.getRepositoryOrganization(webhookConfig) + + "/" + + LPVSPayloadUtil.getRepositoryName(webhookConfig))) + .thenReturn(mocked_repo); + } catch (IOException e) { + log.error("mocked_repo.getRepository error " + e); + } + try { + mocked_pr_1 = new GHPullRequestOurMock(new URL(url_pr_1), null, null, -1, null); + mocked_pr_2 = new GHPullRequestOurMock(new URL(url_pr_2), null, null, -1, null); + } catch (MalformedURLException e) { + log.error( + "TestCommentResults__ProhibitedPresentConflictsPresent.setUp() error " + e); + fail(); + } + try { + when(mocked_repo.getPullRequests(GHIssueState.OPEN)) + .thenReturn(Arrays.asList(mocked_pr_1, mocked_pr_2)); + } catch (IOException e) { + log.error("mocked_repo.getPullRequests error " + e); + } + + lpvs_license_1 = + new LPVSLicense( + 1L, + license_name_1, + spdx_id_1, + access_1, + alternativeName_1, + checklist_url_1); + lpvs_file_1 = + new LPVSFile( + 1L, + file_path_1, + absolute_file_path_1, + snippet_type_1, + snippet_match_1, + matched_lines_1, + Set.of(lpvs_license_1), + component_file_path_1, + component_file_url_1, + component_1, + null, + null, + null, + null); + conflict_1 = new LPVSConflict<>(conflict_1_l1, conflict_1_l2); + + when(mocked_lpvsLicenseRepository.findFirstBySpdxIdOrderByLicenseIdDesc(anyString())) + .thenReturn(lpvs_license_1); + when(mocked_lpvsLicenseRepository.searchByAlternativeLicenseNames(anyString())) + .thenReturn(null); + } + + @Test + public void testCommentResults__ProhibitedPresentConflictsPresent() throws Exception { + // main test + webhookConfig.setHubLink("http://test.com"); gh_service.commentResults( webhookConfig, List.of(lpvs_file_1), List.of(conflict_1), lpvsPullRequest); @@ -2398,7 +2568,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresentA + LPVSPayloadUtil.getRepositoryName(webhookConfig)); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresent() error " + e); fail(); } @@ -2416,7 +2586,7 @@ public void testCommentResults__ProhibitedPresentConflictsPresentLicensePresentA "[LPVS]"); } catch (IOException e) { log.error( - "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresentLicensePresentAlt() error " + "TestCommentResults__ProhibitedPresentConflictsPresent.testCommentResults__ProhibitedPresentConflictsPresent() error " + e); fail(); } @@ -3492,7 +3662,8 @@ class TestCommentResults__ProhibitedAbsentConflictsAbsent { + "**Detected License Conflicts:**\n" + "\n" + "No license conflicts detected.\n" - + "\n"; + + "\n\n\n" + + "######

Check the validation details on the [website](http://example.com)

"; @BeforeEach void setUp() { @@ -3567,6 +3738,7 @@ void setUp() { @Test public void testCommentResults__ProhibitedAbsentConflictsAbsent() throws Exception { // main test + webhookConfig.setHubLink("http://example.com"); gh_service.commentResults( webhookConfig, List.of(lpvs_file_1), List.of(), lpvsPullRequest);