content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.activiti.spring;
  
  import static java.util.Arrays.asList;
  import static org.activiti.api.process.model.events.ApplicationEvent.ApplicationEvents.APPLICATION_DEPLOYED;
  import static org.activiti.api.process.model.events.ApplicationEvent.ApplicationEvents.APPLICATION_ROLLBACK;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.mockito.BDDMockito.given;
  import static org.mockito.Mockito.mock;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  
  import java.util.List;
  import org.activiti.api.process.model.events.ApplicationDeployedEvent;
  import org.activiti.api.process.runtime.events.listener.ProcessRuntimeEventListener;
  import org.activiti.api.runtime.event.impl.ApplicationDeployedEvents;
  import org.activiti.engine.RepositoryService;
  import org.activiti.engine.repository.Deployment;
  import org.activiti.engine.repository.DeploymentQuery;
  import org.activiti.runtime.api.model.impl.APIDeploymentConverter;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.extension.ExtendWith;
  import org.mockito.ArgumentCaptor;
  import org.mockito.Mock;
  import org.mockito.junit.jupiter.MockitoExtension;
  import org.springframework.context.ApplicationEventPublisher;
  
  @ExtendWith(MockitoExtension.class)
  public class ApplicationDeployedEventProducerTest {
  
      private ApplicationDeployedEventProducer producer;
  
      @Mock
      private RepositoryService repositoryService;
  
      @Mock
      private APIDeploymentConverter converter;
  
      @Mock
      private ApplicationEventPublisher eventPublisher;
  
      @Mock
      private ProcessRuntimeEventListener<ApplicationDeployedEvent> firstListener;
  
      @Mock
      private ProcessRuntimeEventListener<ApplicationDeployedEvent> secondListener;
  
      private static final String APPLICATION_DEPLOYMENT_NAME = "SpringAutoDeployment";
  
      @BeforeEach
      public void setUp() {
          producer = new ApplicationDeployedEventProducer(
              repositoryService,
              converter,
              asList(firstListener, secondListener),
              eventPublisher
          );
      }
  
      @Test
      public void shouldPublishEventsWhenApplicationIsDeployed() {
          ArgumentCaptor<ApplicationDeployedEvents> captorPublisher = startEventProducer();
  
          assertThat(captorPublisher.getValue().getApplicationDeployedEvents().get(0).getEventType()).isEqualTo(
              APPLICATION_DEPLOYED
          );
      }
  
      @Test
      public void shouldPublishEventsWhenApplicationIsRollback() {
          producer.setAfterRollback(true);
          ArgumentCaptor<ApplicationDeployedEvents> captorPublisher = startEventProducer();
  
          assertThat(captorPublisher.getValue().getApplicationDeployedEvents().get(0).getEventType()).isEqualTo(
              APPLICATION_ROLLBACK
          );
      }
  
      private ArgumentCaptor<ApplicationDeployedEvents> startEventProducer() {
          DeploymentQuery deploymentQuery = mock(DeploymentQuery.class);
          given(repositoryService.createDeploymentQuery()).willReturn(deploymentQuery);
  
          List<Deployment> internalDeployment = asList(mock(Deployment.class), mock(Deployment.class));
  
          given(deploymentQuery.deploymentName(APPLICATION_DEPLOYMENT_NAME)).willReturn(deploymentQuery);
          given(deploymentQuery.latestVersion()).willReturn(deploymentQuery);
          given(deploymentQuery.list()).willReturn(internalDeployment);
  
          org.activiti.api.process.model.Deployment deployment = mock(org.activiti.api.process.model.Deployment.class);
          when(deployment.getProjectReleaseVersion()).thenReturn("1");
          when(deployment.getId()).thenReturn("123");
          List<org.activiti.api.process.model.Deployment> apiDeployments = asList(deployment);
          given(converter.from(internalDeployment)).willReturn(apiDeployments);
  
          producer.start();
  
          ArgumentCaptor<ApplicationDeployedEvent> captor = ArgumentCaptor.forClass(ApplicationDeployedEvent.class);
          verify(firstListener).onEvent(captor.capture());
          verify(secondListener).onEvent(captor.capture());
  
          List<ApplicationDeployedEvent> allValues = captor.getAllValues();
          assertThat(allValues)
              .extracting(ApplicationDeployedEvent::getEntity)
              .extracting(org.activiti.api.process.model.Deployment::getId)
              .hasSize(2)
              .containsOnly("123");
  
          assertThat(allValues)
              .extracting(ApplicationDeployedEvent::getEntity)
              .extracting(org.activiti.api.process.model.Deployment::getProjectReleaseVersion)
              .hasSize(2)
              .containsOnly("2");
  
          ArgumentCaptor<ApplicationDeployedEvents> captorPublisher = ArgumentCaptor.forClass(
              ApplicationDeployedEvents.class
          );
          verify(eventPublisher).publishEvent(captorPublisher.capture());
          return captorPublisher;
      }
  }
  