Repository: mageddo/dns-proxy-server
Pull request #350 (2023-03-11 03:29:14)

Web endpoints component tests


Patch:
diff --git a/build.gradle b/build.gradle
index 8c6d1b8a..35e74080 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,6 +31,12 @@ configurations.all {
 
 dependencies {
 
+  annotationProcessor("com.google.dagger:dagger-compiler:2.45")
+  implementation("com.google.dagger:dagger:2.45")
+
+  testAnnotationProcessor("com.google.dagger:dagger-compiler:2.45")
+  testImplementation("com.google.dagger:dagger:2.45")
+
   compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.+'
   annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.+'
 
@@ -65,13 +71,21 @@ dependencies {
 }
 
 test {
-  systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
+  exclude "**/*CompTest.class"
   useJUnitPlatform()
   testLogging {
     events "passed", "skipped", "failed"
   }
 }
 
+task compTest(type: Test) {
+  include "**/*CompTest.class"
+  failFast = true
+  testLogging {
+    events "passed", "skipped", "failed"
+  }
+}
+
 compileJava {
   options.encoding = 'UTF-8'
   options.compilerArgs << '-parameters'
diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/Config.java b/src/main/java/com/mageddo/dnsproxyserver/config/Config.java
index d9d0166f..395830d7 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/config/Config.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/config/Config.java
@@ -8,6 +8,9 @@ import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.Value;
 
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -74,6 +77,14 @@ public class Config {
     return SimpleServer.Protocol.BOTH;
   }
 
+  public void resetConfigFile() {
+    try {
+      Files.deleteIfExists(this.getConfigPath());
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
   @Value
   public static class Env {
 
diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAO.java b/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAO.java
index 9157a1b2..1965e530 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAO.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAO.java
@@ -16,6 +16,9 @@ public interface ConfigDAO {
 
   List<Config.Env> findEnvs();
 
+  /**
+   * Find by env and/or hostname
+   */
   List<Config.Entry> findHostnamesBy(String env, String hostname);
 
   void changeActiveEnv(String name);
diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAOJson.java b/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAOJson.java
index 2e05ec02..e45c6ad8 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAOJson.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/config/ConfigDAOJson.java
@@ -16,6 +16,7 @@ import org.apache.commons.lang3.Validate;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.function.Predicate;
@@ -27,7 +28,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public Config.Env findActiveEnv() {
-    final var configJson = loadConfigJson();
+    final var configJson = JsonConfigs.loadConfigJson();
     return findEnv(configJson.getActiveEnv(), configJson);
   }
 
@@ -51,7 +52,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public void addEntry(String env, Config.Entry entry) {
-    final var config = loadConfigJson();
+    final var config = JsonConfigs.loadConfigJson();
     final var found = findOrBind(env, config);
     found.add(ConfigJsonV2.Entry.from(entry));
     save(config);
@@ -59,7 +60,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public boolean updateEntry(String env, Config.Entry entry) {
-    final var config = loadConfigJson();
+    final var config = JsonConfigs.loadConfigJson();
     final var found = findOrBind(env, config);
     final var hostnames = found.getHostnames();
     if (hostnames.isEmpty()) {
@@ -76,7 +77,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public boolean removeEntry(String env, String hostname) {
-    final var config = loadConfigJson();
+    final var config = JsonConfigs.loadConfigJson();
     final var found = findOrBind(env, config);
     final var hostnames = found.getHostnames();
     if (hostnames.isEmpty()) {
@@ -94,7 +95,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public void createEnv(Config.Env env) {
-    final var config = loadConfigJson();
+    final var config = JsonConfigs.loadConfigJson();
 
     final var alreadyExists = config
       .get_envs()
@@ -112,7 +113,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public void deleteEnv(String name) {
-    final var config = loadConfigJson();
+    final var config = JsonConfigs.loadConfigJson();
     final var filtered = config
       .get_envs()
       .stream()
@@ -124,7 +125,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public List<Config.Env> findEnvs() {
-    return loadConfigJson().getEnvs();
+    return JsonConfigs.loadConfigJson().getEnvs();
   }
 
   @Override
@@ -144,7 +145,7 @@ public class ConfigDAOJson implements ConfigDAO {
 
   @Override
   public void changeActiveEnv(String name) {
-    final var config = loadConfigJson()
+    final var config = JsonConfigs.loadConfigJson()
       .setActiveEnv(name);
     save(config);
   }
@@ -156,8 +157,8 @@ public class ConfigDAOJson implements ConfigDAO {
         return env;
       }
     }
-    log.debug("status=notFound, action=usingDefaultEnv, activeEnv={}", Config.Env.DEFAULT_ENV);
-    final var def = ConfigJsonV2.Env.from(Config.Env.theDefault());
+    log.debug("status=envNotFound, action=creating, activeEnv={}", envKey);
+    final var def = ConfigJsonV2.Env.from(Config.Env.of(envKey, Collections.emptyList()));
     configJson.get_envs().add(def);
     return def;
   }
@@ -173,13 +174,6 @@ public class ConfigDAOJson implements ConfigDAO {
     return env;
   }
 
-  static ConfigJsonV2 loadConfigJson() {
-    final var configPath = Configs
-      .getInstance()
-      .getConfigPath();
-    return (ConfigJsonV2) JsonConfigs.loadConfig(configPath);
-  }
-
   static void save(ConfigJsonV2 config) {
     final var configPath = Configs
       .getInstance()
diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/entrypoint/JsonConfigs.java b/src/main/java/com/mageddo/dnsproxyserver/config/entrypoint/JsonConfigs.java
index eb5ba015..4a7cd45a 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/config/entrypoint/JsonConfigs.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/config/entrypoint/JsonConfigs.java
@@ -2,6 +2,7 @@ package com.mageddo.dnsproxyserver.config.entrypoint;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.mageddo.dnsproxyserver.config.Config;
+import com.mageddo.dnsproxyserver.config.Configs;
 import com.mageddo.dnsproxyserver.config.entrypoint.ConfigJsonV2.Entry;
 import com.mageddo.dnsproxyserver.config.entrypoint.ConfigJsonV2.Env;
 import com.mageddo.json.JsonUtils;
@@ -101,4 +102,10 @@ public class JsonConfigs {
     return tree.at("/version").asInt(VERSION_1);
   }
 
+  public static ConfigJsonV2 loadConfigJson() {
+    final var configPath = Configs
+      .getInstance()
+      .getConfigPath();
+    return (ConfigJsonV2) loadConfig(configPath);
+  }
 }
diff --git a/src/main/java/com/mageddo/dnsproxyserver/di/MainModule.java b/src/main/java/com/mageddo/dnsproxyserver/di/MainModule.java
new file mode 100644
index 00000000..a01d9dff
--- /dev/null
+++ b/src/main/java/com/mageddo/dnsproxyserver/di/MainModule.java
@@ -0,0 +1,7 @@
+package com.mageddo.dnsproxyserver.di;
+
+import dagger.Module;
+
+@Module
+public interface MainModule {
+}
diff --git a/src/main/java/com/mageddo/dnsproxyserver/di/ObjGraph.java b/src/main/java/com/mageddo/dnsproxyserver/di/ObjGraph.java
new file mode 100644
index 00000000..2159ab60
--- /dev/null
+++ b/src/main/java/com/mageddo/dnsproxyserver/di/ObjGraph.java
@@ -0,0 +1,13 @@
+package com.mageddo.dnsproxyserver.di;
+
+import dagger.Component;
+
+import javax.inject.Singleton;
+
+@Singleton
+@Component(modules = MainModule.class)
+public interface ObjGraph {
+  static ObjGraph create(){
+    return DaggerObjGraph.create();
+  }
+}
diff --git a/src/main/java/com/mageddo/dnsproxyserver/server/rest/HostnameResource.java b/src/main/java/com/mageddo/dnsproxyserver/server/rest/HostnameResource.java
index fbdb0a6c..a4df1cf9 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/server/rest/HostnameResource.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/server/rest/HostnameResource.java
@@ -2,6 +2,7 @@ package com.mageddo.dnsproxyserver.server.rest;
 
 import com.mageddo.dnsproxyserver.config.ConfigDAO;
 import com.mageddo.dnsproxyserver.server.rest.reqres.HostnameV1;
+import com.mageddo.dnsproxyserver.server.rest.reqres.Message;
 import lombok.AllArgsConstructor;
 
 import javax.inject.Inject;
@@ -14,6 +15,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 
 @Path("/hostname")
 @AllArgsConstructor(onConstructor = @__({@Inject}))
@@ -52,7 +55,17 @@ public class HostnameResource {
   @DELETE
   @Path("/")
   @Consumes(MediaType.APPLICATION_JSON)
-  public void delete(HostnameV1 hostname) {
-    this.configDAO.removeEntry(hostname.getEnv(), hostname.getHostname());
+  public Response delete(HostnameV1 hostname) {
+    final var removed = this.configDAO.removeEntry(hostname.getEnv(), hostname.getHostname());
+    if (removed) {
+      return Response.ok().build();
+    }
+    return Response
+      .status(Status.BAD_REQUEST)
+      .entity(Message.of(
+        Status.BAD_REQUEST.getStatusCode(),
+        String.format("Can't delete hostname: %s", hostname.getHostname())
+      ))
+      .build();
   }
 }
diff --git a/src/main/java/com/mageddo/dnsproxyserver/server/rest/reqres/Message.java b/src/main/java/com/mageddo/dnsproxyserver/server/rest/reqres/Message.java
new file mode 100644
index 00000000..9f4b899a
--- /dev/null
+++ b/src/main/java/com/mageddo/dnsproxyserver/server/rest/reqres/Message.java
@@ -0,0 +1,13 @@
+package com.mageddo.dnsproxyserver.server.rest.reqres;
+
+import lombok.Value;
+
+@Value
+public class Message {
+  private int code;
+  private String message;
+
+  public static Message of(int code, String msg){
+    return new Message(code, msg);
+  }
+}


Test patch:
diff --git a/src/test/java/com/mageddo/dnsproxyserver/server/CacheResourceCompTest.java b/src/test/java/com/mageddo/dnsproxyserver/server/CacheResourceCompTest.java
new file mode 100644
index 00000000..b6aa86fd
--- /dev/null
+++ b/src/test/java/com/mageddo/dnsproxyserver/server/CacheResourceCompTest.java
@@ -0,0 +1,42 @@
+package com.mageddo.dnsproxyserver.server;
+
+import com.mageddo.dnsproxyserver.config.Configs;
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.ws.rs.core.Response;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+@QuarkusTest
+class CacheResourceCompTest {
+
+  @BeforeEach
+  void beforeEach(){
+    Configs
+      .getInstance()
+      .resetConfigFile()
+    ;
+  }
+
+  @Test
+  void mustFindCacheSize() {
+    // arrange
+
+    // act
+    final var response = given()
+      .get("/v1/caches/size")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("{\"size\":0}"))
+      .log()
+    ;
+  }
+}
diff --git a/src/test/java/com/mageddo/dnsproxyserver/server/rest/EnvResourceCompTest.java b/src/test/java/com/mageddo/dnsproxyserver/server/rest/EnvResourceCompTest.java
new file mode 100644
index 00000000..5d7efb26
--- /dev/null
+++ b/src/test/java/com/mageddo/dnsproxyserver/server/rest/EnvResourceCompTest.java
@@ -0,0 +1,153 @@
+package com.mageddo.dnsproxyserver.server.rest;
+
+import com.mageddo.dnsproxyserver.config.Configs;
+import com.mageddo.dnsproxyserver.config.entrypoint.JsonConfigs;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.ws.rs.core.Response;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@QuarkusTest
+class EnvResourceCompTest {
+
+  @BeforeEach
+  void beforeEach(){
+    Configs
+      .getInstance()
+      .resetConfigFile()
+    ;
+  }
+
+  @Test
+  void mustFindDefaultEnvAsActive() {
+    // arrange
+
+    // act
+    final var response = given()
+      .get("/env/active")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("""
+        {"name":""}"""))
+      .log()
+    ;
+  }
+
+  @Test
+  void mustListAvailableEnvs() {
+    // arrange
+    this.changeDefaultEnv();
+//    this.mustCreateEnv();
+
+    // act
+    final var response = given()
+      .get("/env")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("""
+        [{"name":""}]"""))
+      .log()
+    ;
+  }
+
+  @Test
+  void changeDefaultEnv() {
+    // arrange
+    final var body = """
+      {
+        "name": "batata"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .put("/env/active")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.NO_CONTENT.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+    final var activeEnv = JsonConfigs.loadConfigJson().getActiveEnv();
+    assertEquals("batata", activeEnv);
+  }
+
+  @Test
+  void mustCreateEnv() {
+    // arrange
+    final var body = """
+      {
+        "name": "batata"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .post("/env")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.NO_CONTENT.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+  }
+
+  @Test
+  void mustDeleteEnv() {
+    // arrange
+    this.mustCreateEnv();
+
+    final var body = """
+      {
+        "name": "batata"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .delete("/env")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.NO_CONTENT.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+  }
+}
diff --git a/src/test/java/com/mageddo/dnsproxyserver/server/rest/HostnameResourceCompTest.java b/src/test/java/com/mageddo/dnsproxyserver/server/rest/HostnameResourceCompTest.java
new file mode 100644
index 00000000..063fc0aa
--- /dev/null
+++ b/src/test/java/com/mageddo/dnsproxyserver/server/rest/HostnameResourceCompTest.java
@@ -0,0 +1,167 @@
+package com.mageddo.dnsproxyserver.server.rest;
+
+import com.mageddo.dnsproxyserver.config.Configs;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.ws.rs.core.Response;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+@QuarkusTest
+class HostnameResourceCompTest {
+
+  @BeforeEach
+  void beforeEach(){
+    Configs
+      .getInstance()
+      .resetConfigFile()
+    ;
+  }
+
+  @Test
+  void mustFindHostnamesButHasNoResult(){
+    // arrange
+
+    // act
+    final var response = given()
+      .queryParam("env", "")
+      .get("/hostname/find")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("""
+        [{"hostname":"dps-sample.dev","id":"1","ip":[192,168,0,254],"ttl":30,"type":"A"}]"""))
+      .log()
+    ;
+  }
+
+  @Test
+  void mustFindEnvHostnames(){
+    // arrange
+    this.mustCreateHostname();
+
+    // act
+    final var response = given()
+      .queryParam("env", "batata-env")
+      .get("/hostname/find")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("""
+        [{"hostname":"acme.com","id":"1231","ip":[192,168,0,1],"ttl":31,"type":"A"}]"""))
+      .log()
+    ;
+  }
+
+  @Test
+  void mustCreateHostname(){
+
+    // arrange
+    final var body = """
+      {
+        "id": 1231,
+        "hostname": "acme.com",
+        "ip": [192, 168, 0, 1],
+        "ttl": 31,
+        "type": "A",
+        "env": "batata-env"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .post("/hostname")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.NO_CONTENT.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+  }
+
+  @Test
+  void mustUpdateHostname(){
+
+    // arrange
+    this.mustCreateHostname();
+
+    final var body = """
+      {
+        "id": 1231,
+        "hostname": "acme.com",
+        "ip": [192, 168, 0, 5],
+        "ttl": 31,
+        "type": "A",
+        "env": "batata-env"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .put("/hostname")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.NO_CONTENT.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+  }
+
+  @Test
+  void mustDeleteHostname(){
+
+    // arrange
+    this.mustCreateHostname();
+
+    final var body = """
+      {
+        "env": "batata-env",
+        "hostname": "acme.com"
+      }
+      """;
+
+    // act
+    final var response = given()
+      .contentType(ContentType.JSON)
+      .body(body)
+      .delete("/hostname")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo(""))
+      .log()
+    ;
+
+  }
+
+}
diff --git a/src/test/java/com/mageddo/dnsproxyserver/server/rest/NetworkResourceCompTest.java b/src/test/java/com/mageddo/dnsproxyserver/server/rest/NetworkResourceCompTest.java
new file mode 100644
index 00000000..a5360915
--- /dev/null
+++ b/src/test/java/com/mageddo/dnsproxyserver/server/rest/NetworkResourceCompTest.java
@@ -0,0 +1,46 @@
+package com.mageddo.dnsproxyserver.server.rest;
+
+import com.mageddo.dnsproxyserver.docker.DockerNetworkService;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.mockito.InjectMock;
+import org.junit.jupiter.api.Test;
+
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+
+@QuarkusTest
+class NetworkResourceCompTest {
+
+  @InjectMock(convertScopes = true)
+  DockerNetworkService networkService;
+
+  @Test
+  void changeDefaultEnv() {
+    // arrange
+    doReturn(List.of("6c99cf8211c282a50fe5be34dff1aa0c8ce9b0aa194dcf6b80339898de07be59"))
+      .when(this.networkService)
+      .disconnectContainers(anyString())
+    ;
+
+    // act
+    final var response = given()
+      .queryParam("networkId", "net1")
+      .delete("/network/disconnect-containers")
+      .then()
+      .log()
+      .ifValidationFails();
+
+    // assert
+    response
+      .statusCode(Response.Status.OK.getStatusCode())
+      .body(equalTo("[\"6c99cf8211c282a50fe5be34dff1aa0c8ce9b0aa194dcf6b80339898de07be59\"]"))
+      .log()
+    ;
+
+  }
+}
diff --git a/src/test/java/com/mageddo/utils/dagger/TestingApp.java b/src/test/java/com/mageddo/utils/dagger/TestingApp.java
new file mode 100644
index 00000000..e334ae67
--- /dev/null
+++ b/src/test/java/com/mageddo/utils/dagger/TestingApp.java
@@ -0,0 +1,4 @@
+package com.mageddo.utils.dagger;
+
+public class TestingApp {
+}