content: package co.airy.core.contacts;
  
  import co.airy.avro.communication.DeliveryState;
  import co.airy.avro.communication.Message;
  import co.airy.avro.communication.Metadata;
  import co.airy.core.contacts.util.TestContact;
  import co.airy.core.contacts.util.Topics;
  import co.airy.kafka.test.KafkaTestHelper;
  import co.airy.kafka.test.junit.SharedKafkaTestResource;
  import co.airy.model.metadata.MetadataKeys;
  import co.airy.spring.core.AirySpringBootApplication;
  import co.airy.spring.test.WebTestHelper;
  import co.airy.uuid.UUIDv5;
  import org.apache.kafka.clients.producer.ProducerRecord;
  import org.junit.jupiter.api.AfterAll;
  import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.extension.ExtendWith;
  import org.junit.jupiter.api.extension.RegisterExtension;
  import org.mockito.MockitoAnnotations;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.test.context.TestPropertySource;
  import org.springframework.test.context.junit.jupiter.SpringExtension;
  
  import java.time.Instant;
  import java.util.List;
  import java.util.UUID;
  
  import static co.airy.model.metadata.MetadataRepository.getId;
  import static co.airy.model.metadata.MetadataRepository.newConversationMetadata;
  import static co.airy.test.Timing.retryOnException;
  import static org.hamcrest.Matchers.equalTo;
  import static org.hamcrest.Matchers.hasSize;
  import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
  import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AirySpringBootApplication.class)
  @TestPropertySource(value = "classpath:test.properties")
  @AutoConfigureMockMvc
  @ExtendWith(SpringExtension.class)
  public class CreateContactsTest {
      @RegisterExtension
      public static final SharedKafkaTestResource sharedKafkaTestResource = new SharedKafkaTestResource();
      private static KafkaTestHelper kafkaTestHelper;
  
      @Autowired
      private WebTestHelper webTestHelper;
  
      @BeforeAll
      static void beforeAll() throws Exception {
          kafkaTestHelper = new KafkaTestHelper(sharedKafkaTestResource, Topics.getTopics());
          kafkaTestHelper.beforeAll();
      }
  
      @AfterAll
      static void afterAll() throws Exception {
          kafkaTestHelper.afterAll();
      }
  
      @BeforeEach
      void beforeEach() throws Exception {
          MockitoAnnotations.openMocks(this);
          webTestHelper.waitUntilHealthy();
      }
  
      @Autowired
      private TestContact testContact;
  
      @Test
      void shouldCreateContactForNewConversation() throws Exception {
          final String conversationId = UUID.randomUUID().toString();
          final String expectedContactId = UUIDv5.fromName(conversationId).toString();
  
          kafkaTestHelper.produceRecords(List.of(
                  new ProducerRecord<>(Topics.applicationCommunicationMessages.name(), "message-id",
                          Message.newBuilder()
                                  .setId("message-id")
                                  .setSource("source")
                                  .setSentAt(Instant.now().toEpochMilli())
                                  .setSenderId("sourceConversationId")
                                  .setDeliveryState(DeliveryState.DELIVERED)
                                  .setConversationId(conversationId)
                                  .setChannelId("channelId")
                                  .setContent("{\"text\":\"Hello world\"}")
                                  .setIsFromContact(true)
                                  .build())
          ));
  
          retryOnException(() -> {
              webTestHelper.post("/contacts.list")
                      .andExpect(status().isOk())
                      .andExpect(status().isOk())
                      .andExpect(jsonPath("$.data", hasSize(1)));
          }, "Contact was not automatically created");
  
          final String expectedDisplayName = "Barbara Liskov";
  
          // Update the display name
          final Metadata metadata = newConversationMetadata(conversationId, MetadataKeys.ConversationKeys.Contact.DISPLAY_NAME, expectedDisplayName);
          kafkaTestHelper.produceRecords(List.of(
                  new ProducerRecord<>(Topics.applicationCommunicationMetadata.name(), getId(metadata).toString(), metadata)
          ));
  
          retryOnException(() -> {
              webTestHelper.post("/contacts.info", "{\"id\":\"" + expectedContactId + "\"}")
                      .andExpect(status().isOk())
                      .andExpect(jsonPath("$.display_name", equalTo(expectedDisplayName)));
          }, "Contact was not found using expected contact id");
      }
  }
  