修复语音房bug

This commit is contained in:
hy001 2026-04-23 20:14:15 +08:00
parent 5dd445dfee
commit 13d5fbe41e
6 changed files with 417 additions and 71 deletions

View File

@ -1,6 +1,5 @@
package com.red.circle.external.inner.service.message.impl; package com.red.circle.external.inner.service.message.impl;
import com.alibaba.fastjson.JSON;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
@ -39,8 +38,10 @@ import org.springframework.stereotype.Service;
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class ImGroupClientServiceImpl implements ImGroupClientService { public class ImGroupClientServiceImpl implements ImGroupClientService {
private static final Integer GROUP_ALREADY_EXISTS_ERROR_CODE = 10025;
private final RcMessageProperties rcMessageProperties; private final RcMessageProperties rcMessageProperties;
private final ImGroupMemberService imGroupMemberService; private final ImGroupMemberService imGroupMemberService;
private final ImGroupMessageService imGroupMessageService; private final ImGroupMessageService imGroupMessageService;
@ -159,25 +160,33 @@ public class ImGroupClientServiceImpl implements ImGroupClientService {
); );
} }
@Override @Override
public boolean createAVChatRoomGroup(CreateGroupCmd cmd) { public boolean createAVChatRoomGroup(CreateGroupCmd cmd) {
RcHttpClient.ResponseMono<String> group = imGroupManagerService.createGroup( RcHttpClient.ResponseMono<String> group = imGroupManagerService.createGroup(
CreateGroupParam.builder() CreateGroupParam.builder()
.type(GroupType.AVChatRoom) .type(GroupType.AVChatRoom)
.ownerAccount(cmd.getOwnerAccount()) .ownerAccount(cmd.getOwnerAccount())
.groupId(cmd.getGroupId()) .groupId(cmd.getGroupId())
.name(cmd.getName()) .name(cmd.getName())
.introduction(cmd.getIntroduction()) .introduction(cmd.getIntroduction())
.notification(cmd.getNotification()) .notification(cmd.getNotification())
.faceUrl(cmd.getFaceUrl()) .faceUrl(cmd.getFaceUrl())
.build() .build()
); );
log.info("createAVChatRoomGroup: {}", JSON.toJSONString(group)); String response = group.block();
return TencentIMStatusUtils.isSuccess( log.info("createAVChatRoomGroup groupId={}, response={}", cmd.getGroupId(), response);
group.block() Integer errorCode = parseErrorCode(response);
); if (Objects.equals(errorCode, 0)) {
return true;
} }
if (Objects.equals(errorCode, GROUP_ALREADY_EXISTS_ERROR_CODE)) {
log.warn("createAVChatRoomGroup duplicate groupId={}, treat as success", cmd.getGroupId());
return true;
}
return TencentIMStatusUtils.isSuccess(response);
}
@Override @Override
public void addGroupMembers(CreateGroupAddMemberCmd cmd) { public void addGroupMembers(CreateGroupAddMemberCmd cmd) {

View File

@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -16,6 +17,7 @@ import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.framework.dto.ResultResponse; import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.endpoint.live.RoomManagerClient; import com.red.circle.other.inner.endpoint.live.RoomManagerClient;
import com.red.circle.other.inner.model.dto.live.RoomProfileManagerDTO; import com.red.circle.other.inner.model.dto.live.RoomProfileManagerDTO;
import com.red.circle.tool.core.http.RcHttpClient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
class ImGroupClientServiceImplTest { class ImGroupClientServiceImplTest {
@ -68,6 +70,30 @@ class ImGroupClientServiceImplTest {
verifyNoInteractions(roomManagerClient); verifyNoInteractions(roomManagerClient);
} }
@Test
void createAvChatRoomGroupShouldTreatDuplicateGroupAsSuccess() {
ImGroupManagerService imGroupManagerService = mock(ImGroupManagerService.class);
@SuppressWarnings("unchecked")
RcHttpClient.ResponseMono<String> responseMono = mock(RcHttpClient.ResponseMono.class);
when(imGroupManagerService.createGroup(any())).thenReturn(responseMono);
when(responseMono.block()).thenReturn("{\"ErrorCode\":10025,\"ErrorInfo\":\"group id in use\"}");
ImGroupClientServiceImpl service = new ImGroupClientServiceImpl(
mock(RcMessageProperties.class),
mock(ImGroupMemberService.class),
mock(ImGroupMessageService.class),
imGroupManagerService,
mock(RoomManagerClient.class)
);
boolean created = service.createAVChatRoomGroup(new CreateGroupCmd()
.setOwnerAccount("2046161571540955138")
.setGroupId("1001268")
.setName("room1001268"));
assertTrue(created);
}
private static final class TestableImGroupClientServiceImpl extends ImGroupClientServiceImpl { private static final class TestableImGroupClientServiceImpl extends ImGroupClientServiceImpl {
private boolean createResult; private boolean createResult;

View File

@ -1,14 +1,16 @@
package com.red.circle.other.app.command.room; package com.red.circle.other.app.command.room;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.red.circle.common.business.core.ReplaceString; import com.red.circle.common.business.core.ReplaceString;
import com.red.circle.common.business.core.SensitiveWordFilter; import com.red.circle.common.business.core.SensitiveWordFilter;
import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.component.core.i18n.I18nMessageUtils; import com.red.circle.component.core.i18n.I18nMessageUtils;
import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.live.inner.endpoint.LiveMicClient; import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.mq.business.model.event.room.RoomVoiceCreateSuccessEvent; import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.mq.rocket.business.producer.RoomMqMessageService; import com.red.circle.live.inner.endpoint.LiveMicClient;
import com.red.circle.mq.business.model.event.room.RoomVoiceCreateSuccessEvent;
import com.red.circle.mq.rocket.business.producer.RoomMqMessageService;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor; import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor; import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO; import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
@ -50,13 +52,14 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class LiveVoiceRoomCreateCmdExe { public class LiveVoiceRoomCreateCmdExe {
private final LiveMicClient liveMicClient; private final LiveMicClient liveMicClient;
private final RoomMemberService roomMemberService; private final ImGroupClient imGroupClient;
private final UserProfileGateway userProfileGateway; private final RoomMemberService roomMemberService;
private final RoomMqMessageService roomMqMessageService; private final UserProfileGateway userProfileGateway;
private final PropsNobleVipGateway propsNobleVipGateway; private final RoomMqMessageService roomMqMessageService;
private final PropsNobleVipGateway propsNobleVipGateway;
private final SysCountryCodeService sysCountryCodeService; private final SysCountryCodeService sysCountryCodeService;
private final UserProfileAppConvertor userProfileAppConvertor; private final UserProfileAppConvertor userProfileAppConvertor;
private final RoomProfileAppConvertor roomProfileAppConvertor; private final RoomProfileAppConvertor roomProfileAppConvertor;
@ -133,11 +136,23 @@ public class LiveVoiceRoomCreateCmdExe {
roomMqMessageService roomMqMessageService
.createVoiceRoomSuccess(toRoomVoiceCreateSuccessEvent(roomProfile, cmd)); .createVoiceRoomSuccess(toRoomVoiceCreateSuccessEvent(roomProfile, cmd));
// 创建麦克风记录 // 创建麦克风记录
liveMicClient.create(roomProfile.getId(), roomProfile.getSetting().getMikeSize()); liveMicClient.create(roomProfile.getId(), roomProfile.getSetting().getMikeSize());
return roomProfile;
} // 创建群聊
Boolean isSuccess = imGroupClient.createAVChatRoomGroup(new CreateGroupCmd()
.setOwnerAccount(Objects.toString(roomProfile.getUserId()))
.setGroupId(roomProfile.getRoomAccount())
.setFaceUrl(roomProfile.getRoomCover())
.setName(roomProfile.getRoomName())
).getBody();
if (!Objects.equals(isSuccess, Boolean.TRUE)) {
log.warn("创建群聊失败: {}", roomProfile.getUserId());
}
return roomProfile;
}
private RoomSetting createRoomSetting(UserProfile userProfile) { private RoomSetting createRoomSetting(UserProfile userProfile) {
RoomSetting settingV2 = RoomSetting.createDefaultRoomSetting(); RoomSetting settingV2 = RoomSetting.createDefaultRoomSetting();

View File

@ -1,13 +1,16 @@
package com.red.circle.other.app.command.room; package com.red.circle.other.app.command.room;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.external.inner.endpoint.message.TrtcClient; import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.external.inner.endpoint.message.TrtcClient;
import com.red.circle.framework.core.response.CommonErrorCode; import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.framework.core.response.ResponseErrorCode; import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent; import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.mq.rocket.business.producer.TaskMqMessage; import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.other.app.command.rocket.RocketRewardClaimCmdExe; import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent;
import com.red.circle.mq.rocket.business.producer.TaskMqMessage;
import com.red.circle.other.app.command.rocket.RocketRewardClaimCmdExe;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor; import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor; import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.EntryRoomEntrantsCO; import com.red.circle.other.app.dto.clientobject.room.EntryRoomEntrantsCO;
@ -62,10 +65,9 @@ import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Component;
/** /**
* 加入房间检测. * 加入房间检测.
@ -75,11 +77,14 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class RoomEnterCmdExe { public class RoomEnterCmdExe {
private final UserRegionGateway userRegionGateway; private static final String ROOM_IM_GROUP_READY_KEY_PREFIX = "ROOM:IM:GROUP:READY:";
private final UserProfileGateway userProfileGateway; private static final long ROOM_IM_GROUP_READY_SECONDS = 60L;
private final RoomTouristService roomTouristService;
private final UserRegionGateway userRegionGateway;
private final UserProfileGateway userProfileGateway;
private final RoomTouristService roomTouristService;
private final AdministratorService administratorService; private final AdministratorService administratorService;
private final PropsRoomLockService propsRoomLockService; private final PropsRoomLockService propsRoomLockService;
private final UserProfileAppConvertor userProfileAppConvertor; private final UserProfileAppConvertor userProfileAppConvertor;
@ -88,10 +93,12 @@ public class RoomEnterCmdExe {
private final RoomUserBlacklistService roomUserBlacklistService; private final RoomUserBlacklistService roomUserBlacklistService;
private final RoomProfileManagerService roomProfileManagerService; private final RoomProfileManagerService roomProfileManagerService;
private final TrtcClient trtcClient; private final TrtcClient trtcClient;
private final UserAgoraTokenCacheService userAgoraTokenCacheService; private final UserAgoraTokenCacheService userAgoraTokenCacheService;
private final TaskMqMessage taskMqMessage; private final TaskMqMessage taskMqMessage;
private final AdministratorAuthService administratorAuthService; private final AdministratorAuthService administratorAuthService;
private final RocketRewardClaimCmdExe rocketRewardClaimCmdExe; private final RocketRewardClaimCmdExe rocketRewardClaimCmdExe;
private final ImGroupClient imGroupClient;
private final RedisService redisService;
public EntryRoomResponseCO execute(RoomEntryCmd cmd) { public EntryRoomResponseCO execute(RoomEntryCmd cmd) {
//checkEntryUserId(cmd); //checkEntryUserId(cmd);
@ -102,11 +109,12 @@ public class RoomEnterCmdExe {
.userId(cmd.getReqUserId()) .userId(cmd.getReqUserId())
.build()); .build());
RoomProfileManager manager = roomProfileManagerService.getById(cmd.getRoomId()); RoomProfileManager manager = roomProfileManagerService.getById(cmd.getRoomId());
entryRoomCheck(cmd, manager); entryRoomCheck(cmd, manager);
ensureRoomImGroup(manager);
setDefaultRoomSettingTakeMicRole(manager);
setDefaultRoomSettingTakeMicRole(manager);
UserProfileDTO ownUserProfile = userProfileAppConvertor.toUserProfileDTO( UserProfileDTO ownUserProfile = userProfileAppConvertor.toUserProfileDTO(
userProfileGateway.getByUserId(manager.getUserId()) userProfileGateway.getByUserId(manager.getUserId())
@ -148,18 +156,57 @@ public class RoomEnterCmdExe {
.setLayoutCode(getLayoutCode(ownUserProfile)) .setLayoutCode(getLayoutCode(ownUserProfile))
.setRoomTheme(getRoomThemeCO(ownUserProfile)) .setRoomTheme(getRoomThemeCO(ownUserProfile))
) )
.setEntrants( .setEntrants(
new EntryRoomEntrantsCO() new EntryRoomEntrantsCO()
.setRoles(roomManagerCacheService.getRoomUserRoles(cmd.getReqUserId(), .setRoles(roomManagerCacheService.getRoomUserRoles(cmd.getReqUserId(),
cmd.getRoomId())) cmd.getRoomId()))
.setLevel(getUserLevel(cmd.requireReqSysOriginEnum(), cmd.getReqUserId())) .setLevel(getUserLevel(cmd.requireReqSysOriginEnum(), cmd.getReqUserId()))
.setNobleVipAbility(listUserPropsVipActualEquity(cmd)) .setNobleVipAbility(listUserPropsVipActualEquity(cmd))
.setRoomToken(token) .setRoomToken(token)
); );
} }
/** private void ensureRoomImGroup(RoomProfileManager manager) {
* 异步拿声网观众token5分钟拿不到就返回默认一串字符串 if (Objects.isNull(manager) || Objects.isNull(manager.getUserId())
|| StringUtils.isBlank(manager.getRoomAccount())) {
return;
}
String roomAccount = manager.getRoomAccount().trim();
if (!roomAccount.chars().allMatch(Character::isDigit)) {
return;
}
String cacheKey = ROOM_IM_GROUP_READY_KEY_PREFIX + roomAccount;
if (StringUtils.isNotBlank(redisService.getString(cacheKey))) {
return;
}
try {
Boolean ensured = Optional.ofNullable(
imGroupClient.createAVChatRoomGroup(new CreateGroupCmd()
.setOwnerAccount(Objects.toString(manager.getUserId()))
.setGroupId(roomAccount)
.setFaceUrl(manager.getRoomCover())
.setName(manager.getRoomName()))
)
.map(ResultResponse::getBody)
.orElse(Boolean.FALSE);
if (Objects.equals(ensured, Boolean.TRUE)) {
redisService.setIfAbsent(cacheKey, "1", ROOM_IM_GROUP_READY_SECONDS, TimeUnit.SECONDS);
return;
}
log.warn("ensureRoomImGroup fail roomId={}, roomAccount={}", manager.getId(), roomAccount);
} catch (Exception ex) {
log.warn("ensureRoomImGroup exception roomId={}, roomAccount={}", manager.getId(),
roomAccount, ex);
}
}
/**
* 异步拿声网观众token5分钟拿不到就返回默认一串字符串
* @param cmd * @param cmd
* @return * @return
*/ */

View File

@ -0,0 +1,100 @@
package com.red.circle.other.app.command.room;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.live.inner.endpoint.LiveMicClient;
import com.red.circle.mq.business.model.event.room.RoomVoiceCreateSuccessEvent;
import com.red.circle.mq.rocket.business.producer.RoomMqMessageService;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
import com.red.circle.other.domain.gateway.props.PropsNobleVipGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.mongo.entity.live.RoomSetting;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.sys.SysCountryCode;
import com.red.circle.other.infra.database.rds.service.live.RoomMemberService;
import com.red.circle.other.infra.database.rds.service.sys.SysCountryCodeService;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
class LiveVoiceRoomCreateCmdExeTest {
@Test
void executeShouldCreateImRoomGroupForNormalRoom() {
LiveMicClient liveMicClient = mock(LiveMicClient.class);
ImGroupClient imGroupClient = mock(ImGroupClient.class);
RoomMemberService roomMemberService = mock(RoomMemberService.class);
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
RoomMqMessageService roomMqMessageService = mock(RoomMqMessageService.class);
PropsNobleVipGateway propsNobleVipGateway = mock(PropsNobleVipGateway.class);
SysCountryCodeService sysCountryCodeService = mock(SysCountryCodeService.class);
UserProfileAppConvertor userProfileAppConvertor = mock(UserProfileAppConvertor.class);
RoomProfileAppConvertor roomProfileAppConvertor = mock(RoomProfileAppConvertor.class);
RoomProfileManagerService roomProfileManagerService = mock(RoomProfileManagerService.class);
EnumConfigCacheService enumConfigCacheService = mock(EnumConfigCacheService.class);
LiveVoiceRoomCreateCmdExe exe = new LiveVoiceRoomCreateCmdExe(
liveMicClient,
imGroupClient,
roomMemberService,
userProfileGateway,
roomMqMessageService,
propsNobleVipGateway,
sysCountryCodeService,
userProfileAppConvertor,
roomProfileAppConvertor,
roomProfileManagerService,
enumConfigCacheService
);
UserProfile userProfile = new UserProfile();
userProfile.setId(2046161571540955138L);
userProfile.setAccount("1001268");
userProfile.setUserNickname("room-owner");
userProfile.setCountryCode("SA");
userProfile.setCountryName("Saudi Arabia");
userProfile.setOriginSys("LIKEI");
AppExtCommand cmd = mock(AppExtCommand.class);
when(cmd.requiredReqUserId()).thenReturn(2046161571540955138L);
when(cmd.requireReqSysOrigin()).thenReturn("LIKEI");
when(roomProfileManagerService.existsUserRoom(2046161571540955138L)).thenReturn(false);
when(userProfileGateway.getByUserId(2046161571540955138L)).thenReturn(userProfile);
when(enumConfigCacheService.getValue(any(), any())).thenReturn("room-cover.png");
when(imGroupClient.createAVChatRoomGroup(any(CreateGroupCmd.class)))
.thenReturn(ResultResponse.success(Boolean.TRUE));
when(roomProfileAppConvertor.toRoomVoiceCreateSuccessEvent(any()))
.thenReturn(new RoomVoiceCreateSuccessEvent());
when(roomProfileAppConvertor.toRoomVoiceProfileCO(any()))
.thenReturn(new RoomVoiceProfileCO());
when(roomProfileAppConvertor.toRoomSettingCO(any(RoomSetting.class)))
.thenReturn(null);
UserProfileDTO userProfileDTO = new UserProfileDTO();
userProfileDTO.setId(userProfile.getId());
when(userProfileAppConvertor.toUserProfileDTO(userProfile))
.thenReturn(userProfileDTO);
when(sysCountryCodeService.getByCode("SA")).thenReturn(new SysCountryCode());
exe.execute(cmd);
ArgumentCaptor<CreateGroupCmd> captor = ArgumentCaptor.forClass(CreateGroupCmd.class);
verify(imGroupClient).createAVChatRoomGroup(captor.capture());
CreateGroupCmd createGroupCmd = captor.getValue();
assertEquals("2046161571540955138", createGroupCmd.getOwnerAccount());
assertEquals("1001268", createGroupCmd.getGroupId());
assertEquals("room-cover.png", createGroupCmd.getFaceUrl());
assertEquals("room1001268", createGroupCmd.getName());
verify(liveMicClient).create(any(), any());
}
}

View File

@ -0,0 +1,149 @@
package com.red.circle.other.app.command.room;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.endpoint.message.TrtcClient;
import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.mq.rocket.business.producer.TaskMqMessage;
import com.red.circle.other.app.command.rocket.RocketRewardClaimCmdExe;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.EntryRoomResponseCO;
import com.red.circle.other.app.dto.cmd.room.RoomEntryCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.infra.database.cache.service.other.RoomManagerCacheService;
import com.red.circle.other.infra.database.cache.service.user.UserAgoraTokenCacheService;
import com.red.circle.other.infra.database.mongo.entity.live.RoomCounter;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
import com.red.circle.other.infra.database.mongo.entity.live.RoomSetting;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.mongo.service.live.RoomTouristService;
import com.red.circle.other.infra.database.mongo.service.live.RoomUserBlacklistService;
import com.red.circle.other.infra.database.rds.service.props.PropsRoomLockService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorAuthService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.inner.enums.room.RoomEventEnum;
import com.red.circle.other.inner.enums.room.RoomTakeMicRoleEnum;
import com.red.circle.other.inner.enums.live.RoomUserRolesEnum;
import com.red.circle.other.inner.model.dto.live.RoomProfileDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
class RoomEnterCmdExeTest {
@Test
void executeShouldEnsureImRoomGroupBeforeReturn() {
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
RoomTouristService roomTouristService = mock(RoomTouristService.class);
AdministratorService administratorService = mock(AdministratorService.class);
PropsRoomLockService propsRoomLockService = mock(PropsRoomLockService.class);
UserProfileAppConvertor userProfileAppConvertor = mock(UserProfileAppConvertor.class);
RoomProfileAppConvertor roomProfileAppConvertor = mock(RoomProfileAppConvertor.class);
RoomManagerCacheService roomManagerCacheService = mock(RoomManagerCacheService.class);
RoomUserBlacklistService roomUserBlacklistService = mock(RoomUserBlacklistService.class);
RoomProfileManagerService roomProfileManagerService = mock(RoomProfileManagerService.class);
TrtcClient trtcClient = mock(TrtcClient.class);
UserAgoraTokenCacheService userAgoraTokenCacheService = mock(UserAgoraTokenCacheService.class);
TaskMqMessage taskMqMessage = mock(TaskMqMessage.class);
AdministratorAuthService administratorAuthService = mock(AdministratorAuthService.class);
RocketRewardClaimCmdExe rocketRewardClaimCmdExe = mock(RocketRewardClaimCmdExe.class);
ImGroupClient imGroupClient = mock(ImGroupClient.class);
RedisService redisService = mock(RedisService.class);
RoomEnterCmdExe exe = new RoomEnterCmdExe(
userRegionGateway,
userProfileGateway,
roomTouristService,
administratorService,
propsRoomLockService,
userProfileAppConvertor,
roomProfileAppConvertor,
roomManagerCacheService,
roomUserBlacklistService,
roomProfileManagerService,
trtcClient,
userAgoraTokenCacheService,
taskMqMessage,
administratorAuthService,
rocketRewardClaimCmdExe,
imGroupClient,
redisService
);
Long roomId = 2046489424769904642L;
Long userId = 2046161571540955138L;
RoomEntryCmd cmd = mock(RoomEntryCmd.class);
when(cmd.getRoomId()).thenReturn(roomId);
when(cmd.getReqUserId()).thenReturn(userId);
when(cmd.requiredReqUserId()).thenReturn(userId);
when(cmd.requireReqSysOrigin()).thenReturn("LIKEI");
when(cmd.requireReqSysOriginEnum()).thenReturn(SysOriginPlatformEnum.LIKEI);
when(cmd.reqIsSelf(userId)).thenReturn(true);
RoomProfileManager manager = new RoomProfileManager();
manager.setId(roomId);
manager.setUserId(userId);
manager.setRoomAccount("1001268");
manager.setRoomName("Teams stay blessed");
manager.setRoomCover("room-cover.png");
manager.setDel(Boolean.FALSE);
manager.setSysOrigin("LIKEI");
manager.setEvent(RoomEventEnum.WAITING_CONFIRMED.name());
manager.setCounter(new RoomCounter().setAdminCount(0).setMemberCount(1));
manager.setSetting(RoomSetting.createDefaultRoomSetting().setTakeMicRole(RoomTakeMicRoleEnum.ALL.name()));
when(roomProfileManagerService.getById(roomId)).thenReturn(manager);
when(roomProfileManagerService.listProfileByRoomIds(anySet())).thenReturn(Collections.emptyList());
when(roomProfileManagerService.getRoomSysOrigin(roomId)).thenReturn("LIKEI");
when(userProfileGateway.getSysOrigin(userId)).thenReturn("LIKEI");
when(userProfileGateway.getUserNobleAbility(userId)).thenReturn(Collections.emptyList());
when(userProfileGateway.getByUserId(userId)).thenReturn(new com.red.circle.other.domain.model.user.UserProfile());
when(userProfileGateway.getUserConsumptionLevel(SysOriginPlatformEnum.LIKEI, userId)).thenReturn(null);
when(userProfileGateway.listUserActualEquityEnum(userId)).thenReturn(Collections.emptyList());
when(administratorService.existsSupperAdmin(userId)).thenReturn(false);
when(administratorService.existsManager(userId)).thenReturn(false);
when(userAgoraTokenCacheService.getUserAgoraToken(userId, roomId)).thenReturn("agora-token");
when(redisService.getString("ROOM:IM:GROUP:READY:1001268")).thenReturn(null);
when(imGroupClient.createAVChatRoomGroup(any(CreateGroupCmd.class)))
.thenReturn(ResultResponse.success(Boolean.TRUE));
UserProfileDTO userProfileDTO = new UserProfileDTO();
userProfileDTO.setId(userId);
userProfileDTO.setCountryCode("SA");
userProfileDTO.setCountryName("Saudi Arabia");
when(userProfileAppConvertor.toUserProfileDTO(any())).thenReturn(userProfileDTO);
when(userRegionGateway.getRegionCode(userId)).thenReturn("SA");
when(roomProfileAppConvertor.toRoomProfileDTO(manager)).thenReturn(new RoomProfileDTO());
when(roomProfileAppConvertor.toRoomSettingCO(any())).thenReturn(null);
when(roomProfileAppConvertor.toRoomCounterDTO(any())).thenReturn(null);
when(roomManagerCacheService.getRoomUserRoles(userId, roomId))
.thenReturn(RoomUserRolesEnum.HOMEOWNER);
EntryRoomResponseCO response = exe.execute(cmd);
assertNotNull(response);
ArgumentCaptor<CreateGroupCmd> captor = ArgumentCaptor.forClass(CreateGroupCmd.class);
verify(imGroupClient).createAVChatRoomGroup(captor.capture());
verify(redisService).setIfAbsent("ROOM:IM:GROUP:READY:1001268", "1", 60L, TimeUnit.SECONDS);
CreateGroupCmd createGroupCmd = captor.getValue();
org.junit.jupiter.api.Assertions.assertEquals("2046161571540955138",
createGroupCmd.getOwnerAccount());
org.junit.jupiter.api.Assertions.assertEquals("1001268", createGroupCmd.getGroupId());
org.junit.jupiter.api.Assertions.assertEquals("room-cover.png", createGroupCmd.getFaceUrl());
org.junit.jupiter.api.Assertions.assertEquals("Teams stay blessed", createGroupCmd.getName());
}
}