read comments
This commit is contained in:
parent
445311ee1b
commit
f31bcbc6e0
@ -22,6 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "/articles/{slug}")
|
||||
@ -36,13 +38,15 @@ public class ArticleApi {
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<ArticleData> article(@PathVariable("slug") String slug,
|
||||
public ResponseEntity<?> article(@PathVariable("slug") String slug,
|
||||
@AuthenticationPrincipal User user) {
|
||||
return articleQueryService.findBySlug(slug, user).map(ResponseEntity::ok).orElseThrow(ResourceNotFoundException::new);
|
||||
return articleQueryService.findBySlug(slug, user)
|
||||
.map(articleData -> ResponseEntity.ok(articleResponse(articleData)))
|
||||
.orElseThrow(ResourceNotFoundException::new);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public ResponseEntity<ArticleData> updateArticle(@PathVariable("slug") String slug,
|
||||
public ResponseEntity<?> updateArticle(@PathVariable("slug") String slug,
|
||||
@AuthenticationPrincipal User user,
|
||||
@Valid @RequestBody UpdateArticleParam updateArticleParam) {
|
||||
return articleRepository.findBySlug(slug).map(article -> {
|
||||
@ -54,7 +58,7 @@ public class ArticleApi {
|
||||
updateArticleParam.getDescription(),
|
||||
updateArticleParam.getBody());
|
||||
articleRepository.save(article);
|
||||
return ResponseEntity.ok(articleQueryService.findBySlug(slug, user).get());
|
||||
return ResponseEntity.ok(articleResponse(articleQueryService.findBySlug(slug, user).get()));
|
||||
}).orElseThrow(ResourceNotFoundException::new);
|
||||
}
|
||||
|
||||
@ -69,6 +73,12 @@ public class ArticleApi {
|
||||
return ResponseEntity.noContent().build();
|
||||
}).orElseThrow(ResourceNotFoundException::new);
|
||||
}
|
||||
|
||||
private Map<String, Object> articleResponse(ArticleData articleData) {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("article", articleData);
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "/articles")
|
||||
@ -47,7 +48,9 @@ public class ArticlesApi {
|
||||
newArticleParam.getTagList(),
|
||||
user.getId());
|
||||
articleRepository.save(article);
|
||||
return ResponseEntity.ok(articleQueryService.findById(article.getId(), user).get());
|
||||
return ResponseEntity.ok(new HashMap<String, Object>() {{
|
||||
put("article", articleQueryService.findById(article.getId(), user).get());
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -25,6 +26,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.xml.ws.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "/articles/{slug}/comments")
|
||||
@ -43,7 +47,7 @@ public class CommentsApi {
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<CommentData> createComment(@PathVariable("slug") String slug,
|
||||
public ResponseEntity<?> createComment(@PathVariable("slug") String slug,
|
||||
@AuthenticationPrincipal User user,
|
||||
@Valid @RequestBody NewCommentParam newCommentParam,
|
||||
BindingResult bindingResult) {
|
||||
@ -53,12 +57,28 @@ public class CommentsApi {
|
||||
}
|
||||
Comment comment = new Comment(newCommentParam.getBody(), user.getId(), article.getId());
|
||||
commentRepository.save(comment);
|
||||
return ResponseEntity.status(201).body(commentQueryService.findById(comment.getId(), user).get());
|
||||
return ResponseEntity.status(201).body(commentResponse(commentQueryService.findById(comment.getId(), user).get()));
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity getComments(@PathVariable("slug") String slug,
|
||||
@AuthenticationPrincipal User user) {
|
||||
Article article = findArticle(slug);
|
||||
List<CommentData> comments = commentQueryService.findByArticleSlug(article.getSlug(), user);
|
||||
return ResponseEntity.ok(new HashMap<String, Object>() {{
|
||||
put("comments", comments);
|
||||
}});
|
||||
}
|
||||
|
||||
private Article findArticle(String slug) {
|
||||
return articleRepository.findBySlug(slug).map(article -> article).orElseThrow(ResourceNotFoundException::new);
|
||||
}
|
||||
|
||||
private Map<String, Object> commentResponse(CommentData commentData) {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("comment", commentData);
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
@ -2,6 +2,7 @@ package io.spring.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
import io.spring.application.user.UserQueryService;
|
||||
import io.spring.application.user.UserWithToken;
|
||||
import io.spring.core.user.User;
|
||||
import io.spring.core.user.UserRepository;
|
||||
import lombok.Getter;
|
||||
@ -19,6 +20,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "/user")
|
||||
@ -35,7 +38,7 @@ public class CurrentUserApi {
|
||||
@GetMapping
|
||||
public ResponseEntity currentUser(@AuthenticationPrincipal User currentUser,
|
||||
@RequestHeader(value = "Authorization") String authorization) {
|
||||
return ResponseEntity.ok(userQueryService.fetchCurrentUser(currentUser.getUsername(), authorization.split(" ")[1]));
|
||||
return ResponseEntity.ok(userResponse(userQueryService.fetchCurrentUser(currentUser.getUsername(), authorization.split(" ")[1])));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@ -50,7 +53,13 @@ public class CurrentUserApi {
|
||||
updateUserParam.getBio(),
|
||||
updateUserParam.getImage());
|
||||
userRepository.save(currentUser);
|
||||
return ResponseEntity.ok(userQueryService.fetchCurrentUser(currentUser.getUsername(), authorization.split(" ")[1]));
|
||||
return ResponseEntity.ok(userResponse(userQueryService.fetchCurrentUser(currentUser.getUsername(), authorization.split(" ")[1])));
|
||||
}
|
||||
|
||||
private Map<String, Object> userResponse(UserWithToken userWithToken) {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("user", userWithToken);
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@ package io.spring.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
import io.spring.api.exception.InvalidRequestException;
|
||||
import io.spring.application.user.UserData;
|
||||
import io.spring.application.user.UserQueryService;
|
||||
import io.spring.application.user.UserWithToken;
|
||||
import io.spring.core.user.EncryptService;
|
||||
import io.spring.core.user.User;
|
||||
import io.spring.core.user.UserRepository;
|
||||
@ -20,6 +22,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
@ -63,19 +67,25 @@ public class UsersApi {
|
||||
"",
|
||||
defaultImage);
|
||||
userRepository.save(user);
|
||||
return ResponseEntity.status(201).body(userQueryService.fetchNewAuthenticatedUser(user.getUsername()));
|
||||
return ResponseEntity.status(201).body(userResponse(userQueryService.fetchNewAuthenticatedUser(user.getUsername())));
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/users/login", method = POST)
|
||||
public ResponseEntity userLogin(@Valid @RequestBody LoginParam loginParam, BindingResult bindingResult) {
|
||||
Optional<User> optional = userRepository.findByEmail(loginParam.getEmail());
|
||||
if (optional.isPresent() && encryptService.check(loginParam.getPassword(), optional.get().getPassword())) {
|
||||
return ResponseEntity.ok(userQueryService.fetchNewAuthenticatedUser(optional.get().getUsername()));
|
||||
return ResponseEntity.ok(userResponse(userQueryService.fetchNewAuthenticatedUser(optional.get().getUsername())));
|
||||
} else {
|
||||
bindingResult.rejectValue("password", "INVALID", "invalid email or password");
|
||||
throw new InvalidRequestException(bindingResult);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> userResponse(UserWithToken userWithToken) {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("user", userWithToken);
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
@ -15,13 +15,14 @@ public class ErrorResourceSerializer extends JsonSerializer<ErrorResource> {
|
||||
@Override
|
||||
public void serialize(ErrorResource value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
|
||||
Map<String, List<String>> json = new HashMap<>();
|
||||
gen.writeStartObject();
|
||||
gen.writeObjectFieldStart("errors");
|
||||
for (FieldErrorResource fieldErrorResource : value.getFieldErrors()) {
|
||||
if (!json.containsKey(fieldErrorResource.getField())) {
|
||||
json.put(fieldErrorResource.getField(), new ArrayList<String>());
|
||||
}
|
||||
json.get(fieldErrorResource.getField()).add(fieldErrorResource.getMessage());
|
||||
}
|
||||
gen.writeStartObject();
|
||||
for (Map.Entry<String, List<String>> pair : json.entrySet()) {
|
||||
gen.writeArrayFieldStart(pair.getKey());
|
||||
pair.getValue().forEach(content -> {
|
||||
@ -34,5 +35,6 @@ public class ErrorResourceSerializer extends JsonSerializer<ErrorResource> {
|
||||
gen.writeEndArray();
|
||||
}
|
||||
gen.writeEndObject();
|
||||
gen.writeEndObject();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
package io.spring.api.exception;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@JsonRootName("errors")
|
||||
public class InvalidRequestException extends RuntimeException {
|
||||
private final Errors errors;
|
||||
|
||||
|
@ -13,7 +13,6 @@ import java.util.List;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonRootName("article")
|
||||
public class ArticleData {
|
||||
private String id;
|
||||
private String slug;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.spring.application.comment;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
import io.spring.application.profile.ProfileData;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -11,10 +11,10 @@ import org.joda.time.DateTime;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonRootName("comment")
|
||||
public class CommentData {
|
||||
private String id;
|
||||
private String body;
|
||||
@JsonIgnore
|
||||
private String articleId;
|
||||
private DateTime createdAt;
|
||||
private DateTime updatedAt;
|
||||
|
@ -4,6 +4,8 @@ import io.spring.application.profile.UserRelationshipQueryService;
|
||||
import io.spring.core.user.User;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@ -28,4 +30,8 @@ public class CommentQueryService {
|
||||
}
|
||||
return Optional.ofNullable(commentData);
|
||||
}
|
||||
|
||||
public List<CommentData> findByArticleSlug(String slug, User user) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import lombok.NoArgsConstructor;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonRootName("user")
|
||||
public class UserData {
|
||||
private String id;
|
||||
private String email;
|
||||
|
@ -25,21 +25,3 @@ public class UserQueryService {
|
||||
}
|
||||
}
|
||||
|
||||
@JsonRootName("user")
|
||||
@Getter
|
||||
class UserWithToken {
|
||||
private String email;
|
||||
private String username;
|
||||
private String bio;
|
||||
private String image;
|
||||
private String token;
|
||||
|
||||
public UserWithToken(UserData userData, String token) {
|
||||
this.email = userData.getEmail();
|
||||
this.username = userData.getUsername();
|
||||
this.bio = userData.getBio();
|
||||
this.image = userData.getImage();
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
}
|
21
src/main/java/io/spring/application/user/UserWithToken.java
Normal file
21
src/main/java/io/spring/application/user/UserWithToken.java
Normal file
@ -0,0 +1,21 @@
|
||||
package io.spring.application.user;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class UserWithToken {
|
||||
private String email;
|
||||
private String username;
|
||||
private String bio;
|
||||
private String image;
|
||||
private String token;
|
||||
|
||||
public UserWithToken(UserData userData, String token) {
|
||||
this.email = userData.getEmail();
|
||||
this.username = userData.getUsername();
|
||||
this.bio = userData.getBio();
|
||||
this.image = userData.getImage();
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
spring.jackson.deserialization.UNWRAP_ROOT_VALUE=true
|
||||
spring.jackson.serialization.WRAP_ROOT_VALUE=true
|
||||
image.default=https://static.productionready.io/images/smiley-cyrus.jpg
|
||||
jwt.secret=nRvyYC4soFxBdZ-F-5Nnzz5USXstR1YylsTd-mA0aKtI9HUlriGrtkf-TiuDapkLiUCogO3JOK7kwZisrHp6wA
|
||||
jwt.sessionTime=86400
|
||||
|
@ -111,6 +111,7 @@ public class ArticlesApiTest extends TestWithCurrentUser {
|
||||
.body(param)
|
||||
.when()
|
||||
.post("/articles")
|
||||
.prettyPeek()
|
||||
.then()
|
||||
.statusCode(422)
|
||||
.body("errors.body[0]", equalTo("can't be empty"));
|
||||
|
@ -16,6 +16,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -47,6 +48,7 @@ public class CommentsApiTest extends TestWithCurrentUser {
|
||||
private CommentQueryService commentQueryService;
|
||||
|
||||
private Article article;
|
||||
private CommentData commentData;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@ -58,6 +60,13 @@ public class CommentsApiTest extends TestWithCurrentUser {
|
||||
|
||||
article = new Article("title", "desc", "body", new String[]{"test", "java"}, user.getId());
|
||||
when(articleRepository.findBySlug(eq(article.getSlug()))).thenReturn(Optional.of(article));
|
||||
commentData = new CommentData(
|
||||
"123",
|
||||
"comment",
|
||||
article.getId(),
|
||||
new DateTime(),
|
||||
new DateTime(),
|
||||
new ProfileData(user.getId(), user.getUsername(), user.getBio(), user.getImage(), false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -68,14 +77,6 @@ public class CommentsApiTest extends TestWithCurrentUser {
|
||||
}});
|
||||
}};
|
||||
|
||||
CommentData commentData = new CommentData(
|
||||
"123",
|
||||
"comment",
|
||||
article.getId(),
|
||||
new DateTime(),
|
||||
new DateTime(),
|
||||
new ProfileData(user.getId(), user.getUsername(), user.getBio(), user.getImage(), false));
|
||||
|
||||
when(commentQueryService.findById(anyString(), eq(user))).thenReturn(Optional.of(commentData));
|
||||
|
||||
given()
|
||||
@ -108,4 +109,15 @@ public class CommentsApiTest extends TestWithCurrentUser {
|
||||
.body("errors.body[0]", equalTo("can't be empty"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_comments_of_article_success() throws Exception {
|
||||
when(commentQueryService.findByArticleSlug(anyString(), eq(null))).thenReturn(Arrays.asList(commentData));
|
||||
RestAssured.when()
|
||||
.get("/articles/{slug}/comments", article.getSlug())
|
||||
.prettyPeek()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("comments[0].id", equalTo(commentData.getId()));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user