refactor(test): 重构测试套件结构并优化测试配置
feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置 fix(api): 修复数据库实体和仓库的删除操作返回值 style(api): 统一数据库表名和字段命名 perf(api): 添加缓存注解提升配置查询性能 test(api): 添加H2测试数据库配置支持 chore: 清理旧的测试文件和脚本
This commit is contained in:
+53
-90
@@ -35,8 +35,24 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
|
||||
public class SystemRouter {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> dictionaryRoutes(DictionaryHandler dictionaryHandler) {
|
||||
public RouterFunction<ServerResponse> systemRoutes(
|
||||
DictionaryHandler dictionaryHandler,
|
||||
SysUserHandler userHandler,
|
||||
MenuHandler menuHandler,
|
||||
SysRoleHandler roleHandler,
|
||||
SysConfigHandler configHandler,
|
||||
SysLogHandler logHandler,
|
||||
OperationLogHandler operationLogHandler,
|
||||
SysAuthHandler authHandler,
|
||||
StatsHandler statsHandler,
|
||||
SysDictHandler dictHandler,
|
||||
SysNoticeHandler noticeHandler,
|
||||
SysUserMessageHandler messageHandler,
|
||||
SysFileHandler fileHandler,
|
||||
SysPermissionHandler permissionHandler) {
|
||||
|
||||
return route()
|
||||
// ========== 字典路由 ==========
|
||||
.GET("/api/dictionaries", dictionaryHandler::getAllDictionaries)
|
||||
.GET("/api/dictionaries/{id}", dictionaryHandler::getDictionaryById)
|
||||
.GET("/api/dictionaries/type/{type}", dictionaryHandler::getDictionariesByType)
|
||||
@@ -44,47 +60,35 @@ public class SystemRouter {
|
||||
.POST("/api/dictionaries", dictionaryHandler::createDictionary)
|
||||
.PUT("/api/dictionaries/{id}", dictionaryHandler::updateDictionary)
|
||||
.DELETE("/api/dictionaries/{id}", dictionaryHandler::deleteDictionary)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> userRoutes(SysUserHandler userHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 用户路由 ==========
|
||||
.GET("/api/users", userHandler::getAllUsers)
|
||||
.GET("/api/users/page", userHandler::getUsersByPage)
|
||||
.GET("/api/users/count", userHandler::getUserCount)
|
||||
.GET("/api/users/{id}", userHandler::getUserById)
|
||||
.GET("/api/users/username/{username}", userHandler::getUserByUsername)
|
||||
.POST("/api/users", userHandler::createUser)
|
||||
.PUT("/api/users/{id}", userHandler::updateUser)
|
||||
.DELETE("/api/users/{id}", userHandler::deleteUser)
|
||||
.POST("/api/users/{id}/password", userHandler::changePassword)
|
||||
.DELETE("/api/users/{id}/logical", userHandler::logicalDeleteUser)
|
||||
.POST("/api/users/logical-delete", userHandler::logicalDeleteUsers)
|
||||
.POST("/api/users/{id}/restore", userHandler::restoreUser)
|
||||
.POST("/api/users/restore", userHandler::restoreUsers)
|
||||
.GET("/api/users/check/username", userHandler::checkUsernameExists)
|
||||
.GET("/api/users/check/email", userHandler::checkEmailExists)
|
||||
.POST("/api/users/{id}/roles", userHandler::assignRoles)
|
||||
.POST("/api/users", userHandler::createUser)
|
||||
.GET("/api/users/{id}", userHandler::getUserById)
|
||||
.PUT("/api/users/{id}", userHandler::updateUser)
|
||||
.DELETE("/api/users/{id}", userHandler::deleteUser)
|
||||
.POST("/api/users/{id}/action/change-password", userHandler::changePassword)
|
||||
.POST("/api/users/{id}/action/logical-delete", userHandler::logicalDeleteUser)
|
||||
.POST("/api/users/logical-delete", userHandler::logicalDeleteUsers)
|
||||
.POST("/api/users/action/restore", userHandler::restoreUsers)
|
||||
.POST("/api/users/{id}/action/restore", userHandler::restoreUser)
|
||||
.GET("/api/users/{id}/roles", userHandler::getUserRoles)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> menuRoutes(MenuHandler menuHandler) {
|
||||
return route()
|
||||
.POST("/api/users/{id}/roles", userHandler::assignRoles)
|
||||
|
||||
// ========== 菜单路由 ==========
|
||||
.GET("/api/menus", menuHandler::getAllMenus)
|
||||
.GET("/api/menus/tree", menuHandler::getMenuTree)
|
||||
.GET("/api/menus/{id}", menuHandler::getMenuById)
|
||||
.POST("/api/menus", menuHandler::createMenu)
|
||||
.PUT("/api/menus/{id}", menuHandler::updateMenu)
|
||||
.DELETE("/api/menus/{id}", menuHandler::deleteMenu)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> roleRoutes(SysRoleHandler roleHandler, SysPermissionHandler permissionHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 角色路由 ==========
|
||||
.GET("/api/roles", roleHandler::getAllRoles)
|
||||
.GET("/api/roles/page", roleHandler::getRolesByPage)
|
||||
.GET("/api/roles/count", roleHandler::getRoleCount)
|
||||
@@ -97,24 +101,16 @@ public class SystemRouter {
|
||||
.POST("/api/roles/{id}/restore", roleHandler::restoreRole)
|
||||
.GET("/api/roles/{id}/permissions", permissionHandler::getPermissionsByRoleId)
|
||||
.POST("/api/roles/{id}/permissions", permissionHandler::assignPermissionsToRole)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> configRoutes(SysConfigHandler configHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 配置路由 ==========
|
||||
.GET("/api/config", configHandler::getAllConfigs)
|
||||
.GET("/api/config/{id}", configHandler::getConfigById)
|
||||
.GET("/api/config/key/{configKey}", configHandler::getConfigByKey)
|
||||
.POST("/api/config", configHandler::createConfig)
|
||||
.PUT("/api/config/{id}", configHandler::updateConfig)
|
||||
.DELETE("/api/config/{id}", configHandler::deleteConfig)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> logRoutes(SysLogHandler logHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 日志路由 ==========
|
||||
.GET("/api/logs/login", logHandler::getAllLoginLogs)
|
||||
.GET("/api/logs/login/page", logHandler::getLoginLogsByPage)
|
||||
.GET("/api/logs/login/count", logHandler::getLoginLogCount)
|
||||
@@ -126,39 +122,21 @@ public class SystemRouter {
|
||||
.GET("/api/logs/exception/count", logHandler::getExceptionLogCount)
|
||||
.GET("/api/logs/exception/{id}", logHandler::getExceptionLogById)
|
||||
.POST("/api/logs/exception", logHandler::createExceptionLog)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> operationLogRoutes(OperationLogHandler operationLogHandler) {
|
||||
return route()
|
||||
.GET("/api/logs/operation", operationLogHandler::getAllOperationLogs)
|
||||
.GET("/api/logs/operation/page", operationLogHandler::getOperationLogsByPage)
|
||||
.GET("/api/logs/operation/count", operationLogHandler::getOperationLogCount)
|
||||
.GET("/api/logs/operation/{id}", operationLogHandler::getOperationLogById)
|
||||
.POST("/api/logs/operation", operationLogHandler::createOperationLog)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> authRoutes(SysAuthHandler authHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 认证路由 ==========
|
||||
.POST("/api/auth/login", authHandler::login)
|
||||
.POST("/api/auth/register", authHandler::register)
|
||||
.POST("/api/auth/logout", authHandler::logout)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> statsRoutes(StatsHandler statsHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 统计路由 ==========
|
||||
.GET("/api/stats/overview", statsHandler::getOverview)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> dictRoutes(SysDictHandler dictHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 数据字典路由 ==========
|
||||
.GET("/api/dict/types", dictHandler::getAllDictTypes)
|
||||
.GET("/api/dict/types/{id}", dictHandler::getDictTypeById)
|
||||
.GET("/api/dict/types/type/{dictType}", dictHandler::getDictTypeByType)
|
||||
@@ -171,36 +149,24 @@ public class SystemRouter {
|
||||
.POST("/api/dict/data", dictHandler::createDictData)
|
||||
.PUT("/api/dict/data/{id}", dictHandler::updateDictData)
|
||||
.DELETE("/api/dict/data/{id}", dictHandler::deleteDictData)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> noticeRoutes(SysNoticeHandler noticeHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 公告路由 ==========
|
||||
.GET("/api/notices", noticeHandler::getAllNotices)
|
||||
.GET("/api/notices/{id}", noticeHandler::getNoticeById)
|
||||
.GET("/api/notices/status/{status}", noticeHandler::getNoticesByStatus)
|
||||
.POST("/api/notices", noticeHandler::createNotice)
|
||||
.PUT("/api/notices/{id}", noticeHandler::updateNotice)
|
||||
.DELETE("/api/notices/{id}", noticeHandler::deleteNotice)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> messageRoutes(SysUserMessageHandler messageHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 消息路由 ==========
|
||||
.GET("/api/messages/user/{userId}", messageHandler::getMessagesByUser)
|
||||
.GET("/api/messages/user/{userId}/unread", messageHandler::getUnreadCount)
|
||||
.GET("/api/messages/user/{userId}/unread/list", messageHandler::getUnreadList)
|
||||
.POST("/api/messages", messageHandler::createMessage)
|
||||
.PUT("/api/messages/{id}/read", messageHandler::markAsRead)
|
||||
.DELETE("/api/messages/{id}", messageHandler::deleteMessage)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> fileRoutes(SysFileHandler fileHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 文件路由 ==========
|
||||
.GET("/api/files", fileHandler::getAllFiles)
|
||||
.GET("/api/files/{id}", fileHandler::getFileById)
|
||||
.POST("/api/files/upload", fileHandler::uploadFile)
|
||||
@@ -209,12 +175,8 @@ public class SystemRouter {
|
||||
.GET("/api/files/{id}/preview", fileHandler::previewFile)
|
||||
.GET("/api/files/preview/{fileName}", fileHandler::previewFileByName)
|
||||
.DELETE("/api/files/{id}", fileHandler::deleteFile)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> permissionRoutes(SysPermissionHandler permissionHandler) {
|
||||
return route()
|
||||
|
||||
// ========== 权限路由 ==========
|
||||
.GET("/api/permissions", permissionHandler::getAllPermissions)
|
||||
.GET("/api/permissions/{id}", permissionHandler::getPermissionById)
|
||||
.GET("/api/permissions/code/{code}", permissionHandler::getPermissionByCode)
|
||||
@@ -223,6 +185,7 @@ public class SystemRouter {
|
||||
.POST("/api/permissions", permissionHandler::createPermission)
|
||||
.PUT("/api/permissions/{id}", permissionHandler::updatePermission)
|
||||
.DELETE("/api/permissions/{id}", permissionHandler::deletePermission)
|
||||
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# H2数据库配置(用于测试环境)
|
||||
|
||||
spring:
|
||||
r2dbc:
|
||||
url: r2dbc:h2:mem:///testdb
|
||||
username: sa
|
||||
password:
|
||||
pool:
|
||||
initial-size: 5
|
||||
max-size: 20
|
||||
max-idle-time: 30m
|
||||
max-life-time: 1h
|
||||
acquire-timeout: 5s
|
||||
|
||||
datasource:
|
||||
url: jdbc:h2:mem:testdb
|
||||
username: sa
|
||||
password:
|
||||
driver-class-name: org.h2.Driver
|
||||
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
settings:
|
||||
web-allow-others: true
|
||||
|
||||
flyway:
|
||||
enabled: false
|
||||
|
||||
sql:
|
||||
init:
|
||||
mode: always
|
||||
continue-on-error: true
|
||||
|
||||
# 测试专用配置
|
||||
test:
|
||||
database:
|
||||
type: h2
|
||||
in-memory: true
|
||||
cleanup:
|
||||
enabled: true
|
||||
strategy: truncate
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
cn.novalon.manage: DEBUG
|
||||
org.springframework.r2dbc: DEBUG
|
||||
org.springframework.jdbc: DEBUG
|
||||
org.flywaydb: INFO
|
||||
com.h2database: WARN
|
||||
@@ -1,22 +1,65 @@
|
||||
server:
|
||||
port: 8084
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: manage-app
|
||||
r2dbc:
|
||||
url: r2dbc:h2:mem://testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE
|
||||
username: sa
|
||||
password:
|
||||
url: r2dbc:postgresql://localhost:55432/manage_system
|
||||
username: novalon
|
||||
password: novalon123
|
||||
pool:
|
||||
initial-size: 5
|
||||
max-size: 20
|
||||
max-idle-time: 30m
|
||||
max-life-time: 1h
|
||||
acquire-timeout: 5s
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:55432/manage_system
|
||||
username: novalon
|
||||
password: novalon123
|
||||
driver-class-name: org.postgresql.Driver
|
||||
flyway:
|
||||
enabled: true
|
||||
enabled: false
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
security:
|
||||
user:
|
||||
name: disabled
|
||||
password: disabled
|
||||
|
||||
rate:
|
||||
limit:
|
||||
limit-for-period: 10000
|
||||
limit-refresh-period: 1s
|
||||
timeout-duration: 0
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,env,loggers
|
||||
base-path: /actuator
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
metrics:
|
||||
tags:
|
||||
application: ${spring.application.name}
|
||||
environment: ${spring.profiles.active}
|
||||
|
||||
logging:
|
||||
level:
|
||||
cn.novalon.manage: DEBUG
|
||||
org.springframework.r2dbc: DEBUG
|
||||
org.springframework.web: TRACE
|
||||
cn.novalon.manage.db: DEBUG
|
||||
org.flywaydb: INFO
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
path: /api-docs
|
||||
enabled: true
|
||||
swagger-ui:
|
||||
path: /swagger-ui.html
|
||||
enabled: true
|
||||
tags-sorter: alpha
|
||||
operations-sorter: alpha
|
||||
show-actuator: false
|
||||
default-consumes-media-type: application/json
|
||||
default-produces-media-type: application/json
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
╔═══════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ██╗ ██████╗ ███╗ ██╗ ║
|
||||
║ ████╗ ██║██╔═══██╗██║ ██║██╔══██╗██║ ██╔═══██╗████╗ ██║ ║
|
||||
║ ██╔██╗ ██║██║ ██║██║ ██║███████║██║ ██║ ██║██╔██╗ ██║ ║
|
||||
║ ██║╚██╗██║██║ ██║╚██╗ ██╔╝██╔══██║██║ ██║ ██║██║╚██╗██║ ║
|
||||
║ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║███████╗╚██████╔╝██║ ╚████║ ║
|
||||
║ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═══╝ ║
|
||||
║ ║
|
||||
║ ███╗ ███╗ █████╗ ███╗ ██╗ █████╗ ██████╗ ███████╗ ║
|
||||
║ ████╗ ████║██╔══██╗████╗ ██║██╔══██╗██╔════╝ ██╔════╝ ║
|
||||
║ ██╔████╔██║███████║██╔██╗ ██║███████║██║ ███╗█████╗ ║
|
||||
║ ██║╚██╔╝██║██╔══██║██║╚██╗██║██╔══██║██║ ██║██╔══╝ ║
|
||||
║ ██║ ╚═╝ ██║██║ ██║██║ ╚████║██║ ██║╚██████╔╝███████╗ ║
|
||||
║ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ║
|
||||
║ ║
|
||||
║ ███████╗██╗ ██╗███████╗████████╗███████╗███╗ ███╗ ║
|
||||
║ ██╔════╝╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝████╗ ████║ ║
|
||||
║ ███████╗ ╚████╔╝ ███████╗ ██║ █████╗ ██╔████╔██║ ║
|
||||
║ ╚════██║ ╚██╔╝ ╚════██║ ██║ ██╔══╝ ██║╚██╔╝██║ ║
|
||||
║ ███████║ ██║ ███████║ ██║ ███████╗██║ ╚═╝ ██║ ║
|
||||
║ ╚══════╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
:: Novalon Manage System ::
|
||||
Version: ${application.version:Unknown}
|
||||
Spring Boot: ${spring-boot.version}
|
||||
Java: ${java.version}
|
||||
PID: ${PID}
|
||||
Reference in New Issue
Block a user