aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Marion <steve.marion@sonarsource.com>2025-03-18 11:36:37 +0100
committersonartech <sonartech@sonarsource.com>2025-03-18 20:04:07 +0000
commit5f27a59fa2d104ef3712fa72c65eca049ad54c8c (patch)
treeb9c063e764a295664ef4a2060c1817cad8074fe6
parent85a491c9de96fa53977c6335dae2263a70e961d5 (diff)
downloadsonarqube-5f27a59fa2d104ef3712fa72c65eca049ad54c8c.tar.gz
sonarqube-5f27a59fa2d104ef3712fa72c65eca049ad54c8c.zip
SONAR-24616 add new dismissable notice for architecture visualization.
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java11
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java47
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java4
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java88
4 files changed, 94 insertions, 56 deletions
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java
index b2a716df087..f343d99f2b2 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java
@@ -27,18 +27,18 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Suite;
-import org.sonar.db.component.ComponentQualifiers;
-import org.sonar.server.component.ComponentType;
-import org.sonar.server.component.ComponentTypeTree;
-import org.sonar.server.component.ComponentTypes;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.core.platform.PlatformEditionProvider;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentQualifiers;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.common.avatar.AvatarResolverImpl;
+import org.sonar.server.component.ComponentType;
+import org.sonar.server.component.ComponentTypeTree;
+import org.sonar.server.component.ComponentTypes;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionServiceImpl;
import org.sonar.server.tester.UserSessionRule;
@@ -55,7 +55,6 @@ import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFIL
import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
import static org.sonar.db.permission.GlobalPermission.SCAN;
import static org.sonar.db.user.GroupTesting.newGroupDto;
-import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS;
import static org.sonar.test.JsonAssert.assertJson;
@RunWith(Suite.class)
@@ -262,7 +261,7 @@ public class CurrentActionIT {
@Parameterized.Parameters
public static Collection<String> parameterCombination() {
- return AVAILABLE_NOTICE_KEYS;
+ return DismissNoticeAction.DismissNotices.getAvailableKeys();
}
private final String notice;
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java
index a3c6748a49a..4d0c6acf8b5 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java
@@ -20,12 +20,12 @@
package org.sonar.server.user.ws;
import com.tngtech.java.junit.dataprovider.DataProvider;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Optional;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.property.PropertyDto;
@@ -37,20 +37,18 @@ import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS;
-@RunWith(DataProviderRunner.class)
-public class DismissNoticeActionIT {
+class DismissNoticeActionIT {
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ @RegisterExtension
+ private DbTester db = DbTester.create(System2.INSTANCE);
+ @RegisterExtension
+ private UserSessionRule userSessionRule = UserSessionRule.standalone();
private final WsActionTester tester = new WsActionTester(new DismissNoticeAction(userSessionRule, db.getDbClient()));
@Test
- public void authentication_is_required() {
+ void authentication_is_required() {
TestRequest testRequest = tester.newRequest()
.setParam("notice", "anyValue");
@@ -60,7 +58,7 @@ public class DismissNoticeActionIT {
}
@Test
- public void notice_parameter_is_mandatory() {
+ void notice_parameter_is_mandatory() {
userSessionRule.logIn();
TestRequest testRequest = tester.newRequest();
@@ -70,20 +68,19 @@ public class DismissNoticeActionIT {
}
@Test
- public void notice_not_supported() {
+ void notice_not_supported() {
userSessionRule.logIn();
TestRequest testRequest = tester.newRequest()
.setParam("notice", "not_supported_value");
assertThatThrownBy(testRequest::execute)
.isInstanceOf(IllegalArgumentException.class)
- .hasMessage(
- "Value of parameter 'notice' (not_supported_value) must be one of: [educationPrinciples, sonarlintAd, issueCleanCodeGuide, qualityGateCaYCConditionsSimplification, " +
- "overviewZeroNewIssuesSimplification, issueNewIssueStatusAndTransitionGuide, onboardingDismissCaycBranchSummaryGuide, showNewModesTour, showNewModesBanner]");
+ .hasMessageStartingWith(
+ "Value of parameter 'notice' (not_supported_value) must be one of: [");
}
@Test
- public void notice_already_exist_dont_fail() {
+ void notice_already_exist_dont_fail() {
userSessionRule.logIn();
PropertyDto property = new PropertyDto().setKey("user.dismissedNotices.educationPrinciples").setUserUuid(userSessionRule.getUuid());
db.properties().insertProperties(userSessionRule.getLogin(), null, null, null, property);
@@ -97,9 +94,9 @@ public class DismissNoticeActionIT {
assertThat(db.properties().findFirstUserProperty(userSessionRule.getUuid(), "user.dismissedNotices.educationPrinciples")).isPresent();
}
- @Test
- @UseDataProvider("noticeKeys")
- public void dismiss_notice(String noticeKey) {
+ @ParameterizedTest
+ @MethodSource("noticeKeys")
+ void dismiss_notice(String noticeKey) {
userSessionRule.logIn();
TestResponse testResponse = tester.newRequest()
@@ -113,9 +110,7 @@ public class DismissNoticeActionIT {
}
@DataProvider
- public static Object[][] noticeKeys() {
- return AVAILABLE_NOTICE_KEYS.stream()
- .map(noticeKey -> new Object[] {noticeKey})
- .toArray(Object[][]::new);
+ static Set<String> noticeKeys() {
+ return DismissNoticeAction.DismissNotices.getAvailableKeys();
}
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java
index 36a5c376f48..aabb5ff63a4 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java
@@ -49,7 +49,6 @@ import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.sonar.api.web.UserRole.USER;
-import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.APPLICATION;
import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PORTFOLIO;
@@ -124,7 +123,8 @@ public class CurrentAction implements UsersWsAction {
.setHomepage(buildHomepage(dbSession, user))
.setUsingSonarLintConnectedMode(user.getLastSonarlintConnectionDate() != null);
- AVAILABLE_NOTICE_KEYS.forEach(key -> builder.putDismissedNotices(key, isNoticeDismissed(user, key)));
+ DismissNoticeAction.DismissNotices.getAvailableKeys()
+ .forEach(key -> builder.putDismissedNotices(key, isNoticeDismissed(user, key)));
ofNullable(emptyToNull(user.getEmail())).ifPresent(builder::setEmail);
ofNullable(emptyToNull(user.getEmail())).ifPresent(u -> builder.setAvatar(avatarResolver.create(user)));
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java
index 7a779e06308..407ffcf2f36 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java
@@ -19,7 +19,9 @@
*/
package org.sonar.server.user.ws;
-import java.util.List;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
@@ -31,23 +33,52 @@ import org.sonar.db.property.PropertyQuery;
import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkState;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.EDUCATION_PRINCIPLES;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ISSUE_CLEAN_CODE_GUIDE;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_BANNER;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_OPTIN_BANNER;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_TOUR;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_NEW_MODES_BANNER;
+import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_NEW_MODES_TOUR;
public class DismissNoticeAction implements UsersWsAction {
- private static final String EDUCATION_PRINCIPLES = "educationPrinciples";
- private static final String SONARLINT_AD = "sonarlintAd";
- private static final String ISSUE_CLEAN_CODE_GUIDE = "issueCleanCodeGuide";
- private static final String QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION = "qualityGateCaYCConditionsSimplification";
- private static final String OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION = "overviewZeroNewIssuesSimplification";
- private static final String ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE = "issueNewIssueStatusAndTransitionGuide";
- private static final String ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE = "onboardingDismissCaycBranchSummaryGuide";
- private static final String SHOW_NEW_MODES_TOUR = "showNewModesTour";
- private static final String SHOW_NEW_MODES_BANNER = "showNewModesBanner";
-
- protected static final List<String> AVAILABLE_NOTICE_KEYS = List.of(EDUCATION_PRINCIPLES, SONARLINT_AD, ISSUE_CLEAN_CODE_GUIDE, QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION,
- OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION, ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE, ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE, SHOW_NEW_MODES_TOUR, SHOW_NEW_MODES_BANNER);
+ public enum DismissNotices {
+ EDUCATION_PRINCIPLES("educationPrinciples"),
+ SONARLINT_AD("sonarlintAd"),
+ ISSUE_CLEAN_CODE_GUIDE("issueCleanCodeGuide"),
+ QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION("qualityGateCaYCConditionsSimplification"),
+ OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION("overviewZeroNewIssuesSimplification"),
+ ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE("issueNewIssueStatusAndTransitionGuide"),
+ ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE("onboardingDismissCaycBranchSummaryGuide"),
+ SHOW_NEW_MODES_TOUR("showNewModesTour"),
+ SHOW_NEW_MODES_BANNER("showNewModesBanner"),
+ SHOW_DNA_OPTIN_BANNER("showDesignAndArchitectureOptInBanner"),
+ SHOW_DNA_BANNER("showDesignAndArchitectureBanner"),
+ SHOW_DNA_TOUR("showDesignAndArchitectureTour"),
+ ;
+
+ private final String key;
+
+ DismissNotices(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public static Set<String> getAvailableKeys() {
+ return Arrays.stream(values())
+ .map(DismissNotices::getKey)
+ .collect(Collectors.toSet());
+ }
+ }
public static final String USER_DISMISS_CONSTANT = "user.dismissedNotices.";
- public static final String SUPPORT_FOR_NEW_NOTICE_MESSAGE = "Support for new notice '%s' was added.";
+ private static final String SUPPORT_FOR_NEW_NOTICE_MESSAGE = "Support for new notice '%s' was added.";
private final UserSession userSession;
private final DbClient dbClient;
@@ -57,16 +88,29 @@ public class DismissNoticeAction implements UsersWsAction {
this.dbClient = dbClient;
}
+ private static String printNewNotice(DismissNotices notice) {
+ return SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(notice.getKey());
+ }
+
+ private static String printNewNotice(DismissNotices... notices) {
+ String noticesList = Arrays.stream(notices)
+ .map(DismissNotices::getKey)
+ .collect(Collectors.joining(", "));
+ return SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(noticesList);
+ }
+
+
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("dismiss_notice")
.setDescription("Dismiss a notice for the current user. Silently ignore if the notice is already dismissed.")
- .setChangelog(new Change("10.8", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(SHOW_NEW_MODES_TOUR)))
- .setChangelog(new Change("10.8", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(SHOW_NEW_MODES_BANNER)))
- .setChangelog(new Change("10.6", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE)))
- .setChangelog(new Change("10.4", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE)))
- .setChangelog(new Change("10.3", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION)))
- .setChangelog(new Change("10.2", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ISSUE_CLEAN_CODE_GUIDE)))
+ .setChangelog(new Change("25.4", printNewNotice(SHOW_DNA_OPTIN_BANNER, SHOW_DNA_BANNER, SHOW_DNA_TOUR)))
+ .setChangelog(new Change("10.8", printNewNotice(SHOW_NEW_MODES_TOUR)))
+ .setChangelog(new Change("10.8", printNewNotice(SHOW_NEW_MODES_BANNER)))
+ .setChangelog(new Change("10.6", printNewNotice(ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE)))
+ .setChangelog(new Change("10.4", printNewNotice(ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE)))
+ .setChangelog(new Change("10.3", printNewNotice(QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION)))
+ .setChangelog(new Change("10.2", printNewNotice(ISSUE_CLEAN_CODE_GUIDE)))
.setSince("9.6")
.setInternal(true)
.setHandler(this)
@@ -75,7 +119,7 @@ public class DismissNoticeAction implements UsersWsAction {
action.createParam("notice")
.setDescription("notice key to dismiss")
.setExampleValue(EDUCATION_PRINCIPLES)
- .setPossibleValues(AVAILABLE_NOTICE_KEYS);
+ .setPossibleValues(DismissNotices.getAvailableKeys());
}
@Override
@@ -89,7 +133,7 @@ public class DismissNoticeAction implements UsersWsAction {
dismissNotice(response, currentUserUuid, noticeKeyParam);
}
- public void dismissNotice(Response response, String currentUserUuid, String noticeKeyParam) {
+ private void dismissNotice(Response response, String currentUserUuid, String noticeKeyParam) {
try (DbSession dbSession = dbClient.openSession(false)) {
String paramKey = USER_DISMISS_CONSTANT + noticeKeyParam;
PropertyQuery query = new PropertyQuery.Builder()