package de.juplo.kafka.chat.backend;
+import de.juplo.kafka.chat.backend.InMemoryWithMongoDbStorageIT.DataSourceInitializer;
+import de.juplo.kafka.chat.backend.implementation.StorageStrategy;
+import de.juplo.kafka.chat.backend.storage.mongodb.ChatRoomRepository;
+import de.juplo.kafka.chat.backend.storage.mongodb.MessageRepository;
+import de.juplo.kafka.chat.backend.storage.mongodb.MongoDbStorageStrategy;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.server.LocalServerPort;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
-import org.springframework.test.web.reactive.server.WebTestClient;
-import org.testcontainers.containers.BindMode;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.support.TestPropertySourceUtils;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
-import org.testcontainers.shaded.org.awaitility.Awaitility;
-import java.time.Duration;
+import java.time.Clock;
-@SpringBootTest(
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
- properties = {
- "chat.backend.storage=mongodb",
- "spring.data.mongodb.host=localhost",
- "spring.data.mongodb.database=test" })
@Testcontainers
+@ExtendWith({SpringExtension.class})
+@EnableAutoConfiguration
+@AutoConfigureDataMongo
+@ContextConfiguration(initializers = DataSourceInitializer.class)
@Slf4j
-class InMemoryWithMongoDbStorageIT
+public class InMemoryWithMongoDbStorageIT extends AbstractInMemoryStorageIT
{
- @LocalServerPort
- private int port;
- @Autowired
- private WebTestClient webTestClient;
+ @Autowired
+ MongoDbStorageStrategy storageStrategy;
+ @Autowired
+ ChatRoomRepository chatRoomRepository;
+ @Autowired
+ MessageRepository messageRepository;
- @Test
- @DisplayName("The app starts, the data is restored and accessible")
- void test()
- {
- Awaitility
- .await()
- .atMost(Duration.ofSeconds(15))
- .untilAsserted(() ->
- {
- webTestClient
- .get()
- .uri("http://localhost:{port}/actuator/health", port)
- .exchange()
- .expectStatus().isOk()
- .expectBody().jsonPath("$.status").isEqualTo("UP");
- webTestClient
- .get()
- .uri("http://localhost:{port}/4ace69b7-a79f-481b-ad0d-d756d60b66ec", port)
- .accept(MediaType.APPLICATION_JSON)
- .exchange()
- .expectStatus().isOk()
- .expectBody().jsonPath("$.name").isEqualTo("FOO");
- webTestClient
- .get()
- .uri("http://localhost:{port}/4ace69b7-a79f-481b-ad0d-d756d60b66ec/ute/1", port)
- .accept(MediaType.APPLICATION_JSON)
- .exchange()
- .expectStatus().isOk()
- .expectBody().jsonPath("$.text").isEqualTo("Ich bin Ute...");
- webTestClient
- .get()
- .uri("http://localhost:{port}/4ace69b7-a79f-481b-ad0d-d756d60b66ec/peter/1", port)
- .accept(MediaType.APPLICATION_JSON)
- .exchange()
- .expectStatus().isOk()
- .expectBody().jsonPath("$.text").isEqualTo("Hallo, ich heiße Peter!");
- });
- }
- private static final int MONGODB_PORT = 27017;
+ public InMemoryWithMongoDbStorageIT()
+ {
+ super(Clock.systemDefaultZone());
+ }
- @Container
- private static final GenericContainer CONTAINER =
- new GenericContainer("mongo:6")
- .withClasspathResourceMapping(
- "data/mongodb",
- "/docker-entrypoint-initdb.d",
- BindMode.READ_ONLY)
- .withExposedPorts(MONGODB_PORT);
- @DynamicPropertySource
- static void addMongoPortProperty(DynamicPropertyRegistry registry)
- {
- registry.add("spring.data.mongodb.port", () -> CONTAINER.getMappedPort(27017));
- }
+ @Override
+ protected StorageStrategy getStorageStrategy()
+ {
+ return storageStrategy;
+ }
- @BeforeEach
- void setUpLogging()
- {
- Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(log);
- CONTAINER.followOutput(logConsumer);
- }
+ @TestConfiguration
+ static class InMemoryWithMongoDbStorageStrategyITConfig
+ {
+ @Bean
+ MongoDbStorageStrategy storageStrategy(
+ ChatRoomRepository chatRoomRepository,
+ MessageRepository messageRepository,
+ Clock clock)
+ {
+ return new MongoDbStorageStrategy(
+ chatRoomRepository,
+ messageRepository,
+ chatRoomId -> 0);
+ }
+
+ @Bean
+ Clock clock()
+ {
+ return Clock.systemDefaultZone();
+ }
+ }
+
+ private static final int MONGODB_PORT = 27017;
+
+ @Container
+ private static final GenericContainer CONTAINER =
+ new GenericContainer("mongo:6")
+ .withExposedPorts(MONGODB_PORT);
+
+ public static class DataSourceInitializer
+ implements ApplicationContextInitializer<ConfigurableApplicationContext>
+ {
+ @Override
+ public void initialize(ConfigurableApplicationContext applicationContext)
+ {
+ TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
+ applicationContext,
+ "spring.data.mongodb.host=localhost",
+ "spring.data.mongodb.port=" + CONTAINER.getMappedPort(MONGODB_PORT),
+ "spring.data.mongodb.database=test");
+ }
+ }
+
+ @BeforeEach
+ void setUpLogging()
+ {
+ Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(log);
+ CONTAINER.followOutput(logConsumer);
+ chatRoomRepository.deleteAll();
+ messageRepository.deleteAll();
+ }
}