Skip to content

Commit

Permalink
#90 | Implementation of checking whether user has assignment for upda…
Browse files Browse the repository at this point in the history
…te user support status endpoint (#178)
  • Loading branch information
ibrahimdenizz authored Sep 19, 2023
1 parent 9e191dd commit 09328a3
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
public interface AssignmentRepository extends JpaRepository<AssignmentEntity, String>, JpaSpecificationExecutor<AssignmentEntity> {

/**
* Checks whether an assignment exists for a specific user ID.
* Checks whether an assignment exists for a specific user ID and status.
*
* @param userId The ID of the user to check the assignment for.
* @return {@code true} if an assignment exists for the specified user ID, otherwise {@code false}.
* @param status The status of the assignment to check.
* @return {@code true} if an assignment exists for the specified user ID and status, otherwise {@code false}.
*/
boolean existsByUserIdAndStatus(String userId, AssignmentStatus status);


/**
* Retrieves an optional AssignmentEntity based on the provided user ID and institution ID.
*
Expand All @@ -32,6 +32,14 @@ public interface AssignmentRepository extends JpaRepository<AssignmentEntity, St
*/
Optional<AssignmentEntity> findByIdAndInstitutionId(String id, String institutionId);

/**
* Retrieves an optional AssignmentEntity based on the provided user ID.
*
* @param userId The ID of the user to retrieve the assignment for.
* @return An optional AssignmentEntity that matches the specified user ID, or an empty optional if not found.
*/
Optional<AssignmentEntity> findByUserId(String userId);

/**
* Retrieves nearest optional AssignmentEntity based on the provided user location point and institution ID.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ays.common.util.validation.EnumValidation;
import com.ays.user.model.enums.UserSupportStatus;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
Expand All @@ -20,6 +21,7 @@ public class UserSupportStatusUpdateRequest {
@NotNull
private UserSupportStatus supportStatus;

@JsonIgnore
@AssertTrue(message = "IS NOT ACCEPTED")
@SuppressWarnings("This method is unused by the application directly but Spring is using it in the background.")
private boolean isSupportStatusAccepted() {
Expand Down
41 changes: 39 additions & 2 deletions src/main/java/com/ays/user/service/impl/UserSelfServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.ays.user.service.impl;

import com.ays.assignment.repository.AssignmentRepository;
import com.ays.auth.model.AysIdentity;
import com.ays.user.model.dto.request.UserSupportStatusUpdateRequest;
import com.ays.user.model.entity.UserEntity;
import com.ays.user.model.enums.UserSupportStatus;
import com.ays.user.repository.UserRepository;
import com.ays.user.service.UserSelfService;
import com.ays.user.util.exception.AysUserCannotUpdateSupportStatusException;
import com.ays.user.util.exception.AysUserNotExistByIdException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.EnumSet;

/**
* UserSelfServiceImpl is an implementation of the UserSelfService interface.
* It manages a user's own operations.
Expand All @@ -19,6 +24,8 @@ class UserSelfServiceImpl implements UserSelfService {

private final UserRepository userRepository;

private final AssignmentRepository assignmentRepository;

private final AysIdentity identity;

/**
Expand All @@ -29,13 +36,43 @@ class UserSelfServiceImpl implements UserSelfService {
@Override
public void updateUserSupportStatus(UserSupportStatusUpdateRequest updateRequest) {

String userId = identity.getUserId();
final String userId = identity.getUserId();
final UserSupportStatus userSupportStatus = updateRequest.getSupportStatus();

final UserEntity userEntity = userRepository.findById(userId)
.orElseThrow(() -> new AysUserNotExistByIdException(userId));

userEntity.updateSupportStatus(updateRequest.getSupportStatus());
this.checkAssignment(userId, userSupportStatus);

userEntity.updateSupportStatus(userSupportStatus);
userRepository.save(userEntity);

}

/**
* Checks if a user has an assignment when update supportStatus to specific statuses.
*
* @param userId the id of the user to check
* @param userSupportStatus the user support status of the user to check
*/
private void checkAssignment(String userId, UserSupportStatus userSupportStatus) {

final EnumSet<UserSupportStatus> supportStatusesToCheck = EnumSet.of(
UserSupportStatus.IDLE,
UserSupportStatus.READY,
UserSupportStatus.BUSY,
UserSupportStatus.OFFLINE
);

final boolean isAssignmentNeedToCheck = supportStatusesToCheck.contains(userSupportStatus);
if (isAssignmentNeedToCheck) {
assignmentRepository
.findByUserId(userId)
.ifPresent(assignmentEntity -> {
throw new AysUserCannotUpdateSupportStatusException(userId, assignmentEntity.getId());
});
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ays.user.util.exception;

import com.ays.common.util.exception.AysAlreadyException;

import java.io.Serial;

/**
* Exception thrown when a user has assignment and attempting to update user support status.
*/
public class AysUserCannotUpdateSupportStatusException extends AysAlreadyException {

/**
* Unique serial version ID.
*/
@Serial
private static final long serialVersionUID = -3686691276790127586L;

/**
* Constructs a new {@code AysUserCannotUpdateSupportStatusException} with the specified id and assignmentId.
*
* @param id the id of the user
*/
public AysUserCannotUpdateSupportStatusException(String id, String assignmentId) {
super("USER CANNOT UPDATE SUPPORT STATUS BECAUSE USER HAS ASSIGNMENT! id:" + id + " assignmentId:" + assignmentId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.ays.institution.model.entity.InstitutionEntity;
import com.ays.institution.model.entity.InstitutionEntityBuilder;
import com.ays.location.util.AysLocationUtil;
import com.ays.user.model.entity.UserEntity;
import com.ays.user.model.entity.UserEntityBuilder;
import org.locationtech.jts.geom.Point;

import java.util.ArrayList;
Expand All @@ -30,11 +32,14 @@ public static List<AssignmentEntity> generateValidAssignmentEntities(int size) {

public AssignmentEntityBuilder withValidFields() {
InstitutionEntity institutionEntity = new InstitutionEntityBuilder().withValidFields().build();
UserEntity userEntity = new UserEntityBuilder().withValidFields().build();

return this
.withId(AysRandomUtil.generateUUID())
.withInstitutionId(institutionEntity.getId())
.withInstitution(institutionEntity)
.withUserId(userEntity.getId())
.withUser(userEntity)
.withPhoneNumber(new AysPhoneNumberBuilder().withValidFields().build())
.withDescription("Description")
.withFirstName("First Name")
Expand Down Expand Up @@ -64,6 +69,16 @@ public AssignmentEntityBuilder withInstitution(InstitutionEntity institution) {
return this;
}

public AssignmentEntityBuilder withUserId(String userId) {
data.setUserId(userId);
return this;
}

public AssignmentEntityBuilder withUser(UserEntity user) {
data.setUser(user);
return this;
}

public AssignmentEntityBuilder withDescription(String description) {
data.setDescription(description);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void givenValidUserSupportStatusUpdateRequest_whenUserRole_thenReturnSuccess() t
AysResponse<Void> mockAysResponse = AysResponse.SUCCESS;

mockMvc.perform(AysMockMvcRequestBuilders
.put(BASE_PATH.concat("/status/support"), userTokenOne.getAccessToken(), mockUserSupportStatusUpdateRequest))
.put(BASE_PATH.concat("/status/support"), userTokenTwo.getAccessToken(), mockUserSupportStatusUpdateRequest))
.andDo(MockMvcResultHandlers.print())
.andExpect(AysMockResultMatchersBuilders.status().isOk())
.andExpect(AysMockResultMatchersBuilders.time()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.ays.user.service.impl;

import com.ays.AbstractUnitTest;
import com.ays.assignment.model.entity.AssignmentEntity;
import com.ays.assignment.model.entity.AssignmentEntityBuilder;
import com.ays.assignment.repository.AssignmentRepository;
import com.ays.auth.model.AysIdentity;
import com.ays.user.model.dto.request.UserSupportStatusUpdateRequest;
import com.ays.user.model.dto.request.UserSupportStatusUpdateRequestBuilder;
import com.ays.user.model.entity.UserEntity;
import com.ays.user.model.entity.UserEntityBuilder;
import com.ays.user.model.enums.UserSupportStatus;
import com.ays.user.repository.UserRepository;
import com.ays.user.util.exception.AysUserCannotUpdateSupportStatusException;
import com.ays.user.util.exception.AysUserNotExistByIdException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand All @@ -25,6 +29,9 @@ class UserSelfServiceImplTest extends AbstractUnitTest {
@Mock
private UserRepository userRepository;

@Mock
private AssignmentRepository assignmentRepository;

@Mock
private AysIdentity identity;

Expand All @@ -48,6 +55,8 @@ void givenUserSupportStatus_whenUserRole_thenReturnSuccess() {
Mockito.when(identity.getUserId()).thenReturn(mockUserEntity.getId());
Mockito.when(userRepository.findById(mockUserEntity.getId()))
.thenReturn(Optional.of(mockUserEntity));
Mockito.when(assignmentRepository.findByUserId(identity.getUserId()))
.thenReturn(Optional.empty());
Mockito.when(userRepository.save(Mockito.any(UserEntity.class)))
.thenReturn(mockUserEntity);

Expand All @@ -56,6 +65,8 @@ void givenUserSupportStatus_whenUserRole_thenReturnSuccess() {

Mockito.verify(userRepository, Mockito.times(1))
.findById(Mockito.anyString());
Mockito.verify(assignmentRepository, Mockito.times(1))
.findByUserId(Mockito.anyString());
Mockito.verify(userRepository, Mockito.times(1))
.save(Mockito.any(UserEntity.class));

Expand Down Expand Up @@ -93,4 +104,45 @@ void givenUserSupportStatus_whenUserRole_thenThrowAysUserNotExistByIdException()

}

@Test
void givenUserSupportStatus_whenUserHasAssignment_thenThrowAysUserAlreadyHasAssignmentException() {

// Given
UserEntity mockUserEntity = new UserEntityBuilder()
.withValidFields()
.build();
AssignmentEntity mockAssignmentEntity = new AssignmentEntityBuilder()
.withValidFields()
.withUserId(mockUserEntity.getId())
.withUser(mockUserEntity)
.build();

UserSupportStatus userSupportStatus = UserSupportStatus.READY;

UserSupportStatusUpdateRequest userSupportStatusUpdateRequest = new UserSupportStatusUpdateRequestBuilder()
.withSupportStatus(userSupportStatus)
.build();

mockUserEntity.updateSupportStatus(userSupportStatus);

// When
Mockito.when(identity.getUserId()).thenReturn(mockUserEntity.getId());
Mockito.when(userRepository.findById(mockUserEntity.getId()))
.thenReturn(Optional.of(mockUserEntity));
Mockito.when(assignmentRepository.findByUserId(identity.getUserId()))
.thenReturn(Optional.of(mockAssignmentEntity));

// Then
Assertions.assertThrows(
AysUserCannotUpdateSupportStatusException.class,
() -> userSupportStatusService.updateUserSupportStatus(userSupportStatusUpdateRequest)
);

Mockito.verify(userRepository, Mockito.times(1))
.findById(Mockito.anyString());
Mockito.verify(assignmentRepository, Mockito.times(1))
.findByUserId(Mockito.anyString());

}

}

0 comments on commit 09328a3

Please sign in to comment.