content: package io.vividcode.happyride.dispatchservice;
  
  import static io.vividcode.happyride.dispatchservice.TestUtils.acceptanceForDriver;
  import static io.vividcode.happyride.dispatchservice.TestUtils.availableDriver0;
  import static io.vividcode.happyride.dispatchservice.TestUtils.availableDriver1;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.mockito.Mockito.times;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  
  import com.google.common.collect.Sets;
  import com.playtika.test.common.spring.EmbeddedContainersShutdownAutoConfiguration;
  import com.playtika.test.postgresql.EmbeddedPostgreSQLBootstrapConfiguration;
  import com.playtika.test.postgresql.EmbeddedPostgreSQLDependenciesAutoConfiguration;
  import io.vividcode.happyride.dispatchservice.api.events.DispatchDomainEvent;
  import io.vividcode.happyride.dispatchservice.api.events.TripAcceptanceDeclinedEvent;
  import io.vividcode.happyride.dispatchservice.api.events.TripAcceptanceSelectedEvent;
  import io.vividcode.happyride.dispatchservice.api.events.TripDispatchFailedEvent;
  import io.vividcode.happyride.dispatchservice.api.events.TripDispatchedEvent;
  import io.vividcode.happyride.dispatchservice.dataaccess.DispatchRepository;
  import io.vividcode.happyride.dispatchservice.domain.Dispatch;
  import io.vividcode.happyride.dispatchservice.domain.DispatchDomainEventPublisher;
  import io.vividcode.happyride.postgres.common.EmbeddedPostgresConfiguration;
  import java.math.BigDecimal;
  import java.util.List;
  import java.util.Set;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Disabled;
  import org.junit.jupiter.api.DisplayName;
  import org.junit.jupiter.api.Test;
  import org.mockito.ArgumentCaptor;
  import org.mockito.Captor;
  import org.mockito.MockitoAnnotations;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
  import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
  import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
  import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
  import org.springframework.boot.test.mock.mockito.MockBean;
  import org.springframework.context.annotation.ComponentScan;
  import org.springframework.test.context.ContextConfiguration;
  import org.springframework.test.context.TestPropertySource;
  
  @DataJpaTest
  @EnableAutoConfiguration
  @ComponentScan(basePackageClasses = DispatchRepository.class)
  @AutoConfigureTestDatabase(replace = Replace.NONE)
  @ContextConfiguration(classes = {
      EmbeddedPostgresConfiguration.class,
      DispatchService.class
  })
  @ImportAutoConfiguration(classes = {
      EmbeddedPostgreSQLDependenciesAutoConfiguration.class,
      EmbeddedPostgreSQLBootstrapConfiguration.class,
      EmbeddedContainersShutdownAutoConfiguration.class
  })
  @TestPropertySource(properties = {
      "embedded.postgresql.docker-image=postgres:12-alpine",
  })
  @DisplayName("Dispatch service")
  @Disabled
  public class DispatchServiceTest {
  
    @Autowired
    DispatchService dispatchService;
  
    @MockBean
    DispatchDomainEventPublisher eventPublisher;
  
    @MockBean
    DriverLocationService driverLocationService;
  
    @MockBean
    TripAcceptanceService tripAcceptanceService;
  
    @Captor
    private ArgumentCaptor<Dispatch> dispatchCaptor;
  
    @Captor
    private ArgumentCaptor<List<DispatchDomainEvent>> eventsCaptor;
  
    @BeforeEach
    public void init() {
      MockitoAnnotations.initMocks(this);
    }
  
    @Test
    @DisplayName("Successful dispatch")
    public void testSuccessfulDispatch() {
      Set<AvailableDriver> drivers = Sets.newHashSet(
          availableDriver0(),
          availableDriver1()
      );
      when(this.driverLocationService.findAvailableDrivers(BigDecimal.ZERO, BigDecimal.ZERO))
          .thenReturn(drivers);
      String tripId = TestUtils.uuid();
      this.dispatchService.dispatchTrip(tripId, TestUtils.tripDetails0());
      verify(this.eventPublisher).publish(this.dispatchCaptor.capture(), this.eventsCaptor.capture());
  
      assertThat(this.dispatchCaptor.getValue().getTripId()).isEqualTo(tripId);
      assertThat(this.eventsCaptor.getValue()).hasSize(1)
          .hasOnlyElementsOfType(TripDispatchedEvent.class);
      assertThat(this.dispatchService.findCurrentDispatchByTrip(tripId)).isPresent();
    }
  
    @Test
    @DisplayName("Failed dispatch")
    public void testFailedDispatch() {
      when(this.driverLocationService.findAvailableDrivers(BigDecimal.ZERO, BigDecimal.ZERO))
          .thenReturn(Sets.newHashSet());
      String tripId = TestUtils.uuid();
      this.dispatchService.dispatchTrip(tripId, TestUtils.tripDetails0());
      verify(this.eventPublisher).publish(this.dispatchCaptor.capture(), this.eventsCaptor.capture());
  
      assertThat(this.dispatchCaptor.getValue().getTripId()).isEqualTo(tripId);
      assertThat(this.eventsCaptor.getValue()).hasSize(1)
          .hasOnlyElementsOfType(TripDispatchFailedEvent.class);
      assertThat(this.dispatchService.findCurrentDispatchByTrip(tripId)).isNotPresent();
    }
  
    @Test
    @DisplayName("Driver accepts trip")
    public void testDriverAcceptance() {
      AvailableDriver driver1 = availableDriver0();
      AvailableDriver driver2 = availableDriver1();
      Set<AvailableDriver> drivers = Sets.newHashSet(driver1, driver2);
      when(this.driverLocationService.findAvailableDrivers(BigDecimal.ZERO, BigDecimal.ZERO))
          .thenReturn(drivers);
      String tripId = TestUtils.uuid();
      this.dispatchService.dispatchTrip(tripId, TestUtils.tripDetails0());
      this.dispatchService.submitTripAcceptance(tripId, acceptanceForDriver(driver1));
      this.dispatchService.submitTripAcceptance(tripId, acceptanceForDriver(driver2));
      this.dispatchService.selectTripAcceptance(tripId, driver1.getDriverId());
      verify(this.eventPublisher, times(2))
          .publish(this.dispatchCaptor.capture(), this.eventsCaptor.capture());
      List<List<DispatchDomainEvent>> allValues = this.eventsCaptor.getAllValues();
      assertThat(allValues).hasSize(2);
      assertThat(allValues).element(0).asList().hasSize(1)
          .hasOnlyElementsOfType(TripDispatchedEvent.class);
      assertThat(allValues)
          .element(1).asList().hasSize(2).hasOnlyElementsOfTypes(TripAcceptanceSelectedEvent.class,
              TripAcceptanceDeclinedEvent.class);
    }
  }
  