JD-749: handle null status in InvitationService.list(), fix date conversion for Accepted and Revoked statuses. (#55)

* JD-749: handle null status in InvitationService.list(), fix date conversion for Accepted and Revoked statuses.
This commit is contained in:
mr-impossibru 2021-11-09 18:00:37 +03:00 committed by GitHub
parent 2b6e48f696
commit ee3b229a04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 11 deletions

View File

@ -63,7 +63,7 @@ public class InvitationConverter {
break; break;
case ACCEPTED: case ACCEPTED:
invitation = new InvitationAccepted() invitation = new InvitationAccepted()
.acceptedAt(OffsetDateTime.from(entity.getAcceptedAt())) .acceptedAt(entity.getAcceptedAt().atOffset(ZoneOffset.UTC))
.member(new InvitationAcceptedAllOfMember().id(entity.getAcceptedMemberId())); .member(new InvitationAcceptedAllOfMember().id(entity.getAcceptedMemberId()));
break; break;
case EXPIRED: case EXPIRED:
@ -71,7 +71,7 @@ public class InvitationConverter {
break; break;
case REVOKED: case REVOKED:
invitation = new InvitationRevoked() invitation = new InvitationRevoked()
.revokedAt(OffsetDateTime.from(entity.getRevokedAt())) .revokedAt(entity.getRevokedAt().atOffset(ZoneOffset.UTC))
.reason(entity.getRevocationReason()); .reason(entity.getRevocationReason());
break; break;
default: default:

View File

@ -19,6 +19,8 @@ public interface InvitationRepository extends JpaRepository<InvitationEntity, St
List<InvitationEntity> findByOrganizationIdAndStatus(String organizationId, String status); List<InvitationEntity> findByOrganizationIdAndStatus(String organizationId, String status);
List<InvitationEntity> findByOrganizationId(String organizationId);
Optional<InvitationEntity> findByAcceptToken(String token); Optional<InvitationEntity> findByAcceptToken(String token);
@QueryHints(value = { @QueryHints(value = {

View File

@ -72,14 +72,12 @@ public class InvitationService {
.build(); .build();
} }
List<InvitationEntity> entities = invitationRepository.findByOrganizationIdAndStatus(orgId, status.getValue()); List<InvitationEntity> entities = status != null
if (status == InvitationStatusName.PENDING) { ? invitationRepository.findByOrganizationIdAndStatus(orgId, status.getValue())
// Additional check if invitation already expired : invitationRepository.findByOrganizationId(orgId);
entities = entities.stream().filter(invitationEntity -> !invitationEntity.isExpired())
.collect(Collectors.toList());
}
List<Invitation> invitations = entities.stream() List<Invitation> invitations = entities.stream()
.filter(invite -> !isExpiredPendingInvitation(invite))
.map(invitationConverter::toDomain) .map(invitationConverter::toDomain)
.collect(toList()); .collect(toList());
@ -129,4 +127,10 @@ public class InvitationService {
} }
} }
private boolean isExpiredPendingInvitation(InvitationEntity invitationEntity) {
return invitationEntity.getStatus() != null
&& invitationEntity.getStatus().equalsIgnoreCase(InvitationStatusName.PENDING.getValue())
&& invitationEntity.isExpired();
}
} }

View File

@ -1,9 +1,11 @@
package com.rbkmoney.orgmanager.service; package com.rbkmoney.orgmanager.service;
import com.rbkmoney.orgmanager.TestObjectFactory;
import com.rbkmoney.orgmanager.entity.InvitationEntity; import com.rbkmoney.orgmanager.entity.InvitationEntity;
import com.rbkmoney.orgmanager.entity.OrganizationEntity; import com.rbkmoney.orgmanager.entity.OrganizationEntity;
import com.rbkmoney.orgmanager.repository.AbstractRepositoryTest; import com.rbkmoney.orgmanager.repository.AbstractRepositoryTest;
import com.rbkmoney.orgmanager.util.TestData; import com.rbkmoney.orgmanager.util.TestData;
import com.rbkmoney.swag.organizations.model.Invitation;
import com.rbkmoney.swag.organizations.model.InvitationListResult; import com.rbkmoney.swag.organizations.model.InvitationListResult;
import com.rbkmoney.swag.organizations.model.InvitationStatusName; import com.rbkmoney.swag.organizations.model.InvitationStatusName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -12,8 +14,11 @@ import org.springframework.http.ResponseEntity;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class InvitationServiceIntegrationTest extends AbstractRepositoryTest { public class InvitationServiceIntegrationTest extends AbstractRepositoryTest {
@ -52,4 +57,45 @@ public class InvitationServiceIntegrationTest extends AbstractRepositoryTest {
assertEquals(1, responseEntity.getBody().getResult().size()); assertEquals(1, responseEntity.getBody().getResult().size());
} }
@Test
void checkInviteWithEmptyStatusRequest() {
OrganizationEntity organizationEntity = TestData.buildOrganization(ORGANIZATION_ID, MEMBER_ID);
organizationRepository.save(organizationEntity);
final InvitationEntity invite =
TestData.buildInvitation(ORGANIZATION_ID, INVITATION_ID + "_1", LocalDateTime.now().plusDays(1));
final InvitationEntity expiredInvite =
TestData.buildInvitation(ORGANIZATION_ID, INVITATION_ID + "_2", LocalDateTime.now().minusDays(1));
final InvitationEntity acceptedInvite =
TestData.buildInvitation(
ORGANIZATION_ID,
INVITATION_ID + "_3",
LocalDateTime.now().plusDays(1),
InvitationStatusName.ACCEPTED
);
acceptedInvite.setAcceptedAt(LocalDateTime.now().plusHours(2));
acceptedInvite.setAcceptedMemberId(TestObjectFactory.randomString());
final InvitationEntity revokedInvite =
TestData.buildInvitation(
ORGANIZATION_ID,
INVITATION_ID + "_4",
LocalDateTime.now().plusDays(1),
InvitationStatusName.REVOKED
);
revokedInvite.setRevokedAt(LocalDateTime.now().plusHours(2));
revokedInvite.setRevocationReason(TestObjectFactory.randomString());
invitationRepository.saveAll(List.of(invite, expiredInvite, acceptedInvite, revokedInvite));
ResponseEntity<InvitationListResult> responseEntity =
invitationService.list(ORGANIZATION_ID, null);
Map<String, Invitation> invites = responseEntity.getBody().getResult().stream()
.collect(Collectors.toMap(
Invitation::getId,
invitation -> invitation
));
assertEquals(3, invites.size());
assertNotNull(invites.get(INVITATION_ID + "_1"));
assertNotNull(invites.get(INVITATION_ID + "_3"));
assertNotNull(invites.get(INVITATION_ID + "_4"));
}
} }

View File

@ -30,8 +30,10 @@ import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class InvitationServiceTest { public class InvitationServiceTest {
@Mock private InvitationConverter invitationConverter; @Mock
@Mock private InvitationRepository invitationRepository; private InvitationConverter invitationConverter;
@Mock
private InvitationRepository invitationRepository;
@Mock @Mock
private OrganizationRepository organizationRepository; private OrganizationRepository organizationRepository;
@Mock @Mock
@ -132,6 +134,33 @@ public class InvitationServiceTest {
.containsExactly(invitation); .containsExactly(invitation);
} }
@Test
void shouldFindByOrganizationId() {
// Given
String orgId = "orgId";
InvitationEntity entity = new InvitationEntity();
Invitation invitation = new Invitation();
when(organizationRepository.existsById(orgId))
.thenReturn(true);
when(invitationRepository.findByOrganizationId(orgId))
.thenReturn(List.of(entity));
when(invitationConverter.toDomain(entity))
.thenReturn(invitation);
// When
ResponseEntity<InvitationListResult> response = service.list(orgId, null);
// Then
assertThat(response.getStatusCode())
.isEqualTo(HttpStatus.OK);
assertThat(response.getBody())
.isNotNull();
assertThat(response.getBody().getResult())
.containsExactly(invitation);
}
@Test @Test
void shouldReturnNotFoundIfOrganizationDoesNotExist() { void shouldReturnNotFoundIfOrganizationDoesNotExist() {
// Given // Given

View File

@ -43,6 +43,15 @@ public class TestData {
String organizationId, String organizationId,
String invitationId, String invitationId,
LocalDateTime expiresAt LocalDateTime expiresAt
) {
return buildInvitation(organizationId, invitationId, expiresAt, InvitationStatusName.PENDING);
}
public static InvitationEntity buildInvitation(
String organizationId,
String invitationId,
LocalDateTime expiresAt,
InvitationStatusName statusName
) { ) {
return InvitationEntity.builder() return InvitationEntity.builder()
.id(invitationId) .id(invitationId)
@ -52,7 +61,7 @@ public class TestData {
.inviteeContactEmail("contactEmail") .inviteeContactEmail("contactEmail")
.inviteeContactType(InviteeContact.TypeEnum.EMAIL.getValue()) .inviteeContactType(InviteeContact.TypeEnum.EMAIL.getValue())
.organizationId(organizationId) .organizationId(organizationId)
.status("Pending") .status(statusName.getValue())
.inviteeRoles(Set.of( .inviteeRoles(Set.of(
MemberRoleEntity.builder() MemberRoleEntity.builder()
.id("role1") .id("role1")