完善e2e测试与后端测试,微信小程序端UI层测试暂未完成
This commit was merged in pull request #52.
This commit is contained in:
+175
@@ -0,0 +1,175 @@
|
||||
package cn.novalon.gym.manage.auth.handler;
|
||||
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneLoginDto;
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneCodeLoginDto;
|
||||
import cn.novalon.gym.manage.auth.dto.SendCodeRequest;
|
||||
import cn.novalon.gym.manage.auth.service.PhoneAuthService;
|
||||
import cn.novalon.gym.manage.auth.vo.PhoneLoginVO;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PhoneAuthHandlerTest {
|
||||
|
||||
@Mock
|
||||
private PhoneAuthService phoneAuthService;
|
||||
|
||||
private PhoneAuthHandler phoneAuthHandler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
phoneAuthHandler = new PhoneAuthHandler(phoneAuthService);
|
||||
}
|
||||
|
||||
// ==================== oneClickLogin ====================
|
||||
|
||||
@Test
|
||||
void oneClickLogin_shouldReturnOkWithLoginResult() {
|
||||
PhoneLoginVO loginVO = new PhoneLoginVO();
|
||||
loginVO.setAccessToken("test-jwt-token");
|
||||
loginVO.setPhone("13800138000");
|
||||
|
||||
PhoneLoginDto dto = new PhoneLoginDto();
|
||||
dto.setAccessToken("dcloud-access-token");
|
||||
|
||||
when(phoneAuthService.oneClickLogin(any(PhoneLoginDto.class))).thenReturn(Mono.just(loginVO));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(dto));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.oneClickLogin(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
|
||||
verify(phoneAuthService).oneClickLogin(any(PhoneLoginDto.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneClickLogin_shouldPropagateServiceError() {
|
||||
PhoneLoginDto dto = new PhoneLoginDto();
|
||||
dto.setAccessToken("invalid-token");
|
||||
|
||||
when(phoneAuthService.oneClickLogin(any(PhoneLoginDto.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("Auth failed")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(dto));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.oneClickLogin(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
// ==================== sendSmsCode ====================
|
||||
|
||||
@Test
|
||||
void sendSmsCode_shouldReturnOkWithSuccessTrue() {
|
||||
SendCodeRequest sendCodeRequest = new SendCodeRequest();
|
||||
sendCodeRequest.setPhone("13800138000");
|
||||
|
||||
when(phoneAuthService.sendSmsCode("13800138000")).thenReturn(Mono.just(true));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(sendCodeRequest));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.sendSmsCode(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSmsCode_shouldReturnOkWithSuccessFalseWhenServiceReturnsFalse() {
|
||||
SendCodeRequest sendCodeRequest = new SendCodeRequest();
|
||||
sendCodeRequest.setPhone("13800138000");
|
||||
|
||||
when(phoneAuthService.sendSmsCode("13800138000")).thenReturn(Mono.just(false));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(sendCodeRequest));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.sendSmsCode(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSmsCode_shouldPropagateError() {
|
||||
SendCodeRequest sendCodeRequest = new SendCodeRequest();
|
||||
sendCodeRequest.setPhone("13800138000");
|
||||
|
||||
when(phoneAuthService.sendSmsCode("13800138000"))
|
||||
.thenReturn(Mono.error(new RuntimeException("SMS service unavailable")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(sendCodeRequest));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.sendSmsCode(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
// ==================== codeLogin ====================
|
||||
|
||||
@Test
|
||||
void codeLogin_shouldReturnOkWithLoginResult() {
|
||||
PhoneLoginVO loginVO = new PhoneLoginVO();
|
||||
loginVO.setAccessToken("test-jwt-token");
|
||||
|
||||
PhoneCodeLoginDto dto = new PhoneCodeLoginDto();
|
||||
dto.setPhone("13800138000");
|
||||
dto.setCode("123456");
|
||||
|
||||
when(phoneAuthService.codeLogin(any(PhoneCodeLoginDto.class))).thenReturn(Mono.just(loginVO));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(dto));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.codeLogin(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void codeLogin_shouldPropagateServiceError() {
|
||||
PhoneCodeLoginDto dto = new PhoneCodeLoginDto();
|
||||
dto.setPhone("13800138000");
|
||||
dto.setCode("wrong-code");
|
||||
|
||||
when(phoneAuthService.codeLogin(any(PhoneCodeLoginDto.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("Invalid code")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(dto));
|
||||
|
||||
Mono<ServerResponse> result = phoneAuthHandler.codeLogin(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
package cn.novalon.gym.manage.checkin.handler;
|
||||
|
||||
import cn.novalon.gym.manage.checkIn.handler.CheckInHandler;
|
||||
import cn.novalon.gym.manage.checkIn.service.impl.CheckServiceImpl;
|
||||
import cn.novalon.gym.manage.checkIn.vo.QRCodeVo;
|
||||
import cn.novalon.gym.manage.checkIn.vo.SignInRecordVO;
|
||||
import cn.novalon.gym.manage.checkIn.vo.SignInStatsVO;
|
||||
import cn.novalon.gym.manage.sys.util.AuthUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CheckInHandlerTest {
|
||||
|
||||
@Mock
|
||||
private AuthUtil authUtil;
|
||||
|
||||
@Mock
|
||||
private CheckServiceImpl checkService;
|
||||
|
||||
private CheckInHandler checkInHandler;
|
||||
|
||||
private static final Long MEMBER_ID = 10001L;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
checkInHandler = new CheckInHandler(authUtil, checkService);
|
||||
}
|
||||
|
||||
// ==================== checkIn ====================
|
||||
|
||||
@Test
|
||||
void checkIn_shouldReturnOk() {
|
||||
Map<String, Object> body = Map.of("qrContent", "checkin:member:10001");
|
||||
|
||||
when(authUtil.getMemberIdOrThrow(any())).thenReturn(MEMBER_ID);
|
||||
when(checkService.checkIn(MEMBER_ID, "checkin:member:10001")).thenReturn(Mono.just("签到成功"));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(body));
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.checkIn(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
verify(checkService).checkIn(MEMBER_ID, "checkin:member:10001");
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkIn_shouldReturnBadRequestOnError() {
|
||||
Map<String, Object> body = Map.of("qrContent", "invalid-content");
|
||||
|
||||
when(authUtil.getMemberIdOrThrow(any())).thenReturn(MEMBER_ID);
|
||||
when(checkService.checkIn(MEMBER_ID, "invalid-content"))
|
||||
.thenReturn(Mono.error(new RuntimeException("Invalid QR code")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(body));
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.checkIn(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
// ==================== getQRCode ====================
|
||||
|
||||
@Test
|
||||
void getQRCode_shouldReturnOkWithQRCode() {
|
||||
QRCodeVo qrCode = new QRCodeVo("base64content", false, "qr-content", 200, 200, LocalDate.now());
|
||||
|
||||
when(authUtil.getMemberIdOrThrow(any())).thenReturn(MEMBER_ID);
|
||||
when(checkService.getQRCode(MEMBER_ID)).thenReturn(Mono.just(qrCode));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.getQRCode(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getSignInRecords ====================
|
||||
|
||||
@Test
|
||||
void getSignInRecords_shouldReturnOkWithRecords() {
|
||||
List<SignInRecordVO> records = List.of(createTestRecord());
|
||||
|
||||
when(authUtil.getMemberIdOrThrow(any())).thenReturn(MEMBER_ID);
|
||||
when(checkService.getSignInRecords(eq(MEMBER_ID), any(LocalDate.class), any(LocalDate.class)))
|
||||
.thenReturn(Flux.fromIterable(records));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("startDate", "2025-01-01")
|
||||
.queryParam("endDate", "2025-01-31")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.getSignInRecords(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getSignInStatistics ====================
|
||||
|
||||
@Test
|
||||
void getSignInStatistics_shouldReturnOkWithStats() {
|
||||
SignInStatsVO stats = new SignInStatsVO();
|
||||
|
||||
when(authUtil.getMemberIdOrThrow(any())).thenReturn(MEMBER_ID);
|
||||
when(checkService.getSignInStats(eq(MEMBER_ID), any(LocalDate.class), any(LocalDate.class)))
|
||||
.thenReturn(Mono.just(stats));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("startDate", "2025-01-01")
|
||||
.queryParam("endDate", "2025-01-31")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.getSignInStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getDailySignInStats ====================
|
||||
|
||||
@Test
|
||||
void getDailySignInStats_shouldReturnOkWithDailyStats() {
|
||||
SignInStatsVO stats = new SignInStatsVO();
|
||||
|
||||
when(checkService.getDailySignInStats(any(LocalDate.class))).thenReturn(Mono.just(stats));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("date", "2025-01-15")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = checkInHandler.getDailySignInStats(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private SignInRecordVO createTestRecord() {
|
||||
SignInRecordVO record = new SignInRecordVO();
|
||||
record.setId(1L);
|
||||
record.setMemberId(MEMBER_ID);
|
||||
record.setSignInTime(LocalDateTime.now());
|
||||
record.setSignInType("QR_CODE");
|
||||
record.setSignInStatus("SUCCESS");
|
||||
return record;
|
||||
}
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
package cn.novalon.gym.manage.coach.handler;
|
||||
|
||||
import cn.novalon.gym.manage.coach.service.CoachCourseService;
|
||||
import cn.novalon.gym.manage.sys.core.domain.SysUser;
|
||||
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import jakarta.validation.Validator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CoachHandlerTest {
|
||||
|
||||
@Mock
|
||||
private CoachCourseService coachCourseService;
|
||||
|
||||
@Mock
|
||||
private Validator validator;
|
||||
|
||||
private CoachHandler coachHandler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
coachHandler = new CoachHandler(coachCourseService, validator);
|
||||
}
|
||||
|
||||
// ==================== getAllCoaches ====================
|
||||
|
||||
@Test
|
||||
void getAllCoaches_shouldReturnOkWithCoachList() {
|
||||
SysUser coach = mock(SysUser.class);
|
||||
when(coachCourseService.getAllCoaches()).thenReturn(Flux.just(coach));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getAllCoaches(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
verify(coachCourseService).getAllCoaches();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllCoaches_shouldReturnOkWhenEmptyList() {
|
||||
when(coachCourseService.getAllCoaches()).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getAllCoaches(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getCoachCourses ====================
|
||||
|
||||
@Test
|
||||
void getCoachCourses_shouldReturnOkWithCourses() {
|
||||
GroupCourse course = mock(GroupCourse.class);
|
||||
when(coachCourseService.getCoachCourses(anyLong())).thenReturn(Flux.just(course));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getCoachCourses(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCoachCourses_shouldReturnOkWhenEmpty() {
|
||||
when(coachCourseService.getCoachCourses(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getCoachCourses(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== disableCoach ====================
|
||||
|
||||
@Test
|
||||
void disableCoach_shouldReturnOkWhenDisabled() {
|
||||
when(coachCourseService.disableCoach(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.disableCoach(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void disableCoach_shouldReturnBadRequestOnError() {
|
||||
when(coachCourseService.disableCoach(anyLong()))
|
||||
.thenReturn(Mono.error(new RuntimeException("Coach not found")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.disableCoach(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
// ==================== getViolationCounts ====================
|
||||
|
||||
@Test
|
||||
void getViolationCounts_shouldReturnOk() {
|
||||
when(coachCourseService.getViolationCounts()).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getViolationCounts(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getCoachViolations ====================
|
||||
|
||||
@Test
|
||||
void getCoachViolations_shouldReturnOkWithViolations() {
|
||||
when(coachCourseService.getCoachViolations(anyLong())).thenReturn(Flux.just(Map.of("violationId", 1, "reason", "迟到")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getCoachViolations(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCoachViolations_shouldReturnEmptyListWhenNone() {
|
||||
when(coachCourseService.getCoachViolations(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = coachHandler.getCoachViolations(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
package cn.novalon.gym.manage.datacount.handler;
|
||||
|
||||
import cn.novalon.gym.manage.datacount.domain.*;
|
||||
import cn.novalon.gym.manage.datacount.service.IDataStatisticsService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DataStatisticsHandlerTest {
|
||||
|
||||
@Mock
|
||||
private IDataStatisticsService dataStatisticsService;
|
||||
|
||||
private DataStatisticsHandler handler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
handler = new DataStatisticsHandler();
|
||||
java.lang.reflect.Field field = DataStatisticsHandler.class.getDeclaredField("dataStatisticsService");
|
||||
field.setAccessible(true);
|
||||
field.set(handler, dataStatisticsService);
|
||||
}
|
||||
|
||||
// ==================== getStatisticsSummary ====================
|
||||
|
||||
@Test
|
||||
void getStatisticsSummary_shouldReturnOkWithSummary() {
|
||||
StatisticsSummary summary = createTestSummary();
|
||||
when(dataStatisticsService.getStatisticsSummaryWithCache(any(StatisticsQuery.class))).thenReturn(Mono.just(summary));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "DAY")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getStatisticsSummary(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getStatisticsSummary_shouldReturnOkEvenOnError() {
|
||||
when(dataStatisticsService.getStatisticsSummaryWithCache(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("Service error")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "DAY")
|
||||
.build();
|
||||
|
||||
// Error handler returns empty/default summary with 200 OK
|
||||
Mono<ServerResponse> result = handler.getStatisticsSummary(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getMemberStatistics ====================
|
||||
|
||||
@Test
|
||||
void getMemberStatistics_shouldReturnOk() {
|
||||
MemberStatistics stats = new MemberStatistics();
|
||||
when(dataStatisticsService.getMemberStatistics(any(StatisticsQuery.class))).thenReturn(Mono.just(stats));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "WEEK")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getMemberStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMemberStatistics_shouldReturnOkEvenOnError() {
|
||||
when(dataStatisticsService.getMemberStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("Service error")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "WEEK")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getMemberStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getBookingStatistics ====================
|
||||
|
||||
@Test
|
||||
void getBookingStatistics_shouldReturnOk() {
|
||||
BookingStatistics stats = new BookingStatistics();
|
||||
when(dataStatisticsService.getBookingStatistics(any(StatisticsQuery.class))).thenReturn(Mono.just(stats));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "MONTH")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getBookingStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getSignInStatistics ====================
|
||||
|
||||
@Test
|
||||
void getSignInStatistics_shouldReturnOk() {
|
||||
SignInStatistics stats = new SignInStatistics();
|
||||
when(dataStatisticsService.getSignInStatistics(any(StatisticsQuery.class))).thenReturn(Mono.just(stats));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "MONTH")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getSignInStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== queryHistoricalStatistics ====================
|
||||
|
||||
@Test
|
||||
void queryHistoricalStatistics_shouldReturnOkWithList() {
|
||||
when(dataStatisticsService.queryHistoricalStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Flux.just(createTestDataStatistics()));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "YEAR")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.queryHistoricalStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryHistoricalStatistics_shouldReturnOkWhenEmpty() {
|
||||
when(dataStatisticsService.queryHistoricalStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "YEAR")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.queryHistoricalStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== exportStatistics ====================
|
||||
|
||||
@Test
|
||||
void exportStatistics_shouldReturnOkWithExcelContent() {
|
||||
byte[] excelData = "mock-excel-content".getBytes();
|
||||
when(dataStatisticsService.exportStatistics(any(StatisticsQuery.class))).thenReturn(Mono.just(excelData));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("periodType", "MONTH")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.exportStatistics(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== buildQueryFromRequest (via parameterized tests) ====================
|
||||
|
||||
@Test
|
||||
void getStatisticsSummary_shouldUseDefaultPeriodWhenMissing() {
|
||||
StatisticsSummary summary = createTestSummary();
|
||||
when(dataStatisticsService.getStatisticsSummaryWithCache(any(StatisticsQuery.class))).thenReturn(Mono.just(summary));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getStatisticsSummary(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private StatisticsSummary createTestSummary() {
|
||||
StatisticsSummary summary = new StatisticsSummary();
|
||||
summary.setMemberStatistics(new MemberStatistics());
|
||||
summary.setBookingStatistics(new BookingStatistics());
|
||||
summary.setSignInStatistics(new SignInStatistics());
|
||||
summary.setCoachStatistics(new CoachStatistics());
|
||||
return summary;
|
||||
}
|
||||
|
||||
private DataStatistics createTestDataStatistics() {
|
||||
return DataStatistics.builder()
|
||||
.statType("MEMBER")
|
||||
.periodType("DAY")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
package cn.novalon.gym.manage.groupcourse.handler;
|
||||
|
||||
import cn.novalon.gym.manage.common.util.RedisUtil;
|
||||
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
|
||||
import cn.novalon.gym.manage.groupcourse.domain.GroupCourseDetail;
|
||||
import cn.novalon.gym.manage.groupcourse.service.IGroupCourseService;
|
||||
import cn.novalon.gym.manage.groupcourse.vo.GroupCourseVO;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.validation.Validator;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class GroupCourseHandlerTest {
|
||||
|
||||
@Mock
|
||||
private IGroupCourseService groupCourseService;
|
||||
|
||||
@Mock
|
||||
private Validator validator;
|
||||
|
||||
@Mock
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Mock
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private GroupCourseHandler handler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
handler = new GroupCourseHandler(groupCourseService, validator, redisUtil, objectMapper);
|
||||
}
|
||||
|
||||
// ==================== getAllGroupCourse ====================
|
||||
|
||||
@Test
|
||||
void getAllGroupCourse_shouldReturnOkWithCourses() {
|
||||
GroupCourseVO vo1 = mock(GroupCourseVO.class);
|
||||
GroupCourseVO vo2 = mock(GroupCourseVO.class);
|
||||
when(groupCourseService.findAllAsVO(false)).thenReturn(Flux.just(vo1, vo2));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
Mono<ServerResponse> result = handler.getAllGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
verify(groupCourseService).findAllAsVO(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllGroupCourse_shouldReturnOkWhenEmpty() {
|
||||
when(groupCourseService.findAllAsVO(false)).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
Mono<ServerResponse> result = handler.getAllGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== getGroupCourseById ====================
|
||||
|
||||
@Test
|
||||
void getGroupCourseById_shouldReturnOkWhenFound() {
|
||||
GroupCourse course = createTestCourse(1L, "瑜伽课");
|
||||
when(groupCourseService.findById(1L)).thenReturn(Mono.just(course));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.getGroupCourseById(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGroupCourseById_shouldReturnNotFound() {
|
||||
when(groupCourseService.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.getGroupCourseById(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
// ==================== getGroupCourseDetailById ====================
|
||||
|
||||
@Test
|
||||
void getGroupCourseDetailById_shouldReturnOkWhenFound() {
|
||||
GroupCourseDetail detail = mock(GroupCourseDetail.class);
|
||||
when(groupCourseService.findDetailById(1L)).thenReturn(Mono.just(detail));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.getGroupCourseDetailById(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGroupCourseDetailById_shouldReturnNotFound() {
|
||||
when(groupCourseService.findDetailById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.getGroupCourseDetailById(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
// ==================== cancelGroupCourse ====================
|
||||
|
||||
@Test
|
||||
void cancelGroupCourse_shouldReturnOkWhenCancelled() {
|
||||
GroupCourse cancelled = createTestCourse(1L, "瑜伽课");
|
||||
cancelled.setStatus(2L);
|
||||
when(groupCourseService.cancel(1L)).thenReturn(Mono.just(cancelled));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.cancelGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void cancelGroupCourse_shouldReturnNotFound() {
|
||||
when(groupCourseService.cancel(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.cancelGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
// ==================== deleteGroupCourse ====================
|
||||
|
||||
@Test
|
||||
void deleteGroupCourse_shouldReturnOkWhenDeleted() {
|
||||
when(groupCourseService.delete(1L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.deleteGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteGroupCourse_shouldReturnNotFound() {
|
||||
when(groupCourseService.delete(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
Mono<ServerResponse> result = handler.deleteGroupCourse(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== signIn ====================
|
||||
|
||||
@Test
|
||||
void signIn_shouldReturnOk() {
|
||||
GroupCourse course = createTestCourse(1L, "瑜伽课");
|
||||
when(validator.validate(any())).thenReturn(java.util.Collections.emptySet());
|
||||
when(groupCourseService.signIn(eq(1L), eq(10001L))).thenReturn(Mono.just(course));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("courseId", "1")
|
||||
.body(Mono.just(java.util.Map.of("memberId", 10001L, "courseId", 1L)));
|
||||
|
||||
Mono<ServerResponse> result = handler.signIn(request);
|
||||
|
||||
ServerResponse response = result.block();
|
||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private GroupCourse createTestCourse(Long id, String courseName) {
|
||||
GroupCourse course = new GroupCourse();
|
||||
course.setId(id);
|
||||
course.setCourseName(courseName);
|
||||
course.setCourseType(1L);
|
||||
course.setCoachId(1L);
|
||||
course.setStartTime(LocalDateTime.now().plusDays(1));
|
||||
course.setEndTime(LocalDateTime.now().plusDays(1).plusHours(1));
|
||||
course.setLocation("101室");
|
||||
course.setMaxMembers(20);
|
||||
course.setCurrentMembers(5);
|
||||
course.setStatus(0L);
|
||||
return course;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package cn.novalon.gym.manage.file.core.domain;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class SysFileTest {
|
||||
|
||||
@Test
|
||||
void shouldCreateSysFileWithCorrectProperties() {
|
||||
SysFile file = new SysFile();
|
||||
file.setId(1L);
|
||||
file.setFileName("test.png");
|
||||
file.setFileType("image/png");
|
||||
file.setFileSize(1024L);
|
||||
file.setFilePath("/uploads/test.png");
|
||||
file.setCreatedAt(LocalDateTime.of(2025, 1, 1, 10, 0, 0));
|
||||
|
||||
assertThat(file.getId()).isEqualTo(1L);
|
||||
assertThat(file.getFileName()).isEqualTo("test.png");
|
||||
assertThat(file.getFileType()).isEqualTo("image/png");
|
||||
assertThat(file.getFileSize()).isEqualTo(1024L);
|
||||
assertThat(file.getFilePath()).isEqualTo("/uploads/test.png");
|
||||
assertThat(file.getCreatedAt()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleNullValues() {
|
||||
SysFile file = new SysFile();
|
||||
|
||||
assertThat(file.getId()).isNull();
|
||||
assertThat(file.getFileName()).isNull();
|
||||
assertThat(file.getFileType()).isNull();
|
||||
assertThat(file.getFileSize()).isNull();
|
||||
assertThat(file.getFilePath()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSetAndGetAllProperties() {
|
||||
SysFile file = new SysFile();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
file.setId(100L);
|
||||
file.setFileName("document.pdf");
|
||||
file.setFileType("application/pdf");
|
||||
file.setFileSize(20480L);
|
||||
file.setFilePath("/files/2025/document.pdf");
|
||||
file.setCreatedAt(now);
|
||||
file.setDeletedAt(now);
|
||||
|
||||
assertThat(file.getId()).isEqualTo(100L);
|
||||
assertThat(file.getFileSize()).isEqualTo(20480L);
|
||||
assertThat(file.getDeletedAt()).isEqualTo(now);
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
package cn.novalon.gym.manage.notify.core.service.impl;
|
||||
|
||||
import cn.novalon.gym.manage.notify.core.domain.Banner;
|
||||
import cn.novalon.gym.manage.notify.core.repository.IBannerRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BannerServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private IBannerRepository bannerRepository;
|
||||
|
||||
private BannerServiceImpl bannerService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
bannerService = new BannerServiceImpl(bannerRepository);
|
||||
}
|
||||
|
||||
// ==================== getAllBanners ====================
|
||||
|
||||
@Test
|
||||
void getAllBanners_shouldReturnNonDeletedBanners() {
|
||||
Banner banner = createTestBanner(1L, "轮播图1");
|
||||
when(bannerRepository.findByDeletedAtIsNull()).thenReturn(Flux.just(banner));
|
||||
|
||||
Flux<Banner> result = bannerService.getAllBanners();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository).findByDeletedAtIsNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllBanners_shouldReturnEmptyWhenNone() {
|
||||
when(bannerRepository.findByDeletedAtIsNull()).thenReturn(Flux.empty());
|
||||
|
||||
Flux<Banner> result = bannerService.getAllBanners();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getActiveBanners ====================
|
||||
|
||||
@Test
|
||||
void getActiveBanners_shouldReturnActiveBanners() {
|
||||
when(bannerRepository.findActiveBanners()).thenReturn(Flux.just(createTestBanner(1L, "活跃")));
|
||||
|
||||
Flux<Banner> result = bannerService.getActiveBanners();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository).findActiveBanners();
|
||||
}
|
||||
|
||||
// ==================== getBannerById ====================
|
||||
|
||||
@Test
|
||||
void getBannerById_shouldReturnBannerWhenFound() {
|
||||
when(bannerRepository.findById(1L)).thenReturn(Mono.just(createTestBanner(1L, "轮播图1")));
|
||||
|
||||
Mono<Banner> result = bannerService.getBannerById(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBannerById_shouldReturnEmptyWhenNotFound() {
|
||||
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Banner> result = bannerService.getBannerById(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== createBanner ====================
|
||||
|
||||
@Test
|
||||
void createBanner_shouldSaveAndReturn() {
|
||||
Banner banner = createTestBanner(null, "新轮播图");
|
||||
when(bannerRepository.save(any(Banner.class)))
|
||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
|
||||
|
||||
Mono<Banner> result = bannerService.createBanner(banner);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(b -> b.getTitle().equals("新轮播图") && b.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository).save(banner);
|
||||
}
|
||||
|
||||
// ==================== updateBanner ====================
|
||||
|
||||
@Test
|
||||
void updateBanner_shouldUpdateAndReturn() {
|
||||
Banner existing = createTestBanner(1L, "旧标题");
|
||||
Banner update = createTestBanner(1L, "新标题");
|
||||
when(bannerRepository.findById(1L)).thenReturn(Mono.just(existing));
|
||||
when(bannerRepository.save(any(Banner.class)))
|
||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
|
||||
|
||||
Mono<Banner> result = bannerService.updateBanner(1L, update);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(b -> b.getTitle().equals("新标题") && b.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository).save(existing);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateBanner_shouldReturnEmptyWhenNotFound() {
|
||||
Banner update = createTestBanner(999L, "新标题");
|
||||
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Banner> result = bannerService.updateBanner(999L, update);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository, never()).save(any());
|
||||
}
|
||||
|
||||
// ==================== deleteBanner ====================
|
||||
|
||||
@Test
|
||||
void deleteBanner_shouldSoftDelete() {
|
||||
Banner existing = createTestBanner(1L, "轮播图1");
|
||||
when(bannerRepository.findById(1L)).thenReturn(Mono.just(existing));
|
||||
when(bannerRepository.save(any(Banner.class))).thenReturn(Mono.just(existing));
|
||||
|
||||
Mono<Void> result = bannerService.deleteBanner(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(bannerRepository).save(existing);
|
||||
assertThat(existing.getDeletedAt()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteBanner_shouldCompleteEmptyWhenNotFound() {
|
||||
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Void> result = bannerService.deleteBanner(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private Banner createTestBanner(Long id, String title) {
|
||||
Banner banner = new Banner();
|
||||
banner.setId(id);
|
||||
banner.setImageUrl("https://example.com/banner.jpg");
|
||||
banner.setTitle(title);
|
||||
banner.setSubtitle("副标题");
|
||||
banner.setSortOrder(1);
|
||||
banner.setIsActive("1");
|
||||
banner.setCreatedAt(LocalDateTime.now());
|
||||
return banner;
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
package cn.novalon.gym.manage.notify.core.service.impl;
|
||||
|
||||
import cn.novalon.gym.manage.notify.core.domain.SysNotice;
|
||||
import cn.novalon.gym.manage.notify.core.repository.ISysNoticeRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SysNoticeServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ISysNoticeRepository noticeRepository;
|
||||
|
||||
private SysNoticeServiceImpl noticeService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
noticeService = new SysNoticeServiceImpl(noticeRepository);
|
||||
}
|
||||
|
||||
// ==================== getAllNotices ====================
|
||||
|
||||
@Test
|
||||
void getAllNotices_shouldReturnNonDeletedNotices() {
|
||||
SysNotice notice = createTestNotice(1L, "公告1");
|
||||
when(noticeRepository.findByDeletedAtIsNull()).thenReturn(Flux.just(notice));
|
||||
|
||||
Flux<SysNotice> result = noticeService.getAllNotices();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(n -> n.getId().equals(1L) && n.getNoticeTitle().equals("公告1"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository).findByDeletedAtIsNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllNotices_shouldReturnEmptyWhenNone() {
|
||||
when(noticeRepository.findByDeletedAtIsNull()).thenReturn(Flux.empty());
|
||||
|
||||
Flux<SysNotice> result = noticeService.getAllNotices();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getNoticeById ====================
|
||||
|
||||
@Test
|
||||
void getNoticeById_shouldReturnNoticeWhenFound() {
|
||||
SysNotice notice = createTestNotice(1L, "公告1");
|
||||
when(noticeRepository.findById(1L)).thenReturn(Mono.just(notice));
|
||||
|
||||
Mono<SysNotice> result = noticeService.getNoticeById(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(n -> n.getId().equals(1L))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getNoticeById_shouldReturnEmptyWhenNotFound() {
|
||||
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<SysNotice> result = noticeService.getNoticeById(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== createNotice ====================
|
||||
|
||||
@Test
|
||||
void createNotice_shouldSaveAndReturnNotice() {
|
||||
SysNotice notice = createTestNotice(null, "新公告");
|
||||
when(noticeRepository.save(any(SysNotice.class)))
|
||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
|
||||
|
||||
Mono<SysNotice> result = noticeService.createNotice(notice);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(n -> n.getNoticeTitle().equals("新公告"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository).save(notice);
|
||||
}
|
||||
|
||||
// ==================== updateNotice ====================
|
||||
|
||||
@Test
|
||||
void updateNotice_shouldUpdateAndReturn() {
|
||||
SysNotice existing = createTestNotice(1L, "旧标题");
|
||||
SysNotice update = createTestNotice(1L, "新标题");
|
||||
when(noticeRepository.findById(1L)).thenReturn(Mono.just(existing));
|
||||
when(noticeRepository.save(any(SysNotice.class)))
|
||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
|
||||
|
||||
Mono<SysNotice> result = noticeService.updateNotice(1L, update);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(n -> n.getNoticeTitle().equals("新标题"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository).save(existing);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateNotice_shouldReturnEmptyWhenNotFound() {
|
||||
SysNotice update = createTestNotice(999L, "新标题");
|
||||
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<SysNotice> result = noticeService.updateNotice(999L, update);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository, never()).save(any());
|
||||
}
|
||||
|
||||
// ==================== deleteNotice ====================
|
||||
|
||||
@Test
|
||||
void deleteNotice_shouldSoftDelete() {
|
||||
SysNotice existing = createTestNotice(1L, "公告1");
|
||||
when(noticeRepository.findById(1L)).thenReturn(Mono.just(existing));
|
||||
when(noticeRepository.save(any(SysNotice.class))).thenReturn(Mono.just(existing));
|
||||
|
||||
Mono<Void> result = noticeService.deleteNotice(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository).save(existing);
|
||||
assertThat(existing.getDeletedAt()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteNotice_shouldCompleteEmptyWhenNotFound() {
|
||||
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Void> result = noticeService.deleteNotice(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(noticeRepository, never()).save(any());
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private SysNotice createTestNotice(Long id, String title) {
|
||||
SysNotice notice = new SysNotice();
|
||||
notice.setId(id);
|
||||
notice.setNoticeTitle(title);
|
||||
notice.setNoticeContent("公告内容");
|
||||
notice.setNoticeType("1");
|
||||
notice.setStatus("1");
|
||||
return notice;
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
package cn.novalon.gym.manage.notify.core.service.impl;
|
||||
|
||||
import cn.novalon.gym.manage.notify.core.domain.SysUserMessage;
|
||||
import cn.novalon.gym.manage.notify.core.repository.ISysUserMessageRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SysUserMessageServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ISysUserMessageRepository messageRepository;
|
||||
|
||||
private SysUserMessageServiceImpl messageService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
messageService = new SysUserMessageServiceImpl(messageRepository);
|
||||
}
|
||||
|
||||
// ==================== getMessagesByUser ====================
|
||||
|
||||
@Test
|
||||
void getMessagesByUser_shouldReturnMessages() {
|
||||
List<SysUserMessage> messages = List.of(createTestMessage(1L, 1L, "消息1"), createTestMessage(2L, 1L, "消息2"));
|
||||
when(messageRepository.findByUserIdOrderByCreateTimeDesc(1L)).thenReturn(Flux.fromIterable(messages));
|
||||
|
||||
Flux<SysUserMessage> result = messageService.getMessagesByUser(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(2)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMessagesByUser_shouldReturnEmptyWhenNone() {
|
||||
when(messageRepository.findByUserIdOrderByCreateTimeDesc(999L)).thenReturn(Flux.empty());
|
||||
|
||||
Flux<SysUserMessage> result = messageService.getMessagesByUser(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getUnreadCount ====================
|
||||
|
||||
@Test
|
||||
void getUnreadCount_shouldReturnCount() {
|
||||
when(messageRepository.countByUserIdAndIsRead(1L, "0")).thenReturn(Mono.just(5L));
|
||||
|
||||
Mono<Long> result = messageService.getUnreadCount(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext(5L)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUnreadCount_shouldReturnZero() {
|
||||
when(messageRepository.countByUserIdAndIsRead(1L, "0")).thenReturn(Mono.just(0L));
|
||||
|
||||
Mono<Long> result = messageService.getUnreadCount(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext(0L)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getUnreadMessages ====================
|
||||
|
||||
@Test
|
||||
void getUnreadMessages_shouldReturnUnreadOnly() {
|
||||
when(messageRepository.findByUserIdAndIsReadOrderByCreateTimeDesc(1L, "0"))
|
||||
.thenReturn(Flux.just(createTestMessage(1L, 1L, "未读消息")));
|
||||
|
||||
Flux<SysUserMessage> result = messageService.getUnreadMessages(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== createMessage ====================
|
||||
|
||||
@Test
|
||||
void createMessage_shouldSaveAndReturn() {
|
||||
SysUserMessage message = createTestMessage(null, 1L, "新消息");
|
||||
when(messageRepository.save(any(SysUserMessage.class)))
|
||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
|
||||
|
||||
Mono<SysUserMessage> result = messageService.createMessage(message);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(m -> m.getTitle().equals("新消息"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(messageRepository).save(message);
|
||||
}
|
||||
|
||||
// ==================== markAsRead ====================
|
||||
|
||||
@Test
|
||||
void markAsRead_shouldUpdateAndReturnMessage() {
|
||||
SysUserMessage existing = createTestMessage(1L, 1L, "消息");
|
||||
when(messageRepository.findById(1L)).thenReturn(Mono.just(existing));
|
||||
when(messageRepository.save(any(SysUserMessage.class))).thenReturn(Mono.just(existing));
|
||||
|
||||
Mono<SysUserMessage> result = messageService.markAsRead(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(m -> m.getIsRead().equals("1"))
|
||||
.verifyComplete();
|
||||
|
||||
verify(messageRepository).save(existing);
|
||||
assertThat(existing.getIsRead()).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void markAsRead_shouldReturnEmptyWhenNotFound() {
|
||||
when(messageRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<SysUserMessage> result = messageService.markAsRead(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(messageRepository, never()).save(any());
|
||||
}
|
||||
|
||||
// ==================== markAllAsRead ====================
|
||||
|
||||
@Test
|
||||
void markAllAsRead_shouldReturnCount() {
|
||||
when(messageRepository.markAllAsReadByUserId(1L)).thenReturn(Mono.just(2L));
|
||||
|
||||
Mono<Long> result = messageService.markAllAsRead(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext(2L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(messageRepository).markAllAsReadByUserId(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void markAllAsRead_shouldReturnZeroWhenNoUnread() {
|
||||
when(messageRepository.markAllAsReadByUserId(1L)).thenReturn(Mono.just(0L));
|
||||
|
||||
Mono<Long> result = messageService.markAllAsRead(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNext(0L)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== deleteMessage ====================
|
||||
|
||||
@Test
|
||||
void deleteMessage_shouldDelete() {
|
||||
when(messageRepository.deleteById(1L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Void> result = messageService.deleteMessage(1L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(messageRepository).deleteById(1L);
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private SysUserMessage createTestMessage(Long id, Long userId, String title) {
|
||||
SysUserMessage message = new SysUserMessage();
|
||||
message.setId(id);
|
||||
message.setUserId(userId);
|
||||
message.setTitle(title);
|
||||
message.setContent("测试内容");
|
||||
message.setIsRead("0");
|
||||
message.setCreateTime(LocalDateTime.now());
|
||||
return message;
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
package cn.novalon.gym.manage.notify.handler;
|
||||
|
||||
import cn.novalon.gym.manage.notify.core.domain.Banner;
|
||||
import cn.novalon.gym.manage.notify.core.service.IBannerService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BannerHandlerTest {
|
||||
|
||||
@Mock
|
||||
private IBannerService bannerService;
|
||||
|
||||
private BannerHandler bannerHandler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
bannerHandler = new BannerHandler(bannerService);
|
||||
}
|
||||
|
||||
// ==================== getAllBanners ====================
|
||||
|
||||
@Test
|
||||
void getAllBanners_shouldReturnOkWithBanners() {
|
||||
List<Banner> banners = List.of(createTestBanner(1L, "轮播图1"), createTestBanner(2L, "轮播图2"));
|
||||
when(bannerService.getAllBanners()).thenReturn(Flux.fromIterable(banners));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.getAllBanners(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllBanners_shouldReturnOkWhenEmpty() {
|
||||
when(bannerService.getAllBanners()).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.getAllBanners(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getActiveBanners ====================
|
||||
|
||||
@Test
|
||||
void getActiveBanners_shouldReturnOkWithActiveBanners() {
|
||||
when(bannerService.getActiveBanners()).thenReturn(Flux.just(createTestBanner(1L, "活跃轮播图")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder().build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.getActiveBanners(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getBannerById ====================
|
||||
|
||||
@Test
|
||||
void getBannerById_shouldReturnOkWhenFound() {
|
||||
when(bannerService.getBannerById(1L)).thenReturn(Mono.just(createTestBanner(1L, "轮播图1")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.getBannerById(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBannerById_shouldReturnNotFound() {
|
||||
when(bannerService.getBannerById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.getBannerById(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== createBanner ====================
|
||||
|
||||
@Test
|
||||
void createBanner_shouldReturnOkWhenCreated() {
|
||||
Map<String, Object> body = Map.of(
|
||||
"imageUrl", "https://example.com/banner.jpg",
|
||||
"title", "新轮播图",
|
||||
"subtitle", "副标题",
|
||||
"sortOrder", 1,
|
||||
"isActive", true
|
||||
);
|
||||
when(bannerService.createBanner(any(Banner.class))).thenReturn(Mono.just(createTestBanner(1L, "新轮播图")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(body));
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.createBanner(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== updateBanner ====================
|
||||
|
||||
@Test
|
||||
void updateBanner_shouldReturnOkWhenUpdated() {
|
||||
Map<String, Object> body = Map.of("title", "更新标题");
|
||||
when(bannerService.updateBanner(eq(1L), any(Banner.class))).thenReturn(Mono.just(createTestBanner(1L, "更新标题")));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.body(Mono.just(body));
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.updateBanner(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateBanner_shouldReturnNotFound() {
|
||||
Map<String, Object> body = Map.of("title", "更新标题");
|
||||
when(bannerService.updateBanner(eq(999L), any(Banner.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.body(Mono.just(body));
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.updateBanner(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== deleteBanner ====================
|
||||
|
||||
@Test
|
||||
void deleteBanner_shouldReturnNoContent() {
|
||||
Banner banner = createTestBanner(1L, "轮播图1");
|
||||
banner.setDeletedAt(null);
|
||||
when(bannerService.getBannerById(1L)).thenReturn(Mono.just(banner));
|
||||
when(bannerService.deleteBanner(1L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.deleteBanner(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteBanner_shouldReturnNotFound() {
|
||||
when(bannerService.getBannerById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = bannerHandler.deleteBanner(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private Banner createTestBanner(Long id, String title) {
|
||||
Banner banner = new Banner();
|
||||
banner.setId(id);
|
||||
banner.setImageUrl("https://example.com/banner-" + id + ".jpg");
|
||||
banner.setTitle(title);
|
||||
banner.setSubtitle("副标题");
|
||||
banner.setSortOrder(id.intValue());
|
||||
banner.setIsActive("1");
|
||||
banner.setCreatedAt(LocalDateTime.now());
|
||||
return banner;
|
||||
}
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
package cn.novalon.gym.manage.notify.handler;
|
||||
|
||||
import cn.novalon.gym.manage.notify.core.domain.SysUserMessage;
|
||||
import cn.novalon.gym.manage.notify.core.service.ISysUserMessageService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SysUserMessageHandlerTest {
|
||||
|
||||
@Mock
|
||||
private ISysUserMessageService messageService;
|
||||
|
||||
private SysUserMessageHandler handler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
handler = new SysUserMessageHandler(messageService);
|
||||
}
|
||||
|
||||
// ==================== getMessagesByUser ====================
|
||||
|
||||
@Test
|
||||
void getMessagesByUser_shouldReturnOkWithMessages() {
|
||||
List<SysUserMessage> messages = List.of(createTestMessage(1L, "消息1"), createTestMessage(2L, "消息2"));
|
||||
when(messageService.getMessagesByUser(anyLong())).thenReturn(Flux.fromIterable(messages));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getMessagesByUser(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMessagesByUser_shouldReturnEmptyListWhenNone() {
|
||||
when(messageService.getMessagesByUser(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getMessagesByUser(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getUnreadCount ====================
|
||||
|
||||
@Test
|
||||
void getUnreadCount_shouldReturnOkWithCount() {
|
||||
when(messageService.getUnreadCount(anyLong())).thenReturn(Mono.just(5L));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getUnreadCount(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUnreadCount_shouldReturnZero() {
|
||||
when(messageService.getUnreadCount(anyLong())).thenReturn(Mono.just(0L));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getUnreadCount(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== getUnreadList ====================
|
||||
|
||||
@Test
|
||||
void getUnreadList_shouldReturnOk() {
|
||||
when(messageService.getUnreadMessages(anyLong())).thenReturn(Flux.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.getUnreadList(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== createMessage ====================
|
||||
|
||||
@Test
|
||||
void createMessage_shouldReturnCreated() {
|
||||
SysUserMessage message = createTestMessage(1L, "新消息");
|
||||
when(messageService.createMessage(any(SysUserMessage.class))).thenReturn(Mono.just(message));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.body(Mono.just(message));
|
||||
|
||||
Mono<ServerResponse> result = handler.createMessage(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== markAsRead ====================
|
||||
|
||||
@Test
|
||||
void markAsRead_shouldReturnOk() {
|
||||
SysUserMessage message = createTestMessage(1L, "消息");
|
||||
when(messageService.markAsRead(anyLong())).thenReturn(Mono.just(message));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.markAsRead(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void markAsRead_shouldReturnNotFound() {
|
||||
when(messageService.markAsRead(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.markAsRead(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== markAllAsRead ====================
|
||||
|
||||
@Test
|
||||
void markAllAsRead_shouldReturnOk() {
|
||||
when(messageService.markAllAsRead(anyLong())).thenReturn(Mono.just(3L));
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("userId", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.markAllAsRead(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== deleteMessage ====================
|
||||
|
||||
@Test
|
||||
void deleteMessage_shouldReturnOk() {
|
||||
when(messageService.deleteMessage(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "1")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.deleteMessage(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteMessage_shouldReturnNotFound() {
|
||||
when(messageService.deleteMessage(anyLong())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.pathVariable("id", "999")
|
||||
.build();
|
||||
|
||||
Mono<ServerResponse> result = handler.deleteMessage(request);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
// ==================== helper ====================
|
||||
|
||||
private SysUserMessage createTestMessage(Long id, String title) {
|
||||
SysUserMessage message = new SysUserMessage();
|
||||
message.setId(id);
|
||||
message.setUserId(1L);
|
||||
message.setTitle(title);
|
||||
message.setContent("测试内容-" + id);
|
||||
message.setIsRead("0");
|
||||
return message;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user