feat: 完善系统配置审计通知功能并优化异常处理

- 新增异常处理体系(BaseException及其子类)
- 优化密码、邮箱、用户名等基础类型
- 添加字典管理、登录日志、操作日志的E2E测试
- 完善API集成测试和安全测试
- 添加性能测试配置和脚本
- 优化OpenAPI配置和全局异常处理器
This commit is contained in:
张翔
2026-03-24 14:05:35 +08:00
parent be5d5ede90
commit e4721053bd
47 changed files with 3006 additions and 816 deletions
@@ -0,0 +1,300 @@
package cn.novalon.manage.sys.primitive;
import cn.novalon.manage.common.exception.ErrorCode;
import cn.novalon.manage.common.exception.ValidationException;
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.*;
/**
* Password详细测试 - 提升分支覆盖率
*
* @author 张翔
* @date 2026-03-24
*/
class PasswordDetailedTest {
@Test
void testValidPassword() {
Password password = Password.of("Valid@123");
assertNotNull(password);
assertEquals("Valid@123", password.getValue());
}
@Test
void testNullPassword() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of(null);
});
assertEquals(ErrorCode.VALIDATION_REQUIRED, exception.getErrorCode());
}
@Test
void testEmptyPassword() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("");
});
assertEquals(ErrorCode.VALIDATION_REQUIRED, exception.getErrorCode());
}
@Test
void testWhitespacePassword() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of(" ");
});
assertEquals(ErrorCode.VALIDATION_REQUIRED, exception.getErrorCode());
}
@Test
void testTooShortPassword() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("Short1@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_LENGTH, exception.getErrorCode());
assertTrue(exception.getMessage().contains("at least 8 characters"));
}
@Test
void testExactlyMinLengthPassword() {
Password password = Password.of("Valid1@");
assertNotNull(password);
assertEquals("Valid1@", password.getValue());
}
@Test
void testPasswordWithoutUppercase() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("lowercase1@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
assertTrue(exception.getMessage().contains("uppercase letter"));
}
@Test
void testPasswordWithoutLowercase() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("UPPERCASE1@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
assertTrue(exception.getMessage().contains("lowercase letter"));
}
@Test
void testPasswordWithoutDigit() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("NoDigits@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
assertTrue(exception.getMessage().contains("digit"));
}
@Test
void testPasswordWithoutSpecialCharacter() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("NoSpecial123");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
assertTrue(exception.getMessage().contains("special character"));
}
@ParameterizedTest
@ValueSource(strings = {
"Valid@123",
"Another@456",
"Test@789",
"Complex@Pass123",
"Simple@Pass456"
})
void testMultipleValidPasswords(String password) {
Password pwd = Password.of(password);
assertNotNull(pwd);
assertEquals(password, pwd.getValue());
}
@ParameterizedTest
@ValueSource(strings = {
"lowercase@123",
"UPPERCASE@123",
"MixedCase@abc",
"MixedCase123"
})
void testMultipleInvalidPasswords(String password) {
assertThrows(ValidationException.class, () -> {
Password.of(password);
});
}
@Test
void testPasswordWithOnlyUppercaseAndDigit() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("UPPERCASE123");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithOnlyLowercaseAndDigit() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("lowercase123");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithOnlyUppercaseAndSpecial() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("UPPERCASE@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithOnlyLowercaseAndSpecial() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("lowercase@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithOnlyDigitAndSpecial() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("123456@");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithMultipleSpecialCharacters() {
Password password = Password.of("Valid@#$123");
assertNotNull(password);
assertEquals("Valid@#$123", password.getValue());
}
@Test
void testPasswordWithSpaces() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("Valid @123");
});
assertEquals(ErrorCode.VALIDATION_REQUIRED, exception.getErrorCode());
}
@Test
void testVeryLongPassword() {
Password password = Password.of("VeryLongPassword@1234567890");
assertNotNull(password);
assertEquals("VeryLongPassword@1234567890", password.getValue());
}
@Test
void testPasswordEquals() {
Password password1 = Password.of("Valid@123");
Password password2 = Password.of("Valid@123");
assertEquals(password1, password2);
}
@Test
void testPasswordNotEquals() {
Password password1 = Password.of("Valid@123");
Password password2 = Password.of("Different@456");
assertNotEquals(password1, password2);
}
@Test
void testPasswordEqualsNull() {
Password password = Password.of("Valid@123");
assertNotEquals(password, null);
}
@Test
void testPasswordEqualsDifferentClass() {
Password password = Password.of("Valid@123");
assertNotEquals(password, "Valid@123");
}
@Test
void testPasswordEqualsSameInstance() {
Password password = Password.of("Valid@123");
assertEquals(password, password);
}
@Test
void testPasswordHashCode() {
Password password1 = Password.of("Valid@123");
Password password2 = Password.of("Valid@123");
assertEquals(password1.hashCode(), password2.hashCode());
}
@Test
void testPasswordHashCodeDifferent() {
Password password1 = Password.of("Valid@123");
Password password2 = Password.of("Different@456");
assertNotEquals(password1.hashCode(), password2.hashCode());
}
@Test
void testPasswordToString() {
Password password = Password.of("Valid@123");
String toString = password.toString();
assertEquals("********", toString);
assertFalse(toString.contains("Valid"));
assertFalse(toString.contains("123"));
}
@Test
void testPasswordWithUnicodeCharacters() {
Password password = Password.of("密码@123");
assertNotNull(password);
assertEquals("密码@123", password.getValue());
}
@Test
void testPasswordWithNumbersOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("12345678");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithLettersOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("abcdefgh");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithSpecialOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("@#$%^&*()");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithUppercaseLowercaseOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("AbCdEfGh");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithUppercaseDigitOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("ABCDEFGH12345678");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
@Test
void testPasswordWithLowercaseDigitOnly() {
ValidationException exception = assertThrows(ValidationException.class, () -> {
Password.of("abcdefgh12345678");
});
assertEquals(ErrorCode.VALIDATION_INVALID_VALUE, exception.getErrorCode());
}
}