diff options
author | Michal Duda <michal.duda@sonarsource.com> | 2020-09-18 17:08:48 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-09-29 20:07:42 +0000 |
commit | 0ecd8610552ccd59049308c1be46b03470c48538 (patch) | |
tree | d1da42fc9e90627a037696702cb30dd0e7442e6d /server/sonar-db-dao | |
parent | bc413ee3db73258a22059816bd4766bcea66a9ca (diff) | |
download | sonarqube-0ecd8610552ccd59049308c1be46b03470c48538.tar.gz sonarqube-0ecd8610552ccd59049308c1be46b03470c48538.zip |
SONAR-13862 Add a WS for dismissing analysis warning by the current user
Diffstat (limited to 'server/sonar-db-dao')
23 files changed, 629 insertions, 29 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index 9a89ca6b267..205d02d18e2 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -86,6 +86,7 @@ import org.sonar.db.user.RoleDao; import org.sonar.db.user.SamlMessageIdDao; import org.sonar.db.user.SessionTokensDao; import org.sonar.db.user.UserDao; +import org.sonar.db.user.UserDismissedMessagesDao; import org.sonar.db.user.UserGroupDao; import org.sonar.db.user.UserPropertiesDao; import org.sonar.db.user.UserTokenDao; @@ -159,6 +160,7 @@ public class DaoModule extends Module { SchemaMigrationDao.class, SessionTokensDao.class, UserDao.class, + UserDismissedMessagesDao.class, UserGroupDao.class, UserPermissionDao.class, UserPropertiesDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index 022e0c4dc39..78d717373ed 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -84,6 +84,7 @@ import org.sonar.db.user.RoleDao; import org.sonar.db.user.SamlMessageIdDao; import org.sonar.db.user.SessionTokensDao; import org.sonar.db.user.UserDao; +import org.sonar.db.user.UserDismissedMessagesDao; import org.sonar.db.user.UserGroupDao; import org.sonar.db.user.UserPropertiesDao; import org.sonar.db.user.UserTokenDao; @@ -164,6 +165,7 @@ public class DbClient { private final ProjectDao projectDao; private final SessionTokensDao sessionTokensDao; private final SamlMessageIdDao samlMessageIdDao; + private final UserDismissedMessagesDao userDismissedMessagesDao; public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { this.database = database; @@ -242,6 +244,7 @@ public class DbClient { projectDao = getDao(map, ProjectDao.class); sessionTokensDao = getDao(map, SessionTokensDao.class); samlMessageIdDao = getDao(map, SamlMessageIdDao.class); + userDismissedMessagesDao = getDao(map, UserDismissedMessagesDao.class); } public DbSession openSession(boolean batch) { @@ -534,4 +537,8 @@ public class DbClient { return samlMessageIdDao; } + public UserDismissedMessagesDao userDismissedMessagesDao() { + return userDismissedMessagesDao; + } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index bc390ff1fb1..8c1f4a3b487 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -140,6 +140,7 @@ import org.sonar.db.user.GroupMembershipMapper; import org.sonar.db.user.RoleMapper; import org.sonar.db.user.SamlMessageIdMapper; import org.sonar.db.user.SessionTokenMapper; +import org.sonar.db.user.UserDismissedMessagesMapper; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserGroupDto; import org.sonar.db.user.UserGroupMapper; @@ -287,6 +288,7 @@ public class MyBatis implements Startable { SchemaMigrationMapper.class, SessionTokenMapper.class, SnapshotMapper.class, + UserDismissedMessagesMapper.class, UserGroupMapper.class, UserMapper.class, UserPermissionMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDao.java index 6604c0bb682..39c4b8e2fad 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDao.java @@ -20,6 +20,7 @@ package org.sonar.db.ce; import java.util.List; +import java.util.Optional; import org.sonar.db.Dao; import org.sonar.db.DbSession; @@ -28,6 +29,10 @@ public class CeTaskMessageDao implements Dao { getMapper(dbSession).insert(dto); } + public Optional<CeTaskMessageDto> selectByUuid(DbSession dbSession, String uuid) { + return getMapper(dbSession).selectByUuid(uuid); + } + /** * @return the messages for the specific task, if any, in ascending order of column {@code CREATED_AT}. */ @@ -35,6 +40,10 @@ public class CeTaskMessageDao implements Dao { return getMapper(dbSession).selectByTask(taskUuid); } + public void deleteByType(DbSession session, CeTaskMessageType type) { + getMapper(session).deleteByType(type.name()); + } + private static CeTaskMessageMapper getMapper(DbSession dbSession) { return dbSession.getMapper(CeTaskMessageMapper.class); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDto.java index f31bcbc2530..3eb99a6dce4 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageDto.java @@ -35,13 +35,13 @@ public class CeTaskMessageDto { */ private String message; /** - * Timestamp the message was created. Not null + * Type of the message */ - private long createdAt; + private CeTaskMessageType type; /** - * Information if this message can be dismissed by the user + * Timestamp the message was created. Not null */ - private boolean dismissible; + private long createdAt; public String getUuid() { return uuid; @@ -72,21 +72,21 @@ public class CeTaskMessageDto { return this; } - public long getCreatedAt() { - return createdAt; + public CeTaskMessageType getType() { + return type; } - public CeTaskMessageDto setCreatedAt(long createdAt) { - this.createdAt = createdAt; + public CeTaskMessageDto setType(CeTaskMessageType type) { + this.type = type; return this; } - public boolean isDismissible() { - return dismissible; + public long getCreatedAt() { + return createdAt; } - public CeTaskMessageDto setDismissible(boolean dismissible) { - this.dismissible = dismissible; + public CeTaskMessageDto setCreatedAt(long createdAt) { + this.createdAt = createdAt; return this; } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageMapper.java index 5ec953f3b1d..619cd743310 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageMapper.java @@ -20,11 +20,15 @@ package org.sonar.db.ce; import java.util.List; +import java.util.Optional; import org.apache.ibatis.annotations.Param; public interface CeTaskMessageMapper { void insert(@Param("dto") CeTaskMessageDto dto); + Optional<CeTaskMessageDto> selectByUuid(@Param("uuid") String uuid); + List<CeTaskMessageDto> selectByTask(@Param("taskUuid") String taskUuid); + void deleteByType(@Param("ceMessageType") String ceMessageType); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java new file mode 100644 index 00000000000..52bd4b38038 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeTaskMessageType.java @@ -0,0 +1,35 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.ce; + +public enum CeTaskMessageType { + GENERIC(false), + SUGGEST_DEVELOPER_EDITION_UPGRADE(true); + + private final boolean dismissible; + + CeTaskMessageType(boolean dismissible) { + this.dismissible = dismissible; + } + + public boolean isDismissible() { + return dismissible; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 33abd185e2e..b11c7febd7f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -434,4 +434,11 @@ class PurgeCommands { profiler.stop(); } + void deleteUserDismissedMessages(String projectUuid) { + profiler.start("deleteUserDismissedMessages (user_dismissed_messages)"); + purgeMapper.deleteUserDismissedMessagesByProjectUuid(projectUuid); + session.commit(); + profiler.stop(); + } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index e9a0af96f6d..bb39d91a389 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -224,6 +224,7 @@ public class PurgeDao implements Dao { commands.deleteComponents(rootUuid); commands.deleteComponentsByMainBranchProjectUuid(rootUuid); commands.deleteProject(rootUuid); + commands.deleteUserDismissedMessages(rootUuid); } /** diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index 56f09dda6b6..840533516f9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -150,4 +150,6 @@ public interface PurgeMapper { void deleteNewCodePeriodsByRootUuid(String rootUuid); void deleteProjectAlmSettingsByProjectUuid(@Param("projectUuid") String projectUuid); + + void deleteUserDismissedMessagesByProjectUuid(@Param("projectUuid") String projectUuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessageDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessageDto.java new file mode 100644 index 00000000000..96d0d3e8219 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessageDto.java @@ -0,0 +1,92 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.user; + +import org.sonar.db.ce.CeTaskMessageType; + +public class UserDismissedMessageDto { + + private String uuid; + /** + * Uuid of the user that dismissed the message type + */ + private String userUuid; + /** + * Uuid of the project for which the message type was dismissed + */ + private String projectUuid; + /** + * Message type of the dismissed message + */ + private CeTaskMessageType ceMessageType; + /** + * Technical creation date + */ + private long createdAt; + + public UserDismissedMessageDto() { + // nothing to do here + } + + public String getUuid() { + return uuid; + } + + public UserDismissedMessageDto setUuid(String uuid) { + this.uuid = uuid; + return this; + } + + public String getUserUuid() { + return userUuid; + } + + public UserDismissedMessageDto setUserUuid(String userUuid) { + this.userUuid = userUuid; + return this; + } + + public String getProjectUuid() { + return projectUuid; + } + + public UserDismissedMessageDto setProjectUuid(String projectUuid) { + this.projectUuid = projectUuid; + return this; + } + + public CeTaskMessageType getCeMessageType() { + return ceMessageType; + } + + public UserDismissedMessageDto setCeMessageType(CeTaskMessageType ceMessageType) { + this.ceMessageType = ceMessageType; + return this; + } + + public long getCreatedAt() { + return createdAt; + } + + public UserDismissedMessageDto setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesDao.java new file mode 100644 index 00000000000..16843bbd682 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesDao.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.user; + +import java.util.List; +import java.util.Optional; +import org.sonar.api.utils.System2; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; +import org.sonar.db.ce.CeTaskMessageType; +import org.sonar.db.project.ProjectDto; + +public class UserDismissedMessagesDao implements Dao { + private final System2 system2; + + public UserDismissedMessagesDao(System2 system2) { + this.system2 = system2; + } + + public UserDismissedMessageDto insert(DbSession session, UserDismissedMessageDto dto) { + long now = system2.now(); + mapper(session).insert(dto.setCreatedAt(now)); + return dto; + } + + public Optional<UserDismissedMessageDto> selectByUserAndProjectAndMessageType(DbSession session, UserDto user, ProjectDto project, + CeTaskMessageType ceMessageType) { + return mapper(session).selectByUserUuidAndProjectUuidAndMessageType(user.getUuid(), project.getUuid(), ceMessageType.name()); + } + + public List<UserDismissedMessageDto> selectByUser(DbSession session, UserDto user) { + return mapper(session).selectByUserUuid(user.getUuid()); + } + + public void deleteByUser(DbSession session, UserDto user) { + mapper(session).deleteByUserUuid(user.getUuid()); + } + + public void deleteByType(DbSession session, CeTaskMessageType type) { + mapper(session).deleteByType(type.name()); + } + + private static UserDismissedMessagesMapper mapper(DbSession session) { + return session.getMapper(UserDismissedMessagesMapper.class); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesMapper.java new file mode 100644 index 00000000000..f1fbddbfdf8 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDismissedMessagesMapper.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.user; + +import java.util.List; +import java.util.Optional; +import org.apache.ibatis.annotations.Param; + +public interface UserDismissedMessagesMapper { + void insert(@Param("dto") UserDismissedMessageDto dto); + + Optional<UserDismissedMessageDto> selectByUserUuidAndProjectUuidAndMessageType(@Param("userUuid") String userUuid, @Param("projectUuid") String projectUuid, + @Param("ceMessageType") String ceMessageType); + + List<UserDismissedMessageDto> selectByUserUuid(@Param("userUuid") String userUuid); + + void deleteByUserUuid(@Param("userUuid") String userUuid); + + void deleteByType(@Param("ceMessageType") String ceMessageType); +} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeTaskMessageMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeTaskMessageMapper.xml index 1e5ca2cb2f3..360ac4425c1 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeTaskMessageMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeTaskMessageMapper.xml @@ -7,10 +7,19 @@ ctm.uuid, ctm.task_uuid as taskUuid, ctm.message as message, - ctm.created_at as createdAt, - ctm.is_dismissible as dismissible + ctm.message_type as type, + ctm.created_at as createdAt </sql> + <select id="selectByUuid" resultType="org.sonar.db.ce.CeTaskMessageDto"> + select + <include refid="columns"/> + from + ce_task_message ctm + where + ctm.uuid=#{uuid,jdbcType=VARCHAR} + </select> + <select id="selectByTask" resultType="org.sonar.db.ce.CeTaskMessageDto"> select <include refid="columns"/> @@ -28,16 +37,20 @@ uuid, task_uuid, message, - created_at, - is_dismissible + message_type, + created_at ) values ( #{dto.uuid,jdbcType=VARCHAR}, #{dto.taskUuid,jdbcType=VARCHAR}, #{dto.message,jdbcType=VARCHAR}, - #{dto.createdAt,jdbcType=BIGINT}, - #{dto.dismissible,jdbcType=BOOLEAN} + #{dto.type,jdbcType=VARCHAR}, + #{dto.createdAt,jdbcType=BIGINT} ) </insert> + <delete id="deleteByType" parameterType="String"> + delete from ce_task_message where message_type = #{ceMessageType, jdbcType=VARCHAR} + </delete> + </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index 9c854851d61..e4b71806473 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -504,5 +504,9 @@ <delete id="deleteLiveMeasuresByComponentUuids"> delete from live_measures where component_uuid in <foreach item="componentUuid" index="index" collection="componentUuids" open="(" separator="," close=")">#{componentUuid, jdbcType=VARCHAR}</foreach> </delete> + + <delete id="deleteUserDismissedMessagesByProjectUuid"> + delete from user_dismissed_messages where project_uuid = #{projectUuid,jdbcType=VARCHAR} + </delete> </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserDismissedMessagesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserDismissedMessagesMapper.xml new file mode 100644 index 00000000000..12fad9f4643 --- /dev/null +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserDismissedMessagesMapper.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> + +<mapper namespace="org.sonar.db.user.UserDismissedMessagesMapper"> + + <sql id="columns"> + udm.uuid, + udm.user_uuid as userUuid, + udm.project_uuid as projectUuid, + udm.message_type as ceMessageType, + udm.created_at as createdAt + </sql> + + <insert id="insert" parameterType="org.sonar.db.user.UserDismissedMessageDto" useGeneratedKeys="false"> + insert into user_dismissed_messages + ( + uuid, + user_uuid, + project_uuid, + message_type, + created_at + ) + values ( + #{dto.uuid,jdbcType=VARCHAR}, + #{dto.userUuid,jdbcType=VARCHAR}, + #{dto.projectUuid,jdbcType=VARCHAR}, + #{dto.ceMessageType,jdbcType=VARCHAR}, + #{dto.createdAt,jdbcType=BIGINT} + ) + </insert> + + <select id="selectByUserUuidAndProjectUuidAndMessageType" resultType="org.sonar.db.user.UserDismissedMessageDto"> + select + <include refid="columns"/> + from + user_dismissed_messages udm + where + udm.user_uuid=#{userUuid,jdbcType=VARCHAR} and + udm.project_uuid=#{projectUuid,jdbcType=VARCHAR} and + udm.message_type=#{ceMessageType,jdbcType=VARCHAR} + </select> + + <select id="selectByUserUuid" resultType="org.sonar.db.user.UserDismissedMessageDto" parameterType="String"> + select + <include refid="columns"/> + from + user_dismissed_messages udm + where + udm.user_uuid=#{userUuid,jdbcType=VARCHAR} + </select> + + <delete id="deleteByUserUuid" parameterType="String"> + delete from user_dismissed_messages where user_uuid = #{userUuid, jdbcType=VARCHAR} + </delete> + + <delete id="deleteByType" parameterType="String"> + delete from user_dismissed_messages where message_type = #{ceMessageType, jdbcType=VARCHAR} + </delete> + +</mapper> diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index e31dc777fd9..e4f53071172 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -169,10 +169,11 @@ CREATE TABLE "CE_TASK_MESSAGE"( "TASK_UUID" VARCHAR(40) NOT NULL, "MESSAGE" VARCHAR(4000) NOT NULL, "CREATED_AT" BIGINT NOT NULL, - "IS_DISMISSIBLE" BOOLEAN NOT NULL + "MESSAGE_TYPE" VARCHAR(255) NOT NULL ); ALTER TABLE "CE_TASK_MESSAGE" ADD CONSTRAINT "PK_CE_TASK_MESSAGE" PRIMARY KEY("UUID"); CREATE INDEX "CE_TASK_MESSAGE_TASK" ON "CE_TASK_MESSAGE"("TASK_UUID"); +CREATE INDEX "CTM_MESSAGE_TYPE" ON "CE_TASK_MESSAGE"("MESSAGE_TYPE"); CREATE TABLE "COMPONENTS"( "UUID" VARCHAR(50) NOT NULL, @@ -896,6 +897,18 @@ ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "PK_SNAPSHOTS" PRIMARY KEY("UUID"); CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS"("UUID"); CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS"("COMPONENT_UUID"); +CREATE TABLE "USER_DISMISSED_MESSAGES"( + "UUID" VARCHAR(40) NOT NULL, + "USER_UUID" VARCHAR(255) NOT NULL, + "PROJECT_UUID" VARCHAR(40) NOT NULL, + "MESSAGE_TYPE" VARCHAR(255) NOT NULL, + "CREATED_AT" BIGINT NOT NULL +); +ALTER TABLE "USER_DISMISSED_MESSAGES" ADD CONSTRAINT "PK_USER_DISMISSED_MESSAGES" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "UNIQ_USER_DISMISSED_MESSAGES" ON "USER_DISMISSED_MESSAGES"("USER_UUID", "PROJECT_UUID", "MESSAGE_TYPE"); +CREATE INDEX "UDM_PROJECT_UUID" ON "USER_DISMISSED_MESSAGES"("PROJECT_UUID"); +CREATE INDEX "UDM_MESSAGE_TYPE" ON "USER_DISMISSED_MESSAGES"("MESSAGE_TYPE"); + CREATE TABLE "USER_PROPERTIES"( "UUID" VARCHAR(40) NOT NULL, "USER_UUID" VARCHAR(255) NOT NULL, diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java index d53912a6779..c6d08a72d11 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java @@ -139,6 +139,7 @@ public class CeActivityDaoTest { .setUuid(UuidFactoryFast.getInstance().create()) .setTaskUuid(task.getUuid()) .setMessage("message_" + task.getUuid() + "_" + i) + .setType(CeTaskMessageType.GENERIC) .setCreatedAt(task.getUuid().hashCode() + i))); db.commit(); } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeTaskMessageDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeTaskMessageDaoTest.java index 149a81734cf..4ad7e016454 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeTaskMessageDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeTaskMessageDaoTest.java @@ -20,6 +20,7 @@ package org.sonar.db.ce; import java.util.List; +import java.util.Optional; import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; @@ -37,7 +38,7 @@ public class CeTaskMessageDaoTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - private CeTaskMessageDao underTest = new CeTaskMessageDao(); + private final CeTaskMessageDao underTest = new CeTaskMessageDao(); @Test public void insert() { @@ -45,13 +46,17 @@ public class CeTaskMessageDaoTest { .setUuid("uuid_1") .setTaskUuid("task_uuid_1") .setMessage("message_1") + .setType(CeTaskMessageType.GENERIC) .setCreatedAt(1_222_333L)); dbTester.getSession().commit(); - assertThat(dbTester.select("select uuid as \"UUID\", task_uuid as \"TASK_UUID\", message as \"MESSAGE\", created_at as \"CREATED_AT\" from ce_task_message")) - .hasSize(1) - .extracting(t -> t.get("UUID"), t -> t.get("TASK_UUID"), t -> t.get("MESSAGE"), t -> t.get("CREATED_AT")) - .containsOnly(Tuple.tuple("uuid_1", "task_uuid_1", "message_1", 1_222_333L)); + assertThat( + dbTester.select("select uuid as \"UUID\", task_uuid as \"TASK_UUID\", message as \"MESSAGE\", message_type as \"TYPE\", " + + "created_at as \"CREATED_AT\" from ce_task_message")) + .hasSize(1) + .extracting(t -> t.get("UUID"), t -> t.get("TASK_UUID"), t -> t.get("MESSAGE"), t -> CeTaskMessageType.valueOf((String) t.get("TYPE")), + t -> t.get("CREATED_AT")) + .containsOnly(Tuple.tuple("uuid_1", "task_uuid_1", "message_1", CeTaskMessageType.GENERIC, 1_222_333L)); } @Test @@ -88,11 +93,50 @@ public class CeTaskMessageDaoTest { .isEmpty(); } + @Test + public void selectByUuid_returns_object_if_found() { + CeTaskMessageDto dto = insertMessage("526787a4-e8af-46c0-b340-8c48188646a5", 1, 1_222_333L); + + Optional<CeTaskMessageDto> result = underTest.selectByUuid(dbTester.getSession(), dto.getUuid()); + + assertThat(result).isPresent(); + assertThat(result.get().getUuid()).isEqualTo(dto.getUuid()); + } + + @Test + public void selectByUuid_returns_empty_if_no_record_found() { + Optional<CeTaskMessageDto> result = underTest.selectByUuid(dbTester.getSession(), "e2a71626-1f07-402a-aac7-dd4e0bbb4394"); + + assertThat(result).isNotPresent(); + } + + @Test + public void deleteByType_deletes_messages_of_given_type() { + String task1 = "task1"; + CeTaskMessageDto[] messages = { + insertMessage(task1, 0, 1_222_333L, CeTaskMessageType.GENERIC), + insertMessage(task1, 1, 2_222_333L, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE), + insertMessage(task1, 2, 1_111_333L, CeTaskMessageType.GENERIC), + insertMessage(task1, 3, 1_222_111L, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE) + }; + + underTest.deleteByType(dbTester.getSession(), CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + + assertThat(underTest.selectByTask(dbTester.getSession(), task1)) + .extracting(CeTaskMessageDto::getUuid) + .containsExactlyInAnyOrder(messages[0].getUuid(), messages[2].getUuid()); + } + private CeTaskMessageDto insertMessage(String taskUuid, int i, long createdAt) { + return insertMessage(taskUuid, i, createdAt, CeTaskMessageType.GENERIC); + } + + private CeTaskMessageDto insertMessage(String taskUuid, int i, long createdAt, CeTaskMessageType messageType) { CeTaskMessageDto res = new CeTaskMessageDto() .setUuid("message_" + i) .setTaskUuid(taskUuid) .setMessage("test_" + i) + .setType(messageType) .setCreatedAt(createdAt); DbSession dbSession = dbTester.getSession(); underTest.insert(dbSession, res); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java index 596f943d0a2..020cb201687 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java @@ -36,6 +36,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbTester; +import org.sonar.db.ce.CeTaskMessageType; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; @@ -625,6 +626,22 @@ public class PurgeCommandsTest { assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(3); } + @Test + public void deleteUserDismissedMessages_deletes_dismissed_warnings_on_project_for_all_users() { + UserDto user1 = dbTester.users().insertUser(); + UserDto user2 = dbTester.users().insertUser(); + ProjectDto project = dbTester.components().insertPrivateProjectDto(); + ProjectDto anotherProject = dbTester.components().insertPrivateProjectDto(); + dbTester.users().insertUserDismissedMessage(user1, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + dbTester.users().insertUserDismissedMessage(user2, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + dbTester.users().insertUserDismissedMessage(user1, anotherProject, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2); + + purgeCommands.deleteUserDismissedMessages(project.getUuid()); + + assertThat(dbTester.countRowsOfTable("user_dismissed_messages")).isEqualTo(1); + } + private void addPermissions(OrganizationDto organization, ComponentDto root) { if (!root.isPrivate()) { dbTester.users().insertProjectPermissionOnAnyone("foo1", root); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java index e6a9ef93314..cf3dcdb411d 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java @@ -47,7 +47,6 @@ import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; -import org.sonar.db.alm.ALM; import org.sonar.db.alm.setting.AlmSettingDto; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; @@ -55,6 +54,7 @@ import org.sonar.db.ce.CeQueueDto.Status; import org.sonar.db.ce.CeTaskCharacteristicDto; import org.sonar.db.ce.CeTaskInputDao; import org.sonar.db.ce.CeTaskMessageDto; +import org.sonar.db.ce.CeTaskMessageType; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; @@ -78,6 +78,8 @@ import org.sonar.db.project.ProjectDto; import org.sonar.db.property.PropertyDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.source.FileSourceDto; +import org.sonar.db.user.UserDismissedMessageDto; +import org.sonar.db.user.UserDto; import org.sonar.db.webhook.WebhookDeliveryLiteDto; import org.sonar.db.webhook.WebhookDto; @@ -110,16 +112,16 @@ public class PurgeDaoTest { private static final String PROJECT_UUID = "P1"; - private System2 system2 = mock(System2.class); + private final System2 system2 = mock(System2.class); @Rule public DbTester db = DbTester.create(system2); @Rule public ExpectedException expectedException = ExpectedException.none(); - private DbClient dbClient = db.getDbClient(); - private DbSession dbSession = db.getSession(); - private PurgeDao underTest = db.getDbClient().purgeDao(); + private final DbClient dbClient = db.getDbClient(); + private final DbSession dbSession = db.getSession(); + private final PurgeDao underTest = db.getDbClient().purgeDao(); @Test public void purge_failed_ce_tasks() { @@ -703,6 +705,25 @@ public class PurgeDaoTest { } @Test + public void delete_rows_in_user_dismissed_messages_when_deleting_project() { + UserDto user1 = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + ProjectDto anotherProject = db.components().insertPrivateProjectDto(); + + UserDismissedMessageDto msg1 = db.users().insertUserDismissedMessage(user1, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + UserDismissedMessageDto msg2 = db.users().insertUserDismissedMessage(user2, project, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + UserDismissedMessageDto msg3 = db.users().insertUserDismissedMessage(user1, anotherProject, CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); + + assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg1.getUuid(), msg2.getUuid(), msg3.getUuid()); + + underTest.deleteProject(dbSession, project.getUuid()); + dbSession.commit(); + + assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg3.getUuid()); + } + + @Test public void delete_tasks_in_ce_queue_when_deleting_project() { ComponentDto projectToBeDeleted = db.components().insertPrivateProject(); ComponentDto anotherLivingProject = db.components().insertPrivateProject(); @@ -1629,6 +1650,7 @@ public class PurgeDaoTest { .setUuid(UuidFactoryFast.getInstance().create()) .setTaskUuid(uuid) .setMessage("key_" + uuid.hashCode() + i) + .setType(CeTaskMessageType.GENERIC) .setCreatedAt(2_333_444L + i)) .forEach(dto -> dbClient.ceTaskMessageDao().insert(dbSession, dto)); dbSession.commit(); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDismissedMessagesDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDismissedMessagesDaoTest.java new file mode 100644 index 00000000000..e7b640ab0bd --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDismissedMessagesDaoTest.java @@ -0,0 +1,152 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.user; + +import java.util.List; +import java.util.Optional; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.core.util.Uuids; +import org.sonar.db.DbTester; +import org.sonar.db.ce.CeTaskMessageType; +import org.sonar.db.project.ProjectDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.sonar.db.ce.CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE; + +public class UserDismissedMessagesDaoTest { + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + + private final UserDismissedMessagesDao underTest = db.getDbClient().userDismissedMessagesDao(); + + @Test + public void insert_user_dismissed_message() { + ProjectDto project = db.components().insertPrivateProjectDto(); + UserDto user = db.users().insertUser(); + UserDismissedMessageDto dto = newDto(project, user); + + underTest.insert(db.getSession(), dto); + + Optional<UserDismissedMessageDto> dtoFromDb = underTest.selectByUserAndProjectAndMessageType(db.getSession(), user, project, dto.getCeMessageType()); + assertThat(dtoFromDb).isPresent(); + assertThat(dtoFromDb.get().getUuid()).isEqualTo(dto.getUuid()); + assertThat(dtoFromDb.get().getUserUuid()).isEqualTo(dto.getUserUuid()); + assertThat(dtoFromDb.get().getProjectUuid()).isEqualTo(dto.getProjectUuid()); + assertThat(dtoFromDb.get().getCeMessageType()).isEqualTo(dto.getCeMessageType()); + assertThat(dtoFromDb.get().getCeMessageType().isDismissible()).isEqualTo(dto.getCeMessageType().isDismissible()); + assertThat(dtoFromDb.get().getCreatedAt()).isEqualTo(dto.getCreatedAt()); + } + + @Test + public void selectByUserAndProjectAndMessageType_returns_object_if_record_found() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + db.users().insertUserDismissedMessage(user, project, CeTaskMessageType.GENERIC); + + Optional<UserDismissedMessageDto> result = underTest.selectByUserAndProjectAndMessageType(db.getSession(), user, project, CeTaskMessageType.GENERIC); + + assertThat(result).isPresent(); + assertThat(result.get().getUserUuid()).isEqualTo(user.getUuid()); + assertThat(result.get().getProjectUuid()).isEqualTo(project.getUuid()); + assertThat(result.get().getCeMessageType()).isEqualTo(CeTaskMessageType.GENERIC); + } + + @Test + public void selectByUserAndProjectAndMessageType_returns_absent_if_no_record_found() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + db.users().insertUserDismissedMessage(user, project, CeTaskMessageType.GENERIC); + + Optional<UserDismissedMessageDto> result = underTest.selectByUserAndProjectAndMessageType(db.getSession(), user, project, SUGGEST_DEVELOPER_EDITION_UPGRADE); + + assertThat(result).isNotPresent(); + } + + @Test + public void selectByUserUuid_returns_all_dismissed_messages_of_a_user() { + UserDto user1 = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + ProjectDto project1 = db.components().insertPrivateProjectDto(); + ProjectDto project2 = db.components().insertPrivateProjectDto(); + db.users().insertUserDismissedMessage(user1, project1, CeTaskMessageType.GENERIC); + db.users().insertUserDismissedMessage(user1, project2, CeTaskMessageType.GENERIC); + UserDismissedMessageDto dto1 = db.users().insertUserDismissedMessage(user2, project1, CeTaskMessageType.GENERIC); + UserDismissedMessageDto dto2 = db.users().insertUserDismissedMessage(user2, project2, CeTaskMessageType.GENERIC); + + List<UserDismissedMessageDto> result = underTest.selectByUser(db.getSession(), user2); + + assertThat(result).hasSize(2); + assertThat(result).extracting(UserDismissedMessageDto::getUuid, UserDismissedMessageDto::getUserUuid, UserDismissedMessageDto::getProjectUuid, + UserDismissedMessageDto::getCeMessageType) + .containsExactlyInAnyOrder( + tuple(dto1.getUuid(), user2.getUuid(), project1.getUuid(), CeTaskMessageType.GENERIC), + tuple(dto2.getUuid(), user2.getUuid(), project2.getUuid(), CeTaskMessageType.GENERIC)); + } + + @Test + public void deleteByUserUuid_removes_dismiss_warning_data_of_a_user() { + UserDto user1 = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + ProjectDto project1 = db.components().insertPrivateProjectDto(); + ProjectDto project2 = db.components().insertPrivateProjectDto(); + db.users().insertUserDismissedMessage(user1, project1, CeTaskMessageType.GENERIC); + db.users().insertUserDismissedMessage(user1, project2, CeTaskMessageType.GENERIC); + db.users().insertUserDismissedMessage(user2, project1, CeTaskMessageType.GENERIC); + db.users().insertUserDismissedMessage(user2, project2, CeTaskMessageType.GENERIC); + + underTest.deleteByUser(db.getSession(), user2); + + assertThat(underTest.selectByUser(db.getSession(), user1)).hasSize(2); + assertThat(underTest.selectByUser(db.getSession(), user2)).isEmpty(); + } + + @Test + public void deleteByUserUuid_removes_dismissed_messages_of_that_type() { + UserDto user1 = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + ProjectDto project1 = db.components().insertPrivateProjectDto(); + ProjectDto project2 = db.components().insertPrivateProjectDto(); + UserDismissedMessageDto dto1 = db.users().insertUserDismissedMessage(user1, project1, CeTaskMessageType.GENERIC); + db.users().insertUserDismissedMessage(user1, project2, SUGGEST_DEVELOPER_EDITION_UPGRADE); + db.users().insertUserDismissedMessage(user2, project1, SUGGEST_DEVELOPER_EDITION_UPGRADE); + UserDismissedMessageDto dto2 = db.users().insertUserDismissedMessage(user2, project2, CeTaskMessageType.GENERIC); + + underTest.deleteByType(db.getSession(), SUGGEST_DEVELOPER_EDITION_UPGRADE); + + assertThat(underTest.selectByUser(db.getSession(), user1)) + .extracting(UserDismissedMessageDto::getUuid) + .containsExactly(dto1.getUuid()); + assertThat(underTest.selectByUser(db.getSession(), user2)) + .extracting(UserDismissedMessageDto::getUuid) + .containsExactly(dto2.getUuid()); + } + + public static UserDismissedMessageDto newDto(ProjectDto project, UserDto user) { + return new UserDismissedMessageDto() + .setUuid(Uuids.createFast()) + .setCeMessageType(CeTaskMessageType.GENERIC) + .setUserUuid(user.getUuid()) + .setProjectUuid(project.getUuid()); + } +} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java index 079e15fe109..d3b3d4540e3 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java @@ -32,11 +32,13 @@ import org.sonar.core.util.Uuids; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; import org.sonar.db.DbTester; +import org.sonar.db.ce.CeTaskMessageType; import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.permission.GroupPermissionDto; import org.sonar.db.permission.OrganizationPermission; import org.sonar.db.permission.UserPermissionDto; +import org.sonar.db.project.ProjectDto; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -403,4 +405,15 @@ public class UserDbTester { return dto; } + public final UserDismissedMessageDto insertUserDismissedMessage(UserDto userDto, ProjectDto projectDto, CeTaskMessageType messageType) { + UserDismissedMessageDto dto = new UserDismissedMessageDto() + .setUuid(Uuids.create()) + .setUserUuid(userDto.getUuid()) + .setProjectUuid(projectDto.getUuid()) + .setCeMessageType(messageType); + db.getDbClient().userDismissedMessagesDao().insert(db.getSession(), dto); + db.commit(); + return dto; + } + } |