From aad7c2f8536d4deb95434c9ade6db8d0a8ce461d Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 18:40:55 +0200 Subject: [PATCH 01/11] Added EmergencyCrud entity and CRUD for it --- .../EmergencyContactController.java | 71 ++++++++++++++ .../contact/dto/EmergencyContactDto.java | 22 +++++ .../contact/entity/EmergencyContact.java | 26 ++++++ .../EmergencyContactRepository.java | 8 ++ .../service/EmergencyContactService.java | 17 ++++ .../impl/EmergencyContactServiceImpl.java | 93 +++++++++++++++++++ 6 files changed, 237 insertions(+) create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java new file mode 100644 index 0000000..f0d5170 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -0,0 +1,71 @@ +package com.code4ro.nextdoor.emergency.contact.controller; + +import com.code4ro.nextdoor.core.exception.NextDoorValidationException; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Objects; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/emergency-contacts") +public class EmergencyContactController { + + private final EmergencyContactService emergencyContactService; + + public EmergencyContactController(EmergencyContactService emergencyContactService) { + this.emergencyContactService = emergencyContactService; + } + + @PostMapping + public ResponseEntity save(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.save(emergencyContactDto); + + return new ResponseEntity<>(savedEmergencyContact, HttpStatus.CREATED); + } + + @PutMapping + public ResponseEntity update(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.update(emergencyContactDto); + + return ResponseEntity.ok(savedEmergencyContact); + } + + @DeleteMapping("/id/{id}") + public ResponseEntity deleteById(@PathVariable("id") String id) { + emergencyContactService.deleteById(id); + + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @GetMapping("/id/{id}") + public ResponseEntity getById(@PathVariable("id") String id) { + final EmergencyContactDto emergencyContactDto = + emergencyContactService.findByUUID(id); + + if (Objects.isNull(emergencyContactDto)) { + throw new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND); + } + + return ResponseEntity.ok(emergencyContactDto); + } + + @GetMapping + public ResponseEntity> getAll() { + final List emergencyContactDtoList = + emergencyContactService.findAll(); + + return ResponseEntity.ok(emergencyContactDtoList); + } +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java new file mode 100644 index 0000000..dc810fa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java @@ -0,0 +1,22 @@ +package com.code4ro.nextdoor.emergency.contact.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContactDto { + private String id; + + private String name; + private String surname; + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java new file mode 100644 index 0000000..f1c7caa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java @@ -0,0 +1,26 @@ +package com.code4ro.nextdoor.emergency.contact.entity; + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.Column; +import javax.persistence.Entity; + +@Entity +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContact extends BaseEntity { + private String name; + private String surname; + @Column(unique = true) + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java new file mode 100644 index 0000000..1826527 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java @@ -0,0 +1,8 @@ +package com.code4ro.nextdoor.emergency.contact.repository; + +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EmergencyContactRepository extends JpaRepository { +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java new file mode 100644 index 0000000..740bf51 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java @@ -0,0 +1,17 @@ +package com.code4ro.nextdoor.emergency.contact.service; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import java.util.List; + +public interface EmergencyContactService { + + EmergencyContactDto save(EmergencyContactDto emergencyContactDto); + + EmergencyContactDto update(EmergencyContactDto emergencyContactDto); + + void deleteById(String id); + + EmergencyContactDto findByUUID(String id); + + List findAll(); +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java new file mode 100644 index 0000000..6e6542f --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -0,0 +1,93 @@ +package com.code4ro.nextdoor.emergency.contact.service.impl; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; + +@Service +public class EmergencyContactServiceImpl implements EmergencyContactService { + + private final EmergencyContactRepository emergencyContactRepository; + + public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { + this.emergencyContactRepository = emergencyContactRepository; + } + + @Override + public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { + EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); + EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); + + return mapDtoToDTO(emergencyContactDB); + } + + @Override + public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(emergencyContactDto.getId())); + + if (dbEntity.isPresent()) { + EmergencyContact dbEmergencyContact = dbEntity.get(); + dbEmergencyContact.setAddress(emergencyContactDto.getAddress()); + dbEmergencyContact.setEmail(emergencyContactDto.getEmail()); + dbEmergencyContact.setName(emergencyContactDto.getName()); + dbEmergencyContact.setSurname(emergencyContactDto.getSurname()); + dbEmergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); + return mapDtoToDTO(emergencyContactRepository.save(dbEmergencyContact)); + } else { + return save(emergencyContactDto); + } + } + + @Override + public void deleteById(String id) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(id)); + + if (dbEntity.isPresent()) { + emergencyContactRepository.deleteById(UUID.fromString(id)); + } + } + + @Override + public EmergencyContactDto findByUUID(String id) { + return emergencyContactRepository.findById(UUID.fromString(id)) + .map(this::mapDtoToDTO) + .orElse(null); + } + + @Override + public List findAll() { + return emergencyContactRepository.findAll() + .stream() + .map(this::mapDtoToDTO) + .collect(Collectors.toList()); + } + + private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) { + return EmergencyContact.builder() + .name(emergencyContactDto.getName()) + .surname(emergencyContactDto.getSurname()) + .address(emergencyContactDto.getAddress()) + .email(emergencyContactDto.getEmail()) + .telephoneNumber(emergencyContactDto.getTelephoneNumber()) + .build(); + } + + private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { + return EmergencyContactDto.builder() + .id(String.valueOf(emergencyContact.getId())) + .name(emergencyContact.getName()) + .surname(emergencyContact.getSurname()) + .address(emergencyContact.getAddress()) + .email(emergencyContact.getEmail()) + .telephoneNumber(emergencyContact.getTelephoneNumber()) + .build(); + } +} From 742b896714c8ab7315ee75e0d86a0d085d85610f Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 18:40:55 +0200 Subject: [PATCH 02/11] Added EmergencyCrud entity and CRUD for it --- .../EmergencyContactController.java | 71 ++++++++++++++ .../contact/dto/EmergencyContactDto.java | 22 +++++ .../contact/entity/EmergencyContact.java | 26 ++++++ .../EmergencyContactRepository.java | 8 ++ .../service/EmergencyContactService.java | 17 ++++ .../impl/EmergencyContactServiceImpl.java | 93 +++++++++++++++++++ 6 files changed, 237 insertions(+) create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java new file mode 100644 index 0000000..f0d5170 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -0,0 +1,71 @@ +package com.code4ro.nextdoor.emergency.contact.controller; + +import com.code4ro.nextdoor.core.exception.NextDoorValidationException; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Objects; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/emergency-contacts") +public class EmergencyContactController { + + private final EmergencyContactService emergencyContactService; + + public EmergencyContactController(EmergencyContactService emergencyContactService) { + this.emergencyContactService = emergencyContactService; + } + + @PostMapping + public ResponseEntity save(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.save(emergencyContactDto); + + return new ResponseEntity<>(savedEmergencyContact, HttpStatus.CREATED); + } + + @PutMapping + public ResponseEntity update(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.update(emergencyContactDto); + + return ResponseEntity.ok(savedEmergencyContact); + } + + @DeleteMapping("/id/{id}") + public ResponseEntity deleteById(@PathVariable("id") String id) { + emergencyContactService.deleteById(id); + + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @GetMapping("/id/{id}") + public ResponseEntity getById(@PathVariable("id") String id) { + final EmergencyContactDto emergencyContactDto = + emergencyContactService.findByUUID(id); + + if (Objects.isNull(emergencyContactDto)) { + throw new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND); + } + + return ResponseEntity.ok(emergencyContactDto); + } + + @GetMapping + public ResponseEntity> getAll() { + final List emergencyContactDtoList = + emergencyContactService.findAll(); + + return ResponseEntity.ok(emergencyContactDtoList); + } +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java new file mode 100644 index 0000000..dc810fa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java @@ -0,0 +1,22 @@ +package com.code4ro.nextdoor.emergency.contact.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContactDto { + private String id; + + private String name; + private String surname; + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java new file mode 100644 index 0000000..f1c7caa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java @@ -0,0 +1,26 @@ +package com.code4ro.nextdoor.emergency.contact.entity; + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.Column; +import javax.persistence.Entity; + +@Entity +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContact extends BaseEntity { + private String name; + private String surname; + @Column(unique = true) + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java new file mode 100644 index 0000000..1826527 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java @@ -0,0 +1,8 @@ +package com.code4ro.nextdoor.emergency.contact.repository; + +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EmergencyContactRepository extends JpaRepository { +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java new file mode 100644 index 0000000..740bf51 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java @@ -0,0 +1,17 @@ +package com.code4ro.nextdoor.emergency.contact.service; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import java.util.List; + +public interface EmergencyContactService { + + EmergencyContactDto save(EmergencyContactDto emergencyContactDto); + + EmergencyContactDto update(EmergencyContactDto emergencyContactDto); + + void deleteById(String id); + + EmergencyContactDto findByUUID(String id); + + List findAll(); +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java new file mode 100644 index 0000000..6e6542f --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -0,0 +1,93 @@ +package com.code4ro.nextdoor.emergency.contact.service.impl; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; + +@Service +public class EmergencyContactServiceImpl implements EmergencyContactService { + + private final EmergencyContactRepository emergencyContactRepository; + + public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { + this.emergencyContactRepository = emergencyContactRepository; + } + + @Override + public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { + EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); + EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); + + return mapDtoToDTO(emergencyContactDB); + } + + @Override + public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(emergencyContactDto.getId())); + + if (dbEntity.isPresent()) { + EmergencyContact dbEmergencyContact = dbEntity.get(); + dbEmergencyContact.setAddress(emergencyContactDto.getAddress()); + dbEmergencyContact.setEmail(emergencyContactDto.getEmail()); + dbEmergencyContact.setName(emergencyContactDto.getName()); + dbEmergencyContact.setSurname(emergencyContactDto.getSurname()); + dbEmergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); + return mapDtoToDTO(emergencyContactRepository.save(dbEmergencyContact)); + } else { + return save(emergencyContactDto); + } + } + + @Override + public void deleteById(String id) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(id)); + + if (dbEntity.isPresent()) { + emergencyContactRepository.deleteById(UUID.fromString(id)); + } + } + + @Override + public EmergencyContactDto findByUUID(String id) { + return emergencyContactRepository.findById(UUID.fromString(id)) + .map(this::mapDtoToDTO) + .orElse(null); + } + + @Override + public List findAll() { + return emergencyContactRepository.findAll() + .stream() + .map(this::mapDtoToDTO) + .collect(Collectors.toList()); + } + + private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) { + return EmergencyContact.builder() + .name(emergencyContactDto.getName()) + .surname(emergencyContactDto.getSurname()) + .address(emergencyContactDto.getAddress()) + .email(emergencyContactDto.getEmail()) + .telephoneNumber(emergencyContactDto.getTelephoneNumber()) + .build(); + } + + private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { + return EmergencyContactDto.builder() + .id(String.valueOf(emergencyContact.getId())) + .name(emergencyContact.getName()) + .surname(emergencyContact.getSurname()) + .address(emergencyContact.getAddress()) + .email(emergencyContact.getEmail()) + .telephoneNumber(emergencyContact.getTelephoneNumber()) + .build(); + } +} From e2e14469e5343218bb8ea52f0ea22ffdbc298594 Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 20:57:44 +0200 Subject: [PATCH 03/11] Comments for EmergencyContact and started unit tests --- .../EmergencyContactController.java | 12 +- .../EmergencyContactServiceImplTest.java | 103 ++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java index f0d5170..ce360d0 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -3,6 +3,8 @@ import com.code4ro.nextdoor.core.exception.NextDoorValidationException; import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import java.util.List; import java.util.Objects; import org.springframework.http.HttpStatus; @@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController +@Api(value = "Emergency Contact CRUD Controller") @RequestMapping("/api/emergency-contacts") public class EmergencyContactController { @@ -27,6 +30,7 @@ public EmergencyContactController(EmergencyContactService emergencyContactServic } @PostMapping + @ApiOperation(value = "Saves an Emergency Contact") public ResponseEntity save(@RequestBody EmergencyContactDto emergencyContactDto) { final EmergencyContactDto savedEmergencyContact = emergencyContactService.save(emergencyContactDto); @@ -35,6 +39,7 @@ public ResponseEntity save(@RequestBody EmergencyContactDto } @PutMapping + @ApiOperation(value = "Updates an Emergency Contact") public ResponseEntity update(@RequestBody EmergencyContactDto emergencyContactDto) { final EmergencyContactDto savedEmergencyContact = emergencyContactService.update(emergencyContactDto); @@ -42,14 +47,16 @@ public ResponseEntity update(@RequestBody EmergencyContactD return ResponseEntity.ok(savedEmergencyContact); } - @DeleteMapping("/id/{id}") + @DeleteMapping("/{id}") + @ApiOperation(value = "Deletes an Emergency Contact by id") public ResponseEntity deleteById(@PathVariable("id") String id) { emergencyContactService.deleteById(id); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - @GetMapping("/id/{id}") + @GetMapping("/{id}") + @ApiOperation(value = "Gets an Emergency Contact by id") public ResponseEntity getById(@PathVariable("id") String id) { final EmergencyContactDto emergencyContactDto = emergencyContactService.findByUUID(id); @@ -62,6 +69,7 @@ public ResponseEntity getById(@PathVariable("id") String id } @GetMapping + @ApiOperation(value = "Gets all Emergency Contacts") public ResponseEntity> getAll() { final List emergencyContactDtoList = emergencyContactService.findAll(); diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java new file mode 100644 index 0000000..0ae948c --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java @@ -0,0 +1,103 @@ +package com.code4ro.nextdoor.emergency.contact.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.mapper.EmergencyContactMapper; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EmergencyContactServiceImplTest { + + private static final String ID = "14022837-be98-4457-af25-075d7a136a33"; + private static final UUID UID = UUID.fromString(ID); + + @InjectMocks + private EmergencyContactServiceImpl underTest; + + @Mock + private EmergencyContactRepository emergencyContactRepository; + + @Mock + private EmergencyContactMapper emergencyContactMapper; + + private static EmergencyContact emergencyContact = + EmergencyContact.builder() + .address("address") + .email("email@something.com") + .name("name") + .surname("surname") + .telephoneNumber("07xx43x56x") + .build(); + + @Test + public void testFindAll() { + when(emergencyContactRepository.findAll()). + thenReturn(Arrays.asList(emergencyContact)); + + List result = underTest.findAll(); + + assertEquals(1, result.size()); + assertEquals(emergencyContact.getAddress(), result.get(0).getAddress()); + assertEquals(emergencyContact.getEmail(), result.get(0).getEmail()); + assertEquals(emergencyContact.getName(), result.get(0).getName()); + assertEquals(emergencyContact.getSurname(), result.get(0).getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.get(0).getTelephoneNumber()); + } + + @Test + public void testFindById() { + when(emergencyContactRepository.findById(UID)). + thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); + + EmergencyContactDto result = underTest.findByUUID(ID); + + assertEquals(emergencyContact.getAddress(), result.getAddress()); + assertEquals(emergencyContact.getEmail(), result.getEmail()); + assertEquals(emergencyContact.getName(), result.getName()); + assertEquals(emergencyContact.getSurname(), result.getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.getTelephoneNumber()); + } + + @Test + public void testFindByNonExistingId() { + when(emergencyContactRepository.findById(UID)). + thenReturn(Optional.empty()); + + EmergencyContactDto result = underTest.findByUUID(ID); + + assertNull(result); + } + + @Test + public void testDeleteById() { + when(emergencyContactRepository.findById(UID)) + .thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); + doNothing().when(emergencyContactRepository).deleteById(UID); + + underTest.deleteById(ID); + + verify(emergencyContactRepository, times(1)).deleteById(UID); + } + + private EmergencyContact getEmergencyContactWithId(EmergencyContact emergencyContact) { + emergencyContact.setId(UID); + + return emergencyContact; + } +} From 27ff8d6d699376c152a23996776466c0bff6a097 Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 21:24:14 +0200 Subject: [PATCH 04/11] More code review changes --- .../EmergencyContactController.java | 13 +++-- .../service/EmergencyContactService.java | 3 +- .../impl/EmergencyContactServiceImpl.java | 50 +++++++++---------- .../EmergencyContactServiceImplTest.java | 23 +++------ 4 files changed, 40 insertions(+), 49 deletions(-) diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java index ce360d0..3dc2707 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -6,7 +6,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import java.util.List; -import java.util.Objects; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -25,6 +26,7 @@ public class EmergencyContactController { private final EmergencyContactService emergencyContactService; + @Autowired public EmergencyContactController(EmergencyContactService emergencyContactService) { this.emergencyContactService = emergencyContactService; } @@ -58,14 +60,11 @@ public ResponseEntity deleteById(@PathVariable("id") String id) { @GetMapping("/{id}") @ApiOperation(value = "Gets an Emergency Contact by id") public ResponseEntity getById(@PathVariable("id") String id) { - final EmergencyContactDto emergencyContactDto = + Optional emergencyContactDto = emergencyContactService.findByUUID(id); - if (Objects.isNull(emergencyContactDto)) { - throw new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND); - } - - return ResponseEntity.ok(emergencyContactDto); + return emergencyContactDto.map(ResponseEntity::ok) + .orElseThrow(() -> new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND)); } @GetMapping diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java index 740bf51..8df539e 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java @@ -2,6 +2,7 @@ import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import java.util.List; +import java.util.Optional; public interface EmergencyContactService { @@ -11,7 +12,7 @@ public interface EmergencyContactService { void deleteById(String id); - EmergencyContactDto findByUUID(String id); + Optional findByUUID(String id); List findAll(); } diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java index 6e6542f..1d79934 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service @@ -15,6 +16,7 @@ public class EmergencyContactServiceImpl implements EmergencyContactService { private final EmergencyContactRepository emergencyContactRepository; + @Autowired public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { this.emergencyContactRepository = emergencyContactRepository; } @@ -24,49 +26,34 @@ public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); - return mapDtoToDTO(emergencyContactDB); + return mapEntityToDto(emergencyContactDB); } @Override public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { - Optional dbEntity = emergencyContactRepository.findById( - UUID.fromString(emergencyContactDto.getId())); - - if (dbEntity.isPresent()) { - EmergencyContact dbEmergencyContact = dbEntity.get(); - dbEmergencyContact.setAddress(emergencyContactDto.getAddress()); - dbEmergencyContact.setEmail(emergencyContactDto.getEmail()); - dbEmergencyContact.setName(emergencyContactDto.getName()); - dbEmergencyContact.setSurname(emergencyContactDto.getSurname()); - dbEmergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); - return mapDtoToDTO(emergencyContactRepository.save(dbEmergencyContact)); - } else { - return save(emergencyContactDto); - } + return emergencyContactRepository.findById(UUID.fromString(emergencyContactDto.getId())) + .map(emergencyContact -> updateEntityWithDataFromDto(emergencyContact, emergencyContactDto)) + .map(emergencyContactRepository::save) + .map(this::mapEntityToDto) + .orElseGet(() -> save(emergencyContactDto)); } @Override public void deleteById(String id) { - Optional dbEntity = emergencyContactRepository.findById( - UUID.fromString(id)); - - if (dbEntity.isPresent()) { - emergencyContactRepository.deleteById(UUID.fromString(id)); - } + emergencyContactRepository.deleteById(UUID.fromString(id)); } @Override - public EmergencyContactDto findByUUID(String id) { + public Optional findByUUID(String id) { return emergencyContactRepository.findById(UUID.fromString(id)) - .map(this::mapDtoToDTO) - .orElse(null); + .map(this::mapEntityToDto); } @Override public List findAll() { return emergencyContactRepository.findAll() .stream() - .map(this::mapDtoToDTO) + .map(this::mapEntityToDto) .collect(Collectors.toList()); } @@ -80,7 +67,7 @@ private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) .build(); } - private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { + private EmergencyContactDto mapEntityToDto(EmergencyContact emergencyContact) { return EmergencyContactDto.builder() .id(String.valueOf(emergencyContact.getId())) .name(emergencyContact.getName()) @@ -90,4 +77,15 @@ private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { .telephoneNumber(emergencyContact.getTelephoneNumber()) .build(); } + + private EmergencyContact updateEntityWithDataFromDto(EmergencyContact emergencyContact, EmergencyContactDto emergencyContactDto) { + emergencyContact.setAddress(emergencyContactDto.getAddress()); + emergencyContact.setEmail(emergencyContactDto.getEmail()); + emergencyContact.setSurname(emergencyContactDto.getSurname()); + emergencyContact.setName(emergencyContactDto.getName()); + emergencyContact.setName(emergencyContactDto.getName()); + emergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); + + return emergencyContact; + } } diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java index 0ae948c..e2bbf90 100644 --- a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java @@ -1,14 +1,12 @@ package com.code4ro.nextdoor.emergency.contact.service; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; -import com.code4ro.nextdoor.emergency.contact.mapper.EmergencyContactMapper; import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; import java.util.Arrays; @@ -33,9 +31,6 @@ public class EmergencyContactServiceImplTest { @Mock private EmergencyContactRepository emergencyContactRepository; - @Mock - private EmergencyContactMapper emergencyContactMapper; - private static EmergencyContact emergencyContact = EmergencyContact.builder() .address("address") @@ -65,13 +60,13 @@ public void testFindById() { when(emergencyContactRepository.findById(UID)). thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); - EmergencyContactDto result = underTest.findByUUID(ID); + Optional result = underTest.findByUUID(ID); - assertEquals(emergencyContact.getAddress(), result.getAddress()); - assertEquals(emergencyContact.getEmail(), result.getEmail()); - assertEquals(emergencyContact.getName(), result.getName()); - assertEquals(emergencyContact.getSurname(), result.getSurname()); - assertEquals(emergencyContact.getTelephoneNumber(), result.getTelephoneNumber()); + assertEquals(emergencyContact.getAddress(), result.get().getAddress()); + assertEquals(emergencyContact.getEmail(), result.get().getEmail()); + assertEquals(emergencyContact.getName(), result.get().getName()); + assertEquals(emergencyContact.getSurname(), result.get().getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.get().getTelephoneNumber()); } @Test @@ -79,15 +74,13 @@ public void testFindByNonExistingId() { when(emergencyContactRepository.findById(UID)). thenReturn(Optional.empty()); - EmergencyContactDto result = underTest.findByUUID(ID); + Optional result = underTest.findByUUID(ID); - assertNull(result); + assertEquals(Optional.empty(), result); } @Test public void testDeleteById() { - when(emergencyContactRepository.findById(UID)) - .thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); doNothing().when(emergencyContactRepository).deleteById(UID); underTest.deleteById(ID); From 503207d0d9806f7be0b244f590cb71b5b07939bc Mon Sep 17 00:00:00 2001 From: George Bejan Date: Sun, 29 Mar 2020 11:12:37 +0300 Subject: [PATCH 05/11] Add support for groups --- api/build.gradle | 6 +- .../nextdoor/core/dto/BaseEntityDto.java | 14 +++ .../nextdoor/core/service/MapperService.java | 13 +++ .../core/service/impl/MapperServiceImpl.java | 77 +++++++++++++ .../group/controller/GroupController.java | 47 ++++++++ .../nextdoor/group/dto/GroupCreateDto.java | 13 +++ .../code4ro/nextdoor/group/dto/GroupDto.java | 13 +++ .../group/dto/GroupSecurityPolicyDto.java | 11 ++ .../nextdoor/group/dto/GroupUpdateDto.java | 12 ++ .../code4ro/nextdoor/group/entity/Group.java | 26 +++++ .../group/entity/GroupSecurityPolicy.java | 19 ++++ .../group/repository/GroupRepository.java | 9 ++ .../nextdoor/group/service/GroupService.java | 15 +++ .../group/service/impl/GroupServiceImpl.java | 57 ++++++++++ .../AbstractControllerIntegrationTest.java | 37 +++++++ .../nextdoor/core/RandomObjectFiller.java | 80 ++++++++++++++ .../group/GroupControllerIntegrationTest.java | 83 ++++++++++++++ .../code4ro/nextdoor/group/GroupFactory.java | 33 ++++++ .../nextdoor/group/GroupServiceTest.java | 104 ++++++++++++++++++ api/src/test/resources/application.yml | 12 ++ 20 files changed, 678 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/com/code4ro/nextdoor/core/dto/BaseEntityDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/core/service/MapperService.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/controller/GroupController.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/dto/GroupCreateDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/dto/GroupDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/dto/GroupSecurityPolicyDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/dto/GroupUpdateDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/entity/Group.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/entity/GroupSecurityPolicy.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/repository/GroupRepository.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/service/GroupService.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/group/service/impl/GroupServiceImpl.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/core/AbstractControllerIntegrationTest.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/core/RandomObjectFiller.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/group/GroupControllerIntegrationTest.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/group/GroupFactory.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/group/GroupServiceTest.java create mode 100644 api/src/test/resources/application.yml diff --git a/api/build.gradle b/api/build.gradle index fc510d3..174bdc5 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -21,13 +21,13 @@ dependencies { implementation 'org.flywaydb:flyway-core:6.3.2' implementation 'io.springfox:springfox-swagger2:2.9.2' implementation 'io.springfox:springfox-swagger-ui:2.9.2' + implementation 'org.modelmapper:modelmapper:2.3.6' + implementation 'org.apache.commons:commons-lang3:3.9' runtimeOnly 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java' - testImplementation('org.springframework.boot:spring-boot-starter-test') { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - } + testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation 'org.springframework.security:spring-security-test' } diff --git a/api/src/main/java/com/code4ro/nextdoor/core/dto/BaseEntityDto.java b/api/src/main/java/com/code4ro/nextdoor/core/dto/BaseEntityDto.java new file mode 100644 index 0000000..86ec49b --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/core/dto/BaseEntityDto.java @@ -0,0 +1,14 @@ +package com.code4ro.nextdoor.core.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Setter +@Getter +public class BaseEntityDto { + private UUID id; + private LocalDateTime creationDate; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/core/service/MapperService.java b/api/src/main/java/com/code4ro/nextdoor/core/service/MapperService.java new file mode 100644 index 0000000..3b50421 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/core/service/MapperService.java @@ -0,0 +1,13 @@ +package com.code4ro.nextdoor.core.service; + +import org.springframework.data.domain.Page; + +import java.util.List; + +public interface MapperService { + T map(Object source, Class targetType); + + List mapList(List sourceList, Class targetClass); + + Page mapPage(Page sourcePage, Class targetClass); +} diff --git a/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java new file mode 100644 index 0000000..454bc78 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java @@ -0,0 +1,77 @@ +package com.code4ro.nextdoor.core.service.impl; + +import com.code4ro.nextdoor.core.dto.BaseEntityDto; +import com.code4ro.nextdoor.core.entity.BaseEntity; +import com.code4ro.nextdoor.core.service.MapperService; +import com.code4ro.nextdoor.group.dto.GroupDto; +import com.code4ro.nextdoor.group.dto.GroupSecurityPolicyDto; +import com.code4ro.nextdoor.group.entity.Group; +import com.code4ro.nextdoor.group.entity.GroupSecurityPolicy; +import org.modelmapper.AbstractConverter; +import org.modelmapper.ModelMapper; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class MapperServiceImpl implements MapperService, ApplicationListener { + private final ModelMapper modelMapper; + + public MapperServiceImpl() { + this.modelMapper = new ModelMapper(); + + addCustomMappings(); + addCustomTypeMaps(); + } + + private void addCustomMappings() { + modelMapper.createTypeMap(BaseEntity.class, BaseEntityDto.class) + .addMapping(BaseEntity::getId, BaseEntityDto::setId); + modelMapper.createTypeMap(BaseEntityDto.class, BaseEntity.class) + .addMapping(BaseEntityDto::getId, BaseEntity::setId); + } + + private void addCustomTypeMaps() { + modelMapper.createTypeMap(Group.class, GroupDto.class) + .includeBase(BaseEntity.class, BaseEntityDto.class); + modelMapper.createTypeMap(GroupSecurityPolicy.class, GroupSecurityPolicyDto.class); + } + + @Override + public T map(final Object source, final Class targetType) { + return source != null ? modelMapper.map(source, targetType) : null; + } + + @Override + public List mapList(final List sourceList, final Class targetClass) { + if (sourceList == null) { + return Collections.emptyList(); + } + + return sourceList.stream() + .map(listElement -> modelMapper.map(listElement, targetClass)) + .collect(Collectors.toList()); + } + + @Override + public Page mapPage(final Page sourcePage, final Class targetClass) { + if (sourcePage == null) { + return Page.empty(); + } + + return sourcePage.map(pageElement -> modelMapper.map(pageElement, targetClass)); + } + + @Override + public void onApplicationEvent(final ContextRefreshedEvent event) { + final Collection converters = + event.getApplicationContext().getBeansOfType(AbstractConverter.class).values(); + converters.forEach(modelMapper::addConverter); + } +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/controller/GroupController.java b/api/src/main/java/com/code4ro/nextdoor/group/controller/GroupController.java new file mode 100644 index 0000000..e62d9f5 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/controller/GroupController.java @@ -0,0 +1,47 @@ +package com.code4ro.nextdoor.group.controller; + +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; +import com.code4ro.nextdoor.group.service.GroupService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.UUID; + +@Api("Group Controller") +@RestController +@RequestMapping("/api/groups") +public class GroupController { + private final GroupService groupService; + + @Autowired + public GroupController(final GroupService groupService) { + this.groupService = groupService; + } + + @ApiOperation("Create group") + @PostMapping + public ResponseEntity create(@RequestBody final GroupCreateDto createDto) { + final GroupDto groupDto = groupService.create(createDto); + return ResponseEntity.ok(groupDto); + } + + @ApiOperation("Update group") + @PutMapping("/{id}") + public ResponseEntity update(@PathVariable("id") final UUID id, + @RequestBody final GroupUpdateDto updateDto) { + final GroupDto groupDto = groupService.update(id, updateDto); + return ResponseEntity.ok(groupDto); + } + + @ApiOperation("Get group") + @GetMapping("/{id}") + public ResponseEntity get(@PathVariable("id") final UUID id) { + final GroupDto groupDto = groupService.get(id); + return ResponseEntity.ok(groupDto); + } +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupCreateDto.java b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupCreateDto.java new file mode 100644 index 0000000..b88ed04 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupCreateDto.java @@ -0,0 +1,13 @@ +package com.code4ro.nextdoor.group.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class GroupCreateDto { + private GroupSecurityPolicyDto securityPolicy; + private String name; + private String description; + private Boolean open; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupDto.java b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupDto.java new file mode 100644 index 0000000..f9153bc --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupDto.java @@ -0,0 +1,13 @@ +package com.code4ro.nextdoor.group.dto; + +import com.code4ro.nextdoor.core.dto.BaseEntityDto; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class GroupDto extends BaseEntityDto { + private String name; + private String description; + private Boolean open; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupSecurityPolicyDto.java b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupSecurityPolicyDto.java new file mode 100644 index 0000000..9906117 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupSecurityPolicyDto.java @@ -0,0 +1,11 @@ +package com.code4ro.nextdoor.group.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class GroupSecurityPolicyDto { + private String question; + private String answer; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupUpdateDto.java b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupUpdateDto.java new file mode 100644 index 0000000..d2fb0e0 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/dto/GroupUpdateDto.java @@ -0,0 +1,12 @@ +package com.code4ro.nextdoor.group.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class GroupUpdateDto { + private String name; + private String description; + private Boolean open; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/entity/Group.java b/api/src/main/java/com/code4ro/nextdoor/group/entity/Group.java new file mode 100644 index 0000000..f102c0c --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/entity/Group.java @@ -0,0 +1,26 @@ +package com.code4ro.nextdoor.group.entity; + + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.Cascade; +import org.hibernate.annotations.CascadeType; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Table(name = "groups") +@Entity +@Getter +@Setter +public class Group extends BaseEntity { + private String name; + private String description; + private Boolean open; + @Cascade(CascadeType.ALL) + @OneToOne(fetch = FetchType.LAZY) + private GroupSecurityPolicy securityPolicy; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/entity/GroupSecurityPolicy.java b/api/src/main/java/com/code4ro/nextdoor/group/entity/GroupSecurityPolicy.java new file mode 100644 index 0000000..0cbdefa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/entity/GroupSecurityPolicy.java @@ -0,0 +1,19 @@ +package com.code4ro.nextdoor.group.entity; + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.Entity; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +@Entity +public class GroupSecurityPolicy extends BaseEntity { + private String question; + private String answer; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/repository/GroupRepository.java b/api/src/main/java/com/code4ro/nextdoor/group/repository/GroupRepository.java new file mode 100644 index 0000000..d346cd2 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/repository/GroupRepository.java @@ -0,0 +1,9 @@ +package com.code4ro.nextdoor.group.repository; + +import com.code4ro.nextdoor.group.entity.Group; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface GroupRepository extends JpaRepository { +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/service/GroupService.java b/api/src/main/java/com/code4ro/nextdoor/group/service/GroupService.java new file mode 100644 index 0000000..a29cd08 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/service/GroupService.java @@ -0,0 +1,15 @@ +package com.code4ro.nextdoor.group.service; + +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; + +import java.util.UUID; + +public interface GroupService { + GroupDto create(GroupCreateDto createDto); + + GroupDto update(UUID id, GroupUpdateDto updateDto); + + GroupDto get(UUID id); +} diff --git a/api/src/main/java/com/code4ro/nextdoor/group/service/impl/GroupServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/group/service/impl/GroupServiceImpl.java new file mode 100644 index 0000000..dd91095 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/group/service/impl/GroupServiceImpl.java @@ -0,0 +1,57 @@ +package com.code4ro.nextdoor.group.service.impl; + +import com.code4ro.nextdoor.core.service.MapperService; +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; +import com.code4ro.nextdoor.group.entity.Group; +import com.code4ro.nextdoor.group.repository.GroupRepository; +import com.code4ro.nextdoor.group.service.GroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityNotFoundException; +import java.util.UUID; + +@Service +public class GroupServiceImpl implements GroupService { + private final GroupRepository groupRepository; + private final MapperService mapperService; + + @Autowired + public GroupServiceImpl(final GroupRepository groupRepository, + final MapperService mapperService) { + this.groupRepository = groupRepository; + this.mapperService = mapperService; + } + + @Override + @Transactional + public GroupDto create(final GroupCreateDto createDto) { + final Group group = mapperService.map(createDto, Group.class); + if (group.getOpen()) { + group.setSecurityPolicy(null); + } + + final Group savedGroup = groupRepository.save(group); + return mapperService.map(savedGroup, GroupDto.class); + } + + @Override + public GroupDto update(final UUID id, final GroupUpdateDto updateDto) { + final Group group = groupRepository.findById(id).orElseThrow(EntityNotFoundException::new); + group.setName(updateDto.getName()); + group.setDescription(updateDto.getDescription()); + group.setOpen(updateDto.getOpen()); + + final Group savedGroup = groupRepository.save(group); + return mapperService.map(savedGroup, GroupDto.class); + } + + @Override + public GroupDto get(final UUID id) { + final Group group = groupRepository.findById(id).orElseThrow(EntityNotFoundException::new); + return mapperService.map(group, GroupDto.class); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/core/AbstractControllerIntegrationTest.java b/api/src/test/java/com/code4ro/nextdoor/core/AbstractControllerIntegrationTest.java new file mode 100644 index 0000000..3704939 --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/core/AbstractControllerIntegrationTest.java @@ -0,0 +1,37 @@ +package com.code4ro.nextdoor.core; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; +import org.junit.runner.RunWith; +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.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class AbstractControllerIntegrationTest { + @Autowired + protected MockMvc mvc; + + @Autowired + protected ObjectMapper objectMapper; + + protected static String endpoint(Object... args) { + final List stringArgs = Arrays.stream(args) + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); + return StringUtils.join(stringArgs, '/'); + } + +} diff --git a/api/src/test/java/com/code4ro/nextdoor/core/RandomObjectFiller.java b/api/src/test/java/com/code4ro/nextdoor/core/RandomObjectFiller.java new file mode 100644 index 0000000..e16ac41 --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/core/RandomObjectFiller.java @@ -0,0 +1,80 @@ +package com.code4ro.nextdoor.core; + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; + +import javax.validation.constraints.Email; +import javax.validation.constraints.Size; +import java.lang.reflect.Field; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.UUID; + +public class RandomObjectFiller { + public static T createAndFill(Class clazz) { + try { + final T instance = clazz.getDeclaredConstructor().newInstance(); + for (final Field field : clazz.getDeclaredFields()) { + field.setAccessible(true); + Object value = getRandomValueForField(field); + field.set(instance, value); + } + return instance; + } catch (Exception e) { + return null; + } + } + + public static T createAndFillWithBaseEntity(Class clazz) { + final T instance = (T) createAndFill(clazz); + ((BaseEntity) instance).setId(UUID.randomUUID()); + return instance; + } + + private static Object getRandomValueForField(Field field) { + final Class type = field.getType(); + + if (type.isEnum()) { + Object[] enumValues = type.getEnumConstants(); + return enumValues[RandomUtils.nextInt(0, enumValues.length)]; + } else if (type.equals(Integer.TYPE) || type.equals(Integer.class)) { + return RandomUtils.nextInt(); + } else if (type.equals(Long.TYPE) || type.equals(Long.class)) { + return RandomUtils.nextLong(); + } else if (type.equals(Double.TYPE) || type.equals(Double.class)) { + return RandomUtils.nextDouble(); + } else if (type.equals(Float.TYPE) || type.equals(Float.class)) { + return RandomUtils.nextFloat(); + } else if (type.equals(UUID.class)) { + return UUID.randomUUID(); + } else if (type.equals(BigInteger.class)) { + return BigInteger.valueOf(RandomUtils.nextInt()); + } else if (type.equals(String.class)) { + return getFieldWithContraint(field); + } else if (type.equals(Boolean.class)) { + return false; + } else if (type.equals(Date.class)) { + int randomYear = RandomUtils.nextInt(1990, 2020); + int randomDay = RandomUtils.nextInt(1, 366); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, randomYear); + calendar.set(Calendar.DAY_OF_YEAR, randomDay); + return calendar.getTime(); + } + return createAndFill(type); + } + + private static String getFieldWithContraint(final Field field) { + final Email email = field.getAnnotation(Email.class); + if (email != null) { + return RandomStringUtils.randomAlphabetic(10) + "@email.com"; + } + final Size size = field.getAnnotation(Size.class); + if (size != null) { + return RandomStringUtils.randomAlphabetic(size.min(), size.max()); + } + return RandomStringUtils.randomAlphabetic(10); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/group/GroupControllerIntegrationTest.java b/api/src/test/java/com/code4ro/nextdoor/group/GroupControllerIntegrationTest.java new file mode 100644 index 0000000..ac77d53 --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/group/GroupControllerIntegrationTest.java @@ -0,0 +1,83 @@ +package com.code4ro.nextdoor.group; + +import com.code4ro.nextdoor.core.AbstractControllerIntegrationTest; +import com.code4ro.nextdoor.core.RandomObjectFiller; +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; +import com.code4ro.nextdoor.group.entity.Group; +import com.code4ro.nextdoor.group.repository.GroupRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class GroupControllerIntegrationTest extends AbstractControllerIntegrationTest { + @Autowired + private GroupRepository groupRepository; + @Autowired + private ObjectMapper objectMapper; + + @Transactional + @SneakyThrows + @Test + @WithMockUser + public void createGroup() { + final GroupCreateDto createDto = RandomObjectFiller.createAndFill(GroupCreateDto.class); + + mvc.perform(post(endpoint("/api/groups/")) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(createDto)) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Transactional + @SneakyThrows + @Test + @WithMockUser + public void updateGroup() { + final GroupUpdateDto updateDto = RandomObjectFiller.createAndFill(GroupUpdateDto.class); + final Group group = groupRepository.save(RandomObjectFiller.createAndFill(Group.class)); + + final MvcResult mvcResult = mvc.perform(put(endpoint("/api/groups/" + group.getId())) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(updateDto)) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + final GroupDto groupDto = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), GroupDto.class); + assertThat(groupDto.getName()).isEqualTo(updateDto.getName()); + assertThat(group.getDescription()).isEqualTo(updateDto.getDescription()); + assertThat(group.getOpen()).isEqualTo(updateDto.getOpen()); + } + + @SneakyThrows + @Test + @WithMockUser + public void getGroup() { + final Group group = groupRepository.save(RandomObjectFiller.createAndFill(Group.class)); + + final MvcResult mvcResult = mvc.perform(get(endpoint("/api/groups/" + group.getId())) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + final GroupDto groupDto = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), GroupDto.class); + assertThat(groupDto.getName()).isEqualTo(group.getName()); + assertThat(groupDto.getDescription()).isEqualTo(group.getDescription()); + assertThat(groupDto.getOpen()).isEqualTo(group.getOpen()); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/group/GroupFactory.java b/api/src/test/java/com/code4ro/nextdoor/group/GroupFactory.java new file mode 100644 index 0000000..e59f386 --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/group/GroupFactory.java @@ -0,0 +1,33 @@ +package com.code4ro.nextdoor.group; + +import com.code4ro.nextdoor.core.RandomObjectFiller; +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; +import com.code4ro.nextdoor.group.entity.Group; + +public class GroupFactory { + + public static Group createOpenGroup() { + final Group group = RandomObjectFiller.createAndFill(Group.class); + group.setOpen(true); + return group; + } + + public static Group createClosedGroup() { + final Group group = RandomObjectFiller.createAndFill(Group.class); + group.setOpen(false); + return group; + } + + public static Group entity() { + return RandomObjectFiller.createAndFill(Group.class); + } + + public static GroupCreateDto createDto() { + return RandomObjectFiller.createAndFill(GroupCreateDto.class); + } + + public static GroupUpdateDto updateDto() { + return RandomObjectFiller.createAndFill(GroupUpdateDto.class); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/group/GroupServiceTest.java b/api/src/test/java/com/code4ro/nextdoor/group/GroupServiceTest.java new file mode 100644 index 0000000..438c7aa --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/group/GroupServiceTest.java @@ -0,0 +1,104 @@ +package com.code4ro.nextdoor.group; + +import com.code4ro.nextdoor.core.service.MapperService; +import com.code4ro.nextdoor.group.dto.GroupCreateDto; +import com.code4ro.nextdoor.group.dto.GroupUpdateDto; +import com.code4ro.nextdoor.group.entity.Group; +import com.code4ro.nextdoor.group.repository.GroupRepository; +import com.code4ro.nextdoor.group.service.impl.GroupServiceImpl; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.persistence.EntityNotFoundException; +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GroupServiceTest { + @Mock + private GroupRepository groupRepository; + @Mock + private MapperService mapperService; + + @InjectMocks + private GroupServiceImpl groupService; + @Captor + private ArgumentCaptor groupArgumentCaptor; + + @Test + public void createOpenGroup() { + final GroupCreateDto createDto = GroupFactory.createDto(); + final Group group = GroupFactory.createOpenGroup(); + + when(mapperService.map(createDto, Group.class)).thenReturn(group); + + groupService.create(createDto); + + verify(groupRepository).save(groupArgumentCaptor.capture()); + assertThat(groupArgumentCaptor.getValue().getSecurityPolicy()).isNull(); + } + + @Test + public void createClosedGroup() { + final GroupCreateDto createDto = GroupFactory.createDto(); + final Group group = GroupFactory.createClosedGroup(); + + when(mapperService.map(createDto, Group.class)).thenReturn(group); + + groupService.create(createDto); + + verify(groupRepository).save(groupArgumentCaptor.capture()); + assertThat(groupArgumentCaptor.getValue().getSecurityPolicy()).isNotNull(); + } + + @Test(expected = EntityNotFoundException.class) + public void updateNonExistentGroup() { + final GroupUpdateDto updateDto = GroupFactory.updateDto(); + + when(groupRepository.findById(any())).thenReturn(Optional.empty()); + + groupService.update(UUID.randomUUID(), updateDto); + } + + @Test + public void updateExistingGroup() { + final GroupUpdateDto updateDto = GroupFactory.updateDto(); + + when(groupRepository.findById(any())).thenReturn(Optional.of(GroupFactory.entity())); + + groupService.update(UUID.randomUUID(), updateDto); + verify(groupRepository).save(groupArgumentCaptor.capture()); + final Group updatedGroup = groupArgumentCaptor.getValue(); + + assertThat(updatedGroup.getName()).isEqualTo(updateDto.getName()); + assertThat(updatedGroup.getDescription()).isEqualTo(updateDto.getDescription()); + assertThat(updatedGroup.getOpen()).isEqualTo(updateDto.getOpen()); + } + + @Test(expected = EntityNotFoundException.class) + public void getNonExistingGroup() { + when(groupRepository.findById(any())).thenReturn(Optional.empty()); + + groupService.get(UUID.randomUUID()); + } + + @Test + public void getExistingGroup() { + when(groupRepository.findById(any())).thenReturn(Optional.of(GroupFactory.entity())); + + final UUID requestedId = UUID.randomUUID(); + groupService.get(requestedId); + + verify(groupRepository).findById(requestedId); + } +} diff --git a/api/src/test/resources/application.yml b/api/src/test/resources/application.yml new file mode 100644 index 0000000..4b590f7 --- /dev/null +++ b/api/src/test/resources/application.yml @@ -0,0 +1,12 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: root + password: root + jpa: + hibernate.ddl-auto: create-drop + generate-ddl: true +app: + jwtSecret: test + jwtExpirationInMs: 172800000 From 701100abbb64641762e1754dac5eba8092b37a7f Mon Sep 17 00:00:00 2001 From: Mihai Rinzis Date: Sun, 29 Mar 2020 20:25:24 +0300 Subject: [PATCH 06/11] Add compose with the db --- README.md | 8 ++++++++ etc/docker/docker-compose.yml | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 etc/docker/docker-compose.yml diff --git a/README.md b/README.md index 9d5588c..f849649 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,14 @@ Mention all related repos and projects. Guide users through getting your code up and running on their own system. In this section you can talk about: 1. Installation process +1.2 install [Docker](https://docs.docker.com/install/) +1.3 install `docker-compose` + * with [pip](https://packaging.python.org/tutorials/installing-packages/): `pip install docker-compose` +1.3 create and run docker images for all server dependencies (mysql for now): +``` shell +docker-compose -f etc/docker/docker-compose.yml up +``` + 2. Software dependencies 3. Latest releases 4. API references diff --git a/etc/docker/docker-compose.yml b/etc/docker/docker-compose.yml new file mode 100644 index 0000000..a918890 --- /dev/null +++ b/etc/docker/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.7' + +services: + mysql: + container_name: mysql + image: mysql:5.7 + restart: always + environment: + MYSQL_DATABASE: 'nextdoor' + MYSQL_ROOT_PASSWORD: 'root' + ports: + - '3306:3306' + expose: + - '3306' + volumes: + - mysql-vol:/var/lib/mysql +volumes: + mysql-vol: From ec591606b0d625fa6bb4573b3f9843378df82b53 Mon Sep 17 00:00:00 2001 From: George Bejan Date: Sun, 29 Mar 2020 20:45:54 +0300 Subject: [PATCH 07/11] Fix CORS --- .../security/config/WebMvcConfig.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 api/src/main/java/com/code4ro/nextdoor/security/config/WebMvcConfig.java diff --git a/api/src/main/java/com/code4ro/nextdoor/security/config/WebMvcConfig.java b/api/src/main/java/com/code4ro/nextdoor/security/config/WebMvcConfig.java new file mode 100644 index 0000000..ecfdeb9 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/security/config/WebMvcConfig.java @@ -0,0 +1,22 @@ +package com.code4ro.nextdoor.security.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + private static final long MAX_AGE_SECS = 3600; + + /** + * allow cross origin requests from the client + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("*") + .allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE") + .maxAge(MAX_AGE_SECS); + } +} From 4f4a84b0dc9be4e489b37c8fa700c272dd0e65d3 Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 18:40:55 +0200 Subject: [PATCH 08/11] Added EmergencyCrud entity and CRUD for it --- .../EmergencyContactController.java | 71 ++++++++++++++ .../contact/dto/EmergencyContactDto.java | 22 +++++ .../contact/entity/EmergencyContact.java | 26 ++++++ .../EmergencyContactRepository.java | 8 ++ .../service/EmergencyContactService.java | 17 ++++ .../impl/EmergencyContactServiceImpl.java | 93 +++++++++++++++++++ 6 files changed, 237 insertions(+) create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java create mode 100644 api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java new file mode 100644 index 0000000..f0d5170 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -0,0 +1,71 @@ +package com.code4ro.nextdoor.emergency.contact.controller; + +import com.code4ro.nextdoor.core.exception.NextDoorValidationException; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Objects; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/emergency-contacts") +public class EmergencyContactController { + + private final EmergencyContactService emergencyContactService; + + public EmergencyContactController(EmergencyContactService emergencyContactService) { + this.emergencyContactService = emergencyContactService; + } + + @PostMapping + public ResponseEntity save(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.save(emergencyContactDto); + + return new ResponseEntity<>(savedEmergencyContact, HttpStatus.CREATED); + } + + @PutMapping + public ResponseEntity update(@RequestBody EmergencyContactDto emergencyContactDto) { + final EmergencyContactDto savedEmergencyContact = + emergencyContactService.update(emergencyContactDto); + + return ResponseEntity.ok(savedEmergencyContact); + } + + @DeleteMapping("/id/{id}") + public ResponseEntity deleteById(@PathVariable("id") String id) { + emergencyContactService.deleteById(id); + + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @GetMapping("/id/{id}") + public ResponseEntity getById(@PathVariable("id") String id) { + final EmergencyContactDto emergencyContactDto = + emergencyContactService.findByUUID(id); + + if (Objects.isNull(emergencyContactDto)) { + throw new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND); + } + + return ResponseEntity.ok(emergencyContactDto); + } + + @GetMapping + public ResponseEntity> getAll() { + final List emergencyContactDtoList = + emergencyContactService.findAll(); + + return ResponseEntity.ok(emergencyContactDtoList); + } +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java new file mode 100644 index 0000000..dc810fa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/dto/EmergencyContactDto.java @@ -0,0 +1,22 @@ +package com.code4ro.nextdoor.emergency.contact.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContactDto { + private String id; + + private String name; + private String surname; + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java new file mode 100644 index 0000000..f1c7caa --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/entity/EmergencyContact.java @@ -0,0 +1,26 @@ +package com.code4ro.nextdoor.emergency.contact.entity; + +import com.code4ro.nextdoor.core.entity.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.Column; +import javax.persistence.Entity; + +@Entity +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmergencyContact extends BaseEntity { + private String name; + private String surname; + @Column(unique = true) + private String email; + private String address; + private String telephoneNumber; +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java new file mode 100644 index 0000000..1826527 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/repository/EmergencyContactRepository.java @@ -0,0 +1,8 @@ +package com.code4ro.nextdoor.emergency.contact.repository; + +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EmergencyContactRepository extends JpaRepository { +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java new file mode 100644 index 0000000..740bf51 --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java @@ -0,0 +1,17 @@ +package com.code4ro.nextdoor.emergency.contact.service; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import java.util.List; + +public interface EmergencyContactService { + + EmergencyContactDto save(EmergencyContactDto emergencyContactDto); + + EmergencyContactDto update(EmergencyContactDto emergencyContactDto); + + void deleteById(String id); + + EmergencyContactDto findByUUID(String id); + + List findAll(); +} diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java new file mode 100644 index 0000000..6e6542f --- /dev/null +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -0,0 +1,93 @@ +package com.code4ro.nextdoor.emergency.contact.service.impl; + +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; + +@Service +public class EmergencyContactServiceImpl implements EmergencyContactService { + + private final EmergencyContactRepository emergencyContactRepository; + + public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { + this.emergencyContactRepository = emergencyContactRepository; + } + + @Override + public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { + EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); + EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); + + return mapDtoToDTO(emergencyContactDB); + } + + @Override + public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(emergencyContactDto.getId())); + + if (dbEntity.isPresent()) { + EmergencyContact dbEmergencyContact = dbEntity.get(); + dbEmergencyContact.setAddress(emergencyContactDto.getAddress()); + dbEmergencyContact.setEmail(emergencyContactDto.getEmail()); + dbEmergencyContact.setName(emergencyContactDto.getName()); + dbEmergencyContact.setSurname(emergencyContactDto.getSurname()); + dbEmergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); + return mapDtoToDTO(emergencyContactRepository.save(dbEmergencyContact)); + } else { + return save(emergencyContactDto); + } + } + + @Override + public void deleteById(String id) { + Optional dbEntity = emergencyContactRepository.findById( + UUID.fromString(id)); + + if (dbEntity.isPresent()) { + emergencyContactRepository.deleteById(UUID.fromString(id)); + } + } + + @Override + public EmergencyContactDto findByUUID(String id) { + return emergencyContactRepository.findById(UUID.fromString(id)) + .map(this::mapDtoToDTO) + .orElse(null); + } + + @Override + public List findAll() { + return emergencyContactRepository.findAll() + .stream() + .map(this::mapDtoToDTO) + .collect(Collectors.toList()); + } + + private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) { + return EmergencyContact.builder() + .name(emergencyContactDto.getName()) + .surname(emergencyContactDto.getSurname()) + .address(emergencyContactDto.getAddress()) + .email(emergencyContactDto.getEmail()) + .telephoneNumber(emergencyContactDto.getTelephoneNumber()) + .build(); + } + + private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { + return EmergencyContactDto.builder() + .id(String.valueOf(emergencyContact.getId())) + .name(emergencyContact.getName()) + .surname(emergencyContact.getSurname()) + .address(emergencyContact.getAddress()) + .email(emergencyContact.getEmail()) + .telephoneNumber(emergencyContact.getTelephoneNumber()) + .build(); + } +} From b2d1184e19cb098d1012204afd2035d82f373a72 Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 20:57:44 +0200 Subject: [PATCH 09/11] Comments for EmergencyContact and started unit tests --- .../EmergencyContactController.java | 12 +- .../EmergencyContactServiceImplTest.java | 103 ++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java index f0d5170..ce360d0 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -3,6 +3,8 @@ import com.code4ro.nextdoor.core.exception.NextDoorValidationException; import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import com.code4ro.nextdoor.emergency.contact.service.EmergencyContactService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import java.util.List; import java.util.Objects; import org.springframework.http.HttpStatus; @@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController +@Api(value = "Emergency Contact CRUD Controller") @RequestMapping("/api/emergency-contacts") public class EmergencyContactController { @@ -27,6 +30,7 @@ public EmergencyContactController(EmergencyContactService emergencyContactServic } @PostMapping + @ApiOperation(value = "Saves an Emergency Contact") public ResponseEntity save(@RequestBody EmergencyContactDto emergencyContactDto) { final EmergencyContactDto savedEmergencyContact = emergencyContactService.save(emergencyContactDto); @@ -35,6 +39,7 @@ public ResponseEntity save(@RequestBody EmergencyContactDto } @PutMapping + @ApiOperation(value = "Updates an Emergency Contact") public ResponseEntity update(@RequestBody EmergencyContactDto emergencyContactDto) { final EmergencyContactDto savedEmergencyContact = emergencyContactService.update(emergencyContactDto); @@ -42,14 +47,16 @@ public ResponseEntity update(@RequestBody EmergencyContactD return ResponseEntity.ok(savedEmergencyContact); } - @DeleteMapping("/id/{id}") + @DeleteMapping("/{id}") + @ApiOperation(value = "Deletes an Emergency Contact by id") public ResponseEntity deleteById(@PathVariable("id") String id) { emergencyContactService.deleteById(id); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - @GetMapping("/id/{id}") + @GetMapping("/{id}") + @ApiOperation(value = "Gets an Emergency Contact by id") public ResponseEntity getById(@PathVariable("id") String id) { final EmergencyContactDto emergencyContactDto = emergencyContactService.findByUUID(id); @@ -62,6 +69,7 @@ public ResponseEntity getById(@PathVariable("id") String id } @GetMapping + @ApiOperation(value = "Gets all Emergency Contacts") public ResponseEntity> getAll() { final List emergencyContactDtoList = emergencyContactService.findAll(); diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java new file mode 100644 index 0000000..0ae948c --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java @@ -0,0 +1,103 @@ +package com.code4ro.nextdoor.emergency.contact.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.mapper.EmergencyContactMapper; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EmergencyContactServiceImplTest { + + private static final String ID = "14022837-be98-4457-af25-075d7a136a33"; + private static final UUID UID = UUID.fromString(ID); + + @InjectMocks + private EmergencyContactServiceImpl underTest; + + @Mock + private EmergencyContactRepository emergencyContactRepository; + + @Mock + private EmergencyContactMapper emergencyContactMapper; + + private static EmergencyContact emergencyContact = + EmergencyContact.builder() + .address("address") + .email("email@something.com") + .name("name") + .surname("surname") + .telephoneNumber("07xx43x56x") + .build(); + + @Test + public void testFindAll() { + when(emergencyContactRepository.findAll()). + thenReturn(Arrays.asList(emergencyContact)); + + List result = underTest.findAll(); + + assertEquals(1, result.size()); + assertEquals(emergencyContact.getAddress(), result.get(0).getAddress()); + assertEquals(emergencyContact.getEmail(), result.get(0).getEmail()); + assertEquals(emergencyContact.getName(), result.get(0).getName()); + assertEquals(emergencyContact.getSurname(), result.get(0).getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.get(0).getTelephoneNumber()); + } + + @Test + public void testFindById() { + when(emergencyContactRepository.findById(UID)). + thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); + + EmergencyContactDto result = underTest.findByUUID(ID); + + assertEquals(emergencyContact.getAddress(), result.getAddress()); + assertEquals(emergencyContact.getEmail(), result.getEmail()); + assertEquals(emergencyContact.getName(), result.getName()); + assertEquals(emergencyContact.getSurname(), result.getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.getTelephoneNumber()); + } + + @Test + public void testFindByNonExistingId() { + when(emergencyContactRepository.findById(UID)). + thenReturn(Optional.empty()); + + EmergencyContactDto result = underTest.findByUUID(ID); + + assertNull(result); + } + + @Test + public void testDeleteById() { + when(emergencyContactRepository.findById(UID)) + .thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); + doNothing().when(emergencyContactRepository).deleteById(UID); + + underTest.deleteById(ID); + + verify(emergencyContactRepository, times(1)).deleteById(UID); + } + + private EmergencyContact getEmergencyContactWithId(EmergencyContact emergencyContact) { + emergencyContact.setId(UID); + + return emergencyContact; + } +} From 822fc8335850ac5202f8908959f5f11e4183cc8a Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Sat, 28 Mar 2020 21:24:14 +0200 Subject: [PATCH 10/11] More code review changes --- .../EmergencyContactController.java | 13 +++-- .../service/EmergencyContactService.java | 3 +- .../impl/EmergencyContactServiceImpl.java | 50 +++++++++---------- .../EmergencyContactServiceImplTest.java | 23 +++------ 4 files changed, 40 insertions(+), 49 deletions(-) diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java index ce360d0..3dc2707 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/controller/EmergencyContactController.java @@ -6,7 +6,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import java.util.List; -import java.util.Objects; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -25,6 +26,7 @@ public class EmergencyContactController { private final EmergencyContactService emergencyContactService; + @Autowired public EmergencyContactController(EmergencyContactService emergencyContactService) { this.emergencyContactService = emergencyContactService; } @@ -58,14 +60,11 @@ public ResponseEntity deleteById(@PathVariable("id") String id) { @GetMapping("/{id}") @ApiOperation(value = "Gets an Emergency Contact by id") public ResponseEntity getById(@PathVariable("id") String id) { - final EmergencyContactDto emergencyContactDto = + Optional emergencyContactDto = emergencyContactService.findByUUID(id); - if (Objects.isNull(emergencyContactDto)) { - throw new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND); - } - - return ResponseEntity.ok(emergencyContactDto); + return emergencyContactDto.map(ResponseEntity::ok) + .orElseThrow(() -> new NextDoorValidationException("id.not.found", HttpStatus.NOT_FOUND)); } @GetMapping diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java index 740bf51..8df539e 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactService.java @@ -2,6 +2,7 @@ import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import java.util.List; +import java.util.Optional; public interface EmergencyContactService { @@ -11,7 +12,7 @@ public interface EmergencyContactService { void deleteById(String id); - EmergencyContactDto findByUUID(String id); + Optional findByUUID(String id); List findAll(); } diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java index 6e6542f..1d79934 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service @@ -15,6 +16,7 @@ public class EmergencyContactServiceImpl implements EmergencyContactService { private final EmergencyContactRepository emergencyContactRepository; + @Autowired public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { this.emergencyContactRepository = emergencyContactRepository; } @@ -24,49 +26,34 @@ public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); - return mapDtoToDTO(emergencyContactDB); + return mapEntityToDto(emergencyContactDB); } @Override public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { - Optional dbEntity = emergencyContactRepository.findById( - UUID.fromString(emergencyContactDto.getId())); - - if (dbEntity.isPresent()) { - EmergencyContact dbEmergencyContact = dbEntity.get(); - dbEmergencyContact.setAddress(emergencyContactDto.getAddress()); - dbEmergencyContact.setEmail(emergencyContactDto.getEmail()); - dbEmergencyContact.setName(emergencyContactDto.getName()); - dbEmergencyContact.setSurname(emergencyContactDto.getSurname()); - dbEmergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); - return mapDtoToDTO(emergencyContactRepository.save(dbEmergencyContact)); - } else { - return save(emergencyContactDto); - } + return emergencyContactRepository.findById(UUID.fromString(emergencyContactDto.getId())) + .map(emergencyContact -> updateEntityWithDataFromDto(emergencyContact, emergencyContactDto)) + .map(emergencyContactRepository::save) + .map(this::mapEntityToDto) + .orElseGet(() -> save(emergencyContactDto)); } @Override public void deleteById(String id) { - Optional dbEntity = emergencyContactRepository.findById( - UUID.fromString(id)); - - if (dbEntity.isPresent()) { - emergencyContactRepository.deleteById(UUID.fromString(id)); - } + emergencyContactRepository.deleteById(UUID.fromString(id)); } @Override - public EmergencyContactDto findByUUID(String id) { + public Optional findByUUID(String id) { return emergencyContactRepository.findById(UUID.fromString(id)) - .map(this::mapDtoToDTO) - .orElse(null); + .map(this::mapEntityToDto); } @Override public List findAll() { return emergencyContactRepository.findAll() .stream() - .map(this::mapDtoToDTO) + .map(this::mapEntityToDto) .collect(Collectors.toList()); } @@ -80,7 +67,7 @@ private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) .build(); } - private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { + private EmergencyContactDto mapEntityToDto(EmergencyContact emergencyContact) { return EmergencyContactDto.builder() .id(String.valueOf(emergencyContact.getId())) .name(emergencyContact.getName()) @@ -90,4 +77,15 @@ private EmergencyContactDto mapDtoToDTO(EmergencyContact emergencyContact) { .telephoneNumber(emergencyContact.getTelephoneNumber()) .build(); } + + private EmergencyContact updateEntityWithDataFromDto(EmergencyContact emergencyContact, EmergencyContactDto emergencyContactDto) { + emergencyContact.setAddress(emergencyContactDto.getAddress()); + emergencyContact.setEmail(emergencyContactDto.getEmail()); + emergencyContact.setSurname(emergencyContactDto.getSurname()); + emergencyContact.setName(emergencyContactDto.getName()); + emergencyContact.setName(emergencyContactDto.getName()); + emergencyContact.setTelephoneNumber(emergencyContactDto.getTelephoneNumber()); + + return emergencyContact; + } } diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java index 0ae948c..e2bbf90 100644 --- a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java @@ -1,14 +1,12 @@ package com.code4ro.nextdoor.emergency.contact.service; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; -import com.code4ro.nextdoor.emergency.contact.mapper.EmergencyContactMapper; import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; import java.util.Arrays; @@ -33,9 +31,6 @@ public class EmergencyContactServiceImplTest { @Mock private EmergencyContactRepository emergencyContactRepository; - @Mock - private EmergencyContactMapper emergencyContactMapper; - private static EmergencyContact emergencyContact = EmergencyContact.builder() .address("address") @@ -65,13 +60,13 @@ public void testFindById() { when(emergencyContactRepository.findById(UID)). thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); - EmergencyContactDto result = underTest.findByUUID(ID); + Optional result = underTest.findByUUID(ID); - assertEquals(emergencyContact.getAddress(), result.getAddress()); - assertEquals(emergencyContact.getEmail(), result.getEmail()); - assertEquals(emergencyContact.getName(), result.getName()); - assertEquals(emergencyContact.getSurname(), result.getSurname()); - assertEquals(emergencyContact.getTelephoneNumber(), result.getTelephoneNumber()); + assertEquals(emergencyContact.getAddress(), result.get().getAddress()); + assertEquals(emergencyContact.getEmail(), result.get().getEmail()); + assertEquals(emergencyContact.getName(), result.get().getName()); + assertEquals(emergencyContact.getSurname(), result.get().getSurname()); + assertEquals(emergencyContact.getTelephoneNumber(), result.get().getTelephoneNumber()); } @Test @@ -79,15 +74,13 @@ public void testFindByNonExistingId() { when(emergencyContactRepository.findById(UID)). thenReturn(Optional.empty()); - EmergencyContactDto result = underTest.findByUUID(ID); + Optional result = underTest.findByUUID(ID); - assertNull(result); + assertEquals(Optional.empty(), result); } @Test public void testDeleteById() { - when(emergencyContactRepository.findById(UID)) - .thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); doNothing().when(emergencyContactRepository).deleteById(UID); underTest.deleteById(ID); From 8b9987b40f4411cc4ef189e00add3e547e1c66a9 Mon Sep 17 00:00:00 2001 From: Alexandra Tincu Date: Tue, 31 Mar 2020 13:54:49 +0300 Subject: [PATCH 11/11] Refactored tests and used modelmapper --- .../core/service/impl/MapperServiceImpl.java | 6 + .../impl/EmergencyContactServiceImpl.java | 38 ++----- .../contact/EmergencyContactFactory.java | 33 ++++++ .../contact/EmergencyContactServiceTest.java | 104 ++++++++++++++++++ .../EmergencyContactServiceImplTest.java | 96 ---------------- 5 files changed, 153 insertions(+), 124 deletions(-) create mode 100644 api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactFactory.java create mode 100644 api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactServiceTest.java delete mode 100644 api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java diff --git a/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java index 454bc78..31839ff 100644 --- a/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java +++ b/api/src/main/java/com/code4ro/nextdoor/core/service/impl/MapperServiceImpl.java @@ -3,6 +3,8 @@ import com.code4ro.nextdoor.core.dto.BaseEntityDto; import com.code4ro.nextdoor.core.entity.BaseEntity; import com.code4ro.nextdoor.core.service.MapperService; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; import com.code4ro.nextdoor.group.dto.GroupDto; import com.code4ro.nextdoor.group.dto.GroupSecurityPolicyDto; import com.code4ro.nextdoor.group.entity.Group; @@ -40,7 +42,11 @@ private void addCustomMappings() { private void addCustomTypeMaps() { modelMapper.createTypeMap(Group.class, GroupDto.class) .includeBase(BaseEntity.class, BaseEntityDto.class); + modelMapper.createTypeMap(GroupSecurityPolicy.class, GroupSecurityPolicyDto.class); + + modelMapper.createTypeMap(EmergencyContact.class, EmergencyContactDto.class); + modelMapper.createTypeMap(EmergencyContactDto.class, EmergencyContact.class); } @Override diff --git a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java index 1d79934..039d871 100644 --- a/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java +++ b/api/src/main/java/com/code4ro/nextdoor/emergency/contact/service/impl/EmergencyContactServiceImpl.java @@ -1,5 +1,6 @@ package com.code4ro.nextdoor.emergency.contact.service.impl; +import com.code4ro.nextdoor.core.service.MapperService; import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; @@ -15,18 +16,20 @@ public class EmergencyContactServiceImpl implements EmergencyContactService { private final EmergencyContactRepository emergencyContactRepository; + private final MapperService mapperService; @Autowired - public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository) { + public EmergencyContactServiceImpl(EmergencyContactRepository emergencyContactRepository, MapperService mapperService) { this.emergencyContactRepository = emergencyContactRepository; + this.mapperService = mapperService; } @Override public EmergencyContactDto save(EmergencyContactDto emergencyContactDto) { - EmergencyContact emergencyContact = mapDtoToEntity(emergencyContactDto); - EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); + final EmergencyContact emergencyContact = mapperService.map(emergencyContactDto, EmergencyContact.class); + final EmergencyContact emergencyContactDB = emergencyContactRepository.save(emergencyContact); - return mapEntityToDto(emergencyContactDB); + return mapperService.map(emergencyContactDB, EmergencyContactDto.class); } @Override @@ -34,7 +37,7 @@ public EmergencyContactDto update(EmergencyContactDto emergencyContactDto) { return emergencyContactRepository.findById(UUID.fromString(emergencyContactDto.getId())) .map(emergencyContact -> updateEntityWithDataFromDto(emergencyContact, emergencyContactDto)) .map(emergencyContactRepository::save) - .map(this::mapEntityToDto) + .map(emergencyContact -> mapperService.map(emergencyContact, EmergencyContactDto.class)) .orElseGet(() -> save(emergencyContactDto)); } @@ -46,38 +49,17 @@ public void deleteById(String id) { @Override public Optional findByUUID(String id) { return emergencyContactRepository.findById(UUID.fromString(id)) - .map(this::mapEntityToDto); + .map(emergencyContact -> mapperService.map(emergencyContact, EmergencyContactDto.class)); } @Override public List findAll() { return emergencyContactRepository.findAll() .stream() - .map(this::mapEntityToDto) + .map(emergencyContact -> mapperService.map(emergencyContact, EmergencyContactDto.class)) .collect(Collectors.toList()); } - private EmergencyContact mapDtoToEntity(EmergencyContactDto emergencyContactDto) { - return EmergencyContact.builder() - .name(emergencyContactDto.getName()) - .surname(emergencyContactDto.getSurname()) - .address(emergencyContactDto.getAddress()) - .email(emergencyContactDto.getEmail()) - .telephoneNumber(emergencyContactDto.getTelephoneNumber()) - .build(); - } - - private EmergencyContactDto mapEntityToDto(EmergencyContact emergencyContact) { - return EmergencyContactDto.builder() - .id(String.valueOf(emergencyContact.getId())) - .name(emergencyContact.getName()) - .surname(emergencyContact.getSurname()) - .address(emergencyContact.getAddress()) - .email(emergencyContact.getEmail()) - .telephoneNumber(emergencyContact.getTelephoneNumber()) - .build(); - } - private EmergencyContact updateEntityWithDataFromDto(EmergencyContact emergencyContact, EmergencyContactDto emergencyContactDto) { emergencyContact.setAddress(emergencyContactDto.getAddress()); emergencyContact.setEmail(emergencyContactDto.getEmail()); diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactFactory.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactFactory.java new file mode 100644 index 0000000..3a93d58 --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactFactory.java @@ -0,0 +1,33 @@ +package com.code4ro.nextdoor.emergency.contact; + +import com.code4ro.nextdoor.core.RandomObjectFiller; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class EmergencyContactFactory { + + public static EmergencyContact createEntity() { + return RandomObjectFiller.createAndFill(EmergencyContact.class); + } + + public static EmergencyContactDto createDto() { + return RandomObjectFiller.createAndFill(EmergencyContactDto.class); + } + + public static List createEntityList() { + return IntStream.range(1, 10) + .boxed() + .map(element -> RandomObjectFiller.createAndFill(EmergencyContact.class)) + .collect(Collectors.toList()); + } + + public static List createDtoList() { + return IntStream.range(1, 10) + .boxed() + .map(element -> RandomObjectFiller.createAndFill(EmergencyContactDto.class)) + .collect(Collectors.toList()); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactServiceTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactServiceTest.java new file mode 100644 index 0000000..8efcb7a --- /dev/null +++ b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/EmergencyContactServiceTest.java @@ -0,0 +1,104 @@ +package com.code4ro.nextdoor.emergency.contact; + +import static com.code4ro.nextdoor.emergency.contact.EmergencyContactFactory.createEntityList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.code4ro.nextdoor.core.service.MapperService; +import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; +import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; +import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; +import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import org.junit.Test; +import org.junit.jupiter.api.DisplayName; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class EmergencyContactServiceTest { + + private static final String ID = "14022837-be98-4457-af25-075d7a136a33"; + + @InjectMocks + private EmergencyContactServiceImpl underTest; + + @Mock + private EmergencyContactRepository emergencyContactRepository; + + @Mock + private MapperService mapperService; + + @Test + @DisplayName("Save emergency contact") + public void testSave() { + final EmergencyContactDto createDto = EmergencyContactFactory.createDto(); + final EmergencyContact entity = EmergencyContactFactory.createEntity(); + + when(mapperService.map(createDto, EmergencyContact.class)).thenReturn(entity); + when(emergencyContactRepository.save(entity)).thenReturn(entity); + when(mapperService.map(entity, EmergencyContactDto.class)).thenReturn(createDto); + + EmergencyContactDto result = underTest.save(createDto); + + verify(emergencyContactRepository).save(entity); + assertThat(result).isNotNull(); + assertThat(result).isEqualTo(createDto); + } + + @Test + @DisplayName("Search and find an emergency contact by UUID") + public void testFindByUUID() { + final EmergencyContactDto dto = EmergencyContactFactory.createDto(); + final EmergencyContact entity = EmergencyContactFactory.createEntity(); + + when(emergencyContactRepository.findById(UUID.fromString(ID))).thenReturn(Optional.of(entity)); + when(mapperService.map(entity, EmergencyContactDto.class)).thenReturn(dto); + + Optional result = underTest.findByUUID(ID); + + verify(emergencyContactRepository).findById(UUID.fromString(ID)); + assertThat(result).isNotNull(); + assertThat(result.get()).isEqualTo(dto); + } + + @Test + @DisplayName("Search an emergency contact by a non existing UUID in DB") + public void testFindByNonExistingUUID() { + when(emergencyContactRepository.findById(UUID.fromString(ID))).thenReturn(Optional.empty()); + + Optional result = underTest.findByUUID(ID); + + verify(emergencyContactRepository).findById(UUID.fromString(ID)); + assertThat(result).isEmpty(); + } + + @Test + @DisplayName("Delete emergency contact by id") + public void testDeleteById() { + doNothing().when(emergencyContactRepository).deleteById(UUID.fromString(ID)); + + underTest.deleteById(ID); + + verify(emergencyContactRepository).deleteById(UUID.fromString(ID)); + } + + @Test + @DisplayName("Find all emergency contacts in database") + public void testFindAll() { + List entityList = createEntityList(); + + when(emergencyContactRepository.findAll()).thenReturn(entityList); + + List result = underTest.findAll(); + + verify(emergencyContactRepository).findAll(); + assertThat(result).isNotEmpty(); + assertThat(result).hasSize(entityList.size()); + } +} diff --git a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java b/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java deleted file mode 100644 index e2bbf90..0000000 --- a/api/src/test/java/com/code4ro/nextdoor/emergency/contact/service/EmergencyContactServiceImplTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.code4ro.nextdoor.emergency.contact.service; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import com.code4ro.nextdoor.emergency.contact.dto.EmergencyContactDto; -import com.code4ro.nextdoor.emergency.contact.entity.EmergencyContact; -import com.code4ro.nextdoor.emergency.contact.repository.EmergencyContactRepository; -import com.code4ro.nextdoor.emergency.contact.service.impl.EmergencyContactServiceImpl; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -public class EmergencyContactServiceImplTest { - - private static final String ID = "14022837-be98-4457-af25-075d7a136a33"; - private static final UUID UID = UUID.fromString(ID); - - @InjectMocks - private EmergencyContactServiceImpl underTest; - - @Mock - private EmergencyContactRepository emergencyContactRepository; - - private static EmergencyContact emergencyContact = - EmergencyContact.builder() - .address("address") - .email("email@something.com") - .name("name") - .surname("surname") - .telephoneNumber("07xx43x56x") - .build(); - - @Test - public void testFindAll() { - when(emergencyContactRepository.findAll()). - thenReturn(Arrays.asList(emergencyContact)); - - List result = underTest.findAll(); - - assertEquals(1, result.size()); - assertEquals(emergencyContact.getAddress(), result.get(0).getAddress()); - assertEquals(emergencyContact.getEmail(), result.get(0).getEmail()); - assertEquals(emergencyContact.getName(), result.get(0).getName()); - assertEquals(emergencyContact.getSurname(), result.get(0).getSurname()); - assertEquals(emergencyContact.getTelephoneNumber(), result.get(0).getTelephoneNumber()); - } - - @Test - public void testFindById() { - when(emergencyContactRepository.findById(UID)). - thenReturn(Optional.of(getEmergencyContactWithId(emergencyContact))); - - Optional result = underTest.findByUUID(ID); - - assertEquals(emergencyContact.getAddress(), result.get().getAddress()); - assertEquals(emergencyContact.getEmail(), result.get().getEmail()); - assertEquals(emergencyContact.getName(), result.get().getName()); - assertEquals(emergencyContact.getSurname(), result.get().getSurname()); - assertEquals(emergencyContact.getTelephoneNumber(), result.get().getTelephoneNumber()); - } - - @Test - public void testFindByNonExistingId() { - when(emergencyContactRepository.findById(UID)). - thenReturn(Optional.empty()); - - Optional result = underTest.findByUUID(ID); - - assertEquals(Optional.empty(), result); - } - - @Test - public void testDeleteById() { - doNothing().when(emergencyContactRepository).deleteById(UID); - - underTest.deleteById(ID); - - verify(emergencyContactRepository, times(1)).deleteById(UID); - } - - private EmergencyContact getEmergencyContactWithId(EmergencyContact emergencyContact) { - emergencyContact.setId(UID); - - return emergencyContact; - } -}