Skip to content

Commit

Permalink
SLCORE-613 refactor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sophio-japharidze-sonarsource committed Nov 6, 2023
1 parent ef22f06 commit 2efd3d6
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ class OpenHotspotInIdeMediumTests {
.withAuthor("author")
.withFilePath("file/path")
.withStatus(HotspotReviewStatus.SAFE)
.withTextRange(new TextRange(1, 0, 3, 4)))))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))
.withTextRange(new TextRange(1, 0, 3, 4)))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))))
.start();
static ServerFixture.Server serverWithoutHotspot = newSonarQubeServer("1.2.3")
.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ void it_should_automatically_synchronize_bound_projects_that_have_an_active_bran
var serverWithIssues = newSonarQubeServer("9.6")
.withProject("projectKey",
project -> project.withBranch("branchName",
branch -> branch.withIssue("key", "ruleKey", "msg", "author", "file/path", "REVIEWED", "SAFE", "", new TextRange(1, 0, 3, 4))))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))
branch -> branch.withIssue("key", "ruleKey", "msg", "author", "file/path", "REVIEWED", "SAFE", "", new TextRange(1, 0, 3, 4))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))))
.start();
backend = newBackend()
.withSonarQubeConnection("connectionId", serverWithIssues)
Expand All @@ -67,8 +67,8 @@ void it_should_automatically_synchronize_bound_projects_when_the_active_branch_c
var serverWithIssues = newSonarQubeServer("9.6")
.withProject("projectKey",
project -> project.withBranch("branchName",
branch -> branch.withIssue("key", "ruleKey", "msg", "author", "file/path", "REVIEWED", "SAFE", "", new TextRange(1, 0, 3, 4))))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))
branch -> branch.withIssue("key", "ruleKey", "msg", "author", "file/path", "REVIEWED", "SAFE", "", new TextRange(1, 0, 3, 4))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile"))))
.start();
backend = newBackend()
.withSonarQubeConnection("connectionId", serverWithIssues)
Expand Down
166 changes: 103 additions & 63 deletions medium-tests/src/test/java/mediumtest/fixtures/ServerFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.UnaryOperator;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.sonar.scanner.protocol.Constants;
import org.sonar.scanner.protocol.input.ScannerInput;
import org.sonarsource.sonarlint.core.commons.HotspotReviewStatus;
Expand Down Expand Up @@ -80,7 +82,6 @@ public static class ServerBuilder {
private final ServerKind serverKind;
private final String version;
private final Map<String, ServerProjectBuilder> projectByProjectKey = new HashMap<>();
private final Map<String, ServerSourceFileBuilder> sourceFileByComponentKey = new HashMap<>();
private ServerStatus serverStatus = ServerStatus.UP;
private boolean smartNotificationsSupported;

Expand All @@ -100,25 +101,20 @@ public ServerBuilder withProject(String projectKey, UnaryOperator<ServerProjectB
return this;
}

public ServerBuilder withSourceFile(String componentKey, UnaryOperator<ServerSourceFileBuilder> sourceFileBuilder) {
var builder = new ServerSourceFileBuilder();
this.sourceFileByComponentKey.put(componentKey, sourceFileBuilder.apply(builder));
return this;
}

public ServerBuilder withSmartNotificationsSupported(boolean smartNotificationsSupported) {
this.smartNotificationsSupported = smartNotificationsSupported;
return this;
}

public Server start() {
var server = new Server(serverKind, serverStatus, version, projectByProjectKey, sourceFileByComponentKey, smartNotificationsSupported);
var server = new Server(serverKind, serverStatus, version, projectByProjectKey, smartNotificationsSupported);
server.start();
return server;
}

public static class ServerProjectBuilder {
private final Map<String, ServerProjectBranchBuilder> branchesByName = new HashMap<>();
private final Map<String, ServerProjectPullRequestBuilder> pullRequestsByName = new HashMap<>();

public ServerProjectBuilder withEmptyBranch(String branchName) {
var builder = new ServerProjectBranchBuilder();
Expand All @@ -132,14 +128,21 @@ public ServerProjectBuilder withBranch(String branchName, UnaryOperator<ServerPr
return this;
}

public ServerProjectBuilder withPullRequest(String pullRequestNumber, UnaryOperator<ServerProjectPullRequestBuilder> pullRequestBuilder) {
var builder = new ServerProjectPullRequestBuilder();
this.pullRequestsByName.put(pullRequestNumber, pullRequestBuilder.apply(builder));
return this;
}

public ServerProjectBuilder withDefaultBranch(UnaryOperator<ServerProjectBranchBuilder> branchBuilder) {
return withBranch(null, branchBuilder);
}
}

public static class ServerProjectBranchBuilder {
private final Collection<ServerHotspot> hotspots = new ArrayList<>();
private final Collection<ServerIssue> issues = new ArrayList<>();
protected final Collection<ServerHotspot> hotspots = new ArrayList<>();
protected final Collection<ServerIssue> issues = new ArrayList<>();
protected final Map<String, ServerSourceFileBuilder> sourceFileByComponentKey = new HashMap<>();

public ServerProjectBranchBuilder withHotspot(String hotspotKey) {
return withHotspot(hotspotKey, UnaryOperator.identity());
Expand All @@ -158,7 +161,13 @@ public ServerProjectBranchBuilder withIssue(String issueKey, String ruleKey, Str
return this;
}

private static class ServerHotspot {
public ServerProjectBranchBuilder withSourceFile(String componentKey, UnaryOperator<ServerSourceFileBuilder> sourceFileBuilder) {
var builder = new ServerSourceFileBuilder();
this.sourceFileByComponentKey.put(componentKey, sourceFileBuilder.apply(builder));
return this;
}

protected static class ServerHotspot {
private final String hotspotKey;
private final String ruleKey;
private final String message;
Expand Down Expand Up @@ -189,7 +198,7 @@ public String getFilePath() {
}
}

private static class ServerIssue {
protected static class ServerIssue {
private final String issueKey;
private final String ruleKey;
private final String message;
Expand Down Expand Up @@ -219,6 +228,9 @@ public String getFilePath() {
}
}

public static class ServerProjectPullRequestBuilder extends ServerProjectBranchBuilder {
}

public static class ServerSourceFileBuilder {
private String code;

Expand Down Expand Up @@ -300,17 +312,15 @@ public static class Server {
@Nullable
private final Version version;
private final Map<String, ServerBuilder.ServerProjectBuilder> projectsByProjectKey;
private final Map<String, ServerBuilder.ServerSourceFileBuilder> sourceFileByComponentKey;
private final boolean smartNotificationsSupported;

public Server(ServerKind serverKind, ServerStatus serverStatus, @Nullable String version,
Map<String, ServerBuilder.ServerProjectBuilder> projectsByProjectKey,
Map<String, ServerBuilder.ServerSourceFileBuilder> sourceFileByComponentKey, boolean smartNotificationsSupported) {
boolean smartNotificationsSupported) {
this.serverKind = serverKind;
this.serverStatus = serverStatus;
this.version = version != null ? Version.create(version) : null;
this.projectsByProjectKey = projectsByProjectKey;
this.sourceFileByComponentKey = sourceFileByComponentKey;
this.smartNotificationsSupported = smartNotificationsSupported;
}

Expand Down Expand Up @@ -391,49 +401,73 @@ private void registerApiHotspotSearchResponses() {
}

private void registerSearchIssueApiResponses() {
projectsByProjectKey.forEach((projectKey, project) -> project.branchesByName.forEach((branchName, branch) -> {
var issuesPerFilePath = branch.issues.stream()
.collect(groupingBy(ServerBuilder.ServerProjectBranchBuilder.ServerIssue::getFilePath,
mapping(issue -> {
var builder = Issues.Issue.newBuilder()
.setKey(issue.issueKey)
.setComponent(projectKey + ":" + issue.filePath)
.setRule(issue.ruleKey)
.setMessage(issue.message)
.setTextRange(Common.TextRange.newBuilder()
.setStartLine(issue.textRange.getStartLine())
.setStartOffset(issue.textRange.getStartLineOffset())
.setEndLine(issue.textRange.getEndLine())
.setEndOffset(issue.textRange.getEndLineOffset())
.build())
.setCreationDate(issue.creationDate)
.setStatus(issue.status)
.setAssignee(issue.author);
return builder.build();
}, toList())));

var allIssues = issuesPerFilePath.values().stream().flatMap(Collection::stream).collect(toList());

allIssues.forEach(issue -> {
var searchUrl = "/api/issues/search.protobuf?issues=".concat(urlEncode(issue.getKey()))
.concat("&componentKeys=").concat(projectKey)
.concat("&ps=1&p=1");
if (issue.getKey().contains("PR")) {
searchUrl = searchUrl.concat("&pullRequest=").concat("pullRequest");
} else {
searchUrl = searchUrl.concat("&branch=").concat(branchName);
}
mockServer.stubFor(get(searchUrl)
.willReturn(aResponse().withResponseBody(protobufBody(Issues.SearchWsResponse.newBuilder()
.addIssues(
Issues.Issue.newBuilder()
.setKey(issue.getKey()).setRule(issue.getRule()).setCreationDate(issue.getCreationDate()).setMessage(issue.getMessage())
.setTextRange(issue.getTextRange()).setComponent(issue.getComponent()).build())
.addComponents(Issues.Component.newBuilder().setPath(issue.getComponent()).setKey(issue.getComponent()).build())
.setRules(Issues.SearchWsResponse.newBuilder().getRulesBuilder().addRules(Common.Rule.newBuilder().setKey(issue.getRule()).build()))
.build()))));
projectsByProjectKey.forEach((projectKey, project) -> {
project.pullRequestsByName.forEach((pullRequestName, pullRequest) -> {
var issuesPerFilePath = getIssuesPerFilePath(projectKey, pullRequest);

var allIssues = issuesPerFilePath.values().stream().flatMap(Collection::stream).collect(toList());

allIssues.forEach(issue -> {
var searchUrl = "/api/issues/search.protobuf?issues=".concat(urlEncode(issue.getKey()))
.concat("&componentKeys=").concat(projectKey)
.concat("&ps=1&p=1")
.concat("&pullRequest=").concat(pullRequestName);
mockServer.stubFor(get(searchUrl)
.willReturn(aResponse().withResponseBody(protobufBody(Issues.SearchWsResponse.newBuilder()
.addIssues(
Issues.Issue.newBuilder()
.setKey(issue.getKey()).setRule(issue.getRule()).setCreationDate(issue.getCreationDate()).setMessage(issue.getMessage())
.setTextRange(issue.getTextRange()).setComponent(issue.getComponent()).build())
.addComponents(Issues.Component.newBuilder().setPath(issue.getComponent()).setKey(issue.getComponent()).build())
.setRules(Issues.SearchWsResponse.newBuilder().getRulesBuilder().addRules(Common.Rule.newBuilder().setKey(issue.getRule()).build()))
.build()))));
});
});
}));
project.branchesByName.forEach((branchName, branch) -> {
var issuesPerFilePath = getIssuesPerFilePath(projectKey, branch);

var allIssues = issuesPerFilePath.values().stream().flatMap(Collection::stream).collect(toList());

allIssues.forEach(issue -> {
var searchUrl = "/api/issues/search.protobuf?issues=".concat(urlEncode(issue.getKey()))
.concat("&componentKeys=").concat(projectKey)
.concat("&ps=1&p=1")
.concat("&branch=").concat(branchName);
mockServer.stubFor(get(searchUrl)
.willReturn(aResponse().withResponseBody(protobufBody(Issues.SearchWsResponse.newBuilder()
.addIssues(
Issues.Issue.newBuilder()
.setKey(issue.getKey()).setRule(issue.getRule()).setCreationDate(issue.getCreationDate()).setMessage(issue.getMessage())
.setTextRange(issue.getTextRange()).setComponent(issue.getComponent()).build())
.addComponents(Issues.Component.newBuilder().setPath(issue.getComponent()).setKey(issue.getComponent()).build())
.setRules(Issues.SearchWsResponse.newBuilder().getRulesBuilder().addRules(Common.Rule.newBuilder().setKey(issue.getRule()).build()))
.build()))));
});
});
});
}

@NotNull
private static Map<String, List<Issues.Issue>> getIssuesPerFilePath(String projectKey, ServerBuilder.ServerProjectBranchBuilder pullRequestOrBranch) {
return pullRequestOrBranch.issues.stream()
.collect(groupingBy(ServerBuilder.ServerProjectBranchBuilder.ServerIssue::getFilePath,
mapping(issue -> {
var builder = Issues.Issue.newBuilder()
.setKey(issue.issueKey)
.setComponent(projectKey + ":" + issue.filePath)
.setRule(issue.ruleKey)
.setMessage(issue.message)
.setTextRange(Common.TextRange.newBuilder()
.setStartLine(issue.textRange.getStartLine())
.setStartOffset(issue.textRange.getStartLineOffset())
.setEndLine(issue.textRange.getEndLine())
.setEndOffset(issue.textRange.getEndLineOffset())
.build())
.setCreationDate(issue.creationDate)
.setStatus(issue.status)
.setAssignee(issue.author);
return builder.build();
}, toList())));
}

private void registerApiHotspotsPullResponses() {
Expand Down Expand Up @@ -572,14 +606,20 @@ private void registerIssueAnticipateTransitionResponses() {
}

private void registerSourceApiResponses() {
sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey) + "&branch=branchName").willReturn(aResponse().withBody(sourceFile.code))));
projectsByProjectKey.forEach((projectKey, project) -> project.pullRequestsByName.forEach((pullRequestName, pullRequest) ->
pullRequest.sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey) + "&pullRequest=" + urlEncode(pullRequestName)).willReturn(aResponse().withBody(sourceFile.code))))));

sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey) + "&pullRequest=pullRequest").willReturn(aResponse().withBody(sourceFile.code))));
projectsByProjectKey.forEach((projectKey, project) -> project.branchesByName.forEach((branchName, branch) -> {
if (branchName != null) {
branch.sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey) + "&branch=" + urlEncode(branchName)).willReturn(aResponse().withBody(sourceFile.code))));
}
}));

sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey)).willReturn(aResponse().withBody(sourceFile.code))));
projectsByProjectKey.forEach((projectKey, project) -> project.branchesByName.forEach((branchName, branch) ->
branch.sourceFileByComponentKey
.forEach((componentKey, sourceFile) -> mockServer.stubFor(get("/api/sources/raw?key=" + urlEncode(componentKey)).willReturn(aResponse().withBody(sourceFile.code))))));
}

private void registerDevelopersApiResponses() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,19 @@ class ShowIssueMediumTests {
private static final String BRANCH_NAME = "branchName";
private ServerFixture.Server serverWithIssues = newSonarQubeServer("10.2")
.withProject(PROJECT_KEY,
project -> project.withBranch("branchName",
branch -> {
branch.withIssue(ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(1, 0, 3, 4));
branch.withIssue(PR_ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(1, 0, 3, 4));
return branch.withIssue(FILE_LEVEL_ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(0, 0, 0, 0));
}))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile\nfive\nlines"))
project -> {
project.withPullRequest("1234", pullRequest -> (ServerFixture.ServerBuilder.ServerProjectPullRequestBuilder) pullRequest.withIssue(PR_ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(1, 0, 3, 4))
.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile\nfive\nlines")));
return project.withBranch("branchName",
branch -> {
branch.withIssue(ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(1, 0, 3, 4));
branch.withIssue(FILE_LEVEL_ISSUE_KEY, RULE_KEY, "msg", "author", "file/path", "OPEN", "", "2023-05-13T17:55:39+0202",
new TextRange(0, 0, 0, 0));
return branch.withSourceFile("projectKey:file/path", sourceFile -> sourceFile.withCode("source\ncode\nfile\nfive\nlines"));
});
})
.start();
private SonarLintTestBackend backend;

Expand Down Expand Up @@ -138,7 +141,7 @@ void it_should_open_pr_issue_in_ide() throws IOException, InterruptedException {
.withEmbeddedServer()
.build(fakeClient);

var statusCode = executeOpenIssueRequest(PR_ISSUE_KEY, PROJECT_KEY, BRANCH_NAME, "pullRequest");
var statusCode = executeOpenIssueRequest(PR_ISSUE_KEY, PROJECT_KEY, BRANCH_NAME, "1234");

assertThat(statusCode).isEqualTo(200);
await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> assertThat(fakeClient.getIssueParamsToShowByIssueKey()).containsOnlyKeys(PR_ISSUE_KEY));
Expand Down

0 comments on commit 2efd3d6

Please sign in to comment.