Skip to content

Commit

Permalink
SONAR-7789 WS api/qualityprofiles/search return lastUsed field
Browse files Browse the repository at this point in the history
  • Loading branch information
teryk committed Jun 27, 2016
1 parent 6cffa97 commit c467e84
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 48 deletions.
Expand Up @@ -34,6 +34,7 @@ public class QProfile {
private String parent;
private boolean isDefault;
private String rulesUpdatedAt;
private Long lastUsed;

/**
* @deprecated in 4.4
Expand Down Expand Up @@ -111,6 +112,16 @@ public QProfile setRulesUpdatedAt(String rulesUpdatedAt) {
return this;
}

@CheckForNull
public Long getLastUsed() {
return lastUsed;
}

public QProfile setLastUsed(@Nullable Long lastUsed) {
this.lastUsed = lastUsed;
return this;
}

public static QProfile from(QualityProfileDto dto) {
return new QProfile()
.setId(dto.getId())
Expand All @@ -119,7 +130,8 @@ public static QProfile from(QualityProfileDto dto) {
.setLanguage(dto.getLanguage())
.setParent(dto.getParentKee())
.setDefault(dto.isDefault())
.setRulesUpdatedAt(dto.getRulesUpdatedAt());
.setRulesUpdatedAt(dto.getRulesUpdatedAt())
.setLastUsed(dto.getLastUsed());
}

@Override
Expand Down
Expand Up @@ -19,24 +19,23 @@
*/
package org.sonar.server.qualityprofile.ws;

import com.google.common.base.Function;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import java.util.stream.Collectors;
import org.sonar.api.resources.Languages;
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.server.ws.WebService.NewAction;
import org.sonar.server.component.ws.LanguageParamUtils;
import org.sonar.server.qualityprofile.QProfile;
import org.sonarqube.ws.QualityProfiles;
import org.sonarqube.ws.QualityProfiles.SearchWsResponse;
import org.sonarqube.ws.QualityProfiles.SearchWsResponse.QualityProfile;
import org.sonarqube.ws.client.qualityprofile.SearchWsRequest;

import static com.google.common.collect.Maps.uniqueIndex;
import static java.lang.String.format;
import static java.util.function.Function.identity;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.server.ws.WsUtils.writeProtobuf;

public class SearchAction implements QProfileWsAction {
Expand Down Expand Up @@ -108,13 +107,12 @@ private SearchWsResponse doHandle(SearchWsRequest request) {

private SearchWsResponse buildResponse(SearchData data) {
List<QProfile> profiles = data.getProfiles();
Map<String, QProfile> profilesByKey = uniqueIndex(profiles, QProfileToKey.INSTANCE);
Map<String, QProfile> profilesByKey = profiles.stream().collect(Collectors.toMap(QProfile::key, identity()));

QualityProfiles.SearchWsResponse.Builder response = QualityProfiles.SearchWsResponse.newBuilder();
QualityProfile.Builder profileBuilder = QualityProfile.newBuilder();
SearchWsResponse.Builder response = SearchWsResponse.newBuilder();

for (QProfile profile : profiles) {
profileBuilder.clear();
QualityProfile.Builder profileBuilder = response.addProfilesBuilder();

String profileKey = profile.key();
profileBuilder.setKey(profileKey);
Expand All @@ -124,6 +122,9 @@ private SearchWsResponse buildResponse(SearchData data) {
if (profile.getRulesUpdatedAt() != null) {
profileBuilder.setRulesUpdatedAt(profile.getRulesUpdatedAt());
}
if (profile.getLastUsed() != null) {
profileBuilder.setLastUsed(formatDateTime(profile.getLastUsed()));
}
profileBuilder.setActiveRuleCount(data.getActiveRuleCount(profileKey));
profileBuilder.setActiveDeprecatedRuleCount(data.getActiveDeprecatedRuleCount(profileKey));
if (!profile.isDefault()) {
Expand All @@ -134,7 +135,6 @@ private SearchWsResponse buildResponse(SearchData data) {
writeParentFields(profileBuilder, profile, profilesByKey);
profileBuilder.setIsInherited(profile.isInherited());
profileBuilder.setIsDefault(profile.isDefault());
response.addProfiles(profileBuilder);
}

return response.build();
Expand Down Expand Up @@ -165,13 +165,4 @@ private static void writeParentFields(QualityProfile.Builder profileBuilder, QPr
profileBuilder.setParentName(parent.name());
}
}

private enum QProfileToKey implements Function<QProfile, String> {
INSTANCE;

@Override
public String apply(@Nonnull QProfile input) {
return input.key();
}
}
}
Expand Up @@ -8,7 +8,9 @@
"isInherited": false,
"activeRuleCount": 37,
"activeDeprecatedRuleCount": 0,
"isDefault": true
"isDefault": true,
"ruleUpdatedAt": "2016-12-22T19:10:03+0100",
"lastUsed": "2016-12-01T19:10:03+0100"
},
{
"key": "my-bu-profile-java-34567",
Expand All @@ -21,7 +23,9 @@
"activeRuleCount": 72,
"activeDeprecatedRuleCount": 5,
"isDefault": false,
"projectCount": 13
"projectCount": 13,
"ruleUpdatedAt": "2016-12-20T19:10:03+0100",
"lastUsed": "2016-12-21T16:10:03+0100"
},
{
"key": "my-company-profile-java-23456",
Expand All @@ -31,7 +35,8 @@
"isInherited": false,
"isDefault": true,
"activeRuleCount": 42,
"activeDeprecatedRuleCount": 3
"activeDeprecatedRuleCount": 3,
"ruleUpdatedAt": "2016-12-22T19:10:03+0100"
},
{
"key": "sonar-way-python-01234",
Expand All @@ -41,7 +46,8 @@
"isInherited": false,
"activeRuleCount": 125,
"activeDeprecatedRuleCount": 0,
"isDefault": true
"isDefault": true,
"ruleUpdatedAt": "2014-12-22T19:10:03+0100"
}
]
}
Expand Up @@ -38,7 +38,7 @@ public void test_getters_and_setters() {
@Test
public void to_string() {
assertThat(new QProfile().setId(1).setName("Default").setLanguage("java").setParent("Parent").toString())
.contains("[id=1,key=<null>,name=Default,language=java,parent=Parent,isDefault=false,rulesUpdatedAt=<null>]");
.contains("[id=1,key=<null>,name=Default,language=java,parent=Parent,isDefault=false,rulesUpdatedAt=<null>,lastUsed=<null>]");
}

@Test
Expand Down
Expand Up @@ -20,18 +20,21 @@
package org.sonar.server.qualityprofile.ws;

import com.google.common.collect.ImmutableMap;
import java.io.IOException;
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.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileDbTester;
Expand All @@ -41,42 +44,44 @@
import org.sonar.server.qualityprofile.QProfileFactory;
import org.sonar.server.qualityprofile.QProfileLookup;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.QualityProfiles.SearchWsResponse;

import static com.google.common.base.Throwables.propagate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_DEFAULTS;
import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROFILE_NAME;
import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROJECT_KEY;
import static org.sonar.test.JsonAssert.assertJson;

public class SearchActionTest {

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
QualityProfileDbTester qualityProfileDb = new QualityProfileDbTester(db);
ComponentDbTester componentDb = new ComponentDbTester(db);
DbClient dbClient = db.getDbClient();
DbSession dbSession = db.getSession();
QualityProfileDao qualityProfileDao = dbClient.qualityProfileDao();

private ActiveRuleIndex activeRuleIndex = mock(ActiveRuleIndex.class);

final DbClient dbClient = db.getDbClient();
final DbSession dbSession = db.getSession();

private QualityProfileDao qualityProfileDao = dbClient.qualityProfileDao();

private Language xoo1;
private Language xoo2;
private WsActionTester ws;

private QualityProfileDbTester qualityProfileDb;
private WsActionTester ws;

@Before
public void setUp() {
qualityProfileDb = new QualityProfileDbTester(db);

xoo1 = LanguageTesting.newLanguage("xoo1");
xoo2 = LanguageTesting.newLanguage("xoo2");

Expand Down Expand Up @@ -110,18 +115,31 @@ public void search_nominal() throws Exception {
newProjectDto("project-uuid2"));
qualityProfileDao.insertProjectProfileAssociation("project-uuid1", "sonar-way-xoo2-23456", dbSession);
qualityProfileDao.insertProjectProfileAssociation("project-uuid2", "sonar-way-xoo2-23456", dbSession);
commit();
db.commit();

String result = ws.newRequest().execute().getInput();

assertJson(result).isSimilarTo(getClass().getResource("SearchActionTest/search.json"));
}

@Test
public void search_map_dates() {
long time = DateUtils.parseDateTime("2016-12-22T19:10:03+0100").getTime();
qualityProfileDb.insertQualityProfiles(newQualityProfileDto()
.setLanguage(xoo1.getKey())
.setRulesUpdatedAt("2016-12-21T19:10:03+0100")
.setLastUsed(time));

SearchWsResponse result = call(ws.newRequest());

assertThat(result.getProfilesCount()).isEqualTo(1);
assertThat(result.getProfiles(0).getRulesUpdatedAt()).isEqualTo("2016-12-21T19:10:03+0100");
assertThat(parseDateTime(result.getProfiles(0).getLastUsed()).getTime()).isEqualTo(time);
}

@Test
public void search_for_language() throws Exception {
qualityProfileDao.insert(dbSession,
QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way"));
commit();
qualityProfileDb.insertQualityProfiles(QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way"));

String result = ws.newRequest().setParam("language", xoo1.getKey()).execute().getInput();

Expand All @@ -145,7 +163,6 @@ public void search_for_project_qp() {
ComponentDto project = newProjectDto("project-uuid");
qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
qualityProfileDb.insertProjectWithQualityProfileAssociations(project, qualityProfileOnXoo1, qualityProfileOnXoo2);
commit();

String result = ws.newRequest()
.setParam(PARAM_PROJECT_KEY, project.key())
Expand All @@ -171,7 +188,6 @@ public void search_for_default_qp_with_profile_name() {
.setName("Another way")
.setDefault(true);
qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
commit();

String result = ws.newRequest()
.setParam(PARAM_DEFAULTS, Boolean.TRUE.toString())
Expand All @@ -197,10 +213,8 @@ public void search_by_profile_name() {
.setLanguage(xoo1.getKey())
.setRulesUpdatedAtAsDate(new Date())
.setName("Another way");
ComponentDto project = newProjectDto("project-uuid");
qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
dbClient.componentDao().insert(dbSession, project);
commit();
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid"));

String result = ws.newRequest()
.setParam(PARAM_PROJECT_KEY, project.key())
Expand All @@ -210,10 +224,15 @@ public void search_by_profile_name() {
assertThat(result)
.contains("sonar-way-xoo1-12345", "sonar-way-xoo2-12345")
.doesNotContain("sonar-way-xoo1-45678");

}

private void commit() {
dbSession.commit();
private SearchWsResponse call(TestRequest request) {
try {
return SearchWsResponse.parseFrom(request
.setMediaType(MediaTypes.PROTOBUF)
.execute().getInputStream());
} catch (IOException e) {
throw propagate(e);
}
}
}
1 change: 1 addition & 0 deletions sonar-ws/src/main/protobuf/ws-qualityprofiles.proto
Expand Up @@ -41,5 +41,6 @@ message SearchWsResponse {
optional int64 activeDeprecatedRuleCount = 12;
optional int64 projectCount = 10;
optional string rulesUpdatedAt = 11;
optional string lastUsed = 13;
}
}

0 comments on commit c467e84

Please sign in to comment.