Skip to content

Commit

Permalink
fix(authority): Fix handling heading type change update event for aut…
Browse files Browse the repository at this point in the history
…hority with linked instance

* fix(authority): Fix handling heading type change update event for authority with linked instance

- do not hard delete authority when handling heading type change update event

Closes: MODELINKS-242
  • Loading branch information
mukhiddin-yusuf authored Jul 2, 2024
1 parent 2f5efad commit db93713
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
* Add new error code to handle authority source file deletion after authority deletion ([MODELINKS-210](https://issues.folio.org/browse/MODELINKS-210))
* Fix authority record update and `updatedByUserId` field assignment ([MODELINKS-219](https://issues.folio.org/browse/MODELINKS-219))
* Fix saving of Authority file with empty Base URL when another Authority file with empty Base URL already exists ([MODELINKS-216](https://issues.folio.org/browse/MODELINKS-216))
* Fix handling of authority heading type change update event ([MODELINKS-242](https://issues.folio.org/browse/MODELINKS-242))

### Tech Dept
* Create custom Mockito verifies for Hibernate entities ([MODELINKS-209](https://issues.folio.org/browse/MODELINKS-209))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.folio.entlinks.service.messaging.authority.handler;

import static java.util.Collections.emptyList;
import static org.folio.entlinks.service.messaging.authority.model.AuthorityChangeType.DELETE;

import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.folio.entlinks.config.properties.InstanceAuthorityChangeProperties;
import org.folio.entlinks.domain.dto.LinksChangeEvent;
import org.folio.entlinks.service.authority.AuthorityService;
Expand Down Expand Up @@ -42,11 +44,17 @@ public List<LinksChangeEvent> handle(List<AuthorityChangeHolder> changes) {
.toList();

var authorityIds = linksEvents.stream().map(LinksChangeEvent::getAuthorityId).collect(Collectors.toSet());
var softDeleteAuthorityIds = changes.stream().map(AuthorityChangeHolder::getAuthorityId).toList();
var softDeleteAuthorityIds = changes.stream()
.filter(change -> change.getChangeType().equals(DELETE))
.map(AuthorityChangeHolder::getAuthorityId)
.toList();

// delete the links
linkingService.deleteByAuthorityIdIn(authorityIds);
// hard delete the authorities
authorityService.deleteByIds(softDeleteAuthorityIds);
if (CollectionUtils.isNotEmpty(softDeleteAuthorityIds)) {
// hard delete authorities
authorityService.deleteByIds(softDeleteAuthorityIds);
}
return linksEvents;
}

Expand All @@ -57,7 +65,7 @@ public LinksChangeEvent.TypeEnum getReplyEventType() {

@Override
public AuthorityChangeType supportedAuthorityChangeType() {
return AuthorityChangeType.DELETE;
return DELETE;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,38 @@ void handleAuthoritiesChanges_positive_deleteEvent() {
assertThat(messages.get(0).getType()).isEqualTo(LinksChangeEvent.TypeEnum.DELETE);
}

@Test
void handleAuthoritiesChanges_positive_shouldHandleHeadingTypeChangeUpdateEventAndSendDeleteLinksChangeEvent() {
var id = UUID.randomUUID();
final var authorityEvents = List.of(
new AuthorityDomainEvent(
id,
new AuthorityDto().naturalId("n12345").corporateName("Beatles"),
new AuthorityDto().naturalId("n12345").corporateNameTitle("Beatles mono"),
DomainEventType.UPDATE,
TENANT_ID)
);
var changeEvent = new LinksChangeEvent().type(LinksChangeEvent.TypeEnum.DELETE);
when(linkingService.countLinksByAuthorityIds(Set.of(id))).thenReturn(Map.of(id, 1));
when(deleteHandler.handle(changeHolderCaptor.capture())).thenReturn(List.of(changeEvent));
when(folioExecutionContext.getTenantId()).thenReturn(TENANT_ID);

service.handleAuthoritiesChanges(authorityEvents);

verify(updateHandler).supportedAuthorityChangeType();
verify(deleteHandler).supportedAuthorityChangeType();
verifyNoMoreInteractions(updateHandler);
verify(eventProducer, times(1)).sendMessages(eventCaptor.capture());
var changeHolders = changeHolderCaptor.getAllValues().stream().flatMap(Collection::stream).toList();
assertThat(changeHolders)
.hasSize(1)
.extracting(AuthorityChangeHolder::getNumberOfLinks)
.containsExactlyInAnyOrder(1);
var messages = eventCaptor.getAllValues().stream().flatMap(Collection::stream).toList();
assertThat(messages).hasSize(1);
assertThat(messages.get(0).getType()).isEqualTo(LinksChangeEvent.TypeEnum.DELETE);
}

@Test
void handleAuthoritiesChanges_positive_updateEventOnConsortiumCentralTenant() {
final var id = UUID.randomUUID();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.folio.entlinks.domain.dto.LinksChangeEvent.TypeEnum;
import static org.folio.support.base.TestConstants.TENANT_ID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.folio.entlinks.config.properties.InstanceAuthorityChangeProperties;
import org.folio.entlinks.domain.dto.AuthorityDto;
import org.folio.entlinks.domain.dto.ChangeTarget;
import org.folio.entlinks.domain.dto.ChangeTargetLink;
import org.folio.entlinks.domain.dto.LinksChangeEvent;
import org.folio.entlinks.integration.dto.event.AuthorityDomainEvent;
import org.folio.entlinks.integration.dto.event.DomainEventType;
import org.folio.entlinks.service.authority.AuthorityService;
import org.folio.entlinks.service.links.InstanceAuthorityLinkingService;
import org.folio.entlinks.service.messaging.authority.model.AuthorityChangeHolder;
Expand Down Expand Up @@ -61,11 +66,18 @@ void supportedInventoryEventType_positive() {
}

@Test
void handle_positive() {
var eventIds = Set.of(UUID.randomUUID(), UUID.randomUUID());
var events = eventIds.stream()
.map(uuid -> new AuthorityChangeHolder(new AuthorityDomainEvent(uuid), emptyMap(), emptyMap(), 1))
.toList();
void handle_positive_shouldHardDeleteAuthorityAndLinks() {
var id1 = UUID.randomUUID();
var id2 = UUID.randomUUID();
var authorityDto = new AuthorityDto().naturalId("n12345").personalName("name");
var authorityDomainEvent1 = new AuthorityDomainEvent(
id1, authorityDto, authorityDto, DomainEventType.DELETE, TENANT_ID);
var authorityDomainEvent2 = new AuthorityDomainEvent(
id2, authorityDto, authorityDto, DomainEventType.DELETE, TENANT_ID);
var events = List.of(
new AuthorityChangeHolder(authorityDomainEvent1, emptyMap(), emptyMap(), 1),
new AuthorityChangeHolder(authorityDomainEvent2, emptyMap(), emptyMap(), 1)
);
var instanceId1 = UUID.randomUUID();
var instanceId2 = UUID.randomUUID();
var instanceId3 = UUID.randomUUID();
Expand All @@ -75,30 +87,59 @@ void handle_positive() {

doNothing().when(linkingService).deleteByAuthorityIdIn(anySet());
when(properties.getNumPartitions()).thenReturn(1);
when(linkingService.getLinksByAuthorityId(eq(events.get(0).getAuthorityId()), any())).thenReturn(
when(linkingService.getLinksByAuthorityId(eq(id1), any())).thenReturn(
new PageImpl<>(List.of(link1.toEntity(instanceId1)), Pageable.ofSize(1), 2)
).thenReturn(
new PageImpl<>(List.of(link2.toEntity(instanceId2)))
);
when(linkingService.getLinksByAuthorityId(eq(events.get(1).getAuthorityId()), any())).thenReturn(
when(linkingService.getLinksByAuthorityId(eq(id2), any())).thenReturn(
new PageImpl<>(List.of(link3.toEntity(instanceId3)))
);

var actual = handler.handle(events);

verify(linkingService).deleteByAuthorityIdIn(eventIds);
verify(linkingService).deleteByAuthorityIdIn(Set.of(id1, id2));
verify(linkingService, times(3)).getLinksByAuthorityId(any(UUID.class), any(Pageable.class));

assertThat(actual)
.hasSize(3)
.extracting(LinksChangeEvent::getAuthorityId, LinksChangeEvent::getType, LinksChangeEvent::getUpdateTargets)
.contains(
tuple(events.get(0).getAuthorityId(), TypeEnum.DELETE, List.of(changeTarget(instanceId1, link1))),
tuple(events.get(0).getAuthorityId(), TypeEnum.DELETE, List.of(changeTarget(instanceId2, link2))),
tuple(events.get(1).getAuthorityId(), TypeEnum.DELETE, List.of(changeTarget(instanceId3, link3)))
tuple(id1, TypeEnum.DELETE, List.of(changeTarget(instanceId1, link1))),
tuple(id1, TypeEnum.DELETE, List.of(changeTarget(instanceId2, link2))),
tuple(id2, TypeEnum.DELETE, List.of(changeTarget(instanceId3, link3)))
);
verify(authorityService).deleteByIds(anyCollection());
}

@Test
void handle_positive_shouldDeleteLinksOnlyOnHeadingTypeChangeUpdateEvent() {
var id = UUID.randomUUID();
var authorityDomainEvent = new AuthorityDomainEvent(
id,
new AuthorityDto().naturalId("n12345").corporateName("Beatles"),
new AuthorityDto().naturalId("n12345").corporateNameTitle("Beatles mono"),
DomainEventType.UPDATE,
TENANT_ID);
var authorityEvents = List.of(new AuthorityChangeHolder(authorityDomainEvent, emptyMap(), emptyMap(), 1));
var link = TestDataUtils.Link.of(1, 1);
var instanceId = UUID.randomUUID();
doNothing().when(linkingService).deleteByAuthorityIdIn(Set.of(id));
when(properties.getNumPartitions()).thenReturn(1);
when(linkingService.getLinksByAuthorityId(eq(id), any())).thenReturn(
new PageImpl<>(List.of(link.toEntity(instanceId)), Pageable.ofSize(1), 1));

var actual = handler.handle(authorityEvents);

verify(linkingService).getLinksByAuthorityId(eq(id), any());
verify(linkingService).deleteByAuthorityIdIn(Set.of(id));
assertThat(actual)
.hasSize(1)
.extracting(LinksChangeEvent::getAuthorityId, LinksChangeEvent::getType, LinksChangeEvent::getUpdateTargets)
.contains(tuple(id, TypeEnum.DELETE, List.of(changeTarget(instanceId, link))));
verifyNoInteractions(authorityService);
}

@Test
void handle_positive_emptyEventList() {
var actual = handler.handle(emptyList());
Expand Down

0 comments on commit db93713

Please sign in to comment.