mirror of https://github.com/halo-dev/halo
Mark email as not required parameter in BaseComment (#1535)
* Removing email field from the required arguments in comments * Fixed gravatar and added database migration script * Adding validation test cases for PostCommentParam * Added unit test for PostCommentServiceImpl * Address comments: removing identicon in gravatar, renaming migration script * Address comment: removing gravata identicon from CommentProperties * Address comments: Adding more unit tests for comment API * Address comments: Adding integration tests for comment APIpull/1549/head
parent
d965b6c3e7
commit
b301c8e074
|
@ -51,7 +51,7 @@ public class BaseComment extends BaseEntity {
|
||||||
/**
|
/**
|
||||||
* Commentator's email.
|
* Commentator's email.
|
||||||
*/
|
*/
|
||||||
@Column(name = "email", nullable = false)
|
@Column(name = "email")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,6 @@ public abstract class BaseCommentParam<COMMENT> implements InputConverter<COMMEN
|
||||||
@Size(max = 50, message = "评论者昵称的字符长度不能超过 {max}")
|
@Size(max = 50, message = "评论者昵称的字符长度不能超过 {max}")
|
||||||
private String author;
|
private String author;
|
||||||
|
|
||||||
@NotBlank(message = "邮箱不能为空")
|
|
||||||
@Email(message = "邮箱格式不正确")
|
@Email(message = "邮箱格式不正确")
|
||||||
@Size(max = 255, message = "邮箱的字符长度不能超过 {max}")
|
@Size(max = 255, message = "邮箱的字符长度不能超过 {max}")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.persistence.criteria.Predicate;
|
import javax.persistence.criteria.Predicate;
|
||||||
|
@ -330,7 +331,8 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment.getGravatarMd5() == null) {
|
if (comment.getGravatarMd5() == null) {
|
||||||
comment.setGravatarMd5(DigestUtils.md5Hex(comment.getEmail()));
|
comment.setGravatarMd5(
|
||||||
|
DigestUtils.md5Hex(Optional.ofNullable(comment.getEmail()).orElse("")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(comment.getAuthorUrl())) {
|
if (StringUtils.isNotEmpty(comment.getAuthorUrl())) {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
-- Remove notnull for email in comments table
|
||||||
|
|
||||||
|
-- Migrate comments Table
|
||||||
|
alter table comments modify email VARCHAR(255);
|
|
@ -3,9 +3,9 @@ package run.halo.app.it;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
import org.springframework.boot.web.server.LocalServerPort;
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
import run.halo.app.model.params.InstallParam;
|
import run.halo.app.model.params.InstallParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,7 @@ import run.halo.app.model.params.InstallParam;
|
||||||
class BaseApiTest {
|
class BaseApiTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RestTemplate restTemplate;
|
TestRestTemplate restTemplate;
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
int port;
|
int port;
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
package run.halo.app.it;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import run.halo.app.model.dto.BaseCommentDTO;
|
||||||
|
import run.halo.app.model.params.PostCommentParam;
|
||||||
|
import run.halo.app.model.support.BaseResponse;
|
||||||
|
|
||||||
|
public class PostCommentApiTest extends BaseApiTest {
|
||||||
|
|
||||||
|
private static final String COMMENT_NULL_EMAIL_GRAVATAR_MD5 =
|
||||||
|
"d41d8cd98f00b204e9800998ecf8427e";
|
||||||
|
|
||||||
|
private static final String COMMENT_NULL_EMAIL_AVATAR =
|
||||||
|
"//gravatar.com/avatar/" + COMMENT_NULL_EMAIL_GRAVATAR_MD5 + "?s=256&d=";
|
||||||
|
|
||||||
|
private static final String COMMENT_AUTHOR_TEST = "TestAuthor";
|
||||||
|
|
||||||
|
private static final String COMMENT_CONTENT_TEST = "TestContent";
|
||||||
|
|
||||||
|
private static final String COMMENT_VALID_EMAIL_TEST = "test@example.com";
|
||||||
|
|
||||||
|
private static final String COMMENT_INVALID_EMAIL_TEST = "hello world";
|
||||||
|
|
||||||
|
private static final Integer COMMENT_POST_ID_TEST = 1;
|
||||||
|
|
||||||
|
private static final String COMMENT_API_ROUTE = "/api/content/posts/comments";
|
||||||
|
|
||||||
|
private static final String VALIDATION_VIOLATION_MESSAGE = "字段验证错误,请完善后重试!";
|
||||||
|
|
||||||
|
private PostCommentParam postCommentParam;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
private void setUp() {
|
||||||
|
installBlog();
|
||||||
|
postCommentParam = new PostCommentParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
|
||||||
|
public void testCommentWithNullEmail() {
|
||||||
|
// Arrange
|
||||||
|
postCommentParam.setContent(COMMENT_CONTENT_TEST);
|
||||||
|
postCommentParam.setAuthor(COMMENT_AUTHOR_TEST);
|
||||||
|
postCommentParam.setPostId(COMMENT_POST_ID_TEST);
|
||||||
|
HttpEntity<PostCommentParam> request = new HttpEntity<>(postCommentParam);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ResponseEntity<BaseResponse<BaseCommentDTO>>
|
||||||
|
result = restTemplate.exchange(blogUrl + COMMENT_API_ROUTE, HttpMethod.POST, request,
|
||||||
|
new ParameterizedTypeReference<>() {}
|
||||||
|
);
|
||||||
|
BaseCommentDTO comment = Objects.requireNonNull(result.getBody()).getData();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||||
|
Assertions.assertEquals(COMMENT_AUTHOR_TEST, comment.getAuthor());
|
||||||
|
Assertions.assertEquals(COMMENT_CONTENT_TEST, comment.getContent());
|
||||||
|
Assertions.assertNull(comment.getEmail());
|
||||||
|
Assertions.assertEquals(COMMENT_NULL_EMAIL_GRAVATAR_MD5, comment.getGravatarMd5());
|
||||||
|
Assertions.assertEquals(COMMENT_NULL_EMAIL_AVATAR, comment.getAvatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
|
||||||
|
public void testCommentWithInvalidEmail() {
|
||||||
|
// Arrange
|
||||||
|
postCommentParam.setContent(COMMENT_CONTENT_TEST);
|
||||||
|
postCommentParam.setAuthor(COMMENT_AUTHOR_TEST);
|
||||||
|
postCommentParam.setPostId(COMMENT_POST_ID_TEST);
|
||||||
|
postCommentParam.setEmail(COMMENT_INVALID_EMAIL_TEST);
|
||||||
|
HttpEntity<PostCommentParam> request = new HttpEntity<>(postCommentParam);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ResponseEntity<BaseResponse<BaseCommentDTO>>
|
||||||
|
result = restTemplate.exchange(blogUrl + COMMENT_API_ROUTE, HttpMethod.POST, request,
|
||||||
|
new ParameterizedTypeReference<>() {}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
|
||||||
|
Assertions.assertEquals(VALIDATION_VIOLATION_MESSAGE,
|
||||||
|
Objects.requireNonNull(result.getBody()).getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
|
||||||
|
public void testCommentWithValidEmail() {
|
||||||
|
// Arrange
|
||||||
|
postCommentParam.setContent(COMMENT_CONTENT_TEST);
|
||||||
|
postCommentParam.setAuthor(COMMENT_AUTHOR_TEST);
|
||||||
|
postCommentParam.setPostId(COMMENT_POST_ID_TEST);
|
||||||
|
postCommentParam.setEmail(COMMENT_VALID_EMAIL_TEST);
|
||||||
|
HttpEntity<PostCommentParam> request = new HttpEntity<>(postCommentParam);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
ResponseEntity<BaseResponse<BaseCommentDTO>>
|
||||||
|
result = restTemplate.exchange(blogUrl + COMMENT_API_ROUTE, HttpMethod.POST, request,
|
||||||
|
new ParameterizedTypeReference<>() {}
|
||||||
|
);
|
||||||
|
BaseCommentDTO comment = Objects.requireNonNull(result.getBody()).getData();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||||
|
Assertions.assertEquals(COMMENT_AUTHOR_TEST, comment.getAuthor());
|
||||||
|
Assertions.assertEquals(COMMENT_CONTENT_TEST, comment.getContent());
|
||||||
|
Assertions.assertEquals(COMMENT_VALID_EMAIL_TEST, comment.getEmail());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package run.halo.app.model.params.validation;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import javax.validation.ValidatorFactory;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import run.halo.app.model.params.PostCommentParam;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
public class PostCommentParamValidationTest {
|
||||||
|
|
||||||
|
private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||||
|
private static final String TEST_CONTENT = "TestContent";
|
||||||
|
private static final String TEST_AUTHOR = "TestAuthor";
|
||||||
|
private static final String TEST_INVALID_EMAIL = "example.com";
|
||||||
|
|
||||||
|
private Validator validator;
|
||||||
|
private PostCommentParam postCommentParam;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
validator = factory.getValidator();
|
||||||
|
postCommentParam = new PostCommentParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullEmailValidationTest() {
|
||||||
|
// Arrange
|
||||||
|
setupDefaultValuesForPostCommentParam();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Set<ConstraintViolation<PostCommentParam>> violations =
|
||||||
|
validator.validate(postCommentParam);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(0, violations.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void invalidEmailValidationTest() {
|
||||||
|
// Arrange
|
||||||
|
setupDefaultValuesForPostCommentParam();
|
||||||
|
postCommentParam.setEmail(TEST_INVALID_EMAIL);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Set<ConstraintViolation<PostCommentParam>> violations =
|
||||||
|
validator.validate(postCommentParam);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(1, violations.size());
|
||||||
|
Assertions.assertEquals("email", violations.iterator().next().getPropertyPath().toString());
|
||||||
|
Assertions.assertEquals("邮箱格式不正确", violations.iterator().next().getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupDefaultValuesForPostCommentParam() {
|
||||||
|
postCommentParam.setContent(TEST_CONTENT);
|
||||||
|
postCommentParam.setAuthor(TEST_AUTHOR);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package run.halo.app.service.impl;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import run.halo.app.model.dto.BaseCommentDTO;
|
||||||
|
import run.halo.app.model.entity.PostComment;
|
||||||
|
import run.halo.app.model.params.PostCommentParam;
|
||||||
|
import run.halo.app.model.properties.CommentProperties;
|
||||||
|
import run.halo.app.repository.PostCommentRepository;
|
||||||
|
import run.halo.app.repository.PostRepository;
|
||||||
|
import run.halo.app.service.CommentBlackListService;
|
||||||
|
import run.halo.app.service.OptionService;
|
||||||
|
import run.halo.app.service.UserService;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
public class PostCommentServiceImplTest {
|
||||||
|
|
||||||
|
private static final String POST_COMMENT_CONTENT_TEST = "TestContent";
|
||||||
|
|
||||||
|
private static final String POST_COMMENT_AUTHOR_TEST = "TestAuthor";
|
||||||
|
|
||||||
|
private static final String POST_COMMENT_GRAVATAR_MD5_TEST = "d41d8cd98f00b204e9800998ecf8427e";
|
||||||
|
|
||||||
|
private static final String GRAVATAR_SOURCE_TEST = "//example.com/avatar/";
|
||||||
|
|
||||||
|
private static final String GRAVATAR_DEFAULT_TEST = "";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PostCommentRepository mockPostCommentRepository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PostRepository mockPostRepository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private UserService mockUserService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private OptionService mockOptionService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CommentBlackListService mockCommentBlackListService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApplicationEventPublisher mockApplicationEventPublisher;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PostComment mockPostComment;
|
||||||
|
|
||||||
|
private PostCommentServiceImpl postCommentService;
|
||||||
|
|
||||||
|
private PostCommentParam postCommentParam;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.openMocks(this);
|
||||||
|
postCommentService = new PostCommentServiceImpl(
|
||||||
|
mockPostCommentRepository,
|
||||||
|
mockPostRepository,
|
||||||
|
mockUserService,
|
||||||
|
mockOptionService,
|
||||||
|
mockCommentBlackListService,
|
||||||
|
mockApplicationEventPublisher
|
||||||
|
);
|
||||||
|
postCommentParam = new PostCommentParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullEmailWithAuditCreatedByTest() {
|
||||||
|
// Arrange
|
||||||
|
postCommentParam.setContent(POST_COMMENT_CONTENT_TEST);
|
||||||
|
postCommentParam.setAuthor(POST_COMMENT_AUTHOR_TEST);
|
||||||
|
when(mockOptionService.getByPropertyOrDefault(CommentProperties.NEW_NEED_CHECK,
|
||||||
|
Boolean.class, true)).thenReturn(true);
|
||||||
|
when(mockPostComment.getId()).thenReturn(1L);
|
||||||
|
when(mockPostCommentRepository.save(any(PostComment.class))).thenReturn(mockPostComment);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
PostComment result = postCommentService.createBy(postCommentParam);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(mockPostComment, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullEmailWithoutAuditCreatedByTest() {
|
||||||
|
// Arrange
|
||||||
|
postCommentParam.setContent(POST_COMMENT_CONTENT_TEST);
|
||||||
|
postCommentParam.setAuthor(POST_COMMENT_AUTHOR_TEST);
|
||||||
|
when(mockOptionService.getByPropertyOrDefault(CommentProperties.NEW_NEED_CHECK,
|
||||||
|
Boolean.class, true)).thenReturn(false);
|
||||||
|
when(mockPostComment.getId()).thenReturn(1L);
|
||||||
|
when(mockPostCommentRepository.save(any(PostComment.class))).thenReturn(mockPostComment);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
PostComment result = postCommentService.createBy(postCommentParam);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(mockPostComment, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullEmailConvertToTest() {
|
||||||
|
// Arrange
|
||||||
|
when(mockPostComment.getGravatarMd5()).thenReturn(POST_COMMENT_GRAVATAR_MD5_TEST);
|
||||||
|
when(mockOptionService.getByPropertyOrDefault(CommentProperties.GRAVATAR_SOURCE,
|
||||||
|
String.class)).thenReturn(GRAVATAR_SOURCE_TEST);
|
||||||
|
when(mockOptionService.getByPropertyOrDefault(CommentProperties.GRAVATAR_DEFAULT,
|
||||||
|
String.class)).thenReturn(GRAVATAR_DEFAULT_TEST);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
BaseCommentDTO result = postCommentService.convertTo(mockPostComment);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assertions.assertEquals(
|
||||||
|
GRAVATAR_SOURCE_TEST + POST_COMMENT_GRAVATAR_MD5_TEST + "?s=256&d="
|
||||||
|
+ GRAVATAR_DEFAULT_TEST, result.getAvatar());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue