feat: extend operation log service and repository with pagination support
This commit is contained in:
@@ -58,6 +58,34 @@
|
||||
<artifactId>resilience4j-reactor</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>1.19.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>1.19.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>1.19.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.r2dbc</groupId>
|
||||
<artifactId>r2dbc-h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+4
@@ -1,5 +1,7 @@
|
||||
package cn.novalon.manage.sys.core.repository;
|
||||
|
||||
import cn.novalon.manage.common.dto.PageRequest;
|
||||
import cn.novalon.manage.common.dto.PageResponse;
|
||||
import cn.novalon.manage.sys.core.domain.OperationLog;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -24,6 +26,8 @@ public interface IOperationLogRepository {
|
||||
|
||||
Flux<OperationLog> findByUsername(String username);
|
||||
|
||||
Mono<PageResponse<OperationLog>> findOperationLogsByPage(PageRequest pageRequest);
|
||||
|
||||
Mono<Long> count();
|
||||
|
||||
Mono<Long> countByCreatedAtAfter(LocalDateTime dateTime);
|
||||
|
||||
+4
@@ -1,5 +1,7 @@
|
||||
package cn.novalon.manage.sys.core.service;
|
||||
|
||||
import cn.novalon.manage.common.dto.PageRequest;
|
||||
import cn.novalon.manage.common.dto.PageResponse;
|
||||
import cn.novalon.manage.sys.core.domain.OperationLog;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -13,7 +15,9 @@ import reactor.core.publisher.Mono;
|
||||
public interface IOperationLogService {
|
||||
Mono<OperationLog> save(OperationLog log);
|
||||
Flux<OperationLog> findAll();
|
||||
Mono<OperationLog> findById(Long id);
|
||||
Flux<OperationLog> findByUsername(String username);
|
||||
Mono<PageResponse<OperationLog>> findOperationLogsByPage(PageRequest pageRequest);
|
||||
Mono<Long> count();
|
||||
Mono<Long> countToday();
|
||||
}
|
||||
|
||||
+12
@@ -1,5 +1,7 @@
|
||||
package cn.novalon.manage.sys.core.service.impl;
|
||||
|
||||
import cn.novalon.manage.common.dto.PageRequest;
|
||||
import cn.novalon.manage.common.dto.PageResponse;
|
||||
import cn.novalon.manage.sys.core.domain.OperationLog;
|
||||
import cn.novalon.manage.sys.core.repository.IOperationLogRepository;
|
||||
import cn.novalon.manage.sys.core.service.IOperationLogService;
|
||||
@@ -35,11 +37,21 @@ public class OperationLogService implements IOperationLogService {
|
||||
return logRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<OperationLog> findById(Long id) {
|
||||
return logRepository.findById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<OperationLog> findByUsername(String username) {
|
||||
return logRepository.findByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<PageResponse<OperationLog>> findOperationLogsByPage(PageRequest pageRequest) {
|
||||
return logRepository.findOperationLogsByPage(pageRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Long> count() {
|
||||
return logRepository.count();
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package cn.novalon.manage.sys.handler.log;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.OperationLog;
|
||||
import cn.novalon.manage.sys.core.service.IOperationLogService;
|
||||
import cn.novalon.manage.common.dto.PageRequest;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 操作日志处理器
|
||||
*
|
||||
* 文件定义:处理操作日志相关的HTTP请求
|
||||
* 涉及业务:操作日志查询、分页、统计
|
||||
* 算法:使用WebFlux函数式编程模型处理响应式请求
|
||||
*
|
||||
* @author 张翔
|
||||
* @date 2026-03-18
|
||||
*/
|
||||
@Component
|
||||
@Tag(name = "操作日志", description = "操作日志相关操作")
|
||||
public class OperationLogHandler {
|
||||
|
||||
private final IOperationLogService logService;
|
||||
|
||||
public OperationLogHandler(IOperationLogService logService) {
|
||||
this.logService = logService;
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有操作日志", description = "获取系统中所有操作日志列表")
|
||||
public Mono<ServerResponse> getAllOperationLogs(ServerRequest request) {
|
||||
return ServerResponse.ok()
|
||||
.body(logService.findAll(), OperationLog.class);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据ID获取操作日志", description = "根据操作日志ID获取详细信息")
|
||||
public Mono<ServerResponse> getOperationLogById(ServerRequest request) {
|
||||
Long id = Long.valueOf(request.pathVariable("id"));
|
||||
return logService.findById(id)
|
||||
.flatMap(log -> ServerResponse.ok().bodyValue(log))
|
||||
.switchIfEmpty(ServerResponse.notFound().build());
|
||||
}
|
||||
|
||||
@Operation(summary = "分页获取操作日志", description = "根据分页参数获取操作日志列表")
|
||||
public Mono<ServerResponse> getOperationLogsByPage(ServerRequest request) {
|
||||
int page = Integer.parseInt(request.queryParam("page").orElse("0"));
|
||||
int size = Integer.parseInt(request.queryParam("size").orElse("10"));
|
||||
String sort = request.queryParam("sort").orElse("created_at");
|
||||
String order = request.queryParam("order").orElse("desc");
|
||||
String keyword = request.queryParam("keyword").orElse(null);
|
||||
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(page);
|
||||
pageRequest.setSize(size);
|
||||
pageRequest.setSort(sort);
|
||||
pageRequest.setOrder(order);
|
||||
pageRequest.setKeyword(keyword);
|
||||
|
||||
return logService.findOperationLogsByPage(pageRequest)
|
||||
.flatMap(response -> ServerResponse.ok().bodyValue(response));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取操作日志总数", description = "获取系统中操作日志总数")
|
||||
public Mono<ServerResponse> getOperationLogCount(ServerRequest request) {
|
||||
return logService.count()
|
||||
.flatMap(count -> ServerResponse.ok().bodyValue(count));
|
||||
}
|
||||
|
||||
@Operation(summary = "创建操作日志", description = "手动创建操作日志")
|
||||
public Mono<ServerResponse> createOperationLog(ServerRequest request) {
|
||||
return request.bodyToMono(OperationLog.class)
|
||||
.flatMap(logService::save)
|
||||
.flatMap(log -> ServerResponse.status(HttpStatus.CREATED).bodyValue(log));
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
cn.novalon.manage.sys.config.SecurityConfig
|
||||
cn.novalon.manage.sys.config.ExceptionLogConfig
|
||||
@@ -1,68 +0,0 @@
|
||||
server:
|
||||
port: 8084
|
||||
netty:
|
||||
connection-timeout: 60s
|
||||
idle-timeout: 300s
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: novalon-manage-api
|
||||
servlet:
|
||||
multipart:
|
||||
enabled: true
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:55432/manage_system
|
||||
username: postgres
|
||||
password: postgres
|
||||
driver-class-name: org.postgresql.Driver
|
||||
r2dbc:
|
||||
url: r2dbc:pool:postgresql://localhost:55432/manage_system
|
||||
username: postgres
|
||||
password: postgres
|
||||
flyway:
|
||||
enabled: true
|
||||
url: jdbc:postgresql://localhost:55432/manage_system
|
||||
user: postgres
|
||||
password: postgres
|
||||
locations: classpath:db/migration
|
||||
baseline-on-migrate: true
|
||||
|
||||
jwt:
|
||||
secret: novalon-manage-secret-key-change-in-production
|
||||
expiration: 86400000
|
||||
|
||||
websocket:
|
||||
enabled: true
|
||||
heartbeat-interval: 30s
|
||||
idle-timeout: 300s
|
||||
max-text-message-buffer-size: 8192
|
||||
max-binary-message-buffer-size: 8192
|
||||
|
||||
resilience4j:
|
||||
ratelimiter:
|
||||
instances:
|
||||
apiRateLimiter:
|
||||
limit-for-period: 100
|
||||
limit-refresh-period: 1s
|
||||
timeout-duration: 0
|
||||
|
||||
logging:
|
||||
level:
|
||||
cn.novalon.manage: DEBUG
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
metrics:
|
||||
access: read-only
|
||||
prometheus:
|
||||
metrics:
|
||||
export:
|
||||
enabled: true
|
||||
-209
@@ -1,209 +0,0 @@
|
||||
-- Novalon管理系统数据库初始化脚本
|
||||
-- 版本: V1
|
||||
-- 描述: 创建所有核心表
|
||||
|
||||
-- 用户表
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(100),
|
||||
phone VARCHAR(20),
|
||||
role_id BIGINT,
|
||||
status INTEGER DEFAULT 1,
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 角色表
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
role_name VARCHAR(100) NOT NULL,
|
||||
role_key VARCHAR(100) NOT NULL UNIQUE,
|
||||
role_sort INTEGER DEFAULT 0,
|
||||
status INTEGER DEFAULT 1,
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 菜单表
|
||||
CREATE TABLE IF NOT EXISTS menus (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
menu_name VARCHAR(50) NOT NULL,
|
||||
parent_id BIGINT DEFAULT 0,
|
||||
order_num INTEGER DEFAULT 0,
|
||||
menu_type VARCHAR(1) DEFAULT 'C',
|
||||
perms VARCHAR(100),
|
||||
component VARCHAR(200),
|
||||
status INTEGER DEFAULT 1,
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 字典类型表
|
||||
CREATE TABLE IF NOT EXISTS sys_dict_type (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dict_name VARCHAR(100) NOT NULL,
|
||||
dict_type VARCHAR(100) NOT NULL UNIQUE,
|
||||
status VARCHAR(1) DEFAULT '0',
|
||||
remark VARCHAR(500),
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 字典数据表
|
||||
CREATE TABLE IF NOT EXISTS sys_dict_data (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
dict_sort INTEGER DEFAULT 0,
|
||||
dict_label VARCHAR(100) NOT NULL,
|
||||
dict_value VARCHAR(100) NOT NULL,
|
||||
dict_type VARCHAR(100) NOT NULL,
|
||||
css_class VARCHAR(100),
|
||||
list_class VARCHAR(100),
|
||||
is_default VARCHAR(1) DEFAULT 'N',
|
||||
status VARCHAR(1) DEFAULT '0',
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 系统配置表
|
||||
CREATE TABLE IF NOT EXISTS sys_config (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
config_name VARCHAR(100) NOT NULL,
|
||||
config_key VARCHAR(100) NOT NULL UNIQUE,
|
||||
config_value VARCHAR(500) NOT NULL,
|
||||
config_type VARCHAR(1) DEFAULT 'N',
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 登录日志表
|
||||
CREATE TABLE IF NOT EXISTS sys_login_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username VARCHAR(50),
|
||||
ip VARCHAR(50),
|
||||
location VARCHAR(255),
|
||||
browser VARCHAR(50),
|
||||
os VARCHAR(50),
|
||||
status VARCHAR(1),
|
||||
message VARCHAR(255),
|
||||
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 异常日志表
|
||||
CREATE TABLE IF NOT EXISTS sys_exception_log (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username VARCHAR(50),
|
||||
ip VARCHAR(50),
|
||||
location VARCHAR(255),
|
||||
browser VARCHAR(50),
|
||||
os VARCHAR(50),
|
||||
status VARCHAR(1),
|
||||
message VARCHAR(255),
|
||||
exception_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 系统公告表
|
||||
CREATE TABLE IF NOT EXISTS sys_notice (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
notice_title VARCHAR(50) NOT NULL,
|
||||
notice_type VARCHAR(1) NOT NULL,
|
||||
notice_content TEXT,
|
||||
status VARCHAR(1) DEFAULT '0',
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 用户消息表
|
||||
CREATE TABLE IF NOT EXISTS sys_user_message (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL,
|
||||
notice_id BIGINT,
|
||||
message_title VARCHAR(255),
|
||||
message_content TEXT,
|
||||
is_read VARCHAR(1) DEFAULT '0',
|
||||
read_time TIMESTAMP,
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 文件管理表
|
||||
CREATE TABLE IF NOT EXISTS sys_file (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
file_name VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
file_size BIGINT,
|
||||
file_type VARCHAR(100),
|
||||
file_extension VARCHAR(10),
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- OAuth2客户端表
|
||||
CREATE TABLE IF NOT EXISTS oauth2_client (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
client_id VARCHAR(100) NOT NULL UNIQUE,
|
||||
client_secret VARCHAR(255) NOT NULL,
|
||||
client_name VARCHAR(100),
|
||||
web_server_redirect_uri VARCHAR(500),
|
||||
scope VARCHAR(500),
|
||||
authorized_grant_types VARCHAR(500),
|
||||
access_token_validity_seconds INTEGER,
|
||||
refresh_token_validity_seconds INTEGER,
|
||||
auto_approve VARCHAR(1) DEFAULT 'false',
|
||||
enabled VARCHAR(1) DEFAULT 'true',
|
||||
create_by VARCHAR(50),
|
||||
update_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 插入初始管理员用户
|
||||
INSERT INTO users (username, password, email, role_id, status, create_by, update_by)
|
||||
VALUES ('admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi', 'admin@novalon.com', 1, 1, 'system', 'system')
|
||||
ON CONFLICT (username) DO NOTHING;
|
||||
|
||||
-- 插入初始角色
|
||||
INSERT INTO roles (role_name, role_key, role_sort, status, create_by, update_by)
|
||||
VALUES ('超级管理员', 'admin', 1, 1, 'system', 'system')
|
||||
ON CONFLICT (role_key) DO NOTHING;
|
||||
|
||||
-- 插入初始字典类型
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, remark, create_by, update_by)
|
||||
VALUES ('用户状态', 'user_status', '0', '用户状态列表', 'system', 'system')
|
||||
ON CONFLICT (dict_type) DO NOTHING;
|
||||
|
||||
-- 插入初始字典数据
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, status, create_by, update_by)
|
||||
VALUES
|
||||
(1, '正常', '1', 'user_status', '0', 'system', 'system'),
|
||||
(2, '停用', '0', 'user_status', '0', 'system', 'system')
|
||||
ON CONFLICT DO NOTHING;
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
-- 创建字典表
|
||||
CREATE TABLE IF NOT EXISTS sys_dictionary (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
type VARCHAR(100) NOT NULL,
|
||||
code VARCHAR(100) NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
value VARCHAR(500),
|
||||
remark VARCHAR(500),
|
||||
sort INTEGER DEFAULT 0,
|
||||
create_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_dictionary_type ON sys_dictionary(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_dictionary_type_code ON sys_dictionary(type, code);
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import cn.novalon.manage.common.handler.ExceptionLogService;
|
||||
import cn.novalon.manage.sys.handler.ExceptionLogServiceImpl;
|
||||
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 static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ExceptionLogConfigTest {
|
||||
|
||||
@Mock
|
||||
private ExceptionLogServiceImpl exceptionLogServiceImpl;
|
||||
|
||||
private ExceptionLogConfig exceptionLogConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
exceptionLogConfig = new ExceptionLogConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceptionLogService() {
|
||||
ExceptionLogService exceptionLogService = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
|
||||
|
||||
assertThat(exceptionLogService).isNotNull();
|
||||
assertThat(exceptionLogService).isSameAs(exceptionLogServiceImpl);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExceptionLogService_DifferentInstance() {
|
||||
ExceptionLogService exceptionLogService1 = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
|
||||
ExceptionLogService exceptionLogService2 = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
|
||||
|
||||
assertThat(exceptionLogService1).isNotNull();
|
||||
assertThat(exceptionLogService2).isNotNull();
|
||||
assertThat(exceptionLogService1).isSameAs(exceptionLogServiceImpl);
|
||||
assertThat(exceptionLogService2).isSameAs(exceptionLogServiceImpl);
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import cn.novalon.manage.sys.security.JwtAuthenticationFilter;
|
||||
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.HttpMethod;
|
||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SecurityConfigTest {
|
||||
|
||||
@Mock
|
||||
private JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
private SecurityConfig securityConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
securityConfig = new SecurityConfig(jwtAuthenticationFilter);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPasswordEncoder() {
|
||||
PasswordEncoder passwordEncoder = securityConfig.passwordEncoder();
|
||||
|
||||
assertThat(passwordEncoder).isNotNull();
|
||||
assertThat(passwordEncoder).isInstanceOf(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.class);
|
||||
|
||||
String rawPassword = "testPassword123";
|
||||
String encodedPassword = passwordEncoder.encode(rawPassword);
|
||||
|
||||
assertThat(encodedPassword).isNotNull();
|
||||
assertThat(encodedPassword).isNotEqualTo(rawPassword);
|
||||
assertThat(passwordEncoder.matches(rawPassword, encodedPassword)).isTrue();
|
||||
assertThat(passwordEncoder.matches("wrongPassword", encodedPassword)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPasswordEncoder_SamePasswordDifferentHashes() {
|
||||
PasswordEncoder passwordEncoder = securityConfig.passwordEncoder();
|
||||
|
||||
String rawPassword = "testPassword123";
|
||||
String hash1 = passwordEncoder.encode(rawPassword);
|
||||
String hash2 = passwordEncoder.encode(rawPassword);
|
||||
|
||||
assertThat(hash1).isNotEqualTo(hash2);
|
||||
assertThat(passwordEncoder.matches(rawPassword, hash1)).isTrue();
|
||||
assertThat(passwordEncoder.matches(rawPassword, hash2)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPasswordEncoder_EmptyPassword() {
|
||||
PasswordEncoder passwordEncoder = securityConfig.passwordEncoder();
|
||||
|
||||
String encodedPassword = passwordEncoder.encode("");
|
||||
|
||||
assertThat(encodedPassword).isNotNull();
|
||||
assertThat(passwordEncoder.matches("", encodedPassword)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPasswordEncoder_Strength() {
|
||||
PasswordEncoder passwordEncoder = securityConfig.passwordEncoder();
|
||||
|
||||
String rawPassword = "testPassword123";
|
||||
String encodedPassword = passwordEncoder.encode(rawPassword);
|
||||
|
||||
assertThat(encodedPassword.length()).isGreaterThan(50);
|
||||
assertThat(encodedPassword.startsWith("$2a$")).isTrue();
|
||||
}
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
package cn.novalon.manage.sys.core.query;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SysRoleQueryTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("admin");
|
||||
query.setRoleKey("admin");
|
||||
query.setStatus(1);
|
||||
query.setKeyword("admin");
|
||||
|
||||
assertEquals("admin", query.getRoleName());
|
||||
assertEquals("admin", query.getRoleKey());
|
||||
assertEquals(1, query.getStatus());
|
||||
assertEquals("admin", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName(null);
|
||||
query.setRoleKey(null);
|
||||
query.setStatus(null);
|
||||
query.setKeyword(null);
|
||||
|
||||
assertNull(query.getRoleName());
|
||||
assertNull(query.getRoleKey());
|
||||
assertNull(query.getStatus());
|
||||
assertNull(query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyStringValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("");
|
||||
query.setRoleKey("");
|
||||
query.setKeyword("");
|
||||
|
||||
assertEquals("", query.getRoleName());
|
||||
assertEquals("", query.getRoleKey());
|
||||
assertEquals("", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetMultipleValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("user");
|
||||
query.setRoleKey("user");
|
||||
query.setStatus(0);
|
||||
query.setKeyword("user");
|
||||
|
||||
assertEquals("user", query.getRoleName());
|
||||
assertEquals("user", query.getRoleKey());
|
||||
assertEquals(0, query.getStatus());
|
||||
assertEquals("user", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongRoleName() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
String longRoleName = "a".repeat(100);
|
||||
query.setRoleName(longRoleName);
|
||||
assertEquals(longRoleName, query.getRoleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongRoleKey() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
String longRoleKey = "a".repeat(100);
|
||||
query.setRoleKey(longRoleKey);
|
||||
assertEquals(longRoleKey, query.getRoleKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongKeyword() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
String longKeyword = "a".repeat(100);
|
||||
query.setKeyword(longKeyword);
|
||||
assertEquals(longKeyword, query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNegativeStatus() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setStatus(-1);
|
||||
assertEquals(-1, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetZeroStatus() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setStatus(0);
|
||||
assertEquals(0, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPositiveStatus() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setStatus(1);
|
||||
assertEquals(1, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInRoleName() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setRoleName("role@#$%");
|
||||
assertEquals("role@#$%", query.getRoleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInRoleKey() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setRoleKey("role@#$%");
|
||||
assertEquals("role@#$%", query.getRoleKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInKeyword() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setKeyword("keyword@#$%");
|
||||
assertEquals("keyword@#$%", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetWhitespaceInValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName(" test role ");
|
||||
query.setRoleKey(" test key ");
|
||||
query.setKeyword(" test keyword ");
|
||||
|
||||
assertEquals(" test role ", query.getRoleName());
|
||||
assertEquals(" test key ", query.getRoleKey());
|
||||
assertEquals(" test keyword ", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetUnicodeCharacters() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("角色名");
|
||||
query.setRoleKey("角色键");
|
||||
query.setKeyword("关键词");
|
||||
|
||||
assertEquals("角色名", query.getRoleName());
|
||||
assertEquals("角色键", query.getRoleKey());
|
||||
assertEquals("关键词", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNumbersInRoleName() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setRoleName("role123");
|
||||
assertEquals("role123", query.getRoleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNumbersInRoleKey() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
query.setRoleKey("role123");
|
||||
assertEquals("role123", query.getRoleKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetUnderscoreInValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("test_role");
|
||||
query.setRoleKey("test_role");
|
||||
query.setKeyword("test_keyword");
|
||||
|
||||
assertEquals("test_role", query.getRoleName());
|
||||
assertEquals("test_role", query.getRoleKey());
|
||||
assertEquals("test_keyword", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetHyphenInValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("test-role");
|
||||
query.setRoleKey("test-role");
|
||||
query.setKeyword("test-keyword");
|
||||
|
||||
assertEquals("test-role", query.getRoleName());
|
||||
assertEquals("test-role", query.getRoleKey());
|
||||
assertEquals("test-keyword", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetDotInValues() {
|
||||
SysRoleQuery query = new SysRoleQuery();
|
||||
|
||||
query.setRoleName("test.role");
|
||||
query.setRoleKey("test.role");
|
||||
query.setKeyword("test.keyword");
|
||||
|
||||
assertEquals("test.role", query.getRoleName());
|
||||
assertEquals("test.role", query.getRoleKey());
|
||||
assertEquals("test.keyword", query.getKeyword());
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
package cn.novalon.manage.sys.core.query;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SysUserQueryTest {
|
||||
|
||||
@Test
|
||||
void testGettersAndSetters() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername("testuser");
|
||||
query.setEmail("test@example.com");
|
||||
query.setRoleId(1L);
|
||||
query.setStatus(1);
|
||||
query.setKeyword("test");
|
||||
|
||||
assertEquals("testuser", query.getUsername());
|
||||
assertEquals("test@example.com", query.getEmail());
|
||||
assertEquals(1L, query.getRoleId());
|
||||
assertEquals(1, query.getStatus());
|
||||
assertEquals("test", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNullValues() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername(null);
|
||||
query.setEmail(null);
|
||||
query.setRoleId(null);
|
||||
query.setStatus(null);
|
||||
query.setKeyword(null);
|
||||
|
||||
assertNull(query.getUsername());
|
||||
assertNull(query.getEmail());
|
||||
assertNull(query.getRoleId());
|
||||
assertNull(query.getStatus());
|
||||
assertNull(query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEmptyStringValues() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername("");
|
||||
query.setEmail("");
|
||||
query.setKeyword("");
|
||||
|
||||
assertEquals("", query.getUsername());
|
||||
assertEquals("", query.getEmail());
|
||||
assertEquals("", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetMultipleValues() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername("user1");
|
||||
query.setEmail("user1@example.com");
|
||||
query.setRoleId(2L);
|
||||
query.setStatus(0);
|
||||
query.setKeyword("user1");
|
||||
|
||||
assertEquals("user1", query.getUsername());
|
||||
assertEquals("user1@example.com", query.getEmail());
|
||||
assertEquals(2L, query.getRoleId());
|
||||
assertEquals(0, query.getStatus());
|
||||
assertEquals("user1", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongUsername() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
String longUsername = "a".repeat(100);
|
||||
query.setUsername(longUsername);
|
||||
assertEquals(longUsername, query.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongEmail() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
String longEmail = "a".repeat(100) + "@example.com";
|
||||
query.setEmail(longEmail);
|
||||
assertEquals(longEmail, query.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetLongKeyword() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
String longKeyword = "a".repeat(100);
|
||||
query.setKeyword(longKeyword);
|
||||
assertEquals(longKeyword, query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNegativeRoleId() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setRoleId(-1L);
|
||||
assertEquals(-1L, query.getRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetZeroRoleId() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setRoleId(0L);
|
||||
assertEquals(0L, query.getRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPositiveRoleId() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setRoleId(999L);
|
||||
assertEquals(999L, query.getRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetNegativeStatus() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setStatus(-1);
|
||||
assertEquals(-1, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetZeroStatus() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setStatus(0);
|
||||
assertEquals(0, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetPositiveStatus() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setStatus(1);
|
||||
assertEquals(1, query.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInUsername() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setUsername("user@#$%");
|
||||
assertEquals("user@#$%", query.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInEmail() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setEmail("user+test@example.com");
|
||||
assertEquals("user+test@example.com", query.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetSpecialCharactersInKeyword() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
query.setKeyword("keyword@#$%");
|
||||
assertEquals("keyword@#$%", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetWhitespaceInValues() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername(" test user ");
|
||||
query.setEmail(" test@example.com ");
|
||||
query.setKeyword(" test keyword ");
|
||||
|
||||
assertEquals(" test user ", query.getUsername());
|
||||
assertEquals(" test@example.com ", query.getEmail());
|
||||
assertEquals(" test keyword ", query.getKeyword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetUnicodeCharacters() {
|
||||
SysUserQuery query = new SysUserQuery();
|
||||
|
||||
query.setUsername("用户名");
|
||||
query.setEmail("用户@example.com");
|
||||
query.setKeyword("关键词");
|
||||
|
||||
assertEquals("用户名", query.getUsername());
|
||||
assertEquals("用户@example.com", query.getEmail());
|
||||
assertEquals("关键词", query.getKeyword());
|
||||
}
|
||||
}
|
||||
+260
@@ -185,6 +185,82 @@ class SysMenuServiceTest {
|
||||
verify(menuRepository).findById(999L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateMenuWithCommand_WithPartialFields() {
|
||||
SysMenu existingMenu = new SysMenu();
|
||||
existingMenu.setId(1L);
|
||||
existingMenu.setMenuName("系统管理");
|
||||
existingMenu.setParentId(0L);
|
||||
existingMenu.setOrderNum(1);
|
||||
existingMenu.setMenuType("M");
|
||||
existingMenu.setPerms("system");
|
||||
existingMenu.setComponent("system");
|
||||
existingMenu.setStatus(1);
|
||||
|
||||
SysMenu updatedMenu = new SysMenu();
|
||||
updatedMenu.setId(1L);
|
||||
updatedMenu.setMenuName("系统管理");
|
||||
updatedMenu.setParentId(0L);
|
||||
updatedMenu.setOrderNum(1);
|
||||
updatedMenu.setMenuType("M");
|
||||
updatedMenu.setPerms("system");
|
||||
updatedMenu.setComponent("system");
|
||||
updatedMenu.setStatus(1);
|
||||
updatedMenu.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
when(menuRepository.findById(1L)).thenReturn(Mono.just(existingMenu));
|
||||
when(menuRepository.save(any(SysMenu.class))).thenReturn(Mono.just(updatedMenu));
|
||||
|
||||
UpdateMenuCommand command = new UpdateMenuCommand(
|
||||
1L, null, null, null, null, null, null, null
|
||||
);
|
||||
|
||||
StepVerifier.create(menuService.updateMenu(command))
|
||||
.expectNextMatches(menu -> menu.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findById(1L);
|
||||
verify(menuRepository).save(any(SysMenu.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateMenuWithCommand_WithAllFields() {
|
||||
SysMenu existingMenu = new SysMenu();
|
||||
existingMenu.setId(1L);
|
||||
existingMenu.setMenuName("系统管理");
|
||||
existingMenu.setParentId(0L);
|
||||
existingMenu.setOrderNum(1);
|
||||
existingMenu.setMenuType("M");
|
||||
existingMenu.setPerms("system");
|
||||
existingMenu.setComponent("system");
|
||||
existingMenu.setStatus(1);
|
||||
|
||||
SysMenu updatedMenu = new SysMenu();
|
||||
updatedMenu.setId(1L);
|
||||
updatedMenu.setMenuName("系统管理(更新)");
|
||||
updatedMenu.setParentId(2L);
|
||||
updatedMenu.setOrderNum(2);
|
||||
updatedMenu.setMenuType("C");
|
||||
updatedMenu.setPerms("system:manage_updated");
|
||||
updatedMenu.setComponent("system_updated");
|
||||
updatedMenu.setStatus(0);
|
||||
updatedMenu.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
when(menuRepository.findById(1L)).thenReturn(Mono.just(existingMenu));
|
||||
when(menuRepository.save(any(SysMenu.class))).thenReturn(Mono.just(updatedMenu));
|
||||
|
||||
UpdateMenuCommand command = new UpdateMenuCommand(
|
||||
1L, 2L, "系统管理(更新)", "C", 2, "system_updated", "system:manage_updated", 0
|
||||
);
|
||||
|
||||
StepVerifier.create(menuService.updateMenu(command))
|
||||
.expectNextMatches(menu -> menu.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findById(1L);
|
||||
verify(menuRepository).save(any(SysMenu.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteMenu() {
|
||||
when(menuRepository.deleteById(1L)).thenReturn(Mono.empty());
|
||||
@@ -220,4 +296,188 @@ class SysMenuServiceTest {
|
||||
menu.getChildren().size() == 1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindById_WhenMenuNotFound() {
|
||||
when(menuRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
Mono<SysMenu> result = menuService.findById(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findById(999L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindAll_WhenNoMenusExist() {
|
||||
when(menuRepository.findAll()).thenReturn(Flux.empty());
|
||||
|
||||
Flux<SysMenu> result = menuService.findAll();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByParentId_WhenNoChildrenExist() {
|
||||
when(menuRepository.findByParentId(999L)).thenReturn(Flux.empty());
|
||||
|
||||
Flux<SysMenu> result = menuService.findByParentId(999L);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findByParentId(999L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateMenu_WithDefaultStatus() {
|
||||
SysMenu newMenu = new SysMenu();
|
||||
newMenu.setMenuName("新菜单");
|
||||
newMenu.setParentId(0L);
|
||||
newMenu.setOrderNum(1);
|
||||
newMenu.setMenuType("M");
|
||||
newMenu.setPerms("new:menu");
|
||||
newMenu.setComponent("new");
|
||||
newMenu.setStatus(null);
|
||||
|
||||
SysMenu savedMenu = new SysMenu();
|
||||
savedMenu.setId(1L);
|
||||
savedMenu.setMenuName("新菜单");
|
||||
savedMenu.setParentId(0L);
|
||||
savedMenu.setOrderNum(1);
|
||||
savedMenu.setMenuType("M");
|
||||
savedMenu.setPerms("new:menu");
|
||||
savedMenu.setComponent("new");
|
||||
savedMenu.setStatus(1);
|
||||
savedMenu.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(menuRepository.save(any(SysMenu.class))).thenReturn(Mono.just(savedMenu));
|
||||
|
||||
Mono<SysMenu> result = menuService.createMenu(newMenu);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(menu ->
|
||||
menu.getStatus().equals(1) &&
|
||||
menu.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).save(any(SysMenu.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateMenuWithCommand_WithDefaultStatus() {
|
||||
CreateMenuCommand command = new CreateMenuCommand(
|
||||
0L, "日志管理", "M", 3, "log", "log:manage", null
|
||||
);
|
||||
|
||||
SysMenu createdMenu = new SysMenu();
|
||||
createdMenu.setId(3L);
|
||||
createdMenu.setMenuName("日志管理");
|
||||
createdMenu.setParentId(0L);
|
||||
createdMenu.setOrderNum(3);
|
||||
createdMenu.setMenuType("M");
|
||||
createdMenu.setPerms("log:manage");
|
||||
createdMenu.setComponent("log");
|
||||
createdMenu.setStatus(1);
|
||||
createdMenu.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(menuRepository.save(any(SysMenu.class))).thenReturn(Mono.just(createdMenu));
|
||||
|
||||
Mono<SysMenu> result = menuService.createMenu(command);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(menu ->
|
||||
menu.getMenuName().equals("日志管理") &&
|
||||
menu.getStatus().equals(1) &&
|
||||
menu.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).save(any(SysMenu.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildMenuTree_WithEmptyTree() {
|
||||
when(menuRepository.findAll()).thenReturn(Flux.empty());
|
||||
|
||||
Flux<SysMenu> result = menuService.buildMenuTree(menuService.findAll());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildMenuTree_WithMultiLevelTree() {
|
||||
SysMenu rootMenu = new SysMenu();
|
||||
rootMenu.setId(1L);
|
||||
rootMenu.setMenuName("系统管理");
|
||||
rootMenu.setParentId(0L);
|
||||
|
||||
SysMenu level1Menu = new SysMenu();
|
||||
level1Menu.setId(2L);
|
||||
level1Menu.setMenuName("用户管理");
|
||||
level1Menu.setParentId(1L);
|
||||
|
||||
SysMenu level2Menu = new SysMenu();
|
||||
level2Menu.setId(3L);
|
||||
level2Menu.setMenuName("用户列表");
|
||||
level2Menu.setParentId(2L);
|
||||
|
||||
when(menuRepository.findAll()).thenReturn(Flux.just(rootMenu, level1Menu, level2Menu));
|
||||
|
||||
Flux<SysMenu> result = menuService.buildMenuTree(menuService.findAll());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(menu ->
|
||||
menu.getId().equals(1L) &&
|
||||
menu.getChildren() != null &&
|
||||
menu.getChildren().size() == 1 &&
|
||||
menu.getChildren().get(0).getChildren() != null &&
|
||||
menu.getChildren().get(0).getChildren().size() == 1)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildMenuTree_WithMultipleRootMenus() {
|
||||
SysMenu root1 = new SysMenu();
|
||||
root1.setId(1L);
|
||||
root1.setMenuName("系统管理");
|
||||
root1.setParentId(0L);
|
||||
|
||||
SysMenu root2 = new SysMenu();
|
||||
root2.setId(2L);
|
||||
root2.setMenuName("监控管理");
|
||||
root2.setParentId(0L);
|
||||
|
||||
SysMenu child1 = new SysMenu();
|
||||
child1.setId(3L);
|
||||
child1.setMenuName("用户管理");
|
||||
child1.setParentId(1L);
|
||||
|
||||
SysMenu child2 = new SysMenu();
|
||||
child2.setId(4L);
|
||||
child2.setMenuName("性能监控");
|
||||
child2.setParentId(2L);
|
||||
|
||||
when(menuRepository.findAll()).thenReturn(Flux.just(root1, root2, child1, child2));
|
||||
|
||||
Flux<SysMenu> result = menuService.buildMenuTree(menuService.findAll());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextCount(2)
|
||||
.verifyComplete();
|
||||
|
||||
verify(menuRepository).findAll();
|
||||
}
|
||||
}
|
||||
+311
@@ -127,6 +127,118 @@ class SysRoleServiceTest {
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindRolesByPage_WithKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
pageRequest.setKeyword("admin");
|
||||
|
||||
PageResponse<SysRole> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testRole));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(roleRepository.findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(roleService.findRolesByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindRolesByPage_WithoutKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
|
||||
PageResponse<SysRole> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testRole));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(roleRepository.findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(roleService.findRolesByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindRolesByPage_WithEmptyKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
pageRequest.setKeyword("");
|
||||
|
||||
PageResponse<SysRole> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testRole));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(roleRepository.findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(roleService.findRolesByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByQueryWithPagination(any(cn.novalon.manage.sys.core.query.SysRoleQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateRoleWithCommand_WithAllFields() {
|
||||
SysRole existingRole = new SysRole();
|
||||
existingRole.setId(1L);
|
||||
existingRole.setRoleName("oldrole");
|
||||
existingRole.setRoleKey("oldkey");
|
||||
existingRole.setRoleSort(1);
|
||||
existingRole.setStatus(StatusConstants.ENABLED);
|
||||
|
||||
when(roleRepository.findById(1L)).thenReturn(Mono.just(existingRole));
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(testRole));
|
||||
|
||||
cn.novalon.manage.sys.core.command.UpdateRoleCommand command =
|
||||
new cn.novalon.manage.sys.core.command.UpdateRoleCommand(
|
||||
1L, "newrole", "newkey", 2, StatusConstants.DISABLED
|
||||
);
|
||||
|
||||
StepVerifier.create(roleService.updateRole(command))
|
||||
.expectNextMatches(role -> role.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findById(1L);
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateRoleWithCommand_WithPartialFields() {
|
||||
SysRole existingRole = new SysRole();
|
||||
existingRole.setId(1L);
|
||||
existingRole.setRoleName("oldrole");
|
||||
existingRole.setRoleKey("oldkey");
|
||||
existingRole.setRoleSort(1);
|
||||
existingRole.setStatus(StatusConstants.ENABLED);
|
||||
|
||||
when(roleRepository.findById(1L)).thenReturn(Mono.just(existingRole));
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(testRole));
|
||||
|
||||
cn.novalon.manage.sys.core.command.UpdateRoleCommand command =
|
||||
new cn.novalon.manage.sys.core.command.UpdateRoleCommand(
|
||||
1L, null, null, null, null
|
||||
);
|
||||
|
||||
StepVerifier.create(roleService.updateRole(command))
|
||||
.expectNextMatches(role -> role.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findById(1L);
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateRole() {
|
||||
SysRole updateRole = new SysRole();
|
||||
@@ -218,4 +330,203 @@ class SysRoleServiceTest {
|
||||
verify(roleRepository).findByIdIncludingDeleted(1L);
|
||||
verify(roleRepository).updateRole(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateRole_WithNullStatus() {
|
||||
SysRole newRole = new SysRole();
|
||||
newRole.setRoleName("user");
|
||||
newRole.setRoleKey("user");
|
||||
newRole.setStatus(null);
|
||||
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(testRole));
|
||||
|
||||
StepVerifier.create(roleService.createRole(newRole))
|
||||
.expectNextMatches(role ->
|
||||
role.getStatus().equals(StatusConstants.ENABLED) &&
|
||||
role.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateRole_WithExistingStatus() {
|
||||
SysRole newRole = new SysRole();
|
||||
newRole.setRoleName("user");
|
||||
newRole.setRoleKey("user");
|
||||
newRole.setStatus(StatusConstants.DISABLED);
|
||||
|
||||
SysRole savedRole = new SysRole();
|
||||
savedRole.setId(1L);
|
||||
savedRole.setRoleName("user");
|
||||
savedRole.setRoleKey("user");
|
||||
savedRole.setStatus(StatusConstants.DISABLED);
|
||||
savedRole.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(savedRole));
|
||||
|
||||
StepVerifier.create(roleService.createRole(newRole))
|
||||
.expectNextMatches(role ->
|
||||
role.getStatus().equals(StatusConstants.DISABLED) &&
|
||||
role.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateRoleWithCommand_WithAllFields() {
|
||||
cn.novalon.manage.sys.core.command.CreateRoleCommand command =
|
||||
new cn.novalon.manage.sys.core.command.CreateRoleCommand(
|
||||
"manager", "manager", 2, StatusConstants.ENABLED
|
||||
);
|
||||
|
||||
SysRole savedRole = new SysRole();
|
||||
savedRole.setId(1L);
|
||||
savedRole.setRoleName("manager");
|
||||
savedRole.setRoleKey("manager");
|
||||
savedRole.setRoleSort(2);
|
||||
savedRole.setStatus(StatusConstants.ENABLED);
|
||||
savedRole.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(savedRole));
|
||||
|
||||
StepVerifier.create(roleService.createRole(command))
|
||||
.expectNextMatches(role ->
|
||||
role.getRoleName().equals("manager") &&
|
||||
role.getRoleKey().equals("manager") &&
|
||||
role.getRoleSort() == 2 &&
|
||||
role.getStatus().equals(StatusConstants.ENABLED) &&
|
||||
role.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateRoleWithCommand_WithDefaultStatus() {
|
||||
cn.novalon.manage.sys.core.command.CreateRoleCommand command =
|
||||
new cn.novalon.manage.sys.core.command.CreateRoleCommand(
|
||||
"viewer", "viewer", 3, null
|
||||
);
|
||||
|
||||
SysRole savedRole = new SysRole();
|
||||
savedRole.setId(1L);
|
||||
savedRole.setRoleName("viewer");
|
||||
savedRole.setRoleKey("viewer");
|
||||
savedRole.setRoleSort(3);
|
||||
savedRole.setStatus(StatusConstants.ENABLED);
|
||||
savedRole.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(roleRepository.save(any(SysRole.class))).thenReturn(Mono.just(savedRole));
|
||||
|
||||
StepVerifier.create(roleService.createRole(command))
|
||||
.expectNextMatches(role ->
|
||||
role.getRoleName().equals("viewer") &&
|
||||
role.getRoleKey().equals("viewer") &&
|
||||
role.getRoleSort() == 3 &&
|
||||
role.getStatus().equals(StatusConstants.ENABLED) &&
|
||||
role.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateRoleWithCommand_WhenRoleNotFound() {
|
||||
cn.novalon.manage.sys.core.command.UpdateRoleCommand command =
|
||||
new cn.novalon.manage.sys.core.command.UpdateRoleCommand(
|
||||
999L, "newrole", "newkey", 2, StatusConstants.DISABLED
|
||||
);
|
||||
|
||||
when(roleRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.updateRole(command))
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
|
||||
verify(roleRepository).findById(999L);
|
||||
verify(roleRepository, never()).save(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteRole_WhenRoleNotFound() {
|
||||
when(roleRepository.findById(1L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.deleteRole(1L))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
|
||||
verify(roleRepository).findById(1L);
|
||||
verify(userService, never()).updateRoleIdToNullByRoleId(1L);
|
||||
verify(roleRepository, never()).deleteById(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogicalDeleteRole_WhenRoleNotFound() {
|
||||
when(roleRepository.findByIdIncludingDeleted(1L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.logicalDeleteRole(1L))
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByIdIncludingDeleted(1L);
|
||||
verify(roleRepository, never()).updateRole(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRestoreRole_WhenRoleNotFound() {
|
||||
when(roleRepository.findByIdIncludingDeleted(1L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.restoreRole(1L))
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByIdIncludingDeleted(1L);
|
||||
verify(roleRepository, never()).updateRole(any(SysRole.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindById_WhenRoleNotFound() {
|
||||
when(roleRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.findById(999L))
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findById(999L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByRoleName_WhenRoleNotFound() {
|
||||
when(roleRepository.findByRoleName("nonexistent")).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(roleService.findByRoleName("nonexistent"))
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findByRoleName("nonexistent");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindAll_WhenNoRolesExist() {
|
||||
when(roleRepository.findAll()).thenReturn(Flux.empty());
|
||||
|
||||
StepVerifier.create(roleService.findAll())
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).findAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCount_WhenNoRolesExist() {
|
||||
when(roleRepository.count()).thenReturn(Mono.just(0L));
|
||||
|
||||
StepVerifier.create(roleService.count())
|
||||
.expectNext(0L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(roleRepository).count();
|
||||
}
|
||||
}
|
||||
|
||||
+177
-16
@@ -1,6 +1,7 @@
|
||||
package cn.novalon.manage.sys.core.service.impl;
|
||||
|
||||
import cn.novalon.manage.common.util.StatusConstants;
|
||||
import cn.novalon.manage.sys.core.command.UpdateUserCommand;
|
||||
import cn.novalon.manage.sys.core.domain.SysUser;
|
||||
import cn.novalon.manage.sys.core.query.SysUserQuery;
|
||||
import cn.novalon.manage.sys.core.repository.ISysUserRepository;
|
||||
@@ -188,22 +189,6 @@ class SysUserServiceTest {
|
||||
verify(passwordEncoder).encode("raw_password");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateUser() {
|
||||
SysUser updateUser = new SysUser();
|
||||
updateUser.setId(1L);
|
||||
updateUser.setUsername("updated_user");
|
||||
|
||||
when(userRepository.save(any(SysUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
StepVerifier.create(userService.updateUser(updateUser))
|
||||
.expectNextMatches(user -> user.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
ArgumentCaptor<SysUser> userCaptor = ArgumentCaptor.forClass(SysUser.class);
|
||||
verify(userRepository).save(userCaptor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteUser() {
|
||||
when(userRepository.findById(1L)).thenReturn(Mono.just(testUser));
|
||||
@@ -339,4 +324,180 @@ class SysUserServiceTest {
|
||||
|
||||
verify(userRepository).restoreByIds(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateUser_WithNullStatus() {
|
||||
SysUser newUser = new SysUser();
|
||||
newUser.setUsername("newuser");
|
||||
newUser.setPassword("raw_password");
|
||||
newUser.setEmail("new@example.com");
|
||||
newUser.setStatus(null);
|
||||
|
||||
when(passwordEncoder.encode("raw_password")).thenReturn("encoded_password");
|
||||
when(userRepository.save(any(SysUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
StepVerifier.create(userService.createUser(newUser))
|
||||
.expectNextMatches(user ->
|
||||
user.getPassword().equals("encoded_password") &&
|
||||
user.getStatus().equals(StatusConstants.ENABLED) &&
|
||||
user.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(passwordEncoder).encode("raw_password");
|
||||
verify(userRepository).save(any(SysUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateUser_WithExistingStatus() {
|
||||
SysUser newUser = new SysUser();
|
||||
newUser.setUsername("newuser");
|
||||
newUser.setPassword("raw_password");
|
||||
newUser.setEmail("new@example.com");
|
||||
newUser.setStatus(StatusConstants.DISABLED);
|
||||
|
||||
SysUser savedUser = new SysUser();
|
||||
savedUser.setId(1L);
|
||||
savedUser.setUsername("newuser");
|
||||
savedUser.setPassword("encoded_password");
|
||||
savedUser.setEmail("new@example.com");
|
||||
savedUser.setStatus(StatusConstants.DISABLED);
|
||||
savedUser.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
when(passwordEncoder.encode("raw_password")).thenReturn("encoded_password");
|
||||
when(userRepository.save(any(SysUser.class))).thenReturn(Mono.just(savedUser));
|
||||
|
||||
StepVerifier.create(userService.createUser(newUser))
|
||||
.expectNextMatches(user ->
|
||||
user.getPassword().equals("encoded_password") &&
|
||||
user.getStatus().equals(StatusConstants.DISABLED) &&
|
||||
user.getCreatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(passwordEncoder).encode("raw_password");
|
||||
verify(userRepository).save(any(SysUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteUser_UserNotFound() {
|
||||
when(userRepository.findById(999L)).thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier.create(userService.deleteUser(999L))
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
|
||||
verify(userRepository).findById(999L);
|
||||
verify(userRepository, never()).deleteById(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindUsersByPage_WithKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
pageRequest.setKeyword("test");
|
||||
|
||||
PageResponse<SysUser> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testUser));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(userRepository.findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(userService.findUsersByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(userRepository).findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindUsersByPage_WithoutKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
|
||||
PageResponse<SysUser> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testUser));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(userRepository.findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(userService.findUsersByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(userRepository).findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindUsersByPage_WithEmptyKeyword() {
|
||||
PageRequest pageRequest = new PageRequest();
|
||||
pageRequest.setPage(0);
|
||||
pageRequest.setSize(10);
|
||||
pageRequest.setKeyword("");
|
||||
|
||||
PageResponse<SysUser> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(List.of(testUser));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(userRepository.findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest)))
|
||||
.thenReturn(Mono.just(pageResponse));
|
||||
|
||||
StepVerifier.create(userService.findUsersByPage(pageRequest))
|
||||
.expectNextMatches(response -> response.getTotalElements() == 1L)
|
||||
.verifyComplete();
|
||||
|
||||
verify(userRepository).findByQueryWithPagination(any(SysUserQuery.class), eq(pageRequest));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateUserWithCommand_WithAllFields() {
|
||||
SysUser existingUser = new SysUser();
|
||||
existingUser.setId(1L);
|
||||
existingUser.setUsername("olduser");
|
||||
existingUser.setEmail("old@example.com");
|
||||
existingUser.setRoleId(1L);
|
||||
existingUser.setStatus(StatusConstants.ENABLED);
|
||||
|
||||
when(userRepository.findById(1L)).thenReturn(Mono.just(existingUser));
|
||||
when(userRepository.save(any(SysUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
cn.novalon.manage.sys.core.command.UpdateUserCommand command =
|
||||
new cn.novalon.manage.sys.core.command.UpdateUserCommand(
|
||||
1L, "newuser", "newpass", "new@example.com", 2L, StatusConstants.DISABLED
|
||||
);
|
||||
|
||||
StepVerifier.create(userService.updateUser(command))
|
||||
.expectNextMatches(user -> user.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(userRepository).findById(1L);
|
||||
verify(userRepository).save(any(SysUser.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateUserWithCommand_WithPartialFields() {
|
||||
SysUser existingUser = new SysUser();
|
||||
existingUser.setId(1L);
|
||||
existingUser.setUsername("olduser");
|
||||
existingUser.setEmail("old@example.com");
|
||||
existingUser.setRoleId(1L);
|
||||
existingUser.setStatus(StatusConstants.ENABLED);
|
||||
|
||||
when(userRepository.findById(1L)).thenReturn(Mono.just(existingUser));
|
||||
when(userRepository.save(any(SysUser.class))).thenReturn(Mono.just(testUser));
|
||||
|
||||
cn.novalon.manage.sys.core.command.UpdateUserCommand command =
|
||||
new cn.novalon.manage.sys.core.command.UpdateUserCommand(
|
||||
1L, null, null, null, null, null
|
||||
);
|
||||
|
||||
StepVerifier.create(userService.updateUser(command))
|
||||
.expectNextMatches(user -> user.getUpdatedAt() != null)
|
||||
.verifyComplete();
|
||||
|
||||
verify(userRepository).findById(1L);
|
||||
verify(userRepository).save(any(SysUser.class));
|
||||
}
|
||||
}
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
package cn.novalon.manage.sys.filter;
|
||||
|
||||
import io.github.resilience4j.ratelimiter.RateLimiter;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
|
||||
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.server.MockServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RateLimitFilterTest {
|
||||
|
||||
@Mock
|
||||
private RateLimiterRegistry rateLimiterRegistry;
|
||||
|
||||
@Mock
|
||||
private RateLimiter rateLimiter;
|
||||
|
||||
@Mock
|
||||
private WebFilterChain webFilterChain;
|
||||
|
||||
private RateLimitFilter rateLimitFilter;
|
||||
private MockServerWebExchange exchange;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(rateLimiterRegistry.rateLimiter("apiRateLimiter")).thenReturn(rateLimiter);
|
||||
|
||||
rateLimitFilter = new RateLimitFilter(rateLimiterRegistry);
|
||||
|
||||
exchange = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.remoteAddress(new InetSocketAddress("192.168.1.1", 8080))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithPermissionGranted() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithPermissionDenied() {
|
||||
RateLimiterConfig config = RateLimiterConfig.custom()
|
||||
.limitForPeriod(100)
|
||||
.limitRefreshPeriod(Duration.ofSeconds(1))
|
||||
.build();
|
||||
when(rateLimiter.getRateLimiterConfig()).thenReturn(config);
|
||||
when(rateLimiter.acquirePermission()).thenReturn(false);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.TOO_MANY_REQUESTS);
|
||||
assertThat(exchange.getResponse().getHeaders().getFirst("X-RateLimit-Limit")).isEqualTo("100");
|
||||
assertThat(exchange.getResponse().getHeaders().getFirst("X-RateLimit-Remaining")).isEqualTo("0");
|
||||
assertThat(exchange.getResponse().getHeaders().getFirst("Retry-After")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithXForwardedForHeader() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerWebExchange exchangeWithHeader = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.header("X-Forwarded-For", "10.0.0.1")
|
||||
.build()
|
||||
);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchangeWithHeader, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithXRealIPHeader() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerWebExchange exchangeWithHeader = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.header("X-Real-IP", "10.0.0.2")
|
||||
.build()
|
||||
);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchangeWithHeader, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithUnknownIP() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerWebExchange exchangeWithUnknownIP = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.header("X-Forwarded-For", "unknown")
|
||||
.build()
|
||||
);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchangeWithUnknownIP, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithEmptyIP() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerWebExchange exchangeWithEmptyIP = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.header("X-Forwarded-For", "")
|
||||
.build()
|
||||
);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchangeWithEmptyIP, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithNullRemoteAddress() {
|
||||
when(rateLimiter.acquirePermission()).thenReturn(true);
|
||||
when(webFilterChain.filter(any())).thenReturn(Mono.empty());
|
||||
|
||||
MockServerWebExchange exchangeWithNullAddress = MockServerWebExchange.from(
|
||||
org.springframework.mock.http.server.reactive.MockServerHttpRequest.get("/api/test")
|
||||
.header("X-Forwarded-For", "unknown")
|
||||
.header("X-Real-IP", "unknown")
|
||||
.build()
|
||||
);
|
||||
|
||||
Mono<Void> result = rateLimitFilter.filter(exchangeWithNullAddress, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any());
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package cn.novalon.manage.sys.handler;
|
||||
|
||||
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
|
||||
import cn.novalon.manage.sys.core.service.ISysExceptionLogService;
|
||||
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.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ExceptionLogServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ISysExceptionLogService exceptionLogService;
|
||||
|
||||
private ExceptionLogServiceImpl exceptionLogServiceImpl;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
exceptionLogServiceImpl = new ExceptionLogServiceImpl(exceptionLogService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogException() {
|
||||
SysExceptionLog savedLog = new SysExceptionLog();
|
||||
savedLog.setId(1L);
|
||||
savedLog.setTitle("测试异常");
|
||||
savedLog.setExceptionName("TestException");
|
||||
savedLog.setExceptionMsg("测试异常消息");
|
||||
savedLog.setMethodName("testMethod");
|
||||
savedLog.setIp("127.0.0.1");
|
||||
savedLog.setExceptionStack("测试堆栈信息");
|
||||
savedLog.setCreateTime(LocalDateTime.now());
|
||||
|
||||
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
|
||||
|
||||
StepVerifier.create(exceptionLogServiceImpl.logException(
|
||||
"测试异常",
|
||||
"TestException",
|
||||
"测试异常消息",
|
||||
"testMethod",
|
||||
"127.0.0.1",
|
||||
"测试堆栈信息"
|
||||
))
|
||||
.verifyComplete();
|
||||
|
||||
verify(exceptionLogService).save(any(SysExceptionLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogException_WithEmptyFields() {
|
||||
SysExceptionLog savedLog = new SysExceptionLog();
|
||||
savedLog.setId(1L);
|
||||
|
||||
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
|
||||
|
||||
StepVerifier.create(exceptionLogServiceImpl.logException(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
))
|
||||
.verifyComplete();
|
||||
|
||||
verify(exceptionLogService).save(any(SysExceptionLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogException_WithNullFields() {
|
||||
SysExceptionLog savedLog = new SysExceptionLog();
|
||||
savedLog.setId(1L);
|
||||
|
||||
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
|
||||
|
||||
StepVerifier.create(exceptionLogServiceImpl.logException(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
))
|
||||
.verifyComplete();
|
||||
|
||||
verify(exceptionLogService).save(any(SysExceptionLog.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLogException_WithLongStackTrace() {
|
||||
String longStackTrace = "a".repeat(10000);
|
||||
|
||||
SysExceptionLog savedLog = new SysExceptionLog();
|
||||
savedLog.setId(1L);
|
||||
|
||||
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
|
||||
|
||||
StepVerifier.create(exceptionLogServiceImpl.logException(
|
||||
"测试异常",
|
||||
"TestException",
|
||||
"测试异常消息",
|
||||
"testMethod",
|
||||
"127.0.0.1",
|
||||
longStackTrace
|
||||
))
|
||||
.verifyComplete();
|
||||
|
||||
verify(exceptionLogService).save(any(SysExceptionLog.class));
|
||||
}
|
||||
}
|
||||
+46
@@ -152,6 +152,29 @@ class SysLogHandlerTest {
|
||||
verify(loginLogService).findLoginLogsByPage(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLoginLogsByPage_WithKeyword() {
|
||||
PageResponse<SysLoginLog> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(java.util.Collections.singletonList(testLoginLog));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(loginLogService.findLoginLogsByPage(any())).thenReturn(Mono.just(pageResponse));
|
||||
|
||||
ServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("page", "0")
|
||||
.queryParam("size", "10")
|
||||
.queryParam("keyword", "test")
|
||||
.build();
|
||||
Mono<ServerResponse> response = logHandler.getLoginLogsByPage(request);
|
||||
|
||||
StepVerifier.create(response)
|
||||
.expectNextMatches(serverResponse ->
|
||||
serverResponse.statusCode() == HttpStatus.OK)
|
||||
.verifyComplete();
|
||||
|
||||
verify(loginLogService).findLoginLogsByPage(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLoginLogCount() {
|
||||
when(loginLogService.count()).thenReturn(Mono.just(100L));
|
||||
@@ -261,6 +284,29 @@ class SysLogHandlerTest {
|
||||
verify(exceptionLogService).findExceptionLogsByPage(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetExceptionLogsByPage_WithKeyword() {
|
||||
PageResponse<SysExceptionLog> pageResponse = new PageResponse<>();
|
||||
pageResponse.setContent(java.util.Collections.singletonList(testExceptionLog));
|
||||
pageResponse.setTotalElements(1L);
|
||||
|
||||
when(exceptionLogService.findExceptionLogsByPage(any())).thenReturn(Mono.just(pageResponse));
|
||||
|
||||
ServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("page", "0")
|
||||
.queryParam("size", "10")
|
||||
.queryParam("keyword", "test")
|
||||
.build();
|
||||
Mono<ServerResponse> response = logHandler.getExceptionLogsByPage(request);
|
||||
|
||||
StepVerifier.create(response)
|
||||
.expectNextMatches(serverResponse ->
|
||||
serverResponse.statusCode() == HttpStatus.OK)
|
||||
.verifyComplete();
|
||||
|
||||
verify(exceptionLogService).findExceptionLogsByPage(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetExceptionLogCount() {
|
||||
when(exceptionLogService.count()).thenReturn(Mono.just(50L));
|
||||
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
package cn.novalon.manage.sys.primitive;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class EmailTest {
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail() {
|
||||
Email email = Email.of("test@example.com");
|
||||
assertEquals("test@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NullEmail() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of(null)
|
||||
);
|
||||
assertEquals("Email is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_EmptyEmail() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("")
|
||||
);
|
||||
assertEquals("Email is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WhitespaceOnlyEmail() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of(" ")
|
||||
);
|
||||
assertEquals("Email is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_InvalidEmail_NoAtSymbol() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("testexample.com")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_InvalidEmail_NoDomain() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("test@")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_InvalidEmail_NoTLD() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("test@example")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_InvalidEmail_ShortTLD() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("test@example.c")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithSubdomain() {
|
||||
Email email = Email.of("test@mail.example.com");
|
||||
assertEquals("test@mail.example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithPlus() {
|
||||
Email email = Email.of("test+label@example.com");
|
||||
assertEquals("test+label@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithUnderscore() {
|
||||
Email email = Email.of("test_user@example.com");
|
||||
assertEquals("test_user@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithHyphen() {
|
||||
Email email = Email.of("test-user@example.com");
|
||||
assertEquals("test-user@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithDot() {
|
||||
Email email = Email.of("test.user@example.com");
|
||||
assertEquals("test.user@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithNumbers() {
|
||||
Email email = Email.of("test123@example.com");
|
||||
assertEquals("test123@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithMultipleDotsInDomain() {
|
||||
Email email = Email.of("test@example.co.uk");
|
||||
assertEquals("test@example.co.uk", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithHyphenInDomain() {
|
||||
Email email = Email.of("test@example-domain.com");
|
||||
assertEquals("test@example-domain.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOfNullable_NullValue() {
|
||||
Email email = Email.ofNullable(null);
|
||||
assertNull(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOfNullable_EmptyValue() {
|
||||
Email email = Email.ofNullable("");
|
||||
assertNull(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOfNullable_WhitespaceValue() {
|
||||
Email email = Email.ofNullable(" ");
|
||||
assertNull(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOfNullable_ValidEmail() {
|
||||
Email email = Email.ofNullable("test@example.com");
|
||||
assertNotNull(email);
|
||||
assertEquals("test@example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameValue() {
|
||||
Email email1 = Email.of("test@example.com");
|
||||
Email email2 = Email.of("test@example.com");
|
||||
assertEquals(email1, email2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentValue() {
|
||||
Email email1 = Email.of("test1@example.com");
|
||||
Email email2 = Email.of("test2@example.com");
|
||||
assertNotEquals(email1, email2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameObject() {
|
||||
Email email = Email.of("test@example.com");
|
||||
assertEquals(email, email);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_Null() {
|
||||
Email email = Email.of("test@example.com");
|
||||
assertNotEquals(email, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentClass() {
|
||||
Email email = Email.of("test@example.com");
|
||||
assertNotEquals(email, "test@example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_SameValue() {
|
||||
Email email1 = Email.of("test@example.com");
|
||||
Email email2 = Email.of("test@example.com");
|
||||
assertEquals(email1.hashCode(), email2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_DifferentValue() {
|
||||
Email email1 = Email.of("test1@example.com");
|
||||
Email email2 = Email.of("test2@example.com");
|
||||
assertNotEquals(email1.hashCode(), email2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
Email email = Email.of("test@example.com");
|
||||
assertEquals("test@example.com", email.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithLeadingTrailingWhitespace() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of(" test@example.com ")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithNumbersInDomain() {
|
||||
Email email = Email.of("test@123example.com");
|
||||
assertEquals("test@123example.com", email.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithMultipleAtSymbols() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("test@@example.com")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_ValidEmail_WithSpecialCharsInLocalPart() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Email.of("test!#$%&'*+/=?^_`{|}~-@example.com")
|
||||
);
|
||||
assertEquals("Invalid email format", exception.getMessage());
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
package cn.novalon.manage.sys.primitive;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class PasswordTest {
|
||||
|
||||
@Test
|
||||
void testOf_ValidPassword() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertEquals("Test@123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NullPassword() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of(null)
|
||||
);
|
||||
assertEquals("Password is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_EmptyPassword() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("")
|
||||
);
|
||||
assertEquals("Password is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WhitespaceOnlyPassword() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of(" ")
|
||||
);
|
||||
assertEquals("Password is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_TooShortPassword() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("Test@1")
|
||||
);
|
||||
assertEquals("Password must be at least 8 characters long", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NoUppercase() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("test@123")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NoLowercase() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("TEST@123")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NoDigit() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("Test@abc")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NoSpecialCharacter() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("Test1234")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_MinLengthBoundary() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertEquals("Test@123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_LongPassword() {
|
||||
Password password = Password.of("VeryLongPassword@123456");
|
||||
assertEquals("VeryLongPassword@123456", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithMultipleSpecialCharacters() {
|
||||
Password password = Password.of("Test@#$%123");
|
||||
assertEquals("Test@#$%123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithUnderscore() {
|
||||
Password password = Password.of("Test_123");
|
||||
assertEquals("Test_123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithHyphen() {
|
||||
Password password = Password.of("Test-123");
|
||||
assertEquals("Test-123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameValue() {
|
||||
Password password1 = Password.of("Test@123");
|
||||
Password password2 = Password.of("Test@123");
|
||||
assertEquals(password1, password2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentValue() {
|
||||
Password password1 = Password.of("Test@123");
|
||||
Password password2 = Password.of("Test@456");
|
||||
assertNotEquals(password1, password2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameObject() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertEquals(password, password);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_Null() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertNotEquals(password, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentClass() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertNotEquals(password, "Test@123");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_SameValue() {
|
||||
Password password1 = Password.of("Test@123");
|
||||
Password password2 = Password.of("Test@123");
|
||||
assertEquals(password1.hashCode(), password2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_DifferentValue() {
|
||||
Password password1 = Password.of("Test@123");
|
||||
Password password2 = Password.of("Test@456");
|
||||
assertNotEquals(password1.hashCode(), password2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
Password password = Password.of("Test@123");
|
||||
assertEquals("********", password.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithSpacesInPassword() {
|
||||
Password password = Password.of("Test @123");
|
||||
assertEquals("Test @123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithUnicodeCharacters() {
|
||||
Password password = Password.of("Tëst@123");
|
||||
assertEquals("Tëst@123", password.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithNumbersOnly() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("12345678")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithLettersOnly() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Password.of("TestTest")
|
||||
);
|
||||
assertEquals("Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character", exception.getMessage());
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
package cn.novalon.manage.sys.primitive;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class UsernameTest {
|
||||
|
||||
@Test
|
||||
void testOf_ValidUsername() {
|
||||
Username username = Username.of("test_user123");
|
||||
assertEquals("test_user123", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_NullUsername() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of(null)
|
||||
);
|
||||
assertEquals("Username is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_EmptyUsername() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("")
|
||||
);
|
||||
assertEquals("Username is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WhitespaceOnlyUsername() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of(" ")
|
||||
);
|
||||
assertEquals("Username is required", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_TooShortUsername() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("ab")
|
||||
);
|
||||
assertEquals("Username must be at least 3 characters long", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_TooLongUsername() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("a".repeat(51))
|
||||
);
|
||||
assertEquals("Username must be at most 50 characters long", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithSpecialCharacters() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("user@name")
|
||||
);
|
||||
assertEquals("Username can only contain letters, numbers, and underscores", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithSpaces() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("user name")
|
||||
);
|
||||
assertEquals("Username can only contain letters, numbers, and underscores", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithHyphens() {
|
||||
IllegalArgumentException exception = assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Username.of("user-name")
|
||||
);
|
||||
assertEquals("Username can only contain letters, numbers, and underscores", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_MinLengthBoundary() {
|
||||
Username username = Username.of("abc");
|
||||
assertEquals("abc", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_MaxLengthBoundary() {
|
||||
Username username = Username.of("a".repeat(50));
|
||||
assertEquals("a".repeat(50), username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_WithLeadingTrailingWhitespace() {
|
||||
Username username = Username.of(" test_user ");
|
||||
assertEquals(" test_user ", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_OnlyLetters() {
|
||||
Username username = Username.of("username");
|
||||
assertEquals("username", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_OnlyNumbers() {
|
||||
Username username = Username.of("123456");
|
||||
assertEquals("123456", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_OnlyUnderscores() {
|
||||
Username username = Username.of("___");
|
||||
assertEquals("___", username.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameValue() {
|
||||
Username username1 = Username.of("testuser");
|
||||
Username username2 = Username.of("testuser");
|
||||
assertEquals(username1, username2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentValue() {
|
||||
Username username1 = Username.of("testuser1");
|
||||
Username username2 = Username.of("testuser2");
|
||||
assertNotEquals(username1, username2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_SameObject() {
|
||||
Username username = Username.of("testuser");
|
||||
assertEquals(username, username);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_Null() {
|
||||
Username username = Username.of("testuser");
|
||||
assertNotEquals(username, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEquals_DifferentClass() {
|
||||
Username username = Username.of("testuser");
|
||||
assertNotEquals(username, "testuser");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_SameValue() {
|
||||
Username username1 = Username.of("testuser");
|
||||
Username username2 = Username.of("testuser");
|
||||
assertEquals(username1.hashCode(), username2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHashCode_DifferentValue() {
|
||||
Username username1 = Username.of("testuser1");
|
||||
Username username2 = Username.of("testuser2");
|
||||
assertNotEquals(username1.hashCode(), username2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToString() {
|
||||
Username username = Username.of("testuser");
|
||||
assertEquals("testuser", username.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"user_123", "User_123", "USER_123", "123_user", "_user", "user_"})
|
||||
void testOf_ValidFormats(String validUsername) {
|
||||
Username username = Username.of(validUsername);
|
||||
assertEquals(validUsername.trim(), username.getValue());
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package cn.novalon.manage.sys.security;
|
||||
|
||||
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.HttpHeaders;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JwtAuthenticationFilterTest {
|
||||
|
||||
@Mock
|
||||
private JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Mock
|
||||
private WebFilterChain webFilterChain;
|
||||
|
||||
private JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
jwtAuthenticationFilter = new JwtAuthenticationFilter(jwtTokenProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithValidToken() {
|
||||
String validToken = "valid.jwt.token";
|
||||
Long userId = 1L;
|
||||
|
||||
when(jwtTokenProvider.validateToken(validToken)).thenReturn(true);
|
||||
when(jwtTokenProvider.getUserIdFromToken(validToken)).thenReturn(userId);
|
||||
when(webFilterChain.filter(any(ServerWebExchange.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/api/test")
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + validToken)
|
||||
.build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
|
||||
Mono<Void> result = jwtAuthenticationFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(jwtTokenProvider).validateToken(validToken);
|
||||
verify(jwtTokenProvider).getUserIdFromToken(validToken);
|
||||
verify(webFilterChain).filter(any(ServerWebExchange.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithInvalidToken() {
|
||||
String invalidToken = "invalid.jwt.token";
|
||||
|
||||
when(jwtTokenProvider.validateToken(invalidToken)).thenReturn(false);
|
||||
when(webFilterChain.filter(any(ServerWebExchange.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/api/test")
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + invalidToken)
|
||||
.build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
|
||||
Mono<Void> result = jwtAuthenticationFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(jwtTokenProvider).validateToken(invalidToken);
|
||||
verify(webFilterChain).filter(any(ServerWebExchange.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithoutToken() {
|
||||
when(webFilterChain.filter(any(ServerWebExchange.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/api/test")
|
||||
.build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
|
||||
Mono<Void> result = jwtAuthenticationFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any(ServerWebExchange.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithMalformedToken() {
|
||||
String malformedToken = "Bearer";
|
||||
|
||||
when(webFilterChain.filter(any(ServerWebExchange.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/api/test")
|
||||
.header(HttpHeaders.AUTHORIZATION, malformedToken)
|
||||
.build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
|
||||
Mono<Void> result = jwtAuthenticationFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any(ServerWebExchange.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilter_WithTokenWithoutBearerPrefix() {
|
||||
String tokenWithoutBearer = "just.a.token";
|
||||
|
||||
when(webFilterChain.filter(any(ServerWebExchange.class))).thenReturn(Mono.empty());
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/api/test")
|
||||
.header(HttpHeaders.AUTHORIZATION, tokenWithoutBearer)
|
||||
.build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
|
||||
Mono<Void> result = jwtAuthenticationFilter.filter(exchange, webFilterChain);
|
||||
|
||||
StepVerifier.create(result)
|
||||
.verifyComplete();
|
||||
|
||||
verify(webFilterChain).filter(any(ServerWebExchange.class));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user