Skip to content

Commit

Permalink
Merge pull request #18 from TingSHI2015/Add-Tips(preset)-function
Browse files Browse the repository at this point in the history
Add tips(preset) function
  • Loading branch information
TingSHI2015 authored Jul 3, 2024
2 parents 99b8aab + b2c7a8c commit b75a3b6
Show file tree
Hide file tree
Showing 26 changed files with 683 additions and 125 deletions.

This file was deleted.

11 changes: 11 additions & 0 deletions backend/src/main/java/com/github/tingshi2015/backend/tips/Tip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.tingshi2015.backend.tips;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "tips")
public record Tip(
@Id
String id,
String content) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.tingshi2015.backend.tips;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/tips")
@RequiredArgsConstructor
public class TipController {

private final TipService tipService;

// @GetMapping
// public List<String> getDefaultTips(){
// return List.of(
// "Drink water",
// "Call Papa & Mama",
// "Give sb. a Big Hug!",
// "5-minute eye massage",
// "Tell self: u'r great!",
// "Read",
// "Meditate",
// "Water plants"
// );
// }

@GetMapping
List<Tip> getAllTips(){
return tipService.getAllTips();
}

@PostMapping
public Tip addTip(@RequestBody TipDTO tipDTO){
return tipService.addTips(tipDTO);
}

@DeleteMapping("{id}")
public void deleteTip(@PathVariable String id){
tipService.deleteTip(id);
}

@PutMapping("{id}")
public Tip putATip(@RequestBody TipDTO tipDTO, @PathVariable String id){
return tipService.updateATip(tipDTO, id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.tingshi2015.backend.tips;

public record TipDTO(String content) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.github.tingshi2015.backend.tips;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface TipRepository extends MongoRepository<Tip, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.tingshi2015.backend.tips;

import com.github.tingshi2015.backend.reminder.IdService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.NoSuchElementException;


@Service
@RequiredArgsConstructor
public class TipService {
private final TipRepository tipRepository;
private final IdService idService;

private Tip convertToEntity(TipDTO tipDTO){
String id = idService.randomId();
return new Tip(id, tipDTO.content());
}

public List<Tip> getAllTips() {
return tipRepository.findAll();
}

public Tip addTips(TipDTO tipDTO) {
Tip tipToRepo = convertToEntity(tipDTO);
return tipRepository.save(tipToRepo);
}

public void deleteTip(String id) {
if (!tipRepository.existsById(id)){
throw new NoSuchElementException(("Tip with id: " + id + " not found. Can't delete!"));
}
tipRepository.deleteById(id);
}

public Tip updateATip(TipDTO tipDTO, String id) {
if (!tipRepository.existsById(id)){
throw new NoSuchElementException(("Tip with id: " + id + " not found. Can't update!"));
}
Tip tipToUpdate = new Tip(id, tipDTO.content());
return tipRepository.save(tipToUpdate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.github.tingshi2015.backend.tips;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

@SpringBootTest
@AutoConfigureMockMvc
class TipControllerIntegrationTest {

@Autowired
MockMvc mockMvc;

@Autowired
TipRepository tipRepository;

@Test
void getAllTips_shouldReturnEmptyList_whenRepoIsEmpty() throws Exception {
//GIVEN

//WHEN
mockMvc.perform(MockMvcRequestBuilders.get("/api/tips"))
//THEN
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().json("""
[]
"""));
}

@Test
@DirtiesContext
void getAllTips_shouldReturnListWithOneObject_whenOneObjectWasSavedInRepoIsEmpty() throws Exception {
//GIVEN
Tip tip = new Tip("id100", "Drink Water!");
tipRepository.save(tip);

//WHEN
mockMvc.perform(MockMvcRequestBuilders.get("/api/tips"))
//THEN
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().json(
"""
[{
"id": "id100",
"content": "Drink Water!"
}]
"""));
}

@Test
@DirtiesContext
void addTip_shouldReturnCreatedTip() throws Exception {
//GIVEN

//WHEN
mockMvc.perform(MockMvcRequestBuilders.post("/api/tips")
.contentType(MediaType.APPLICATION_JSON)
.content(
"""
{
"content": "Drink Water!"
}
"""))
//THEN
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().json(
"""
{
"content": "Drink Water!"
}
"""))
.andExpect(MockMvcResultMatchers.jsonPath("$.id").isNotEmpty());
}

@Test
@DirtiesContext
void deleteTip() throws Exception {
//GIVEN
Tip existingTip = new Tip("id101", "Drink Beer");
tipRepository.save(existingTip);

//WHEN
mockMvc.perform(MockMvcRequestBuilders.delete("/api/tips/id101"))
//THEN
.andExpect(MockMvcResultMatchers.status().isOk());
}


@Test
@DirtiesContext
void putATip() throws Exception {
//GIVEN
Tip exsistedTip = new Tip("id99", "Hahaha");
tipRepository.save(exsistedTip);

//WHEN
mockMvc.perform(MockMvcRequestBuilders.put("/api/tips/id99")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"content": "Updated-Hahaha"
}
"""))
//THEN
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().json("""
{
"id": "id99",
"content": "Updated-Hahaha"
}
"""));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package com.github.tingshi2015.backend.tips;

import com.github.tingshi2015.backend.reminder.IdService;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.NoSuchElementException;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class TipServiceUnitTest {
TipRepository tipRepository = mock(TipRepository.class);
IdService idService = mock(IdService.class);
TipService tipService = new TipService(tipRepository, idService);


@Test
void getAllTips_shouldReturnAllTips() {
//GIVEN
Tip tip1 = new Tip("id1", "Drink Water.");
Tip tip2 = new Tip("id2", "Call Papa & Mama.");
List<Tip> tips = List.of(tip1, tip2);

when(tipRepository.findAll()).thenReturn(tips);

//WHEN
List<Tip> actual = tipService.getAllTips();

//THEN
verify(tipRepository).findAll();
assertEquals(tips, actual);
}

@Test
void addTips() {
//GIVEN
TipDTO tipDTO = new TipDTO("New Tip");
Tip tipToSave = new Tip("id1", "New Tip");

when(idService.randomId()).thenReturn("id1");
when(tipRepository.save(tipToSave)).thenReturn(tipToSave);

//WHEN
Tip actual = tipService.addTips(tipDTO);

//THEN
verify(idService).randomId();
verify(tipRepository).save(tipToSave);
assertEquals(tipToSave, actual);
}

@Test
void deleteTip_withValidId_shouldInvokeRepositoryDeleteById() {
//GIVEN
String id = "id1";
when(tipRepository.existsById(id)).thenReturn(true);
doNothing().when(tipRepository).deleteById(id);

//WHEN
tipService.deleteTip(id);

//THEN
verify(tipRepository).existsById(id);
verify(tipRepository, times(1)).deleteById(id);
}

@Test
void deleteTip_withInvalidId_shouldThrowException() {
//GIVEN
String id = "id1";
when(tipRepository.existsById(id)).thenReturn(false);

//WHEN
NoSuchElementException exception = assertThrows(NoSuchElementException.class, () -> tipService.deleteTip(id));

//THEN
verify(tipRepository, never()).deleteById(id);
assertEquals("Tip with id: id1 not found. Can't delete!", exception.getMessage());
}

@Test
void updateATip_withValidId_shouldReturnTip() {
//GIVEN
String id = "1ab_c";
TipDTO updateTip = new TipDTO("Drink Water.");
Tip tipToUpdate = new Tip("1ab_c", "Drink Water.");

when(tipRepository.existsById(id)).thenReturn(true);
when(tipRepository.save(tipToUpdate)).thenReturn(tipToUpdate);

//WHEN
Tip actual = tipService.updateATip(updateTip, id);

//THEN
verify(tipRepository).existsById(id);
verify(tipRepository).save(tipToUpdate);
assertEquals(tipToUpdate, actual);
}

@Test
void updateATip_withInvalidId_shouldThrowException() {
//GIVEN
String id = "1ab_c";
TipDTO updateTip = new TipDTO("Drink Water.");

when(tipRepository.existsById(id)).thenReturn(false);

//WHEN
NoSuchElementException exception = assertThrows(NoSuchElementException.class, () -> tipService.updateATip(updateTip, id));

//THEN
verify(tipRepository, never()).save(any(Tip.class));
assertEquals("Tip with id: 1ab_c not found. Can't update!", exception.getMessage());
}


}
Loading

0 comments on commit b75a3b6

Please sign in to comment.