Skip to content

Commit 11b43f3

Browse files
authored
AYS-243 | Prevent Role Passivation if Assigned to a User (#363)
1 parent 4ea2a57 commit 11b43f3

File tree

3 files changed

+78
-3
lines changed

3 files changed

+78
-3
lines changed

src/main/java/org/ays/auth/service/impl/AysRoleUpdateServiceImpl.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,14 @@ public void activate(String id) {
103103
/**
104104
* Passivates an existing role.
105105
* <p>
106-
* This method sets the status of the role identified by its ID to passivate. If the role does not exist,
107-
* an exception is thrown. Additionally, if the role's status is not {@link AysRoleStatus#ACTIVE},
108-
* an exception is thrown.
106+
* This method sets the status of the role identified by its ID to passivate.
107+
* It also verifies that the role belongs to the same institution as the current user's institution
108+
* and no user is assigned to the role.
109109
* </p>
110110
*
111111
* @param id The ID of the role to passivate.
112112
* @throws AysRoleNotExistByIdException if a role with the given ID does not exist.
113+
* @throws AysRoleAssignedToUserException if any user is assigned to the role.
113114
* @throws AysInvalidRoleStatusException if the role's current status is not {@link AysRoleStatus#ACTIVE}.
114115
*/
115116
@Override
@@ -118,6 +119,10 @@ public void passivate(String id) {
118119
.filter(roleFromDatabase -> identity.getInstitutionId().equals(roleFromDatabase.getInstitution().getId()))
119120
.orElseThrow(() -> new AysRoleNotExistByIdException(id));
120121

122+
if (roleReadPort.isRoleUsing(id)) {
123+
throw new AysRoleAssignedToUserException(id);
124+
}
125+
121126
if (!role.isActive()) {
122127
throw new AysInvalidRoleStatusException(AysRoleStatus.ACTIVE);
123128
}

src/test/java/org/ays/auth/controller/AysRoleControllerTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,35 @@ void givenId_whenIdIsNotValidForPassivation_thenReturnValidationError(String inv
836836
.passivate(Mockito.anyString());
837837
}
838838

839+
@Test
840+
void givenValidIdForPassivation_whenRoleUsing_thenReturnConflict() throws Exception {
841+
842+
// Given
843+
String mockId = "13e8ff0e-8d85-4f4f-8e45-efb04d1d8bf8";
844+
845+
// When
846+
Mockito.doThrow(new AysRoleAssignedToUserException(mockId))
847+
.when(roleUpdateService)
848+
.passivate(mockId);
849+
850+
// Then
851+
String endpoint = BASE_PATH.concat("/role/".concat(mockId).concat("/passivate"));
852+
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = AysMockMvcRequestBuilders
853+
.patch(endpoint, mockSuperAdminToken.getAccessToken());
854+
855+
AysErrorResponse mockErrorResponse = AysErrorBuilder.ALREADY_EXIST;
856+
857+
aysMockMvc.perform(mockHttpServletRequestBuilder, mockErrorResponse)
858+
.andExpect(AysMockResultMatchersBuilders.status()
859+
.isConflict())
860+
.andExpect(AysMockResultMatchersBuilders.subErrors()
861+
.doesNotExist());
862+
863+
// Verify
864+
Mockito.verify(roleUpdateService, Mockito.times(1))
865+
.passivate(mockId);
866+
}
867+
839868

840869
@Test
841870
void givenValidId_whenRoleDeleted_thenReturnSuccess() throws Exception {

src/test/java/org/ays/auth/service/impl/AysRoleUpdateServiceImplTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,47 @@ void givenValidId_whenInstitutionIdDoesNotMatch_thenThrowAysRoleNotExistByIdExce
727727
.save(mockRole);
728728
}
729729

730+
@Test
731+
void givenValidIdForPassivation_whenRoleUsing_thenThrowRoleAssignedToUserException() {
732+
733+
// Given
734+
String mockId = "731f4ba4-c34b-41c3-b488-d9a0c69904a3";
735+
736+
// When
737+
AysRole mockRole = new AysRoleBuilder()
738+
.withValidValues()
739+
.withId(mockId)
740+
.build();
741+
742+
Mockito.when(roleReadPort.findById(Mockito.anyString()))
743+
.thenReturn(Optional.of(mockRole));
744+
745+
Mockito.when(identity.getInstitutionId())
746+
.thenReturn(mockRole.getInstitution().getId());
747+
748+
Mockito.when(roleReadPort.isRoleUsing(Mockito.anyString()))
749+
.thenReturn(true);
750+
751+
// Then
752+
Assertions.assertThrows(
753+
AysRoleAssignedToUserException.class,
754+
() -> roleUpdateService.passivate(mockId)
755+
);
756+
757+
// Verify
758+
Mockito.verify(roleReadPort, Mockito.times(1))
759+
.findById(Mockito.anyString());
760+
761+
Mockito.verify(roleReadPort, Mockito.times(1))
762+
.isRoleUsing(Mockito.anyString());
763+
764+
Mockito.verify(identity, Mockito.times(1))
765+
.getInstitutionId();
766+
767+
Mockito.verify(roleSavePort, Mockito.never())
768+
.save(Mockito.any(AysRole.class));
769+
}
770+
730771

731772
@Test
732773
void givenValidId_whenRoleFound_thenDeleteRole() {

0 commit comments

Comments
 (0)