Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/levvel/io/controller/BlogController.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package levvel.io.controller;

import levvel.io.model.Blog;
import levvel.io.model.Comment;
import levvel.io.model.CommentList;
import levvel.io.service.BlogService;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@AllArgsConstructor
@RequestMapping("/blog")
Expand All @@ -24,4 +28,22 @@ public ResponseEntity<Blog> getBlog(@PathVariable String id) {
Blog blog = blogService.getBlog(id);
return ResponseEntity.ok().body(blog);
}

@GetMapping("")
public ResponseEntity<List<Blog>> getBlogs() {
List<Blog> blogs = blogService.getBlogs();
return ResponseEntity.ok().body(blogs);
}

@PostMapping("/post/{id}/comment")
public ResponseEntity<Comment> addComment(@PathVariable String id, @RequestBody Comment comment) {
blogService.addComment(id, comment);
return ResponseEntity.ok().body(comment);
}

@GetMapping("/post/{id}/comment")
public ResponseEntity<List<Comment>> getComments(@PathVariable String id) {
List<Comment> comments = blogService.getComments(id);
return ResponseEntity.ok().body(comments);
}
}
9 changes: 9 additions & 0 deletions src/main/java/levvel/io/data/CommentRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package levvel.io.data;

import levvel.io.model.CommentList;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CommentRepository extends MongoRepository<CommentList, String> {
}
24 changes: 24 additions & 0 deletions src/main/java/levvel/io/model/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package levvel.io.model;

import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;

import java.time.LocalDateTime;

@Data
public class Comment {

@Id
String id;

@CreatedDate
private LocalDateTime createdDate;

@LastModifiedDate
private LocalDateTime lastModifiedDate;

String author;
String text;
}
21 changes: 21 additions & 0 deletions src/main/java/levvel/io/model/CommentList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package levvel.io.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.data.annotation.Id;

import java.util.List;

@Data
@AllArgsConstructor
public class CommentList {

@Id
String blogId;

List<Comment> comments;

public void addComment(Comment comment) {
comments.add(comment);
}
}
9 changes: 9 additions & 0 deletions src/main/java/levvel/io/service/BlogService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package levvel.io.service;

import levvel.io.model.Blog;
import levvel.io.model.Comment;

import java.util.List;

public interface BlogService {

void addBlog(Blog blog);

Blog getBlog(String id);

List<Blog> getBlogs();

void addComment(String id, Comment comment);

List<Comment> getComments(String id);
}
34 changes: 34 additions & 0 deletions src/main/java/levvel/io/service/BlogServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
package levvel.io.service;

import levvel.io.data.BlogRepository;
import levvel.io.data.CommentRepository;
import levvel.io.model.Blog;
import levvel.io.model.Comment;
import levvel.io.model.CommentList;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class BlogServiceImpl implements BlogService {

private BlogRepository blogRepository;
private CommentRepository commentRepository;

@Override
public void addBlog(Blog blog) {
// Save the blog
blogRepository.save(blog);

// Create a comment section for this Blog
CommentList commentList = new CommentList(blog.getId(), new ArrayList<>());
commentRepository.save(commentList);
}

@Override
public Blog getBlog(String id) {
// Get the blog from the id
return blogRepository.findById(id).orElseGet(null);
}

@Override
public List<Blog> getBlogs() {
// Function to get all blogs, useful for debugging
return blogRepository.findAll();
}

@Override
public void addComment(String id, Comment comment) {
// Get current comment list for this blog and append comment to it
CommentList commentList = commentRepository.findById(id).orElseGet(null);
commentList.addComment(comment);
commentRepository.save(commentList);
}

@Override
public List<Comment> getComments(String id) {
// Get the object and extract the list of comments
CommentList commentList = commentRepository.findById(id).orElseGet(null);
return commentList.getComments();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@

server.port=8090
34 changes: 34 additions & 0 deletions src/test/java/levvel/io/BlogTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package levvel.io;

import com.fasterxml.jackson.databind.ObjectMapper;
import levvel.io.model.Blog;
import levvel.io.model.Comment;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

public abstract class BlogTest {

protected static final String ID = "fake_id";

protected Blog getBlogFromResource() throws IOException {
File file = new File(
Objects.requireNonNull(this.getClass().getClassLoader().getResource("addBlog.json")).getFile()
);

ObjectMapper mapper = new ObjectMapper();

return mapper.readValue(file, Blog.class);
}

protected Comment getCommentFromResource() throws IOException {
File file = new File(
Objects.requireNonNull(this.getClass().getClassLoader().getResource("addComment.json")).getFile()
);

ObjectMapper mapper = new ObjectMapper();

return mapper.readValue(file, Comment.class);
}
}
25 changes: 23 additions & 2 deletions src/test/java/levvel/io/WorkSampleApplicationTests.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
package levvel.io;

import levvel.io.controller.BlogController;
import levvel.io.data.BlogRepository;
import levvel.io.data.CommentRepository;
import levvel.io.service.BlogService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class WorkSampleApplicationTests {

@Autowired
private BlogController blogController;

@Autowired
private BlogService blogService;

@Autowired
private BlogRepository blogRepository;

@Autowired
private CommentRepository commentRepository;

@Test
void contextLoads() {
public void contextLoads() {
assert(blogController != null);
assert(blogService != null);
assert(blogRepository != null);
assert(commentRepository != null);
}

}
61 changes: 61 additions & 0 deletions src/test/java/levvel/io/controller/BlogControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package levvel.io.controller;

import levvel.io.BlogTest;
import levvel.io.model.Blog;
import levvel.io.model.Comment;
import levvel.io.service.BlogService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.ResponseEntity;

import java.io.IOException;
import java.util.List;

import static org.mockito.Mockito.mock;

public class BlogControllerTest extends BlogTest {

private BlogController blogController;

private Blog blog;
private Comment comment;

@BeforeEach
void setup() throws IOException {
BlogService blogService = mock(BlogService.class);

blogController = new BlogController(blogService);

blog = getBlogFromResource();
comment = getCommentFromResource();
}

@Test
void testAddBlog() {
ResponseEntity<Blog> response = blogController.addBlog(blog);

Assertions.assertEquals(response.getStatusCodeValue(), 200);
}

@Test
void testGetBlog() {
ResponseEntity<Blog> response = blogController.getBlog(ID);

Assertions.assertEquals(response.getStatusCodeValue(), 200);
}

@Test
void testAddComment() {
ResponseEntity<Comment> response = blogController.addComment(ID, comment);

Assertions.assertEquals(response.getStatusCodeValue(), 200);
}

@Test
void testGetComment() {
ResponseEntity<List<Comment>> response = blogController.getComments(ID);

Assertions.assertEquals(response.getStatusCodeValue(), 200);
}
}
87 changes: 87 additions & 0 deletions src/test/java/levvel/io/service/BlogServiceImplTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package levvel.io.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import levvel.io.BlogTest;
import levvel.io.data.BlogRepository;
import levvel.io.data.CommentRepository;
import levvel.io.model.Blog;
import levvel.io.model.Comment;
import levvel.io.model.CommentList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static java.util.Optional.ofNullable;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

public class BlogServiceImplTest extends BlogTest {

private BlogService blogService;

private BlogRepository blogRepository;
private CommentRepository commentRepository;

private Blog blog;
private Comment comment;
private CommentList commentList;

@BeforeEach
void setup() throws IOException {
blogRepository = mock(BlogRepository.class);
commentRepository = mock(CommentRepository.class);

blogService = new BlogServiceImpl(blogRepository, commentRepository);

blog = getBlogFromResource();
comment = getCommentFromResource();

commentList = new CommentList(blog.getId(), new ArrayList<>());
}

@Test
void testAddBlog() {
blogService.addBlog(blog);

verify(blogRepository).save(any());
verify(commentRepository).save(any());
}

@Test
void testGetBlog() {
when(blogRepository.findById(any())).thenReturn(ofNullable(blog));

Blog returnedBlog = blogService.getBlog(ID);

verify(blogRepository).findById(ID);

Assertions.assertEquals(blog, returnedBlog);
}

@Test
void testAddComment() {
when(commentRepository.findById(any())).thenReturn(ofNullable(commentList));

blogService.addComment(ID, comment);

verify(commentRepository).findById(any());
verify(commentRepository).save(any());
}

@Test
void testGetComments() {
when(commentRepository.findById(any())).thenReturn(ofNullable(commentList));

List<Comment> comments = blogService.getComments(ID);

verify(commentRepository).findById(any());

Assertions.assertEquals(comments, commentList.getComments());
}
}