From 7d5ffb87342db5f3aa2575d4c52642a570fbf852 Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Fri, 30 Aug 2024 19:07:29 +0200 Subject: [PATCH 01/11] feat: create Pet class --- .../greenfoxacademy/backend/models/Pet.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java new file mode 100644 index 00000000..e350c560 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java @@ -0,0 +1,37 @@ +package com.greenfoxacademy.backend.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.util.Date; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Represents a pet entity in the system. This class is a data model + * that maps to the pet table in the database. + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "_pet") +public class Pet { + + @Id + @GeneratedValue + private Integer id; + + @Column(nullable = false) + private String petName; + private String petBreed; + private String petSex; + private Date petBirthDate; + private Date lastCheckUp; + private Date nextCheckUp; +} \ No newline at end of file From e7d08b655d1fd7208d4ed6f32b4f64d8c23c6b0b Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Fri, 30 Aug 2024 19:22:51 +0200 Subject: [PATCH 02/11] feat: create petRepository.java --- .../backend/repositories/petRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java b/backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java new file mode 100644 index 00000000..a626c327 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java @@ -0,0 +1,10 @@ +package com.greenfoxacademy.backend.repositories; + +import com.greenfoxacademy.backend.models.Pet; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * Repository to manage Pet entities. + */ +public interface petRepository extends JpaRepository { +} From d86d62d2df8122096d1c139c7d2cf50d677b7a5b Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Fri, 30 Aug 2024 20:28:38 +0200 Subject: [PATCH 03/11] chore: repair checkstyle issues --- .../backend/config/ResponseEntityErrorHandler.java | 3 +-- .../com/greenfoxacademy/backend/controller/UserController.java | 2 -- .../repositories/{petRepository.java => PetRepository.java} | 2 +- .../greenfoxacademy/backend/repositories/UserRepository.java | 1 - .../com/greenfoxacademy/backend/services/user/UserService.java | 2 +- 5 files changed, 3 insertions(+), 7 deletions(-) rename backend/src/main/java/com/greenfoxacademy/backend/repositories/{petRepository.java => PetRepository.java} (76%) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/ResponseEntityErrorHandler.java b/backend/src/main/java/com/greenfoxacademy/backend/config/ResponseEntityErrorHandler.java index 334cfe06..91df172b 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/config/ResponseEntityErrorHandler.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/config/ResponseEntityErrorHandler.java @@ -3,10 +3,8 @@ import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; - import java.util.HashMap; import java.util.Map; - import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; @@ -75,6 +73,7 @@ public ResponseEntity> handleCannotUpdateUserExceptions( * * @return ResponseEntity with BAD_REQUEST and error key-value pair */ + @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(UnableToDeleteProfileError.class) public ResponseEntity handleUnableToDeleteProfileError(UnableToDeleteProfileError ex) { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index 3e55024f..eacdcecd 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -10,10 +10,8 @@ import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.services.user.UserService; - import java.security.Principal; import java.util.UUID; - import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java b/backend/src/main/java/com/greenfoxacademy/backend/repositories/PetRepository.java similarity index 76% rename from backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java rename to backend/src/main/java/com/greenfoxacademy/backend/repositories/PetRepository.java index a626c327..e53bb6fe 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/repositories/petRepository.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/repositories/PetRepository.java @@ -6,5 +6,5 @@ /** * Repository to manage Pet entities. */ -public interface petRepository extends JpaRepository { +public interface PetRepository extends JpaRepository { } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java b/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java index 877531cf..5a6ce4c6 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java @@ -3,7 +3,6 @@ import com.greenfoxacademy.backend.models.User; import java.util.Optional; import java.util.UUID; - import org.springframework.data.jpa.repository.JpaRepository; /** diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java index 94bc5a9b..f040dcba 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java @@ -6,8 +6,8 @@ import com.greenfoxacademy.backend.dtos.ProfileUpdateResponseDto; import com.greenfoxacademy.backend.dtos.RegisterRequestDto; import com.greenfoxacademy.backend.dtos.RegisterResponseDto; -import com.greenfoxacademy.backend.errors.CannotVerifyUserError; import com.greenfoxacademy.backend.errors.CannotUpdateUserException; +import com.greenfoxacademy.backend.errors.CannotVerifyUserError; import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.User; From a9fd3343f2b5ae6d80fbc0408b7b71f4ebdffc6e Mon Sep 17 00:00:00 2001 From: Hsbalazs Date: Fri, 30 Aug 2024 20:42:43 +0200 Subject: [PATCH 04/11] feat: create join connection between _user and _pet table --- .../java/com/greenfoxacademy/backend/models/Pet.java | 9 ++++++++- .../java/com/greenfoxacademy/backend/models/User.java | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java index e350c560..b213cd56 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java @@ -1,9 +1,12 @@ package com.greenfoxacademy.backend.models; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import java.util.Date; import lombok.AllArgsConstructor; @@ -34,4 +37,8 @@ public class Pet { private Date petBirthDate; private Date lastCheckUp; private Date nextCheckUp; -} \ No newline at end of file + + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "petOwner_Id") + private User petOwner; +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 2d40c708..c2a972ac 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,10 +1,14 @@ package com.greenfoxacademy.backend.models; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; @@ -38,6 +42,9 @@ public class User implements UserDetails { private String password; private UUID verificationId; + @OneToMany(mappedBy = "petOwner", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List pets = new ArrayList<>(); + @Override public Collection getAuthorities() { return List.of(new SimpleGrantedAuthority("ROLE_USER")); From 660f11260d7a16939df2f1060bd583d8e8696bac Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 09:52:09 +0200 Subject: [PATCH 05/11] feat: add owner and vet model --- .../java/com/greenfoxacademy/backend/models/Owner.java | 10 ++++++++++ .../java/com/greenfoxacademy/backend/models/User.java | 8 +++----- .../java/com/greenfoxacademy/backend/models/Vet.java | 7 +++++++ 3 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java new file mode 100644 index 00000000..b604e85a --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java @@ -0,0 +1,10 @@ +package com.greenfoxacademy.backend.models; + +import jakarta.persistence.Entity; + +import java.util.List; + +@Entity +public class Owner extends User { + List pets; +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 2d40c708..9761a596 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,10 +1,7 @@ package com.greenfoxacademy.backend.models; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; + import java.util.Collection; import java.util.List; import java.util.UUID; @@ -22,6 +19,7 @@ */ @Data @Builder +@MappedSuperclass @AllArgsConstructor @NoArgsConstructor @Entity diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java new file mode 100644 index 00000000..5097e41f --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java @@ -0,0 +1,7 @@ +package com.greenfoxacademy.backend.models; + +import jakarta.persistence.Entity; + +@Entity +public class Vet extends User { +} From 1dbeee9397e16e263391638aa02cd838e58ac8d9 Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 10:35:51 +0200 Subject: [PATCH 06/11] refactor: vet and owner class --- .../backend/models/Address.java | 21 +++++++++++++++++++ .../greenfoxacademy/backend/models/Owner.java | 20 +++++++++++++++++- .../greenfoxacademy/backend/models/User.java | 12 +++-------- .../greenfoxacademy/backend/models/Vet.java | 21 +++++++++++++++++++ .../services/user/UserServiceImpl.java | 3 ++- .../controller/UserControllerTest.java | 11 +++++----- .../services/user/UserServiceImplTest.java | 17 ++++++++------- 7 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/models/Address.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Address.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Address.java new file mode 100644 index 00000000..10f394b1 --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Address.java @@ -0,0 +1,21 @@ +package com.greenfoxacademy.backend.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +@Entity +@Data +public class Address { + @Id + private Long id; + private String city; + @Column(length = 4) + private String zip; + private String street; + private String clinicName; + + +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java index b604e85a..2217e77c 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java @@ -1,10 +1,28 @@ package com.greenfoxacademy.backend.models; import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.util.Collection; import java.util.List; @Entity +@SuperBuilder +@RequiredArgsConstructor +@AllArgsConstructor +@Table(name = "_owner") public class Owner extends User { - List pets; + private List pets; + + @Override + @Transient + public Collection getAuthorities() { + return List.of(new SimpleGrantedAuthority("ROLE_OWNER")); + } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 9761a596..df5e35bf 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -9,6 +9,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; @@ -18,13 +19,11 @@ * that maps to the user table in the database. */ @Data -@Builder +@SuperBuilder @MappedSuperclass @AllArgsConstructor @NoArgsConstructor -@Entity -@Table(name = "_user") -public class User implements UserDetails { +public abstract class User implements UserDetails { @Id @GeneratedValue @@ -36,11 +35,6 @@ public class User implements UserDetails { private String password; private UUID verificationId; - @Override - public Collection getAuthorities() { - return List.of(new SimpleGrantedAuthority("ROLE_USER")); - } - @Override public String getUsername() { return email; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java index 5097e41f..7ed4e031 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java @@ -1,7 +1,28 @@ package com.greenfoxacademy.backend.models; import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.util.Collection; +import java.util.List; + +@SuperBuilder +@RequiredArgsConstructor +@AllArgsConstructor @Entity +@Table(name = "_vet") public class Vet extends User { + private Address clinicAddress; + + @Override + @Transient + public Collection getAuthorities() { + return List.of(new SimpleGrantedAuthority("ROLE_VET")); + } } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java index 9a1c5602..d40bcfa8 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java @@ -8,6 +8,7 @@ import com.greenfoxacademy.backend.dtos.RegisterResponseDto; import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; +import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import com.greenfoxacademy.backend.services.auth.AuthService; @@ -36,7 +37,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) throws UserAlreadyExistsError { // @formatter:off - User user = User.builder() + User user = Owner.builder() .email(registerRequestDto.email()) .firstName(registerRequestDto.firstName()) .lastName(registerRequestDto.lastName()) diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index 74efb5d1..fcbbd6f7 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -15,6 +15,7 @@ import com.greenfoxacademy.backend.dtos.LoginRequestDto; import com.greenfoxacademy.backend.dtos.LoginResponseDto; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; +import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import com.greenfoxacademy.backend.services.mail.EmailService; @@ -246,7 +247,7 @@ void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { @Test void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception { - when(userRepository.save(Mockito.any())).thenReturn(User.builder().id(1).build()); + when(userRepository.save(Mockito.any())).thenReturn(Owner.builder().id(1).build()); when(emailService.sendRegistrationEmail(anyString(), anyString(), Mockito.any())) .thenReturn(new EmailSentDto()); String content = """ @@ -271,7 +272,7 @@ void shouldReturnTokenWhenUserIsSuccessfullyLoggedInWithGoodCredentials() throws when(userRepository.existsByEmail("johndoe@gmail.com")).thenReturn(true); when(userRepository.findByEmail("johndoe@gmail.com")) .thenReturn(Optional - .of(User.builder() + .of(Owner.builder() .id(1) .firstName("John") .lastName("Doe") @@ -324,7 +325,7 @@ void shouldNotBeAbleToUpdateProfileIfNotLoggedIn() throws Exception { void shouldBeAbleToUpdateProfileIfLoggedIn() throws Exception { String email = "john.doe@gmail.com"; when(userRepository.findByEmail("john.doe@gmail.com")) - .thenReturn(Optional.of(User.builder() + .thenReturn(Optional.of(Owner.builder() .id(1) .email(email) .firstName("John") @@ -333,7 +334,7 @@ void shouldBeAbleToUpdateProfileIfLoggedIn() throws Exception { .build())); when(userRepository.save(Mockito.any())) - .thenReturn(User.builder() + .thenReturn(Owner.builder() .id(1) .email(email) .firstName("John") @@ -381,7 +382,7 @@ void deleteProfile() throws Exception { "password"); when(userRepository.existsByEmail(loginRequestDto.email())).thenReturn(true); when(userRepository.findByEmail(loginRequestDto.email())) - .thenReturn(Optional.of(User.builder() + .thenReturn(Optional.of(Owner.builder() .id(1) .email(loginRequestDto.email()) .firstName("John") diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java index b6b7d4b8..10913db6 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java @@ -9,6 +9,7 @@ import com.greenfoxacademy.backend.dtos.RegisterRequestDto; import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; +import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.UserRepository; import com.greenfoxacademy.backend.services.auth.AuthService; @@ -51,7 +52,7 @@ void setUp() { @Test void register() { // Given - User asSaved = User.builder().id(1).build(); + User asSaved = Owner.builder().id(1).build(); RegisterRequestDto registerRequestDto = new RegisterRequestDto( "fistName", "lastName", @@ -91,7 +92,7 @@ void registerFails() { @Test void login() throws Exception { // Given - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -115,7 +116,7 @@ void login() throws Exception { @Test void loginUnsuccessful() throws Exception { // Given - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("passwordNOOP")) @@ -141,7 +142,7 @@ void loginUnsuccessful() throws Exception { @Test void profileUpdate() throws Exception { // Given - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -169,7 +170,7 @@ void profileUpdate() throws Exception { @Test void profileUpdateUnsuccessful() throws Exception { // Given - User user = User.builder().id(1).email("email") + User user = Owner.builder().id(1).email("email") .password(passwordEncoder.encode("password")) .build(); String email = "email"; @@ -196,7 +197,7 @@ void profileUpdateUnsuccessful() throws Exception { @Test void loadUserByUsername() { // Given - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -215,7 +216,7 @@ void loadUserByUsername() { @Test void verifyUserById() { UUID id = UUID.randomUUID(); - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -234,7 +235,7 @@ void verifyUserById() { @Test void throwsExceptionEmailIsNotVerified() { UUID id = UUID.randomUUID(); - User user = User.builder() + User user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) From ba5f7b0dffde0f51ec14ca8994cf0caec8252b44 Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 11:28:31 +0200 Subject: [PATCH 07/11] refactor: seperate User to Owner and Vet --- .../backend/controller/UserController.java | 14 ++--- .../{Address.java => ClinicAddress.java} | 9 ++- .../greenfoxacademy/backend/models/Owner.java | 2 + .../greenfoxacademy/backend/models/User.java | 18 +++--- .../greenfoxacademy/backend/models/Vet.java | 2 +- ...erRepository.java => OwnerRepository.java} | 7 ++- .../{UserService.java => OwnerService.java} | 6 +- ...ServiceImpl.java => OwnerServiceImpl.java} | 30 +++++---- .../controller/UserControllerTest.java | 25 ++++---- ...ServiceTest.java => OwnerServiceTest.java} | 14 ++--- .../services/UserRegistrationTest.java | 12 ++-- .../services/mail/EmailServiceImplTest.java | 6 +- ...mplTest.java => OwnerServiceImplTest.java} | 62 +++++++++---------- 13 files changed, 101 insertions(+), 106 deletions(-) rename backend/src/main/java/com/greenfoxacademy/backend/models/{Address.java => ClinicAddress.java} (65%) rename backend/src/main/java/com/greenfoxacademy/backend/repositories/{UserRepository.java => OwnerRepository.java} (61%) rename backend/src/main/java/com/greenfoxacademy/backend/services/user/{UserService.java => OwnerService.java} (89%) rename backend/src/main/java/com/greenfoxacademy/backend/services/user/{UserServiceImpl.java => OwnerServiceImpl.java} (83%) rename backend/src/test/java/com/greenfoxacademy/backend/services/{UserServiceTest.java => OwnerServiceTest.java} (74%) rename backend/src/test/java/com/greenfoxacademy/backend/services/user/{UserServiceImplTest.java => OwnerServiceImplTest.java} (78%) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index eacdcecd..ad3d1a37 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -9,7 +9,7 @@ import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; -import com.greenfoxacademy.backend.services.user.UserService; +import com.greenfoxacademy.backend.services.user.OwnerService; import java.security.Principal; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -30,7 +30,7 @@ @RestController @RequiredArgsConstructor public class UserController { - private final UserService userService; + private final OwnerService ownerService; /** * This method registers a new user. @@ -42,7 +42,7 @@ public class UserController { public ResponseEntity registerUser( @Validated @RequestBody RegisterRequestDto registerRequestDto )throws UserAlreadyExistsError { - return ResponseEntity.status(HttpStatus.OK).body(userService.register(registerRequestDto)); + return ResponseEntity.status(HttpStatus.OK).body(ownerService.register(registerRequestDto)); } /** @@ -57,7 +57,7 @@ public ResponseEntity registerUser( @PostMapping("/login") public ResponseEntity loginUser(@RequestBody LoginRequestDto loginRequestDto) { try { - return ResponseEntity.status(HttpStatus.OK).body(userService.login(loginRequestDto)); + return ResponseEntity.status(HttpStatus.OK).body(ownerService.login(loginRequestDto)); } catch (Exception e) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } @@ -78,7 +78,7 @@ public ResponseEntity userProfileUpdate( ) throws CannotUpdateUserException { return ResponseEntity .status(HttpStatus.OK) - .body(userService.profileUpdate(principal.getName(), profileUpdateRequestDto)); + .body(ownerService.profileUpdate(principal.getName(), profileUpdateRequestDto)); } /** @@ -89,14 +89,14 @@ public ResponseEntity userProfileUpdate( */ @DeleteMapping("/delete-profile") public ResponseEntity deleteProfile(Principal principal) throws UnableToDeleteProfileError { - userService.deleteProfile(principal.getName()); + ownerService.deleteProfile(principal.getName()); return ResponseEntity.status(HttpStatus.ACCEPTED).build(); } // http://localhost:8080/verification?code=56565-55656-56-56-5-65-6-56 @GetMapping("/verification") public ResponseEntity verificationPage(@RequestParam(value = "code") UUID verificationCode) { - userService.verifyUser(verificationCode); + ownerService.verifyUser(verificationCode); return ResponseEntity.status(HttpStatus.OK).build(); } } \ No newline at end of file diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Address.java b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java similarity index 65% rename from backend/src/main/java/com/greenfoxacademy/backend/models/Address.java rename to backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java index 10f394b1..13cb2ed7 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Address.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java @@ -1,19 +1,18 @@ package com.greenfoxacademy.backend.models; import jakarta.persistence.Column; -import jakarta.persistence.Entity; +import jakarta.persistence.Embeddable; import jakarta.persistence.Id; import lombok.Data; -import org.hibernate.validator.constraints.Length; -@Entity +@Embeddable @Data -public class Address { +public class ClinicAddress { @Id private Long id; private String city; @Column(length = 4) - private String zip; + private int zip; private String street; private String clinicName; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java index 2217e77c..3880d09a 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java @@ -1,6 +1,7 @@ package com.greenfoxacademy.backend.models; import jakarta.persistence.Entity; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.persistence.Transient; import lombok.AllArgsConstructor; @@ -18,6 +19,7 @@ @AllArgsConstructor @Table(name = "_owner") public class Owner extends User { + @OneToMany(mappedBy = "petOwner") private List pets; @Override diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index 0362bea4..addebc6b 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,19 +1,19 @@ package com.greenfoxacademy.backend.models; -import jakarta.persistence.*; - +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.OneToMany; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.UUID; - import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; /** @@ -37,10 +37,6 @@ public abstract class User implements UserDetails { private String password; private UUID verificationId; - @OneToMany(mappedBy = "petOwner", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List pets = new ArrayList<>(); - - @Override public String getUsername() { return email; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java index 7ed4e031..204e3d11 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java @@ -18,7 +18,7 @@ @Entity @Table(name = "_vet") public class Vet extends User { - private Address clinicAddress; + private ClinicAddress clinicAddress; @Override @Transient diff --git a/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java b/backend/src/main/java/com/greenfoxacademy/backend/repositories/OwnerRepository.java similarity index 61% rename from backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java rename to backend/src/main/java/com/greenfoxacademy/backend/repositories/OwnerRepository.java index 5a6ce4c6..4af6ca2e 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/repositories/UserRepository.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/repositories/OwnerRepository.java @@ -1,5 +1,6 @@ package com.greenfoxacademy.backend.repositories; +import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; import java.util.Optional; import java.util.UUID; @@ -8,12 +9,12 @@ /** * Repository to manage {@link User} entities. */ -public interface UserRepository extends JpaRepository { +public interface OwnerRepository extends JpaRepository { boolean existsByEmail(String email); - Optional findByEmail(String email); + Optional findByEmail(String email); void deleteByEmail(String email); - Optional findByVerificationId(UUID id); + Optional findByVerificationId(UUID id); } diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java similarity index 89% rename from backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java rename to backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java index f040dcba..fe2a43bf 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserService.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java @@ -10,16 +10,16 @@ import com.greenfoxacademy.backend.errors.CannotVerifyUserError; import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; -import com.greenfoxacademy.backend.models.User; +import com.greenfoxacademy.backend.models.Owner; import java.util.UUID; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; /** - * Service to manage {@link User} related actions. + * Service to manage {@link Owner} related actions. */ @Service -public interface UserService extends UserDetailsService { +public interface OwnerService extends UserDetailsService { RegisterResponseDto register(RegisterRequestDto userDto) throws UserAlreadyExistsError; LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java similarity index 83% rename from backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java rename to backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java index 1b109117..4208e6d8 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java @@ -10,13 +10,11 @@ import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; -import com.greenfoxacademy.backend.repositories.UserRepository; +import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; import jakarta.transaction.Transactional; - import java.util.UUID; - import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -24,12 +22,12 @@ import org.springframework.stereotype.Service; /** - * Service implementation to manage {@link UserService}. + * Service implementation to manage {@link OwnerService}. */ @Service @RequiredArgsConstructor -public class UserServiceImpl implements UserService { - private final UserRepository userRepository; +public class OwnerServiceImpl implements OwnerService { + private final OwnerRepository ownerRepository; private final PasswordEncoder passwordEncoder; private final AuthService authService; private final EmailService emailService; @@ -39,7 +37,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) throws UserAlreadyExistsError { // @formatter:off - User user = Owner.builder() + Owner user = Owner.builder() .email(registerRequestDto.email()) .firstName(registerRequestDto.firstName()) .lastName(registerRequestDto.lastName()) @@ -48,7 +46,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) .build(); // @formatter:on try { - User saved = userRepository.save(user); + Owner saved = ownerRepository.save(user); emailService.sendRegistrationEmail( saved.getEmail(), saved.getFirstName(), @@ -63,7 +61,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) @Override public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception { - User user = userRepository.findByEmail(loginRequestDto.email()) + User user = ownerRepository.findByEmail(loginRequestDto.email()) .orElseThrow(() -> new Exception("User not found")); if (!user.isEnabled()) { throw new Exception("User's email is not verified"); @@ -78,10 +76,10 @@ public ProfileUpdateResponseDto profileUpdate( String email, ProfileUpdateRequestDto profileUpdateRequestDto ) throws CannotUpdateUserException { - User user = userRepository.findByEmail(email) + Owner user = ownerRepository.findByEmail(email) .orElseThrow(() -> new UsernameNotFoundException("User not found")); if ( - userRepository.existsByEmail(profileUpdateRequestDto.email()) + ownerRepository.existsByEmail(profileUpdateRequestDto.email()) && !email.equals(profileUpdateRequestDto.email()) ) { throw new CannotUpdateUserException("Email is already taken!"); @@ -91,13 +89,13 @@ public ProfileUpdateResponseDto profileUpdate( user.setLastName(profileUpdateRequestDto.lastName()); user.setPassword(passwordEncoder.encode(profileUpdateRequestDto.password())); - User updatedUser = userRepository.save(user); + Owner updatedUser = ownerRepository.save(user); return new ProfileUpdateResponseDto(authService.generateToken(updatedUser)); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - return userRepository.findByEmail(username) + return ownerRepository.findByEmail(username) .orElseThrow(() -> new UsernameNotFoundException("No such user!")); } @@ -107,15 +105,15 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx @Transactional @Override public void deleteProfile(String username) { - userRepository.deleteByEmail(username); + ownerRepository.deleteByEmail(username); } /** * Verify the user by id sent as email. */ public void verifyUser(UUID id) { - User userWithId = userRepository.findByVerificationId(id).orElseThrow(); + Owner userWithId = ownerRepository.findByVerificationId(id).orElseThrow(); userWithId.setVerificationId(null); - userRepository.save(userWithId); + ownerRepository.save(userWithId); } } \ No newline at end of file diff --git a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java index fcbbd6f7..5602bf02 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/controller/UserControllerTest.java @@ -16,8 +16,7 @@ import com.greenfoxacademy.backend.dtos.LoginResponseDto; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.Owner; -import com.greenfoxacademy.backend.models.User; -import com.greenfoxacademy.backend.repositories.UserRepository; +import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.mail.EmailService; import java.util.Optional; import org.junit.jupiter.api.DisplayName; @@ -41,7 +40,7 @@ class UserControllerTest { * The UserRepository is mocked, so we can define its behavior in each test. */ @MockBean - private UserRepository userRepository; + private OwnerRepository ownerRepository; /** * The MockMvc is used to perform a request to the controller and validate the response. @@ -226,7 +225,7 @@ void shouldReturnEmailIsInvalidWhenEmailIsInvalid() throws Exception { @DisplayName("Should return email is duplicated when email is duplicated") @Test void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { - when(userRepository.save(Mockito.any())) + when(ownerRepository.save(Mockito.any())) .thenThrow(new UserAlreadyExistsError("Email is already taken!")); String content = """ { @@ -247,7 +246,7 @@ void shouldReturnEmailIsIsDuplicatedWhenEmailIsDuplicated() throws Exception { @Test void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception { - when(userRepository.save(Mockito.any())).thenReturn(Owner.builder().id(1).build()); + when(ownerRepository.save(Mockito.any())).thenReturn(Owner.builder().id(1).build()); when(emailService.sendRegistrationEmail(anyString(), anyString(), Mockito.any())) .thenReturn(new EmailSentDto()); String content = """ @@ -269,8 +268,8 @@ void shouldReturnUserSuccessfullyCreatedIfEverythingIsCorrect() throws Exception @Test void shouldReturnTokenWhenUserIsSuccessfullyLoggedInWithGoodCredentials() throws Exception { - when(userRepository.existsByEmail("johndoe@gmail.com")).thenReturn(true); - when(userRepository.findByEmail("johndoe@gmail.com")) + when(ownerRepository.existsByEmail("johndoe@gmail.com")).thenReturn(true); + when(ownerRepository.findByEmail("johndoe@gmail.com")) .thenReturn(Optional .of(Owner.builder() .id(1) @@ -297,7 +296,7 @@ void shouldReturnTokenWhenUserIsSuccessfullyLoggedInWithGoodCredentials() throws @Test void shouldReturnUnauthenticatedWhenEmailIsNotFound() throws Exception { - when(userRepository.existsByEmail("johndoe@gmail.com")).thenReturn(false); + when(ownerRepository.existsByEmail("johndoe@gmail.com")).thenReturn(false); String content = """ { "email": "johndoe@gmail.com", @@ -324,7 +323,7 @@ void shouldNotBeAbleToUpdateProfileIfNotLoggedIn() throws Exception { @WithMockUser(username = "john.doe@gmail.com", password = "password", roles = "USER") void shouldBeAbleToUpdateProfileIfLoggedIn() throws Exception { String email = "john.doe@gmail.com"; - when(userRepository.findByEmail("john.doe@gmail.com")) + when(ownerRepository.findByEmail("john.doe@gmail.com")) .thenReturn(Optional.of(Owner.builder() .id(1) .email(email) @@ -333,7 +332,7 @@ void shouldBeAbleToUpdateProfileIfLoggedIn() throws Exception { .password(passwordEncoder.encode("password")) .build())); - when(userRepository.save(Mockito.any())) + when(ownerRepository.save(Mockito.any())) .thenReturn(Owner.builder() .id(1) .email(email) @@ -380,8 +379,8 @@ void shouldBeAbleToUpdateProfileIfLoggedIn() throws Exception { void deleteProfile() throws Exception { LoginRequestDto loginRequestDto = new LoginRequestDto("john.doe@gmail.com", "password"); - when(userRepository.existsByEmail(loginRequestDto.email())).thenReturn(true); - when(userRepository.findByEmail(loginRequestDto.email())) + when(ownerRepository.existsByEmail(loginRequestDto.email())).thenReturn(true); + when(ownerRepository.findByEmail(loginRequestDto.email())) .thenReturn(Optional.of(Owner.builder() .id(1) .email(loginRequestDto.email()) @@ -408,7 +407,7 @@ void deleteProfile() throws Exception { ) .andExpect(status().isAccepted()); - Mockito.verify(userRepository, Mockito.times(1)) + Mockito.verify(ownerRepository, Mockito.times(1)) .deleteByEmail(loginRequestDto.email()); } } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/UserServiceTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java similarity index 74% rename from backend/src/test/java/com/greenfoxacademy/backend/services/UserServiceTest.java rename to backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java index 68495a22..d8e3fe68 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/UserServiceTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java @@ -6,8 +6,8 @@ import com.greenfoxacademy.backend.controller.UserController; import com.greenfoxacademy.backend.dtos.RegisterRequestDto; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; -import com.greenfoxacademy.backend.repositories.UserRepository; -import com.greenfoxacademy.backend.services.user.UserService; +import com.greenfoxacademy.backend.repositories.OwnerRepository; +import com.greenfoxacademy.backend.services.user.OwnerService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -18,12 +18,12 @@ * This class runs a test to verify if the register method in the userService is properly called. */ @ExtendWith(MockitoExtension.class) -public class UserServiceTest { +public class OwnerServiceTest { @Mock - private UserService userService; + private OwnerService ownerService; @Mock - private UserRepository userRepository; + private OwnerRepository ownerRepository; @InjectMocks private UserController userController; @@ -37,9 +37,9 @@ public void registerMethodIsSuccessfullyCalled() throws Exception, UserAlreadyEx "password" ); - userService.register(registerRequestDto); + ownerService.register(registerRequestDto); - verify(userService, times(1)).register(registerRequestDto); + verify(ownerService, times(1)).register(registerRequestDto); } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java index a92435e1..3a754ae2 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java @@ -8,9 +8,9 @@ import com.greenfoxacademy.backend.dtos.RegisterRequestDto; import com.greenfoxacademy.backend.dtos.RegisterResponseDto; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; -import com.greenfoxacademy.backend.repositories.UserRepository; +import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.mail.EmailService; -import com.greenfoxacademy.backend.services.user.UserService; +import com.greenfoxacademy.backend.services.user.OwnerService; import java.util.UUID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -29,10 +29,10 @@ public class UserRegistrationTest { @Autowired - private UserService userService; + private OwnerService ownerService; @Autowired - private UserRepository userRepository; + private OwnerRepository ownerRepository; @MockBean private EmailService emailService; @@ -49,11 +49,11 @@ public void userIsSuccessfulRegisteredInDatabase() throws Exception, UserAlready "password" ); - RegisterResponseDto registeredUserDto = userService.register(newUser); + RegisterResponseDto registeredUserDto = ownerService.register(newUser); Assertions.assertEquals(1, registeredUserDto.id()); - boolean isRegistered = userRepository.existsByEmail("john.doe@example.com"); + boolean isRegistered = ownerRepository.existsByEmail("john.doe@example.com"); Assertions.assertTrue(isRegistered); } } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java index 6a154b1c..93101952 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.when; import com.greenfoxacademy.backend.config.EmailConfiguration; -import com.greenfoxacademy.backend.services.user.UserService; +import com.greenfoxacademy.backend.services.user.OwnerService; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; import java.util.UUID; @@ -34,14 +34,14 @@ class EmailServiceImplTest { private EmailConfiguration emailConfiguration; @MockBean - private UserService userService; + private OwnerService ownerService; private EmailServiceImpl emailService; @BeforeEach void setUp() { emailSender = mock(JavaMailSender.class); - userService = mock(UserService.class); + ownerService = mock(OwnerService.class); emailService = new EmailServiceImpl(emailConfiguration, emailSender); } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java similarity index 78% rename from backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java rename to backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java index 10913db6..8d98cc99 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java @@ -11,7 +11,7 @@ import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.Owner; import com.greenfoxacademy.backend.models.User; -import com.greenfoxacademy.backend.repositories.UserRepository; +import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; import java.util.Optional; @@ -28,13 +28,13 @@ import org.springframework.security.crypto.password.PasswordEncoder; @ExtendWith(MockitoExtension.class) -class UserServiceImplTest { - private UserServiceImpl userService; +class OwnerServiceImplTest { + private OwnerServiceImpl userService; private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); @Mock - private UserRepository userRepository; + private OwnerRepository ownerRepository; @Mock private AuthService authService; @@ -44,8 +44,8 @@ class UserServiceImplTest { @BeforeEach void setUp() { - Mockito.reset(userRepository); - userService = new UserServiceImpl(userRepository, passwordEncoder, authService, emailService); + Mockito.reset(ownerRepository); + userService = new OwnerServiceImpl(ownerRepository, passwordEncoder, authService, emailService); } @DisplayName("Register a new user if email not taken") @@ -60,11 +60,11 @@ void register() { "SomePassword123"); // When - when(userRepository.save(any())).thenReturn(asSaved); + when(ownerRepository.save(any())).thenReturn(asSaved); userService.register(registerRequestDto); // Then - Mockito.verify(userRepository, Mockito.times(1)).save(any()); + Mockito.verify(ownerRepository, Mockito.times(1)).save(any()); } @DisplayName("Does not register a new user if email is taken") @@ -78,7 +78,7 @@ void registerFails() { "SomePassword123"); // When - when(userRepository.save(any())) + when(ownerRepository.save(any())) .thenThrow(new UserAlreadyExistsError("Email is already taken!")); Assertions.assertThrows( @@ -92,7 +92,7 @@ void registerFails() { @Test void login() throws Exception { // Given - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -100,14 +100,14 @@ void login() throws Exception { LoginRequestDto userLoginRequestDto = new LoginRequestDto("email", "password"); // When - when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); when(authService.generateToken(any())).thenReturn("token"); userService.login(userLoginRequestDto); // Then Mockito.verify( - userRepository, + ownerRepository, Mockito.times(1)).findByEmail(anyString() ); } @@ -116,7 +116,7 @@ void login() throws Exception { @Test void loginUnsuccessful() throws Exception { // Given - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("passwordNOOP")) @@ -127,13 +127,13 @@ void loginUnsuccessful() throws Exception { ); // When - when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); Assertions.assertThrows(Exception.class, () -> userService.login(userLoginRequestDto)); // Then Mockito.verify( - userRepository, + ownerRepository, Mockito.times(1)).findByEmail(anyString() ); } @@ -142,7 +142,7 @@ void loginUnsuccessful() throws Exception { @Test void profileUpdate() throws Exception { // Given - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -155,14 +155,14 @@ void profileUpdate() throws Exception { "newPassword"); // When - when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); - when(userRepository.save(any())).thenReturn(user); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.save(any())).thenReturn(user); userService.profileUpdate(email, profileUpdateRequestDto); // Then Mockito - .verify(userRepository, Mockito.times(1)) + .verify(ownerRepository, Mockito.times(1)) .findByEmail(anyString()); } @@ -170,7 +170,7 @@ void profileUpdate() throws Exception { @Test void profileUpdateUnsuccessful() throws Exception { // Given - User user = Owner.builder().id(1).email("email") + Owner user = Owner.builder().id(1).email("email") .password(passwordEncoder.encode("password")) .build(); String email = "email"; @@ -184,8 +184,8 @@ void profileUpdateUnsuccessful() throws Exception { // @formatter:on // When - when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); - when(userRepository.existsByEmail("new@email.com")).thenReturn(true); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.existsByEmail("new@email.com")).thenReturn(true); // Then Assertions.assertThrows( @@ -197,18 +197,18 @@ void profileUpdateUnsuccessful() throws Exception { @Test void loadUserByUsername() { // Given - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) .build(); String email = "email"; // When - when(userRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); userService.loadUserByUsername(email); // Then Mockito.verify( - userRepository, + ownerRepository, Mockito.times(1) ).findByEmail(anyString()); } @@ -216,26 +216,26 @@ void loadUserByUsername() { @Test void verifyUserById() { UUID id = UUID.randomUUID(); - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) .verificationId(id) .build(); // When - when(userRepository.findByVerificationId(id)).thenReturn(Optional.of(user)); + when(ownerRepository.findByVerificationId(id)).thenReturn(Optional.of(user)); userService.verifyUser(id); // Then Mockito.verify( - userRepository, + ownerRepository, Mockito.times(1) - ).save(any(User.class)); + ).save(any(Owner.class)); } @Test void throwsExceptionEmailIsNotVerified() { UUID id = UUID.randomUUID(); - User user = Owner.builder() + Owner user = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -244,7 +244,7 @@ void throwsExceptionEmailIsNotVerified() { LoginRequestDto loginRequestDto = new LoginRequestDto(user.getEmail(), "password"); - when(userRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user)); Assertions.assertThrows(Exception.class, () -> userService.login(loginRequestDto)); } From e3b8f78ac1d768c1b96918d80c62c1ebf693c6c0 Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 11:37:48 +0200 Subject: [PATCH 08/11] refactor: User to Owner --- .../services/user/OwnerServiceImpl.java | 25 +++++++------ .../services/user/OwnerServiceImplTest.java | 35 +++++++++---------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java index 4208e6d8..b9e14dbb 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java @@ -9,7 +9,6 @@ import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.Owner; -import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; @@ -37,7 +36,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) throws UserAlreadyExistsError { // @formatter:off - Owner user = Owner.builder() + Owner owner = Owner.builder() .email(registerRequestDto.email()) .firstName(registerRequestDto.firstName()) .lastName(registerRequestDto.lastName()) @@ -46,7 +45,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) .build(); // @formatter:on try { - Owner saved = ownerRepository.save(user); + Owner saved = ownerRepository.save(owner); emailService.sendRegistrationEmail( saved.getEmail(), saved.getFirstName(), @@ -61,14 +60,14 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto) @Override public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception { - User user = ownerRepository.findByEmail(loginRequestDto.email()) + Owner owner = ownerRepository.findByEmail(loginRequestDto.email()) .orElseThrow(() -> new Exception("User not found")); - if (!user.isEnabled()) { + if (!owner.isEnabled()) { throw new Exception("User's email is not verified"); - } else if (!passwordEncoder.matches(loginRequestDto.password(), user.getPassword())) { + } else if (!passwordEncoder.matches(loginRequestDto.password(), owner.getPassword())) { throw new Exception("Invalid password"); } - return new LoginResponseDto(authService.generateToken(user)); + return new LoginResponseDto(authService.generateToken(owner)); } @Override @@ -76,7 +75,7 @@ public ProfileUpdateResponseDto profileUpdate( String email, ProfileUpdateRequestDto profileUpdateRequestDto ) throws CannotUpdateUserException { - Owner user = ownerRepository.findByEmail(email) + Owner owner = ownerRepository.findByEmail(email) .orElseThrow(() -> new UsernameNotFoundException("User not found")); if ( ownerRepository.existsByEmail(profileUpdateRequestDto.email()) @@ -84,12 +83,12 @@ public ProfileUpdateResponseDto profileUpdate( ) { throw new CannotUpdateUserException("Email is already taken!"); } - user.setEmail(profileUpdateRequestDto.email()); - user.setFirstName(profileUpdateRequestDto.firstName()); - user.setLastName(profileUpdateRequestDto.lastName()); - user.setPassword(passwordEncoder.encode(profileUpdateRequestDto.password())); + owner.setEmail(profileUpdateRequestDto.email()); + owner.setFirstName(profileUpdateRequestDto.firstName()); + owner.setLastName(profileUpdateRequestDto.lastName()); + owner.setPassword(passwordEncoder.encode(profileUpdateRequestDto.password())); - Owner updatedUser = ownerRepository.save(user); + Owner updatedUser = ownerRepository.save(owner); return new ProfileUpdateResponseDto(authService.generateToken(updatedUser)); } diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java index 8d98cc99..80a3c875 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java @@ -10,7 +10,6 @@ import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.models.Owner; -import com.greenfoxacademy.backend.models.User; import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; @@ -52,7 +51,7 @@ void setUp() { @Test void register() { // Given - User asSaved = Owner.builder().id(1).build(); + Owner asSaved = Owner.builder().id(1).build(); RegisterRequestDto registerRequestDto = new RegisterRequestDto( "fistName", "lastName", @@ -92,7 +91,7 @@ void registerFails() { @Test void login() throws Exception { // Given - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -100,7 +99,7 @@ void login() throws Exception { LoginRequestDto userLoginRequestDto = new LoginRequestDto("email", "password"); // When - when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(owner)); when(authService.generateToken(any())).thenReturn("token"); userService.login(userLoginRequestDto); @@ -116,7 +115,7 @@ void login() throws Exception { @Test void loginUnsuccessful() throws Exception { // Given - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("passwordNOOP")) @@ -127,7 +126,7 @@ void loginUnsuccessful() throws Exception { ); // When - when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(owner)); Assertions.assertThrows(Exception.class, () -> userService.login(userLoginRequestDto)); @@ -142,7 +141,7 @@ void loginUnsuccessful() throws Exception { @Test void profileUpdate() throws Exception { // Given - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) @@ -155,8 +154,8 @@ void profileUpdate() throws Exception { "newPassword"); // When - when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); - when(ownerRepository.save(any())).thenReturn(user); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(owner)); + when(ownerRepository.save(any())).thenReturn(owner); userService.profileUpdate(email, profileUpdateRequestDto); @@ -170,7 +169,7 @@ void profileUpdate() throws Exception { @Test void profileUpdateUnsuccessful() throws Exception { // Given - Owner user = Owner.builder().id(1).email("email") + Owner owner = Owner.builder().id(1).email("email") .password(passwordEncoder.encode("password")) .build(); String email = "email"; @@ -184,7 +183,7 @@ void profileUpdateUnsuccessful() throws Exception { // @formatter:on // When - when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(owner)); when(ownerRepository.existsByEmail("new@email.com")).thenReturn(true); // Then @@ -197,14 +196,14 @@ void profileUpdateUnsuccessful() throws Exception { @Test void loadUserByUsername() { // Given - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) .build(); String email = "email"; // When - when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(anyString())).thenReturn(Optional.of(owner)); userService.loadUserByUsername(email); // Then Mockito.verify( @@ -216,14 +215,14 @@ void loadUserByUsername() { @Test void verifyUserById() { UUID id = UUID.randomUUID(); - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) .verificationId(id) .build(); // When - when(ownerRepository.findByVerificationId(id)).thenReturn(Optional.of(user)); + when(ownerRepository.findByVerificationId(id)).thenReturn(Optional.of(owner)); userService.verifyUser(id); // Then Mockito.verify( @@ -235,16 +234,16 @@ void verifyUserById() { @Test void throwsExceptionEmailIsNotVerified() { UUID id = UUID.randomUUID(); - Owner user = Owner.builder() + Owner owner = Owner.builder() .id(1) .email("email") .password(passwordEncoder.encode("password")) .verificationId(id) .build(); - LoginRequestDto loginRequestDto = new LoginRequestDto(user.getEmail(), "password"); + LoginRequestDto loginRequestDto = new LoginRequestDto(owner.getEmail(), "password"); - when(ownerRepository.findByEmail(user.getEmail())).thenReturn(Optional.of(user)); + when(ownerRepository.findByEmail(owner.getEmail())).thenReturn(Optional.of(owner)); Assertions.assertThrows(Exception.class, () -> userService.login(loginRequestDto)); } From 4d1ab818c7c14e5274702081c2f365383864713f Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 11:48:44 +0200 Subject: [PATCH 09/11] docs: add JAVADOC, Owner, ClinicAddress, Vet --- .../backend/controller/UserController.java | 2 +- .../backend/models/ClinicAddress.java | 26 +++++++++++++++++++ .../greenfoxacademy/backend/models/Owner.java | 23 ++++++++++++++-- .../greenfoxacademy/backend/models/User.java | 5 ---- .../greenfoxacademy/backend/models/Vet.java | 23 ++++++++++++++-- .../user/{ => owner}/OwnerService.java | 2 +- .../user/{ => owner}/OwnerServiceImpl.java | 3 ++- .../backend/services/OwnerServiceTest.java | 2 +- .../services/UserRegistrationTest.java | 2 +- .../services/mail/EmailServiceImplTest.java | 2 +- .../services/user/OwnerServiceImplTest.java | 1 + 11 files changed, 76 insertions(+), 15 deletions(-) rename backend/src/main/java/com/greenfoxacademy/backend/services/user/{ => owner}/OwnerService.java (96%) rename backend/src/main/java/com/greenfoxacademy/backend/services/user/{ => owner}/OwnerServiceImpl.java (97%) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java index ad3d1a37..a9a5be7d 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/controller/UserController.java @@ -9,7 +9,7 @@ import com.greenfoxacademy.backend.errors.CannotUpdateUserException; import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; -import com.greenfoxacademy.backend.services.user.OwnerService; +import com.greenfoxacademy.backend.services.user.owner.OwnerService; import java.security.Principal; import java.util.UUID; import lombok.RequiredArgsConstructor; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java index 13cb2ed7..cf1020bb 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicAddress.java @@ -5,6 +5,32 @@ import jakarta.persistence.Id; import lombok.Data; +/** + * Represents an address for a clinic. + *

+ * The {@code ClinicAddress} class is used as an embeddable type in JPA entities to store address + * details of a clinic. It includes information such as the street address, city, postal code, + * and clinic name. + *

+ *

+ * This class is marked with {@code @Embeddable} to indicate that it can be embedded in other JPA + * entities. + *

+ *

+ * The {@code id} field is used as a unique identifier for the address. This field is optional and + * is provided for cases where a unique identifier is necessary. + *

+ *

+ * The {@code zip} field represents the postal code for the clinic address and is limited to a + * length of 4 digits. + *

+ *

+ * The {@code clinicName} field specifies the name of the clinic associated with the address. + *

+ * + * @see jakarta.persistence.Embeddable + */ + @Embeddable @Data public class ClinicAddress { diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java index 3880d09a..819e1872 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Owner.java @@ -4,14 +4,33 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.persistence.Transient; +import java.util.Collection; +import java.util.List; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.experimental.SuperBuilder; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import java.util.Collection; -import java.util.List; +/** + * Represents an owner in the system who is also a user. + *

+ * The {@code Owner} class extends the {@code User} class and includes specific information related + * to an owner, such as the list of pets they own. It is marked with {@code @Entity} to indicate + * that it is a JPA entity and is mapped to a database table. + *

+ *

+ * The {@code @Table(name = "_owner")} annotation specifies the name of the database table + * associated with this entity. The table name is prefixed with an underscore to avoid conflicts + * with reserved SQL keywords. + *

+ *

+ * The {@code getAuthorities} method overrides the method from {@code User} to provide specific + * authorities for an owner, granting the role {@code ROLE_OWNER}. + *

+ * + * @see User + */ @Entity @SuperBuilder diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java index addebc6b..26c536d7 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/User.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/User.java @@ -1,14 +1,9 @@ package com.greenfoxacademy.backend.models; -import jakarta.persistence.CascadeType; import jakarta.persistence.Column; -import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; -import jakarta.persistence.OneToMany; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java index 204e3d11..86f0b696 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java @@ -3,14 +3,33 @@ import jakarta.persistence.Entity; import jakarta.persistence.Table; import jakarta.persistence.Transient; +import java.util.Collection; +import java.util.List; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.experimental.SuperBuilder; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import java.util.Collection; -import java.util.List; +/** + * Represents a veterinarian who is also a user in the system. + *

+ * The {@code Vet} class extends the {@code User} class and adds specific information related to + * a veterinarian, such as the clinic address. It is annotated with {@code @Entity} to indicate + * that it is a JPA entity and will be mapped to a database table. + *

+ *

+ * This class is annotated with {@code @Table(name = "_vet")} to specify the name of the database + * table to which this entity is mapped. The table name is prefixed with an underscore to avoid + * conflicts with reserved SQL keywords. + *

+ *

+ * The {@code getAuthorities} method overrides the method from {@code User} to provide specific + * authorities for a veterinarian, in this case, granting the role {@code ROLE_VET}. + *

+ * + * @see User + */ @SuperBuilder @RequiredArgsConstructor diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerService.java similarity index 96% rename from backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java rename to backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerService.java index fe2a43bf..68dba21e 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerService.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerService.java @@ -1,4 +1,4 @@ -package com.greenfoxacademy.backend.services.user; +package com.greenfoxacademy.backend.services.user.owner; import com.greenfoxacademy.backend.dtos.LoginRequestDto; import com.greenfoxacademy.backend.dtos.LoginResponseDto; diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerServiceImpl.java similarity index 97% rename from backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java rename to backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerServiceImpl.java index b9e14dbb..69a93f83 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/OwnerServiceImpl.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/owner/OwnerServiceImpl.java @@ -1,4 +1,4 @@ -package com.greenfoxacademy.backend.services.user; +package com.greenfoxacademy.backend.services.user.owner; import com.greenfoxacademy.backend.dtos.LoginRequestDto; import com.greenfoxacademy.backend.dtos.LoginResponseDto; @@ -12,6 +12,7 @@ import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; +import com.greenfoxacademy.backend.services.user.owner.OwnerService; import jakarta.transaction.Transactional; import java.util.UUID; import lombok.RequiredArgsConstructor; diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java index d8e3fe68..728f4fcb 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/OwnerServiceTest.java @@ -7,7 +7,7 @@ import com.greenfoxacademy.backend.dtos.RegisterRequestDto; import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.repositories.OwnerRepository; -import com.greenfoxacademy.backend.services.user.OwnerService; +import com.greenfoxacademy.backend.services.user.owner.OwnerService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java index 3a754ae2..a2778194 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/UserRegistrationTest.java @@ -10,7 +10,7 @@ import com.greenfoxacademy.backend.errors.UserAlreadyExistsError; import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.mail.EmailService; -import com.greenfoxacademy.backend.services.user.OwnerService; +import com.greenfoxacademy.backend.services.user.owner.OwnerService; import java.util.UUID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java index 93101952..616bdc12 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/mail/EmailServiceImplTest.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.when; import com.greenfoxacademy.backend.config.EmailConfiguration; -import com.greenfoxacademy.backend.services.user.OwnerService; +import com.greenfoxacademy.backend.services.user.owner.OwnerService; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; import java.util.UUID; diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java index 80a3c875..c47bb8a0 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java @@ -13,6 +13,7 @@ import com.greenfoxacademy.backend.repositories.OwnerRepository; import com.greenfoxacademy.backend.services.auth.AuthService; import com.greenfoxacademy.backend.services.mail.EmailService; +import com.greenfoxacademy.backend.services.user.owner.OwnerServiceImpl; import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.Assertions; From 8094573b57cfde141b9f67f90986277165db7202 Mon Sep 17 00:00:00 2001 From: Ramon Trekovanicz Date: Sat, 31 Aug 2024 12:03:57 +0200 Subject: [PATCH 10/11] feat: add ClinicDetails --- .../backend/models/ClinicDetails.java | 27 +++++++++++++++++++ .../greenfoxacademy/backend/models/Vet.java | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/models/ClinicDetails.java diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicDetails.java b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicDetails.java new file mode 100644 index 00000000..fbc1b5fe --- /dev/null +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/ClinicDetails.java @@ -0,0 +1,27 @@ +package com.greenfoxacademy.backend.models; + +import jakarta.persistence.Embeddable; +import lombok.Data; + +/** + * Represents the details of a clinic. + *

+ * The {@code ClinicDetails} class is used as an embeddable type in JPA entities to store detailed + * information about a clinic. This class contains the address of the clinic as well as any + * additional details that may be relevant for clinic management. + *

+ *

+ * This class is annotated with {@code @Embeddable} to indicate that it can be embedded within + * other JPA entities. + *

+ * + * @see ClinicAddress + */ + +@Data +@Embeddable +public class ClinicDetails { + + private ClinicAddress clinicAddress; + +} diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java index 86f0b696..d99bd34c 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Vet.java @@ -37,7 +37,7 @@ @Entity @Table(name = "_vet") public class Vet extends User { - private ClinicAddress clinicAddress; + private ClinicDetails clinicDetails; @Override @Transient From 69b8f08eabc438a38e3f831ac3541707cce204d3 Mon Sep 17 00:00:00 2001 From: markkovari Date: Sat, 7 Sep 2024 15:04:14 +0200 Subject: [PATCH 11/11] fix: imports --- .../src/main/java/com/greenfoxacademy/backend/models/Pet.java | 2 -- .../backend/services/user/OwnerServiceImplTest.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java index 791ff3d6..6fd1d341 100644 --- a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java +++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java @@ -8,9 +8,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; - import java.util.Date; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java index 4fba12ec..bcdde253 100644 --- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java +++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java @@ -17,7 +17,6 @@ import com.greenfoxacademy.backend.services.user.owner.OwnerServiceImpl; import java.util.Optional; import java.util.UUID; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -26,7 +25,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;