diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index f5def7599..9098ec792 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches95.4% \ No newline at end of file +branches81.2% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 8032eb625..58cb94897 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage98% \ No newline at end of file +coverage91.6% \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore index 2671d06ef..6dcd66b83 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -107,7 +107,7 @@ local.properties # .idea/modules.xml # .idea/*.iml # .idea/modules -# *.iml +*.iml # *.ipr # CMake diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityCreateDto.java b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityCreateDto.java deleted file mode 100644 index e0d0fb082..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityCreateDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package ca.bc.gov.backendstartapi.dto; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; - -/** - * This record represents a dto when creating a {@link - * ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity}. - * - * @param title The title of the activity, from {@link ca.bc.gov.backendstartapi.enums.ActivityEnum} - */ -public record FavoriteActivityCreateDto(@Size(min = 2, max = 20) @NotBlank String title) {} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityUpdateDto.java b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityUpdateDto.java deleted file mode 100644 index 30d6ca53b..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavoriteActivityUpdateDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package ca.bc.gov.backendstartapi.dto; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; - -/** - * This record represents a dto when updating a {@link - * ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity}. - * - * @param highlighted A boolean representing if the activity is highlighted - * @param enabled a boolean representing if the activity is enabled - */ -public record FavoriteActivityUpdateDto( - @NotBlank @Pattern(regexp = "^true$|^false$", message = "allowed input: true of false") - Boolean highlighted, - @NotBlank @Pattern(regexp = "^true$|^false$", message = "allowed input: true of false") - Boolean enabled) {} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityCreateDto.java b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityCreateDto.java new file mode 100644 index 000000000..d39bc2dd3 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityCreateDto.java @@ -0,0 +1,12 @@ +package ca.bc.gov.backendstartapi.dto; + +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; +import jakarta.validation.constraints.NotNull; + +/** + * This record represents a dto when creating a {@link FavouriteActivityEntity}. + * + * @param activity The activity from {@link ca.bc.gov.backendstartapi.enums.ActivityEnum} + */ +public record FavouriteActivityCreateDto(@NotNull ActivityEnum activity) {} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityUpdateDto.java b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityUpdateDto.java new file mode 100644 index 000000000..4a26235f6 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/dto/FavouriteActivityUpdateDto.java @@ -0,0 +1,12 @@ +package ca.bc.gov.backendstartapi.dto; + +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import jakarta.validation.constraints.NotNull; + +/** + * This record represents a dto when updating a {@link FavouriteActivityEntity}. + * + * @param highlighted A boolean representing if the activity is highlighted + * @param enabled a boolean representing if the activity is enabled + */ +public record FavouriteActivityUpdateDto(@NotNull Boolean highlighted, @NotNull Boolean enabled) {} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpoint.java b/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpoint.java deleted file mode 100644 index 5295cf38a..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpoint.java +++ /dev/null @@ -1,90 +0,0 @@ -package ca.bc.gov.backendstartapi.endpoint; - -import ca.bc.gov.backendstartapi.dto.FavoriteActivityCreateDto; -import ca.bc.gov.backendstartapi.dto.FavoriteActivityUpdateDto; -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.service.FavoriteActivityService; -import java.util.List; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -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.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -/** This class contains all {@link FavoriteActivityEntity} resources that a user needs. */ -@Setter -@NoArgsConstructor -@RestController -@RequestMapping("/api/favorite_activity") -public class FavoriteActivityEndpoint { - - private FavoriteActivityService favoriteActivityService; - - /** - * Creates a {@link FavoriteActivityEndpoint} instance. - * - * @param favoriteActivityService a {@link FavoriteActivityService} instance - */ - @Autowired - public FavoriteActivityEndpoint(FavoriteActivityService favoriteActivityService) { - this.favoriteActivityService = favoriteActivityService; - } - - /** - * Creates to the logged user a {@link FavoriteActivityEntity} based on the activity title, that - * comes from {@link ca.bc.gov.backendstartapi.enums.ActivityEnum}. - * - * @param createDto a {@link FavoriteActivityCreateDto} with the activity title - * @return a {@link FavoriteActivityEntity} created - */ - @PostMapping(consumes = "application/json", produces = "application/json") - @PreAuthorize("hasRole('user_write')") - public FavoriteActivityEntity createUserActivity( - @RequestBody FavoriteActivityCreateDto createDto) { - return favoriteActivityService.createUserActivity(createDto); - } - - /** - * Retrieve all {@link FavoriteActivityEntity} bounded to the user that made the request. - * - * @return a list of {@link FavoriteActivityEntity} - */ - @GetMapping(produces = "application/json") - @PreAuthorize("hasRole('user_read')") - public List getUserActivities() { - return favoriteActivityService.getAllUserFavoriteActivities(); - } - - /** - * Update a {@link FavoriteActivityEntity} of the logged user. - * - * @param id The id of the {@link FavoriteActivityEntity} - * @param updateDto a {@link FavoriteActivityUpdateDto} containing highlighted and enabled states - * @return the {@link FavoriteActivityEntity} updated - */ - @PutMapping(value = "/{id}", consumes = "application/json", produces = "application/json") - @PreAuthorize("hasRole('user_write')") - public FavoriteActivityEntity updateFavoriteActivity( - @PathVariable Long id, @RequestBody FavoriteActivityUpdateDto updateDto) { - return favoriteActivityService.updateUserActivity(id, updateDto); - } - - /** - * Delete a user's {@link FavoriteActivityEntity}. - * - * @param id The id of the {@link FavoriteActivityEntity} - */ - @DeleteMapping(value = "/{id}", produces = "application/json") - @PreAuthorize("hasRole('user_write')") - public void deleteFavoriteActivity(@PathVariable Long id) { - favoriteActivityService.deleteUserActivity(id); - } -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpoint.java b/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpoint.java new file mode 100644 index 000000000..474f4c8e5 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpoint.java @@ -0,0 +1,85 @@ +package ca.bc.gov.backendstartapi.endpoint; + +import ca.bc.gov.backendstartapi.dto.FavouriteActivityCreateDto; +import ca.bc.gov.backendstartapi.dto.FavouriteActivityUpdateDto; +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.service.FavouriteActivityService; +import jakarta.validation.Valid; +import java.util.List; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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; + +/** This class contains all {@link FavouriteActivityEntity} resources that a user needs. */ +@Setter +@NoArgsConstructor +@RestController +@RequestMapping("/api/favourite-activities") +public class FavouriteActivityEndpoint { + + private FavouriteActivityService favouriteActivityService; + + @Autowired + FavouriteActivityEndpoint(FavouriteActivityService favouriteActivityService) { + this.favouriteActivityService = favouriteActivityService; + } + + /** + * Creates to the logged user a {@link FavouriteActivityEntity} based on the activity title, that + * comes from {@link ca.bc.gov.backendstartapi.enums.ActivityEnum}. + * + * @param createDto a {@link FavouriteActivityCreateDto} with the activity title + * @return a {@link FavouriteActivityEntity} created + */ + @PostMapping(consumes = "application/json", produces = "application/json") + @PreAuthorize("hasRole('user_write')") + public FavouriteActivityEntity createUserActivity( + @Valid @RequestBody FavouriteActivityCreateDto createDto) { + return favouriteActivityService.createUserActivity(createDto); + } + + /** + * Retrieve all {@link FavouriteActivityEntity} bound to the user that made the request. + * + * @return a list of {@link FavouriteActivityEntity} + */ + @GetMapping(produces = "application/json") + @PreAuthorize("hasRole('user_read')") + public List getUserActivities() { + return favouriteActivityService.getAllUserFavoriteActivities(); + } + + /** + * Update a {@link FavouriteActivityEntity} of the logged user. + * + * @param id The id of the {@link FavouriteActivityEntity} + * @param updateDto a {@link FavouriteActivityUpdateDto} containing highlighted and enabled states + * @return the {@link FavouriteActivityEntity} updated + */ + @PutMapping(value = "/{id}", consumes = "application/json", produces = "application/json") + @PreAuthorize("hasRole('user_write')") + public FavouriteActivityEntity updateFavoriteActivity( + @PathVariable Long id, @Valid @RequestBody FavouriteActivityUpdateDto updateDto) { + return favouriteActivityService.updateUserActivity(id, updateDto); + } + + /** + * Delete a user's {@link FavouriteActivityEntity}. + * + * @param id The id of the {@link FavouriteActivityEntity} + */ + @DeleteMapping(value = "/{id}", produces = "application/json") + @PreAuthorize("hasRole('user_write')") + public void deleteFavoriteActivity(@PathVariable Long id) { + favouriteActivityService.deleteUserActivity(id); + } +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavoriteActivityEntity.java b/backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavouriteActivityEntity.java similarity index 51% rename from backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavoriteActivityEntity.java rename to backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavouriteActivityEntity.java index 83ac4463d..00fe0ea81 100644 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavoriteActivityEntity.java +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/entity/FavouriteActivityEntity.java @@ -1,20 +1,17 @@ package ca.bc.gov.backendstartapi.entity; -import ca.bc.gov.backendstartapi.exception.NotRemovableEntityException; -import com.fasterxml.jackson.annotation.JsonIgnore; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.PreRemove; import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; -import lombok.ToString; import lombok.With; /** This class represents a user's favorite activity in the database. */ @@ -23,32 +20,26 @@ @Setter @With @AllArgsConstructor -@Table(name = "favorite_activity") -public class FavoriteActivityEntity { +@Table(name = "favourite_activity") +public class FavouriteActivityEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - @JoinColumn(name = "user_id", nullable = false) - @JsonIgnore - private UserEntity user; + @Column(name = "user_id") + private String userId; - @Column(name = "activity_title", updatable = false) - private String activityTitle; + @Column(name = "activity", updatable = false) + @Enumerated(value = EnumType.STRING) + private ActivityEnum activity; @Column private Boolean highlighted; @Column private Boolean enabled; - public FavoriteActivityEntity() { + public FavouriteActivityEntity() { this.highlighted = false; this.enabled = true; } - - @PreRemove - private void preRemove() { - throw new NotRemovableEntityException(); - } } diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserEntity.java b/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserEntity.java deleted file mode 100644 index b94bcebe6..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserEntity.java +++ /dev/null @@ -1,37 +0,0 @@ -package ca.bc.gov.backendstartapi.entity; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import java.time.LocalDateTime; -import java.util.Set; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -/** This class represents a system User in the database. */ -@Entity -@Getter -@Setter -@Table(name = "user") -@AllArgsConstructor -@NoArgsConstructor -public class UserEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column private String email; - - @Column(name = "last_login") - private LocalDateTime lastLogin; - - @OneToMany(mappedBy = "user") - private Set favoriteActivities; -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserProfileEntity.java b/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserProfileEntity.java new file mode 100644 index 000000000..233925ae7 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/entity/UserProfileEntity.java @@ -0,0 +1,27 @@ +package ca.bc.gov.backendstartapi.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** This class represents a system User in the database. */ +@Entity +@Getter +@Setter +@Table(name = "user_profile") +@AllArgsConstructor +@NoArgsConstructor +public class UserProfileEntity { + + @Id + @Column(name = "user_id") + private String userId; + + @Column(name = "dark_theme") + private Boolean darkTheme; +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/enums/ActivityEnum.java b/backend/src/main/java/ca/bc/gov/backendstartapi/enums/ActivityEnum.java index 11eb46cd4..60a60c8a5 100644 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/enums/ActivityEnum.java +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/enums/ActivityEnum.java @@ -1,55 +1,8 @@ package ca.bc.gov.backendstartapi.enums; -import java.util.Optional; -import lombok.Getter; -import lombok.ToString; - -/** This enumeration contains all possible activities. */ -@Getter -@ToString +/** This enumeration contains the SPAR activities. */ public enum ActivityEnum { - SEEDLOT_REGISTRATION( - "SoilMoistureField", - "Seedlot registration", - "Start a new registration or check on existing seedlots registrations", - "/seedlot-registration"), - PARENT_TREE_ORCHARD( - "Tree", - "Parent tree orchard", - "Manage the parent trees inside your orchard and look for their " - + "latest reports and the latest data.", - "/parent-tree-orchard"), - SEEDLING_REQUEST( - "CropGrowth", - "Seedling request", - "Open a new seedling request for your reforestation needs.", - "/seedling-request"); - - private final String iconName; - private final String title; - private final String description; - private final String page; - - private ActivityEnum( - final String iconName, final String title, final String description, final String page) { - this.iconName = iconName; - this.title = title; - this.description = description; - this.page = page; - } - - /** - * Finds an ActivityEnum by the page title. - * - * @param title the title of the page - * @return an ActivityEnum instance if found, null otherwise - */ - public static Optional getByTitle(String title) { - for (ActivityEnum activityEnum : values()) { - if (activityEnum.title.equals(title)) { - return Optional.of(activityEnum); - } - } - return Optional.empty(); - } + SEEDLOT_REGISTRATION, + PARENT_TREE_ORCHARD, + SEEDLING_REQUEST; } diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/exception/NotRemovableEntityException.java b/backend/src/main/java/ca/bc/gov/backendstartapi/exception/NotRemovableEntityException.java deleted file mode 100644 index 94e07112d..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/exception/NotRemovableEntityException.java +++ /dev/null @@ -1,15 +0,0 @@ -package ca.bc.gov.backendstartapi.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.server.ResponseStatusException; - -/** This exception represents an entity that shouldn't or can't be deleted. */ -@ResponseStatus(value = HttpStatus.BAD_REQUEST) -public class NotRemovableEntityException extends ResponseStatusException { - - /** Creates an NotRemovableEntityException instance. */ - public NotRemovableEntityException() { - super(HttpStatus.BAD_REQUEST, "Entity not removable!"); - } -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepository.java b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepository.java deleted file mode 100644 index 58c0c14a3..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package ca.bc.gov.backendstartapi.repository; - -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.entity.UserEntity; -import java.util.List; -import java.util.Optional; -import org.springframework.data.repository.CrudRepository; - -/** - * This class represents a user's favorite activity repository. - */ -public interface FavoriteActivityRepository extends CrudRepository { - - List findAllByUser(UserEntity user); - - List findAllByEnabledAndUser(Boolean enabled, Long userId); - - Optional findByActivityTitle(String activityTitle); -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepository.java b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepository.java new file mode 100644 index 000000000..c36fe6d97 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepository.java @@ -0,0 +1,17 @@ +package ca.bc.gov.backendstartapi.repository; + +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; +import java.util.List; +import java.util.Optional; +import org.springframework.data.repository.CrudRepository; + +/** This class represents a user's favorite activity repository. */ +public interface FavouriteActivityRepository extends CrudRepository { + + List findAllByUserId(String userId); + + List findAllByEnabledAndUserId(Boolean enabled, String userId); + + Optional findByActivity(ActivityEnum activity); +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserProfileRepository.java b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserProfileRepository.java new file mode 100644 index 000000000..05e8ecc27 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserProfileRepository.java @@ -0,0 +1,11 @@ +package ca.bc.gov.backendstartapi.repository; + +import ca.bc.gov.backendstartapi.entity.UserProfileEntity; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +/** This class contains the methods to retrieve and store users into the database. */ +public interface UserProfileRepository extends JpaRepository { + + Optional findByUserId(String userId); +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserRepository.java b/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserRepository.java deleted file mode 100644 index 32bf7d582..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/repository/UserRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package ca.bc.gov.backendstartapi.repository; - -import ca.bc.gov.backendstartapi.entity.UserEntity; -import java.util.List; -import org.springframework.data.repository.CrudRepository; - -/** This class contains the methods to retrieve and store users into the database. */ -public interface UserRepository extends CrudRepository { - - List findAllByEmail(String email); -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/security/LoggedUserService.java b/backend/src/main/java/ca/bc/gov/backendstartapi/security/LoggedUserService.java new file mode 100644 index 000000000..6b9a3cf7a --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/security/LoggedUserService.java @@ -0,0 +1,66 @@ +package ca.bc.gov.backendstartapi.security; + +import ca.bc.gov.backendstartapi.exception.UserNotFoundException; +import java.util.Optional; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** This class contains all user related methods and artifacts. */ +@Setter +@Service +@NoArgsConstructor +public class LoggedUserService { + + private UserAuthenticationHelper userAuthenticationHelper; + + /** + * Create a {@link LoggedUserService} instance. + * + * @param userAuthenticationHelper a {@link UserAuthenticationHelper} instance + */ + @Autowired + public LoggedUserService(UserAuthenticationHelper userAuthenticationHelper) { + this.userAuthenticationHelper = userAuthenticationHelper; + } + + /** + * Get all user info included in the JWT decoded token. + * + * @return an optional of {@link UserInfo}. It'll be empty then not logged in + */ + public Optional getLoggedUserInfo() { + return userAuthenticationHelper.getUserInfo(); + } + + /** + * Get the email address from the logged user. + * + * @return a String containing the email address if logged in + * @throws UserNotFoundException when not logged in + */ + public String getLoggedUserEmail() { + Optional userInfo = userAuthenticationHelper.getUserInfo(); + if (userInfo.isEmpty()) { + throw new UserNotFoundException(); + } + + return userInfo.get().email(); + } + + /** + * Get the ID from the logged user. + * + * @return a String containing the id if logged in. Or an empty string otherwise + * @throws UserNotFoundException when not logged in + */ + public String getLoggedUserId() { + Optional userInfo = userAuthenticationHelper.getUserInfo(); + if (userInfo.isEmpty()) { + throw new UserNotFoundException(); + } + + return userInfo.get().id(); + } +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelper.java b/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelper.java index 6ff1d46b1..d22e20ce4 100644 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelper.java +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelper.java @@ -6,7 +6,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.stereotype.Component; @@ -18,30 +17,13 @@ public class UserAuthenticationHelper { /** * Get the logged user information. * - * @return An Optional of {@link UserInfo} with all information from JWT token, if logged in - * or empty Optional otherwise. + * @return An Optional of {@link UserInfo} with all information from JWT token, if logged in or + * empty Optional otherwise. */ public Optional getUserInfo() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication.isAuthenticated()) { - // For test cases, integration tests - if (authentication.getPrincipal() instanceof User) { - UserInfo userInfo = - new UserInfo( - "Test User", - "user@test.com", - new HashSet<>(), - "idir", - "test", - "test", - false, - "User", - "Test User", - "Test"); - return Optional.of(userInfo); - } - Jwt jwtPrincipal = (Jwt) authentication.getPrincipal(); Set roles = new HashSet<>(); @@ -51,16 +33,15 @@ public Optional getUserInfo() { UserInfo userInfo = new UserInfo( - jwtPrincipal.getClaimAsString("name"), - jwtPrincipal.getClaimAsString("email"), - roles, - jwtPrincipal.getClaimAsString("identity_provider"), - jwtPrincipal.getClaimAsString("idir_username"), - jwtPrincipal.getClaimAsString("businessbceid_username"), - Boolean.valueOf(jwtPrincipal.getClaimAsString("email_verified")), + jwtPrincipal.getClaimAsString("sub"), jwtPrincipal.getClaimAsString("given_name"), + jwtPrincipal.getClaimAsString("family_name"), + jwtPrincipal.getClaimAsString("email"), jwtPrincipal.getClaimAsString("display_name"), - jwtPrincipal.getClaimAsString("family_name")); + jwtPrincipal.getClaimAsString("idir_username"), + jwtPrincipal.getClaimAsString("bceid_business_name"), + jwtPrincipal.getClaimAsString("identity_provider"), + roles); return Optional.of(userInfo); } diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserInfo.java b/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserInfo.java index 613f375c4..7f33f19e6 100644 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserInfo.java +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/security/UserInfo.java @@ -1,16 +1,136 @@ package ca.bc.gov.backendstartapi.security; +import java.util.Collections; import java.util.Set; -/** This record represents a user logged and his information from JWT token. */ +/** This record represents a user logged and his information from JWT decoded token. To learn more + * about the attributes and see reference list, you can see here: + * IDP Attributes + */ public record UserInfo( - String name, + String id, + String firstName, + String lastName, String email, - Set roles, - String identityProvider, - String idirUsername, - String businessbceidUsername, - Boolean emailVerified, - String givenName, String displayName, - String familyName) {} + String idirUsername, + String businessName, + String identityProvider, + Set roles) { + + /** + * Constructor only for ensuring immutability for the user's roles. + * + * @param id see the access method + * @param firstName see the access method + * @param lastName see the access method + * @param email see the access method + * @param displayName see the access method + * @param idirUsername see the access method + * @param businessName see the access method + * @param identityProvider see the access method + * @param roles see the access method + */ + public UserInfo { + roles = Collections.unmodifiableSet(roles); + } + + /** + * The user's ID. This prop comes from JWT 'sub' property and will exist when logged with both + * IDIR and Business BCeID. E.g.: 123456789...45689@idir + * + * @return The user ID + */ + @Override + public String id() { + return id; + } + + /** + * The user's first name. This prop comes from JWT 'given_name' claim and only exists when logged + * with IDIR. + * + * @return The first name + */ + @Override + public String firstName() { + return firstName; + } + + /** + * The user's last name. This prop comes from JWT 'family_name' claim and only exists when logged + * with IDIR. + * + * @return The last name + */ + @Override + public String lastName() { + return lastName; + } + + /** + * The user's email. This prop comes from JWT 'email' claim and exists for both IDIR and Business + * BCeID. + * + * @return The email + */ + @Override + public String email() { + return email; + } + + /** + * The name that should be displayed for this user. This prop comes from JWT 'display_name' claim + * and exists for both IDIR and Business BCeID. E.g.: Potter, Harry LWRS:EX + * + * @return The display name + */ + @Override + public String displayName() { + return displayName; + } + + /** + * The user's IDIR username containing eight characters. This prop comes from JWT 'idir_username' + * claim and exists only when logged with IDIR. E.g.: HAPOTTER + * + * @return The IDIR username + */ + @Override + public String idirUsername() { + return idirUsername; + } + + /** + * The business' name. This prop comes from JWT 'bceid_business_name' claim and exists only when + * logged with Business BCeID. + * + * @return The business name + */ + @Override + public String businessName() { + return businessName; + } + + /** + * The identity provider used to authenticate. This prop comes from JWT 'identity_provider' claim + * and exists for both IDIR and Business BCeID. + * + * @return The identity provider. Possible values are: 'idir' or 'bceidbusiness' + */ + @Override + public String identityProvider() { + return identityProvider; + } + + /** + * The user's roles. This prop comes from JWT 'client_roles' claim and exists only when the logged + * user has one or more roles. It can occur for both IDIR and Business BCeID. + * + * @return The set of roles + */ + @Override + public Set roles() { + return roles; + } +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavoriteActivityService.java b/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavoriteActivityService.java deleted file mode 100644 index 611680868..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavoriteActivityService.java +++ /dev/null @@ -1,122 +0,0 @@ -package ca.bc.gov.backendstartapi.service; - -import ca.bc.gov.backendstartapi.dto.FavoriteActivityCreateDto; -import ca.bc.gov.backendstartapi.dto.FavoriteActivityUpdateDto; -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.entity.UserEntity; -import ca.bc.gov.backendstartapi.enums.ActivityEnum; -import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; -import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; -import ca.bc.gov.backendstartapi.repository.FavoriteActivityRepository; -import java.util.List; -import java.util.Optional; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** This class contains all routines and database access to a users' favorite activity. */ -@Slf4j -@Setter -@Service -@NoArgsConstructor -public class FavoriteActivityService { - - private FavoriteActivityRepository favoriteActivityRepository; - - private UserService userService; - - /** - * Create a {@link FavoriteActivityService} instance. - * - * @param userService a {@link UserService} instance - * @param favoriteActivityRepository a {@link FavoriteActivityRepository} instance - */ - @Autowired - public FavoriteActivityService( - UserService userService, FavoriteActivityRepository favoriteActivityRepository) { - this.userService = userService; - this.favoriteActivityRepository = favoriteActivityRepository; - } - - /** - * Create a user's activity in the database. - * - * @param activityDto a {@link FavoriteActivityCreateDto} containing the activity title - * @return the {@link FavoriteActivityEntity} created - */ - public FavoriteActivityEntity createUserActivity(FavoriteActivityCreateDto activityDto) { - UserEntity user = userService.getLoggerUserEntity(); - - log.info("Creating activity {} to user {}", activityDto.title(), user.getId()); - - Optional activityEnum = ActivityEnum.getByTitle(activityDto.title()); - if (activityEnum.isEmpty()) { - throw new ActivityNotFoundException(); - } - - List userFavList = favoriteActivityRepository.findAllByUser(user); - if (userFavList.stream().anyMatch(ac -> ac.getActivityTitle().equals(activityDto.title()))) { - throw new FavoriteActivityExistsToUser(); - } - - FavoriteActivityEntity activityEntity = new FavoriteActivityEntity(); - activityEntity.setUser(user); - activityEntity.setActivityTitle(activityEnum.get().getTitle()); - return favoriteActivityRepository.save(activityEntity); - } - - /** - * Retrieve all favorite activities to a specific user. - * - * @return a list of FavoriteActivityEntity or an empty list - */ - public List getAllUserFavoriteActivities() { - UserEntity user = userService.getLoggerUserEntity(); - return favoriteActivityRepository.findAllByEnabledAndUser(Boolean.TRUE, user.getId()); - } - - /** - * Updates a user activity. - * - * @param id the {@link Long} value as the id of the activity to be updated - * @param updateDto a {@link FavoriteActivityUpdateDto} containing the values to be updated - * @return a {@link FavoriteActivityEntity} updated - * @throws ActivityNotFoundException if the activity doesn't exist - */ - public FavoriteActivityEntity updateUserActivity(Long id, FavoriteActivityUpdateDto updateDto) { - UserEntity user = userService.getLoggerUserEntity(); - - log.info("Updating activity {} to user {}", id, user.getId()); - Optional activityEntity = favoriteActivityRepository.findById(id); - if (activityEntity.isEmpty()) { - throw new ActivityNotFoundException(); - } - - FavoriteActivityEntity entity = - activityEntity - .get() - .withHighlighted(updateDto.highlighted()) - .withEnabled(updateDto.enabled()); - - return favoriteActivityRepository.save(entity); - } - - /** - * Deletes a user activity by the activity id number. - * - * @param id A {@link Long} value as the id of the activity - */ - public void deleteUserActivity(Long id) { - UserEntity user = userService.getLoggerUserEntity(); - - log.info("Deleting activity {} to user {}", id, user.getId()); - Optional activityEntity = favoriteActivityRepository.findById(id); - if (activityEntity.isEmpty()) { - throw new ActivityNotFoundException(); - } - - favoriteActivityRepository.deleteById(id); - } -} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavouriteActivityService.java b/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavouriteActivityService.java new file mode 100644 index 000000000..ee44defc8 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/backendstartapi/service/FavouriteActivityService.java @@ -0,0 +1,123 @@ +package ca.bc.gov.backendstartapi.service; + +import ca.bc.gov.backendstartapi.dto.FavouriteActivityCreateDto; +import ca.bc.gov.backendstartapi.dto.FavouriteActivityUpdateDto; +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; +import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; +import ca.bc.gov.backendstartapi.repository.FavouriteActivityRepository; +import ca.bc.gov.backendstartapi.security.LoggedUserService; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** This class contains all routines and database access to a users' favorite activity. */ +@Slf4j +@Setter +@Service +@NoArgsConstructor +public class FavouriteActivityService { + + private FavouriteActivityRepository favouriteActivityRepository; + + private LoggedUserService loggedUserService; + + /** + * Create a {@link FavouriteActivityService} instance. + * + * @param loggedUserService a {@link LoggedUserService} instance + * @param favouriteActivityRepository a {@link FavouriteActivityRepository} instance + */ + @Autowired + public FavouriteActivityService( + LoggedUserService loggedUserService, + FavouriteActivityRepository favouriteActivityRepository) { + this.loggedUserService = loggedUserService; + this.favouriteActivityRepository = favouriteActivityRepository; + } + + /** + * Create a user's activity in the database. + * + * @param activityDto a {@link FavouriteActivityCreateDto} containing the activity title + * @return the {@link FavouriteActivityEntity} created + */ + public FavouriteActivityEntity createUserActivity(FavouriteActivityCreateDto activityDto) { + String userId = loggedUserService.getLoggedUserId(); + log.info("Creating activity {} to user {}", activityDto.activity(), userId); + + if (Objects.isNull(activityDto.activity())) { + throw new ActivityNotFoundException(); + } + + List userFavList = favouriteActivityRepository.findAllByUserId(userId); + if (userFavList.stream().anyMatch(ac -> ac.getActivity().equals(activityDto.activity()))) { + log.info("Activity {} already exists to user {}!", activityDto.activity(), userId); + throw new FavoriteActivityExistsToUser(); + } + + FavouriteActivityEntity activityEntity = new FavouriteActivityEntity(); + activityEntity.setUserId(userId); + activityEntity.setActivity(activityDto.activity()); + return favouriteActivityRepository.save(activityEntity); + } + + /** + * Retrieve all favorite activities to a specific user. + * + * @return a list of FavoriteActivityEntity or an empty list + */ + public List getAllUserFavoriteActivities() { + String userId = loggedUserService.getLoggedUserId(); + log.info("Retrieving all favorite activities to user {}", userId); + return favouriteActivityRepository.findAllByEnabledAndUserId(Boolean.TRUE, userId); + } + + /** + * Updates a user activity. + * + * @param id the {@link Long} value as the id of the activity to be updated + * @param updateDto a {@link FavouriteActivityUpdateDto} containing the values to be updated + * @return a {@link FavouriteActivityEntity} updated + * @throws ActivityNotFoundException if the activity doesn't exist + */ + public FavouriteActivityEntity updateUserActivity(Long id, FavouriteActivityUpdateDto updateDto) { + String userId = loggedUserService.getLoggedUserId(); + + log.info("Updating activity {} to user {}", id, userId); + Optional activityEntity = favouriteActivityRepository.findById(id); + if (activityEntity.isEmpty()) { + throw new ActivityNotFoundException(); + } + + FavouriteActivityEntity entity = + activityEntity + .get() + .withHighlighted(updateDto.highlighted()) + .withEnabled(updateDto.enabled()); + + return favouriteActivityRepository.save(entity); + } + + /** + * Deletes a user activity by the activity id number. + * + * @param id A {@link Long} value as the id of the activity + */ + public void deleteUserActivity(Long id) { + String userId = loggedUserService.getLoggedUserId(); + + log.info("Deleting activity {} to user {}", id, userId); + Optional activityEntity = favouriteActivityRepository.findById(id); + if (activityEntity.isEmpty()) { + throw new ActivityNotFoundException(); + } + + favouriteActivityRepository.deleteById(id); + } +} diff --git a/backend/src/main/java/ca/bc/gov/backendstartapi/service/UserService.java b/backend/src/main/java/ca/bc/gov/backendstartapi/service/UserService.java deleted file mode 100644 index e97930658..000000000 --- a/backend/src/main/java/ca/bc/gov/backendstartapi/service/UserService.java +++ /dev/null @@ -1,79 +0,0 @@ -package ca.bc.gov.backendstartapi.service; - -import ca.bc.gov.backendstartapi.entity.UserEntity; -import ca.bc.gov.backendstartapi.exception.UserNotFoundException; -import ca.bc.gov.backendstartapi.repository.UserRepository; -import ca.bc.gov.backendstartapi.security.UserAuthenticationHelper; -import ca.bc.gov.backendstartapi.security.UserInfo; -import java.util.List; -import java.util.Optional; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** This class contains all user related methods and artifacts. */ -@Setter -@Service -@NoArgsConstructor -public class UserService { - - private UserRepository userRepository; - - private UserAuthenticationHelper userAuthenticationHelper; - - /** - * Create a {@link UserService} instance. - * - * @param userRepository a {@link UserRepository} instance - * @param userAuthenticationHelper a {@link UserAuthenticationHelper} instance - */ - @Autowired - public UserService( - UserRepository userRepository, UserAuthenticationHelper userAuthenticationHelper) { - this.userRepository = userRepository; - this.userAuthenticationHelper = userAuthenticationHelper; - } - - /** - * Get the logged user email address. - * - * @return a {@link String} containing the email address if logged in. Or an empty string - * otherwise. - */ - public String getLoggedUserEmail() { - Optional userInfo = userAuthenticationHelper.getUserInfo(); - if (userInfo.isEmpty()) { - throw new UserNotFoundException(); - } - - return userInfo.get().email(); - } - - /** - * Get all user info included in the JWT decoded token. - * - * @return an optional of {@link UserInfo} - */ - public Optional getLoggerUserInfo() { - return userAuthenticationHelper.getUserInfo(); - } - - /** - * Get the system entity related to the logged user. - * - * @return an optional of UserEntity. - */ - public UserEntity getLoggerUserEntity() { - String loggedUserEmail = getLoggedUserEmail(); - - // Note: since the user table allows repeated emails, the 'find' method should return - // a list instead of only one. - List userList = userRepository.findAllByEmail(loggedUserEmail); - if (userList.isEmpty()) { - throw new UserNotFoundException(); - } - - return userList.get(0); - } -} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 4ca961c38..dbe451143 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,6 +1,8 @@ # Server and application spring.application.name = nr-spar-backend server.port = 8090 +# Enable Response Exception Status to include reason message +server.error.include-message=always # Key Cloak, authentication and security keycloak-auth = ${KEYCLOAK_REALM_URL:https://empty.com/auth} @@ -26,6 +28,7 @@ spring.datasource.hikari.keepaliveTime = 30000 spring.datasource.hikari.poolName = NrSparDbPool spring.datasource.hikari.minimumIdle = 1 spring.datasource.hikari.maximumPoolSize = 3 +spring.jpa.properties.hibernate.default_schema=spar spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.flyway.enabled = true spring.flyway.baselineonmigrate=true \ No newline at end of file diff --git a/backend/src/main/resources/db/migration/V2__create_user.sql b/backend/src/main/resources/db/migration/V2__create_user.sql deleted file mode 100644 index 173d5560c..000000000 --- a/backend/src/main/resources/db/migration/V2__create_user.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE IF NOT EXISTS spar.user ( - id SERIAL, - email VARCHAR(100) NOT NULL, - last_login TIMESTAMP NOT NULL DEFAULT NOW(), - CONSTRAINT user_pk - primary key(id) -); diff --git a/backend/src/main/resources/db/migration/V2__create_user_profile.sql b/backend/src/main/resources/db/migration/V2__create_user_profile.sql new file mode 100644 index 000000000..dd2df6d27 --- /dev/null +++ b/backend/src/main/resources/db/migration/V2__create_user_profile.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS spar.user_profile ( + user_id VARCHAR(70) NOT NULL, + dark_theme BOOLEAN DEFAULT FALSE, + CONSTRAINT user_pk + primary key(user_id) +); diff --git a/backend/src/main/resources/db/migration/V3__create_favorite_activity.sql b/backend/src/main/resources/db/migration/V3__create_favorite_activity.sql deleted file mode 100644 index f257a1fa5..000000000 --- a/backend/src/main/resources/db/migration/V3__create_favorite_activity.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE IF NOT EXISTS spar.favorite_activity ( - id SERIAL, - user_id INT NOT NULL, - activity_title VARCHAR(50) NOT NULL, - highlighted BIT DEFAULT 0::bit, - enabled BIT DEFAULT 1::bit, - CONSTRAINT favorite_activity_pk - primary key(id), - CONSTRAINT favorite_activity_user_fk - foreign key(user_id) REFERENCES spar.user(id) -); diff --git a/backend/src/main/resources/db/migration/V3__create_favourite_activity.sql b/backend/src/main/resources/db/migration/V3__create_favourite_activity.sql new file mode 100644 index 000000000..b6290fe12 --- /dev/null +++ b/backend/src/main/resources/db/migration/V3__create_favourite_activity.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS spar.favourite_activity ( + id SERIAL, + user_id VARCHAR(70) NOT NULL, + activity VARCHAR(50) NOT NULL, + highlighted BOOLEAN DEFAULT FALSE, + enabled BOOLEAN DEFAULT TRUE, + CONSTRAINT favourite_activity_pk + primary key(id) +); diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpointTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpointTest.java deleted file mode 100644 index 293e7760c..000000000 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavoriteActivityEndpointTest.java +++ /dev/null @@ -1,277 +0,0 @@ -package ca.bc.gov.backendstartapi.endpoint; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.when; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -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.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import ca.bc.gov.backendstartapi.dto.FavoriteActivityCreateDto; -import ca.bc.gov.backendstartapi.dto.FavoriteActivityUpdateDto; -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.enums.ActivityEnum; -import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; -import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; -import ca.bc.gov.backendstartapi.exception.UserNotFoundException; -import ca.bc.gov.backendstartapi.service.FavoriteActivityService; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.databind.SerializationFeature; -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.web.servlet.MockMvc; - -@ExtendWith(SpringExtension.class) -@WebMvcTest(FavoriteActivityEndpoint.class) -class FavoriteActivityEndpointTest { - - @Autowired private MockMvc mockMvc; - - @MockBean private FavoriteActivityService favoriteActivityService; - - private String stringify(Object obj) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false); - ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter(); - return ow.writeValueAsString(obj); - } - - private FavoriteActivityEntity createEntity(ActivityEnum activityEnum) { - FavoriteActivityEntity activityEntity = new FavoriteActivityEntity(); - activityEntity.setActivityTitle(activityEnum.getTitle()); - activityEntity.setHighlighted(Boolean.FALSE); - activityEntity.setEnabled(Boolean.TRUE); - return activityEntity; - } - - @Test - @DisplayName("createFavoriteActivitySuccessTest") - @WithMockUser(roles = "user_write") - void createFavoriteActivitySuccessTest() throws Exception { - FavoriteActivityCreateDto activityDto = - new FavoriteActivityCreateDto(ActivityEnum.SEEDLING_REQUEST.getTitle()); - - FavoriteActivityEntity activityEntity = createEntity(ActivityEnum.SEEDLING_REQUEST); - when(favoriteActivityService.createUserActivity(any())).thenReturn(activityEntity); - - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(activityDto))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.activityTitle").value("Seedling request")) - .andExpect(jsonPath("$.highlighted").value("false")) - .andExpect(jsonPath("$.enabled").value("true")) - .andReturn(); - } - - @Test - @DisplayName("createFavoriteActivityUserNotFoundTest") - @WithMockUser(roles = "user_write") - void createFavoriteActivityUserNotFoundTest() throws Exception { - FavoriteActivityCreateDto activityDto = - new FavoriteActivityCreateDto(ActivityEnum.SEEDLING_REQUEST.getTitle()); - - when(favoriteActivityService.createUserActivity(any())).thenThrow(new UserNotFoundException()); - - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(activityDto))) - .andExpect(status().isNotFound()) - .andReturn(); - } - - @Test - @DisplayName("createFavoriteActivityNotFoundTest") - @WithMockUser(roles = "user_write") - void createFavoriteActivityNotFoundTest() throws Exception { - FavoriteActivityCreateDto activityDto = new FavoriteActivityCreateDto("Any Title Here"); - - when(favoriteActivityService.createUserActivity(any())) - .thenThrow(new ActivityNotFoundException()); - - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(activityDto))) - .andExpect(status().isNotFound()) - .andReturn(); - } - - @Test - @DisplayName("createFavoriteActivityDuplicatedTest") - @WithMockUser(roles = "user_write") - void createFavoriteActivityDuplicatedTest() throws Exception { - FavoriteActivityCreateDto activityDto = - new FavoriteActivityCreateDto(ActivityEnum.SEEDLING_REQUEST.getTitle()); - - String contentString = stringify(activityDto); - FavoriteActivityEntity activityEntity = createEntity(ActivityEnum.SEEDLING_REQUEST); - when(favoriteActivityService.createUserActivity(any())).thenReturn(activityEntity); - - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(contentString)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.activityTitle").value("Seedling request")) - .andExpect(jsonPath("$.highlighted").value("false")) - .andExpect(jsonPath("$.enabled").value("true")) - .andReturn(); - - when(favoriteActivityService.createUserActivity(any())) - .thenThrow(new FavoriteActivityExistsToUser()); - - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(contentString)) - .andExpect(status().isBadRequest()) - .andReturn(); - } - - @Test - @DisplayName("getAllUsersActivityTest") - @WithMockUser(roles = "user_write") - void getAllUsersActivityTest() throws Exception { - - FavoriteActivityEntity activityEntityOne = createEntity(ActivityEnum.SEEDLING_REQUEST); - FavoriteActivityEntity activityEntityTwo = createEntity(ActivityEnum.SEEDLOT_REGISTRATION); - activityEntityTwo.setHighlighted(Boolean.TRUE); - List favoriteActivityEntities = - List.of(activityEntityOne, activityEntityTwo); - when(favoriteActivityService.getAllUserFavoriteActivities()) - .thenReturn(favoriteActivityEntities); - mockMvc - .perform( - get("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].activityTitle").value("Seedling request")) - .andExpect(jsonPath("$[0].highlighted").value("false")) - .andExpect(jsonPath("$[0].enabled").value("true")) - .andExpect( - jsonPath("$[1].activityTitle").value(ActivityEnum.SEEDLOT_REGISTRATION.getTitle())) - .andExpect(jsonPath("$[1].highlighted").value("true")) - .andExpect(jsonPath("$[1].enabled").value("true")) - .andReturn(); - } - - @Test - @DisplayName("updateUserFavoriteActivity") - @WithMockUser(roles = "user_write") - void updateUserFavoriteActivity() throws Exception { - FavoriteActivityEntity activityEntity = createEntity(ActivityEnum.PARENT_TREE_ORCHARD); - activityEntity.setId(10000L); - - when(favoriteActivityService.createUserActivity(any())).thenReturn(activityEntity); - - String title = ActivityEnum.PARENT_TREE_ORCHARD.getTitle(); - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(activityEntity))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.activityTitle").value(title)) - .andExpect(jsonPath("$.highlighted").value("false")) - .andExpect(jsonPath("$.enabled").value("true")) - .andReturn(); - - FavoriteActivityEntity activityUpdated = activityEntity.withHighlighted(true); - - when(favoriteActivityService.updateUserActivity(any(), any())).thenReturn(activityUpdated); - - FavoriteActivityUpdateDto updateDto = new FavoriteActivityUpdateDto(true, true); - - mockMvc - .perform( - put("/api/favorite_activity/{id}", activityEntity.getId()) - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(updateDto))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.activityTitle").value(title)) - .andExpect(jsonPath("$.highlighted").value("true")) - .andExpect(jsonPath("$.enabled").value("true")) - .andReturn(); - } - - @Test - @DisplayName("deleteUserFavoriteActivity") - @WithMockUser(roles = "user_write") - void deleteUserFavoriteActivity() throws Exception { - FavoriteActivityEntity activityEntity = createEntity(ActivityEnum.PARENT_TREE_ORCHARD); - activityEntity.setId(10000L); - - when(favoriteActivityService.createUserActivity(any())).thenReturn(activityEntity); - - String title = ActivityEnum.PARENT_TREE_ORCHARD.getTitle(); - mockMvc - .perform( - post("/api/favorite_activity") - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON) - .content(stringify(activityEntity))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.activityTitle").value(title)) - .andExpect(jsonPath("$.highlighted").value("false")) - .andExpect(jsonPath("$.enabled").value("true")) - .andReturn(); - - FavoriteActivityEntity activityUpdated = activityEntity.withHighlighted(true); - - doNothing().when(favoriteActivityService).deleteUserActivity(any()); - - mockMvc - .perform( - delete("/api/favorite_activity/{id}", activityEntity.getId()) - .with(csrf().asHeader()) - .header("Content-Type", "application/json") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andReturn(); - } - - @Test - @DisplayName("createFavoriteActivityEndpointTest") - void createFavoriteActivityEndpointTest() { - FavoriteActivityEndpoint activityEndpoint = new FavoriteActivityEndpoint(); - activityEndpoint.setFavoriteActivityService(favoriteActivityService); - } -} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpointTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpointTest.java new file mode 100644 index 000000000..f6f157f3f --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/endpoint/FavouriteActivityEndpointTest.java @@ -0,0 +1,255 @@ +package ca.bc.gov.backendstartapi.endpoint; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +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.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; +import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; +import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; +import ca.bc.gov.backendstartapi.service.FavouriteActivityService; +import java.util.List; +import java.util.Objects; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; + +@ExtendWith(SpringExtension.class) +@WebMvcTest(FavouriteActivityEndpoint.class) +class FavouriteActivityEndpointTest { + + @Autowired private MockMvc mockMvc; + + @MockBean private FavouriteActivityService favouriteActivityService; + + private static final String API_PATH = "/api/favourite-activities"; + + private static final String CONTENT_HEADER = "Content-Type"; + + private static final String JSON = "application/json"; + + private String stringifyCreate(ActivityEnum activityEnum) { + StringBuilder json = new StringBuilder("{"); + if (!Objects.isNull(activityEnum)) { + json.append("\"activity\":\"").append(activityEnum).append("\""); + } + json.append("}"); + return json.toString(); + } + + private String stringifyUpdate(Boolean highlighted, Boolean enabled) { + StringBuilder json = new StringBuilder("{"); + if (!Objects.isNull(highlighted)) { + json.append("\"highlighted\":\"").append(highlighted).append("\""); + } + if (!Objects.isNull(enabled)) { + if (!json.toString().equals("{")) { + json.append(","); + } + json.append("\"enabled\":\"").append(enabled).append("\""); + } + json.append("}"); + return json.toString(); + } + + private FavouriteActivityEntity createEntity(ActivityEnum activityEnum) { + FavouriteActivityEntity activityEntity = new FavouriteActivityEntity(); + activityEntity.setActivity(activityEnum); + activityEntity.setHighlighted(Boolean.FALSE); + activityEntity.setEnabled(Boolean.TRUE); + return activityEntity; + } + + @Test + @DisplayName("createFavoriteActivitySuccessTest") + @WithMockUser(roles = "user_write") + void createFavoriteActivitySuccessTest() throws Exception { + FavouriteActivityEntity activityEntity = createEntity(ActivityEnum.SEEDLING_REQUEST); + when(favouriteActivityService.createUserActivity(any())).thenReturn(activityEntity); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stringifyCreate(ActivityEnum.SEEDLING_REQUEST))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.activity").value(ActivityEnum.SEEDLING_REQUEST.toString())) + .andExpect(jsonPath("$.highlighted").value("false")) + .andExpect(jsonPath("$.enabled").value("true")) + .andReturn(); + } + + @Test + @DisplayName("createFavoriteActivityNotFoundTest") + @WithMockUser(roles = "user_write") + void createFavoriteActivityNotFoundTest() throws Exception { + when(favouriteActivityService.createUserActivity(any())) + .thenThrow(new ActivityNotFoundException()); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stringifyCreate(null))) + .andExpect(status().isBadRequest()) + .andReturn(); + } + + @Test + @DisplayName("createFavoriteActivityDuplicatedTest") + @WithMockUser(roles = "user_write") + void createFavoriteActivityDuplicatedTest() throws Exception { + String contentString = stringifyCreate(ActivityEnum.SEEDLING_REQUEST); + FavouriteActivityEntity activityEntity = createEntity(ActivityEnum.SEEDLING_REQUEST); + when(favouriteActivityService.createUserActivity(any())).thenReturn(activityEntity); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(contentString)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.activity").value(ActivityEnum.SEEDLING_REQUEST.toString())) + .andExpect(jsonPath("$.highlighted").value("false")) + .andExpect(jsonPath("$.enabled").value("true")) + .andReturn(); + + when(favouriteActivityService.createUserActivity(any())) + .thenThrow(new FavoriteActivityExistsToUser()); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(contentString)) + .andExpect(status().isBadRequest()) + .andReturn(); + } + + @Test + @DisplayName("getAllUsersActivityTest") + @WithMockUser(roles = "user_write") + void getAllUsersActivityTest() throws Exception { + + FavouriteActivityEntity activityEntityOne = createEntity(ActivityEnum.SEEDLING_REQUEST); + FavouriteActivityEntity activityEntityTwo = createEntity(ActivityEnum.SEEDLOT_REGISTRATION); + activityEntityTwo.setHighlighted(Boolean.TRUE); + List favoriteActivityEntities = + List.of(activityEntityOne, activityEntityTwo); + when(favouriteActivityService.getAllUserFavoriteActivities()) + .thenReturn(favoriteActivityEntities); + mockMvc + .perform( + get(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].activity").value(ActivityEnum.SEEDLING_REQUEST.toString())) + .andExpect(jsonPath("$[0].highlighted").value("false")) + .andExpect(jsonPath("$[0].enabled").value("true")) + .andExpect(jsonPath("$[1].activity").value(ActivityEnum.SEEDLOT_REGISTRATION.toString())) + .andExpect(jsonPath("$[1].highlighted").value("true")) + .andExpect(jsonPath("$[1].enabled").value("true")) + .andReturn(); + } + + @Test + @DisplayName("updateUserFavoriteActivity") + @WithMockUser(roles = "user_write") + void updateUserFavoriteActivity() throws Exception { + FavouriteActivityEntity activityEntity = createEntity(ActivityEnum.PARENT_TREE_ORCHARD); + activityEntity.setId(10000L); + when(favouriteActivityService.createUserActivity(any())).thenReturn(activityEntity); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stringifyCreate(ActivityEnum.PARENT_TREE_ORCHARD))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.activity").value(ActivityEnum.PARENT_TREE_ORCHARD.toString())) + .andExpect(jsonPath("$.highlighted").value("false")) + .andExpect(jsonPath("$.enabled").value("true")) + .andReturn(); + + FavouriteActivityEntity activityUpdated = activityEntity.withHighlighted(true); + + when(favouriteActivityService.updateUserActivity(any(), any())).thenReturn(activityUpdated); + + mockMvc + .perform( + put(API_PATH + "/{id}", activityEntity.getId()) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stringifyUpdate(true, true))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.activity").value(ActivityEnum.PARENT_TREE_ORCHARD.toString())) + .andExpect(jsonPath("$.highlighted").value("true")) + .andExpect(jsonPath("$.enabled").value("true")) + .andReturn(); + } + + @Test + @DisplayName("deleteUserFavoriteActivity") + @WithMockUser(roles = "user_write") + void deleteUserFavoriteActivity() throws Exception { + FavouriteActivityEntity activityEntity = createEntity(ActivityEnum.PARENT_TREE_ORCHARD); + activityEntity.setId(10000L); + + when(favouriteActivityService.createUserActivity(any())).thenReturn(activityEntity); + + mockMvc + .perform( + post(API_PATH) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON) + .content(stringifyCreate(ActivityEnum.PARENT_TREE_ORCHARD))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.activity").value(ActivityEnum.PARENT_TREE_ORCHARD.toString())) + .andExpect(jsonPath("$.highlighted").value("false")) + .andExpect(jsonPath("$.enabled").value("true")) + .andReturn(); + + FavouriteActivityEntity activityUpdated = activityEntity.withHighlighted(true); + + doNothing().when(favouriteActivityService).deleteUserActivity(any()); + + mockMvc + .perform( + delete(API_PATH + "/{id}", activityUpdated.getId()) + .with(csrf().asHeader()) + .header(CONTENT_HEADER, JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + } + +} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/enums/ActivityEnumTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/enums/ActivityEnumTest.java index 959f10ca7..269b16799 100644 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/enums/ActivityEnumTest.java +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/enums/ActivityEnumTest.java @@ -1,49 +1,24 @@ package ca.bc.gov.backendstartapi.enums; -import java.util.Optional; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class ActivityEnumTest { - private static final String DESCRIPTION = - "Start a new registration or check on existing seedlots registrations"; - - @Test - @DisplayName("getPropsTest") - void getPropsTest() { - ActivityEnum seedlotRegistration = ActivityEnum.SEEDLOT_REGISTRATION; - - Assertions.assertEquals("SoilMoistureField", seedlotRegistration.getIconName()); - Assertions.assertEquals("Seedlot registration", seedlotRegistration.getTitle()); - Assertions.assertEquals(DESCRIPTION, seedlotRegistration.getDescription()); - Assertions.assertEquals("/seedlot-registration", seedlotRegistration.getPage()); - } - @Test - @DisplayName("getByTitleTest") - void getByTitleTest() { - String title = "Seedlot registration"; - Optional seedlotRegistration = ActivityEnum.getByTitle(title); - Assertions.assertTrue(seedlotRegistration.isPresent()); - - ActivityEnum activityEnum = seedlotRegistration.get(); - Assertions.assertEquals("SoilMoistureField", activityEnum.getIconName()); - Assertions.assertEquals("Seedlot registration", activityEnum.getTitle()); - Assertions.assertEquals(DESCRIPTION, activityEnum.getDescription()); - Assertions.assertEquals("/seedlot-registration", activityEnum.getPage()); - - Optional notExisting = ActivityEnum.getByTitle("Nothing"); - Assertions.assertFalse(notExisting.isPresent()); - - ActivityEnum myEnum = ActivityEnum.valueOf("SEEDLOT_REGISTRATION"); - - String enumToString = "ActivityEnum.SEEDLOT_REGISTRATION(" - + "iconName=SoilMoistureField, " - + "title=Seedlot registration, " - + "description=Start a new registration or check on existing seedlots registrations, " - + "page=/seedlot-registration)"; - Assertions.assertEquals(enumToString, myEnum.toString()); + @DisplayName("valueOfTest") + void fromStringTest() { + ActivityEnum seedlotRegistration = ActivityEnum.valueOf("SEEDLOT_REGISTRATION"); + Assertions.assertNotNull(seedlotRegistration); + Assertions.assertEquals(ActivityEnum.SEEDLOT_REGISTRATION, seedlotRegistration); + + ActivityEnum parentTreeOrchard = ActivityEnum.valueOf("PARENT_TREE_ORCHARD"); + Assertions.assertNotNull(parentTreeOrchard); + Assertions.assertEquals(ActivityEnum.PARENT_TREE_ORCHARD, parentTreeOrchard); + + ActivityEnum seedlingRequest = ActivityEnum.valueOf("SEEDLING_REQUEST"); + Assertions.assertNotNull(seedlingRequest); + Assertions.assertEquals(ActivityEnum.SEEDLING_REQUEST, seedlingRequest); } } diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepositoryTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepositoryTest.java deleted file mode 100644 index 89a75ff08..000000000 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavoriteActivityRepositoryTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package ca.bc.gov.backendstartapi.repository; - -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.entity.UserEntity; -import ca.bc.gov.backendstartapi.enums.ActivityEnum; -import ca.bc.gov.backendstartapi.exception.NotRemovableEntityException; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.jdbc.Sql; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@DataJpaTest -@AutoConfigureTestDatabase(replace = Replace.NONE) -@TestMethodOrder(OrderAnnotation.class) -class FavoriteActivityRepositoryTest { - - private static final String USER_TEST_EMAIL = "test.user@gov.bc.ca"; - - @Autowired private FavoriteActivityRepository favoriteActivityRepository; - - @Autowired private UserRepository userRepository; - - @Test - @DisplayName("createWithDefaultValuesTest") - @Order(1) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_user.sql"}) - void createWithDefaultValuesTest() { - List users = userRepository.findAllByEmail(USER_TEST_EMAIL); - Assertions.assertFalse(users.isEmpty()); - - FavoriteActivityEntity activity = new FavoriteActivityEntity(); - activity.setUser(users.get(0)); - activity.setActivityTitle(ActivityEnum.SEEDLOT_REGISTRATION.getTitle()); - FavoriteActivityEntity created = favoriteActivityRepository.save(activity); - - Assertions.assertEquals(1L, created.getId()); - Assertions.assertEquals( - ActivityEnum.SEEDLOT_REGISTRATION.getTitle(), created.getActivityTitle()); - Assertions.assertFalse(created.getHighlighted()); - Assertions.assertTrue(created.getEnabled()); - } - - @Test - @DisplayName("createWithAllValuesTest") - @Order(2) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_user.sql"}) - void createWithAllValuesTest() { - List users = userRepository.findAllByEmail(USER_TEST_EMAIL); - Assertions.assertFalse(users.isEmpty()); - - FavoriteActivityEntity activity = new FavoriteActivityEntity(); - activity.setUser(users.get(0)); - activity.setActivityTitle(ActivityEnum.SEEDLING_REQUEST.getTitle()); - activity.setHighlighted(true); - activity.setEnabled(false); - FavoriteActivityEntity created = favoriteActivityRepository.save(activity); - - Assertions.assertEquals(ActivityEnum.SEEDLING_REQUEST.getTitle(), created.getActivityTitle()); - Assertions.assertTrue(created.getHighlighted()); - Assertions.assertFalse(created.getEnabled()); - } - - @Test - @DisplayName("preventFromDuplicateUserTest") - @Order(3) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) - void preventFromDuplicateUserTest() { - List userList = userRepository.findAllByEmail(USER_TEST_EMAIL); - Assertions.assertFalse(userList.isEmpty()); - UserEntity user = userList.get(0); - - FavoriteActivityEntity activity = new FavoriteActivityEntity(); - activity.setUser(user); - activity.setActivityTitle(ActivityEnum.SEEDLOT_REGISTRATION.getTitle()); - favoriteActivityRepository.save(activity); - } - - @Test - @DisplayName("findAllByUserTest") - @Order(4) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) - void findAllByUserTest() { - List userList = userRepository.findAllByEmail(USER_TEST_EMAIL); - Assertions.assertFalse(userList.isEmpty()); - UserEntity user = userList.get(0); - List allByUser = favoriteActivityRepository.findAllByUser(user); - Assertions.assertFalse(allByUser.isEmpty()); - Assertions.assertEquals(2, allByUser.size()); - } - - @Test - @DisplayName("updateActivityTest") - @Order(5) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) - void updateActivityTest() { - String title = "Activity one"; - Optional getOne = favoriteActivityRepository.findByActivityTitle(title); - Assertions.assertTrue(getOne.isPresent()); - - FavoriteActivityEntity activity = getOne.get(); - Assertions.assertEquals("Activity one", activity.getActivityTitle()); - Assertions.assertFalse(activity.getHighlighted()); - Assertions.assertTrue(activity.getEnabled()); - - activity.setEnabled(Boolean.FALSE); - activity.setHighlighted(Boolean.TRUE); - FavoriteActivityEntity saved = favoriteActivityRepository.save(activity); - - Long activityId = activity.getId(); - Assertions.assertEquals(activityId, saved.getId()); - Assertions.assertEquals("Activity one", saved.getActivityTitle()); - Assertions.assertTrue(saved.getHighlighted()); - Assertions.assertFalse(saved.getEnabled()); - } - - @Test - @DisplayName("deleteActivityTest") - @Order(6) - @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) - void deleteActivityTest() { - String title = "Activity one"; - Optional getOne = favoriteActivityRepository.findByActivityTitle(title); - Assertions.assertTrue(getOne.isPresent()); - - Exception e = - Assertions.assertThrows( - NotRemovableEntityException.class, - () -> favoriteActivityRepository.delete(getOne.get())); - - String message = e.getMessage(); - Assertions.assertEquals("400 BAD_REQUEST \"Entity not removable!\"", message); - } -} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepositoryTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepositoryTest.java new file mode 100644 index 000000000..53dcb2936 --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/repository/FavouriteActivityRepositoryTest.java @@ -0,0 +1,116 @@ +package ca.bc.gov.backendstartapi.repository; + +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@DataJpaTest +@AutoConfigureTestDatabase(replace = Replace.NONE) +@TestMethodOrder(OrderAnnotation.class) +class FavouriteActivityRepositoryTest { + + @Autowired private FavouriteActivityRepository favouriteActivityRepository; + + private static final String USER_ID = "123456789123456789@idir"; + + @Test + @DisplayName("createWithDefaultValuesTest") + @Order(1) + void createWithDefaultValuesTest() { + FavouriteActivityEntity activity = new FavouriteActivityEntity(); + activity.setUserId(USER_ID); + activity.setActivity(ActivityEnum.SEEDLOT_REGISTRATION); + FavouriteActivityEntity created = favouriteActivityRepository.save(activity); + + Assertions.assertEquals(1L, created.getId()); + Assertions.assertEquals(USER_ID, created.getUserId()); + Assertions.assertEquals(ActivityEnum.SEEDLOT_REGISTRATION, created.getActivity()); + Assertions.assertFalse(created.getHighlighted()); + Assertions.assertTrue(created.getEnabled()); + } + + @Test + @DisplayName("createWithAllValuesTest") + @Order(2) + void createWithAllValuesTest() { + FavouriteActivityEntity activity = new FavouriteActivityEntity(); + activity.setUserId(USER_ID); + activity.setActivity(ActivityEnum.SEEDLING_REQUEST); + activity.setHighlighted(true); + activity.setEnabled(false); + FavouriteActivityEntity created = favouriteActivityRepository.save(activity); + + Assertions.assertEquals(ActivityEnum.SEEDLING_REQUEST, created.getActivity()); + Assertions.assertEquals(USER_ID, created.getUserId()); + Assertions.assertTrue(created.getHighlighted()); + Assertions.assertFalse(created.getEnabled()); + } + + @Test + @DisplayName("findAllByUserTest") + @Order(3) + @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) + void findAllByUserIdTest() { + List allByUser = favouriteActivityRepository.findAllByUserId(USER_ID); + Assertions.assertFalse(allByUser.isEmpty()); + Assertions.assertEquals(2, allByUser.size()); + } + + @Test + @DisplayName("updateActivityTest") + @Order(4) + @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) + void updateActivityTest() { + Optional getOne = + favouriteActivityRepository.findByActivity(ActivityEnum.SEEDLOT_REGISTRATION); + Assertions.assertTrue(getOne.isPresent()); + + FavouriteActivityEntity activity = getOne.get(); + Assertions.assertEquals(USER_ID, activity.getUserId()); + Assertions.assertEquals(ActivityEnum.SEEDLOT_REGISTRATION, activity.getActivity()); + Assertions.assertFalse(activity.getHighlighted()); + Assertions.assertTrue(activity.getEnabled()); + + activity.setEnabled(Boolean.FALSE); + activity.setHighlighted(Boolean.TRUE); + FavouriteActivityEntity saved = favouriteActivityRepository.save(activity); + + Long activityId = activity.getId(); + Assertions.assertEquals(activityId, saved.getId()); + Assertions.assertEquals(USER_ID, saved.getUserId()); + Assertions.assertEquals(ActivityEnum.SEEDLOT_REGISTRATION, saved.getActivity()); + Assertions.assertTrue(saved.getHighlighted()); + Assertions.assertFalse(saved.getEnabled()); + } + + @Test + @DisplayName("deleteActivityTest") + @Order(5) + @Sql(scripts = {"classpath:sql_scripts/FavoriteActivityRepositoryTest_favorite.sql"}) + void deleteActivityTest() { + Optional getOne = + favouriteActivityRepository.findByActivity(ActivityEnum.SEEDLOT_REGISTRATION); + Assertions.assertTrue(getOne.isPresent()); + + favouriteActivityRepository.delete(getOne.get()); + + Optional removed = + favouriteActivityRepository.findByActivity(ActivityEnum.SEEDLOT_REGISTRATION); + Assertions.assertTrue(removed.isEmpty()); + } +} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelperTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelperTest.java index e2ef94b56..8b60d924e 100644 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelperTest.java +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserAuthenticationHelperTest.java @@ -29,8 +29,8 @@ void setup() { } @Test - @DisplayName("getUserInfoTestSuccess") - void getUserInfoTestSuccess() { + @DisplayName("getUserInfoIdirTest") + void getUserInfoIdirTest() { Authentication authentication = mock(Authentication.class); SecurityContext securityContext = mock(SecurityContext.class); SecurityContextHolder.setContext(securityContext); @@ -41,15 +41,12 @@ void getUserInfoTestSuccess() { Jwt.Builder builder = Jwt.withTokenValue("myTokenValue"); builder.header("alg", "HS256"); builder.header("typ", "JWT"); - builder.claim("name", "Bilbo"); - builder.claim("email", "bilbo.baggings@gov.bc.ca"); - builder.claim("identity_provider", "idir"); - builder.claim("idir_username", "BAGGINGS"); - builder.claim("businessbceid_username", null); - builder.claim("email_verified", "false"); builder.claim("given_name", "Bilbo"); - builder.claim("display_name", "Baggings, Bilbo LWRS:EX"); builder.claim("family_name", "Baggings"); + builder.claim("email", "bilbo.baggings@gov.bc.ca"); + builder.claim("display_name", "Baggings, Bilbo LWRS:EX"); + builder.claim("idir_username", "BAGGINGS"); + builder.claim("identity_provider", "idir"); when(authentication.getPrincipal()).thenReturn(builder.build()); @@ -57,20 +54,17 @@ void getUserInfoTestSuccess() { Assertions.assertTrue(userInfoOptional.isPresent()); UserInfo userInfo = userInfoOptional.get(); - Assertions.assertEquals("Bilbo", userInfo.name()); + Assertions.assertEquals("Bilbo", userInfo.firstName()); + Assertions.assertEquals("Baggings", userInfo.lastName()); Assertions.assertEquals("bilbo.baggings@gov.bc.ca", userInfo.email()); - Assertions.assertEquals("idir", userInfo.identityProvider()); - Assertions.assertEquals("BAGGINGS", userInfo.idirUsername()); - Assertions.assertNull(userInfo.businessbceidUsername()); - Assertions.assertFalse(userInfo.emailVerified()); - Assertions.assertEquals("Bilbo", userInfo.givenName()); Assertions.assertEquals("Baggings, Bilbo LWRS:EX", userInfo.displayName()); - Assertions.assertEquals("Baggings", userInfo.familyName()); + Assertions.assertEquals("BAGGINGS", userInfo.idirUsername()); + Assertions.assertEquals("idir", userInfo.identityProvider()); } @Test - @DisplayName("getUserInfoTestUserInstance") - void getUserInfoTestUserInstance() { + @DisplayName("getUserInfoBusinessBceidTest") + void getUserInfoBusinessBceidTest() { Authentication authentication = mock(Authentication.class); SecurityContext securityContext = mock(SecurityContext.class); SecurityContextHolder.setContext(securityContext); @@ -78,31 +72,26 @@ void getUserInfoTestUserInstance() { when(securityContext.getAuthentication()).thenReturn(authentication); when(authentication.isAuthenticated()).thenReturn(true); - User user = new User( - "Gimli", - "myAxe", - true, - false, - false, - true, - List.of(new SimpleGrantedAuthority("ROLE_user_read")) - ); + Jwt.Builder builder = Jwt.withTokenValue("myTokenValue"); + builder.header("alg", "HS256"); + builder.header("typ", "JWT"); + builder.claim("email", "lord.sauron@mordor.middleearth"); + builder.claim("display_name", "Sauron, Mordor LWRS:EX"); + builder.claim("bceid_business_name", "Mordor LLC"); + builder.claim("identity_provider", "businessbceid"); - when(authentication.getPrincipal()).thenReturn(user); + when(authentication.getPrincipal()).thenReturn(builder.build()); Optional userInfoOptional = userAuthenticationHelper.getUserInfo(); Assertions.assertTrue(userInfoOptional.isPresent()); UserInfo userInfo = userInfoOptional.get(); - Assertions.assertEquals("Test User", userInfo.name()); - Assertions.assertEquals("user@test.com", userInfo.email()); - Assertions.assertEquals("idir", userInfo.identityProvider()); - Assertions.assertEquals("test", userInfo.idirUsername()); - Assertions.assertEquals("test", userInfo.businessbceidUsername()); - Assertions.assertFalse(userInfo.emailVerified()); - Assertions.assertEquals("User", userInfo.givenName()); - Assertions.assertEquals("Test User", userInfo.displayName()); - Assertions.assertEquals("Test", userInfo.familyName()); + Assertions.assertNull(userInfo.firstName()); + Assertions.assertNull(userInfo.lastName()); + Assertions.assertEquals("lord.sauron@mordor.middleearth", userInfo.email()); + Assertions.assertEquals("Sauron, Mordor LWRS:EX", userInfo.displayName()); + Assertions.assertEquals("Mordor LLC", userInfo.businessName()); + Assertions.assertEquals("businessbceid", userInfo.identityProvider()); } @Test diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserInfoTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserInfoTest.java index c7dfffc80..0e1f141ef 100644 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserInfoTest.java +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserInfoTest.java @@ -12,26 +12,24 @@ class UserInfoTest { void createUserInfo() { UserInfo userInfo = new UserInfo( + "123456789@idir", "Bilbo", + "Baggings", "bilbo.baggings@gov.bc.ca", - new HashSet<>(), - "idir", + "Baggings, Bilbo LWRS:EX", "BAGGINGS", null, - false, - "Bilbo", - "Baggings, Bilbo LWRS:EX", - "Baggings"); + "idir", + new HashSet<>()); Assertions.assertNotNull(userInfo); - Assertions.assertEquals("Bilbo", userInfo.name()); + Assertions.assertEquals("Bilbo", userInfo.firstName()); + Assertions.assertEquals("Baggings", userInfo.lastName()); Assertions.assertEquals("bilbo.baggings@gov.bc.ca", userInfo.email()); - Assertions.assertEquals("idir", userInfo.identityProvider()); - Assertions.assertEquals("BAGGINGS", userInfo.idirUsername()); - Assertions.assertNull(userInfo.businessbceidUsername()); - Assertions.assertFalse(userInfo.emailVerified()); - Assertions.assertEquals("Bilbo", userInfo.givenName()); Assertions.assertEquals("Baggings, Bilbo LWRS:EX", userInfo.displayName()); - Assertions.assertEquals("Baggings", userInfo.familyName()); + Assertions.assertEquals("BAGGINGS", userInfo.idirUsername()); + Assertions.assertNull(userInfo.businessName()); + Assertions.assertEquals("idir", userInfo.identityProvider()); + Assertions.assertTrue(userInfo.roles().isEmpty()); } } diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserServiceTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserServiceTest.java new file mode 100644 index 000000000..5b0b64d4e --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/security/UserServiceTest.java @@ -0,0 +1,85 @@ +package ca.bc.gov.backendstartapi.security; + +import static org.mockito.Mockito.when; + +import ca.bc.gov.backendstartapi.exception.UserNotFoundException; +import ca.bc.gov.backendstartapi.repository.UserProfileRepository; +import ca.bc.gov.backendstartapi.security.LoggedUserService; +import ca.bc.gov.backendstartapi.security.UserAuthenticationHelper; +import ca.bc.gov.backendstartapi.security.UserInfo; +import java.util.HashSet; +import java.util.Optional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class UserServiceTest { + + @Mock UserProfileRepository userProfileRepository; + + @Mock UserAuthenticationHelper userAuthenticationHelper; + + private LoggedUserService loggedUserService; + + private UserInfo userInfo; + + @BeforeEach + void setup() { + loggedUserService = new LoggedUserService(userAuthenticationHelper); + userInfo = + new UserInfo( + "123456789@idir", + "User", + "Test", + "user@test.com", + "Test, User: LWRS:EX", + "USERT", + null, + "idir", + new HashSet<>()); + } + + @Test + @DisplayName("getLoggedUserEmailTest") + void getLoggedUserEmailTest() { + when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); + + String userEmail = loggedUserService.getLoggedUserEmail(); + + Assertions.assertEquals("user@test.com", userEmail); + } + + @Test + @DisplayName("getLoggedUserEmailExceptionTest") + void getLoggedUserEmailExceptionTest() { + Exception e = + Assertions.assertThrows( + UserNotFoundException.class, + () -> { + loggedUserService.getLoggedUserEmail(); + }); + + Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage()); + } + + @Test + @DisplayName("getLoggerUserInfoTest") + void getLoggerUserInfoTest() { + when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); + + Optional userInfoOp = loggedUserService.getLoggedUserInfo(); + + Assertions.assertTrue(userInfoOp.isPresent()); + } + + @Test + void createUserService() { + LoggedUserService loggedUserService1 = new LoggedUserService(); + loggedUserService1.setUserAuthenticationHelper(userAuthenticationHelper); + } +} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavoriteActivityServiceTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavoriteActivityServiceTest.java deleted file mode 100644 index c57ba4995..000000000 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavoriteActivityServiceTest.java +++ /dev/null @@ -1,217 +0,0 @@ -package ca.bc.gov.backendstartapi.service; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.when; - -import ca.bc.gov.backendstartapi.dto.FavoriteActivityCreateDto; -import ca.bc.gov.backendstartapi.dto.FavoriteActivityUpdateDto; -import ca.bc.gov.backendstartapi.entity.FavoriteActivityEntity; -import ca.bc.gov.backendstartapi.entity.UserEntity; -import ca.bc.gov.backendstartapi.enums.ActivityEnum; -import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; -import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; -import ca.bc.gov.backendstartapi.repository.FavoriteActivityRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class FavoriteActivityServiceTest { - - @Mock FavoriteActivityRepository favoriteActivityRepository; - - @Mock UserService userService; - - private FavoriteActivityService favoriteActivityService; - - @BeforeEach - void setup() { - favoriteActivityService = new FavoriteActivityService(userService, favoriteActivityRepository); - } - - private UserEntity createUserEntity() { - UserEntity user = new UserEntity(); - user.setId(1L); - user.setEmail("user@test.com"); - return user; - } - - @Test - @DisplayName("createUserActivityTest") - void createUserActivityTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - String title = ActivityEnum.SEEDLING_REQUEST.getTitle(); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(title); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.save(any())).thenReturn(entity); - - FavoriteActivityCreateDto createDto = new FavoriteActivityCreateDto(title); - FavoriteActivityEntity entitySaved = favoriteActivityService.createUserActivity(createDto); - - Assertions.assertNotNull(entitySaved); - Assertions.assertEquals(title, entitySaved.getActivityTitle()); - Assertions.assertFalse(entitySaved.getHighlighted()); - Assertions.assertTrue(entitySaved.getEnabled()); - } - - @Test - @DisplayName("createUserActivityExceptionTest") - void createUserActivityExceptionTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - String title = ActivityEnum.SEEDLING_REQUEST.getTitle(); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(title); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.save(any())).thenReturn(entity); - - FavoriteActivityCreateDto createDto = new FavoriteActivityCreateDto("NotExists"); - - Exception notFoundExc = - Assertions.assertThrows( - ActivityNotFoundException.class, - () -> { - favoriteActivityService.createUserActivity(createDto); - }); - - Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", notFoundExc.getMessage()); - - List userFavList = List.of(entity); - when(favoriteActivityRepository.findAllByUser(any())).thenReturn(userFavList); - - FavoriteActivityCreateDto createAnotherDto = new FavoriteActivityCreateDto(title); - - Exception activityExists = - Assertions.assertThrows( - FavoriteActivityExistsToUser.class, - () -> { - favoriteActivityService.createUserActivity(createAnotherDto); - }); - - Assertions.assertEquals( - "400 BAD_REQUEST \"Activity already registered to this user!\"", - activityExists.getMessage()); - } - - @Test - @DisplayName("getAllUserFavoriteActivitiesTest") - void getAllUserFavoriteActivitiesTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - FavoriteActivityEntity activityOne = new FavoriteActivityEntity(); - FavoriteActivityEntity activityTwo = new FavoriteActivityEntity(); - List activityEntities = - new ArrayList<>(List.of(activityOne, activityTwo)); - when(favoriteActivityRepository.findAllByEnabledAndUser(true, 1L)).thenReturn(activityEntities); - - List entityList = - favoriteActivityService.getAllUserFavoriteActivities(); - - Assertions.assertFalse(entityList.isEmpty()); - } - - @Test - @DisplayName("updateUserActivityTest") - void updateUserActivityTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(ActivityEnum.SEEDLING_REQUEST.getTitle()); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.findById(any())).thenReturn(Optional.of(entity)); - - when(favoriteActivityRepository.save(any())).thenReturn(entity); - - FavoriteActivityUpdateDto updateDto = new FavoriteActivityUpdateDto(true, true); - FavoriteActivityEntity saved = favoriteActivityService.updateUserActivity(1L, updateDto); - - Assertions.assertNotNull(saved); - } - - @Test - @DisplayName("updateUserActivityExceptionTest") - void updateUserActivityExceptionTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(ActivityEnum.SEEDLING_REQUEST.getTitle()); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.findById(any())).thenReturn(Optional.empty()); - - when(favoriteActivityRepository.save(any())).thenReturn(entity); - - FavoriteActivityUpdateDto updateDto = new FavoriteActivityUpdateDto(true, true); - - Exception e = - Assertions.assertThrows( - ActivityNotFoundException.class, - () -> { - favoriteActivityService.updateUserActivity(1L, updateDto); - }); - - Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", e.getMessage()); - } - - @Test - @DisplayName("deleteUserActivityTest") - void deleteUserActivityTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(ActivityEnum.SEEDLING_REQUEST.getTitle()); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.findById(any())).thenReturn(Optional.of(entity)); - - doNothing().when(favoriteActivityRepository).deleteById(any()); - - favoriteActivityService.deleteUserActivity(1L); - } - - @Test - @DisplayName("deleteUserActivityExceptionTest") - void deleteUserActivityExceptionTest() { - when(userService.getLoggerUserEntity()).thenReturn(createUserEntity()); - - FavoriteActivityEntity entity = new FavoriteActivityEntity(); - entity.setActivityTitle(ActivityEnum.SEEDLING_REQUEST.getTitle()); - entity.setHighlighted(false); - entity.setEnabled(true); - when(favoriteActivityRepository.findById(any())).thenReturn(Optional.empty()); - - doNothing().when(favoriteActivityRepository).deleteById(any()); - - Exception e = - Assertions.assertThrows( - ActivityNotFoundException.class, - () -> { - favoriteActivityService.deleteUserActivity(1L); - }); - - Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", e.getMessage()); - } - - @Test - @DisplayName("createFavoriteActivityService") - void createFavoriteActivityService() { - FavoriteActivityService activityService = new FavoriteActivityService(); - activityService.setUserService(userService); - activityService.setFavoriteActivityRepository(favoriteActivityRepository); - } -} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavouriteActivityServiceTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavouriteActivityServiceTest.java new file mode 100644 index 000000000..f149a26e9 --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/backendstartapi/service/FavouriteActivityServiceTest.java @@ -0,0 +1,207 @@ +package ca.bc.gov.backendstartapi.service; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import ca.bc.gov.backendstartapi.dto.FavouriteActivityCreateDto; +import ca.bc.gov.backendstartapi.dto.FavouriteActivityUpdateDto; +import ca.bc.gov.backendstartapi.entity.FavouriteActivityEntity; +import ca.bc.gov.backendstartapi.enums.ActivityEnum; +import ca.bc.gov.backendstartapi.exception.ActivityNotFoundException; +import ca.bc.gov.backendstartapi.exception.FavoriteActivityExistsToUser; +import ca.bc.gov.backendstartapi.repository.FavouriteActivityRepository; +import ca.bc.gov.backendstartapi.security.LoggedUserService; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.util.Assert; + +@ExtendWith(SpringExtension.class) +class FavouriteActivityServiceTest { + + @Mock FavouriteActivityRepository favouriteActivityRepository; + + @Mock LoggedUserService loggedUserService; + + private FavouriteActivityService favouriteActivityService; + + private static final String USER_ID = "123456789123456789@idir"; + + @BeforeEach + void setup() { + favouriteActivityService = + new FavouriteActivityService(loggedUserService, favouriteActivityRepository); + } + + @Test + @DisplayName("createUserActivityTest") + void createUserActivityTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity entity = new FavouriteActivityEntity(); + entity.setActivity(ActivityEnum.SEEDLING_REQUEST); + entity.setHighlighted(false); + entity.setEnabled(true); + when(favouriteActivityRepository.save(any())).thenReturn(entity); + + FavouriteActivityCreateDto createDto = + new FavouriteActivityCreateDto(ActivityEnum.SEEDLING_REQUEST); + FavouriteActivityEntity entitySaved = favouriteActivityService.createUserActivity(createDto); + + Assertions.assertNotNull(entitySaved); + Assertions.assertEquals(ActivityEnum.SEEDLING_REQUEST, entitySaved.getActivity()); + Assertions.assertFalse(entitySaved.getHighlighted()); + Assertions.assertTrue(entitySaved.getEnabled()); + } + + @Test + @DisplayName("createUserActivityExceptionTest") + void createUserActivityExceptionTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity entity = new FavouriteActivityEntity(); + entity.setActivity(ActivityEnum.SEEDLING_REQUEST); + entity.setHighlighted(false); + entity.setEnabled(true); + when(favouriteActivityRepository.save(any())).thenReturn(entity); + + FavouriteActivityCreateDto createDto = new FavouriteActivityCreateDto(null); + + Exception notFoundExc = + Assertions.assertThrows( + ActivityNotFoundException.class, + () -> favouriteActivityService.createUserActivity(createDto)); + + Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", notFoundExc.getMessage()); + + List userFavList = List.of(entity); + when(favouriteActivityRepository.findAllByUserId(any())).thenReturn(userFavList); + + FavouriteActivityCreateDto createAnotherDto = + new FavouriteActivityCreateDto(ActivityEnum.SEEDLING_REQUEST); + + Exception activityExists = + Assertions.assertThrows( + FavoriteActivityExistsToUser.class, + () -> favouriteActivityService.createUserActivity(createAnotherDto)); + + Assertions.assertEquals( + "400 BAD_REQUEST \"Activity already registered to this user!\"", + activityExists.getMessage()); + } + + @Test + @DisplayName("getAllUserFavoriteActivitiesTest") + void getAllUserFavoriteActivitiesTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity activityOne = new FavouriteActivityEntity(); + FavouriteActivityEntity activityTwo = new FavouriteActivityEntity(); + List activityEntities = + new ArrayList<>(List.of(activityOne, activityTwo)); + when(favouriteActivityRepository.findAllByEnabledAndUserId(true, USER_ID)) + .thenReturn(activityEntities); + + List entityList = + favouriteActivityService.getAllUserFavoriteActivities(); + + Assertions.assertFalse(entityList.isEmpty()); + } + + @Test + @DisplayName("updateUserActivityTest") + void updateUserActivityTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity entity = new FavouriteActivityEntity(); + entity.setActivity(ActivityEnum.SEEDLING_REQUEST); + entity.setHighlighted(false); + entity.setEnabled(true); + when(favouriteActivityRepository.findById(any())).thenReturn(Optional.of(entity)); + + when(favouriteActivityRepository.save(any())).thenReturn(entity); + + FavouriteActivityUpdateDto updateDto = new FavouriteActivityUpdateDto(true, true); + FavouriteActivityEntity saved = favouriteActivityService.updateUserActivity(1L, updateDto); + + Assertions.assertNotNull(saved); + } + + @Test + @DisplayName("updateUserActivityExceptionTest") + void updateUserActivityExceptionTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity entity = new FavouriteActivityEntity(); + entity.setActivity(ActivityEnum.SEEDLING_REQUEST); + entity.setHighlighted(false); + entity.setEnabled(true); + when(favouriteActivityRepository.findById(any())).thenReturn(Optional.empty()); + + when(favouriteActivityRepository.save(any())).thenReturn(entity); + + FavouriteActivityUpdateDto updateDto = new FavouriteActivityUpdateDto(true, true); + + Exception e = + Assertions.assertThrows( + ActivityNotFoundException.class, + () -> favouriteActivityService.updateUserActivity(1L, updateDto)); + + Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", e.getMessage()); + } + + @Test + @DisplayName("deleteUserActivityTest") + void deleteUserActivityTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + FavouriteActivityEntity entity = new FavouriteActivityEntity(); + entity.setActivity(ActivityEnum.SEEDLING_REQUEST); + entity.setHighlighted(false); + entity.setEnabled(true); + when(favouriteActivityRepository.findById(any())).thenReturn(Optional.of(entity)); + + doNothing().when(favouriteActivityRepository).deleteById(any()); + + favouriteActivityService.deleteUserActivity(1L); + + when(favouriteActivityRepository.findById(any())).thenReturn(Optional.empty()); + + Optional entityOp = favouriteActivityRepository.findById(1L); + + Assertions.assertTrue(entityOp.isEmpty()); + } + + @Test + @DisplayName("deleteUserActivityExceptionTest") + void deleteUserActivityExceptionTest() { + when(loggedUserService.getLoggedUserId()).thenReturn(USER_ID); + + when(favouriteActivityRepository.findById(any())).thenReturn(Optional.empty()); + + doNothing().when(favouriteActivityRepository).deleteById(any()); + + Exception e = + Assertions.assertThrows( + ActivityNotFoundException.class, + () -> favouriteActivityService.deleteUserActivity(1L)); + + Assertions.assertEquals("404 NOT_FOUND \"Activity don't exist!\"", e.getMessage()); + } + + @Test + @DisplayName("createFavoriteActivityService") + void createFavoriteActivityService() { + FavouriteActivityService activityService = new FavouriteActivityService(); + activityService.setLoggedUserService(loggedUserService); + activityService.setFavouriteActivityRepository(favouriteActivityRepository); + } +} diff --git a/backend/src/test/java/ca/bc/gov/backendstartapi/service/UserServiceTest.java b/backend/src/test/java/ca/bc/gov/backendstartapi/service/UserServiceTest.java deleted file mode 100644 index b609f3980..000000000 --- a/backend/src/test/java/ca/bc/gov/backendstartapi/service/UserServiceTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package ca.bc.gov.backendstartapi.service; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import ca.bc.gov.backendstartapi.entity.UserEntity; -import ca.bc.gov.backendstartapi.exception.UserNotFoundException; -import ca.bc.gov.backendstartapi.repository.UserRepository; -import ca.bc.gov.backendstartapi.security.UserAuthenticationHelper; -import ca.bc.gov.backendstartapi.security.UserInfo; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class UserServiceTest { - - @Mock UserRepository userRepository; - - @Mock UserAuthenticationHelper userAuthenticationHelper; - - private UserService userService; - - private UserInfo userInfo; - - @BeforeEach - void setup() { - userService = new UserService(userRepository, userAuthenticationHelper); - userInfo = - new UserInfo( - "User", - "user@test.com", - new HashSet<>(), - "idir", - "USERT", - "bceid", - false, - "User", - "User", - "Test"); - } - - @Test - @DisplayName("getLoggedUserEmailTest") - void getLoggedUserEmailTest() { - when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); - - String userEmail = userService.getLoggedUserEmail(); - - Assertions.assertEquals("user@test.com", userEmail); - } - - @Test - @DisplayName("getLoggedUserEmailExceptionTest") - void getLoggedUserEmailExceptionTest() { - Exception e = - Assertions.assertThrows( - UserNotFoundException.class, - () -> { - userService.getLoggedUserEmail(); - }); - - Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage()); - } - - @Test - @DisplayName("getLoggerUserInfoTest") - void getLoggerUserInfoTest() { - when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); - - Optional userInfoOp = userService.getLoggerUserInfo(); - - Assertions.assertTrue(userInfoOp.isPresent()); - } - - @Test - @DisplayName("getLoggerUserEntityTest") - void getLoggerUserEntityTest() { - when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); - - UserEntity userEntity = new UserEntity(); - when(userRepository.findAllByEmail(any())).thenReturn(List.of(userEntity)); - - UserEntity user = userService.getLoggerUserEntity(); - - Assertions.assertNotNull(user); - } - - @Test - @DisplayName("getLoggerUserEntityExceptionTest") - void getLoggerUserEntityExceptionTest() { - when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo)); - - when(userRepository.findAllByEmail(any())).thenReturn(List.of()); - - Exception e = - Assertions.assertThrows( - UserNotFoundException.class, - () -> { - userService.getLoggerUserEntity(); - }); - - Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage()); - } - - @Test - void createUserService() { - UserService userService1 = new UserService(); - userService1.setUserRepository(userRepository); - userService1.setUserAuthenticationHelper(userAuthenticationHelper); - } -} diff --git a/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_favorite.sql b/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_favorite.sql index ca4f92569..3cf683176 100644 --- a/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_favorite.sql +++ b/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_favorite.sql @@ -1,8 +1,5 @@ -INSERT INTO user (email) - VALUES ('test.user@gov.bc.ca'); +INSERT INTO favourite_activity (user_id, activity, highlighted, enabled) + VALUES ('123456789123456789@idir', 'SEEDLOT_REGISTRATION', 0, 1); -INSERT INTO favorite_activity (user_id, activity_title, highlighted, enabled) - VALUES ((SELECT id FROM user where email = 'test.user@gov.bc.ca'), 'Activity one', 0, 1); - -INSERT INTO favorite_activity (user_id, activity_title, highlighted, enabled) - VALUES ((SELECT id FROM user where email = 'test.user@gov.bc.ca'), 'Activity two', 0, 1); \ No newline at end of file +INSERT INTO favourite_activity (user_id, activity, highlighted, enabled) + VALUES ('123456789123456789@idir', 'PARENT_TREE_ORCHARD', 0, 1); \ No newline at end of file diff --git a/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_user.sql b/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_user.sql deleted file mode 100644 index 939ed6b2c..000000000 --- a/backend/src/test/resources/sql_scripts/FavoriteActivityRepositoryTest_user.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO user (email) - VALUES ('test.user@gov.bc.ca'); \ No newline at end of file