diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ad6fee1..f220ac1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,6 +13,8 @@ jobs: 11 17 distribution: 'temurin' + - name: Run tests + run: mvn --batch-mode test - name: Cache SonarQube packages uses: actions/cache@v4 with: @@ -26,10 +28,11 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Build and analyze + if: ${{ github.ref == 'refs/heads/main' }} env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: >- - mvn -B verify sonar:sonar + mvn --batch-mode verify sonar:sonar -Dsonar.java.jdkHome=$JAVA_HOME_11_X64 -Dsonar.projectKey=pgmarc_space-java-client -Pcoverage diff --git a/src/main/java/io/github/pgmarc/space/App.java b/src/main/java/io/github/pgmarc/space/App.java deleted file mode 100644 index 09de44f..0000000 --- a/src/main/java/io/github/pgmarc/space/App.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.pgmarc.space; - -public class App { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -} diff --git a/src/main/java/io/github/pgmarc/space/Config.java b/src/main/java/io/github/pgmarc/space/Config.java deleted file mode 100644 index 0c046b8..0000000 --- a/src/main/java/io/github/pgmarc/space/Config.java +++ /dev/null @@ -1,98 +0,0 @@ -package io.github.pgmarc.space; - -import java.time.Duration; -import java.util.Objects; - -import okhttp3.HttpUrl; - -public final class Config { - - private static final String DEFAULT_SCHEME = "http"; - - private final String apiKey; - private final String host; - private final int port; - private final String prefixPath; - private final Duration readTimeout; - private final Duration writeTimeout; - - private Config(Builder builder) { - this.host = builder.host; - this.apiKey = builder.apiKey; - this.port = builder.port; - this.prefixPath = builder.prefixPath; - this.readTimeout = builder.readTimeout; - this.writeTimeout = builder.writeTimeout; - } - - public String getApiKey() { - return apiKey; - } - - public Duration getReadTimeout() { - return readTimeout; - } - - public Duration getWriteTimeout() { - return writeTimeout; - } - - public HttpUrl getUrl() { - return new HttpUrl.Builder().scheme(DEFAULT_SCHEME) - .host(this.host).port(this.port) - .addPathSegments(prefixPath).build(); - } - - public static Builder builder(String host, String apiKey) { - return new Builder(host, apiKey); - } - - public static final class Builder { - - private final String host; - private final String apiKey; - private int port = 5403; - private String prefixPath = "api/v1"; - private Duration readTimeout; - private Duration writeTimeout; - - private Builder(String host, String apiKey) { - this.host = host; - this.apiKey = apiKey; - } - - public Builder port(int port) { - this.port = port; - return this; - } - - public Builder readTimeout(Duration duration) { - if (duration != null) { - this.readTimeout = duration; - } - return this; - } - - public Builder writeTimeout(Duration duration) { - if (duration != null) { - this.writeTimeout = duration; - } - return this; - } - - public Builder prefixPath(String prefixPath) { - if (prefixPath != null) { - this.prefixPath = prefixPath; - } - return this; - } - - public Config build() { - Objects.requireNonNull(this.host, "host must not be null"); - Objects.requireNonNull(this.apiKey, "api key must not be null"); - return new Config(this); - } - - } - -} diff --git a/src/main/java/io/github/pgmarc/space/contracts/ContractsEndpoint.java b/src/main/java/io/github/pgmarc/space/ContractsEndpoint.java similarity index 93% rename from src/main/java/io/github/pgmarc/space/contracts/ContractsEndpoint.java rename to src/main/java/io/github/pgmarc/space/ContractsEndpoint.java index 2014a99..f598c59 100644 --- a/src/main/java/io/github/pgmarc/space/contracts/ContractsEndpoint.java +++ b/src/main/java/io/github/pgmarc/space/ContractsEndpoint.java @@ -1,10 +1,13 @@ -package io.github.pgmarc.space.contracts; +package io.github.pgmarc.space; import java.io.IOException; import java.util.Objects; import org.json.JSONObject; +import io.github.pgmarc.space.contracts.Subscription; +import io.github.pgmarc.space.contracts.SubscriptionRequest; +import io.github.pgmarc.space.contracts.SubscriptionUpdateRequest; import io.github.pgmarc.space.deserializers.ErrorDeserializer; import io.github.pgmarc.space.deserializers.SubscriptionDeserializer; import io.github.pgmarc.space.exceptions.SpaceApiException; @@ -33,7 +36,7 @@ public final class ContractsEndpoint { private final ErrorDeserializer errorDeserializer = new ErrorDeserializer(); private final Headers requiredHeaders; - public ContractsEndpoint(OkHttpClient client, HttpUrl baseUrl, String apiKey) { + ContractsEndpoint(OkHttpClient client, HttpUrl baseUrl, String apiKey) { this.client = client; this.baseUrl = baseUrl; this.requiredHeaders = new Headers.Builder().add("Accept", JSON.toString()) diff --git a/src/main/java/io/github/pgmarc/space/SpaceClient.java b/src/main/java/io/github/pgmarc/space/SpaceClient.java new file mode 100644 index 0000000..953d53d --- /dev/null +++ b/src/main/java/io/github/pgmarc/space/SpaceClient.java @@ -0,0 +1,107 @@ +package io.github.pgmarc.space; + +import java.time.Duration; +import java.util.Objects; + +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; + +public final class SpaceClient { + + private final OkHttpClient httpClient; + private final HttpUrl baseUrl; + private final String apiKey; + + private ContractsEndpoint contracts; + + private SpaceClient(OkHttpClient httpClient, HttpUrl baseUrl, String apiKey) { + this.httpClient = httpClient; + this.baseUrl = baseUrl; + this.apiKey = apiKey; + } + + public ContractsEndpoint contracts() { + if (contracts == null) { + this.contracts = new ContractsEndpoint(httpClient, baseUrl, apiKey); + } + return contracts; + } + + public static Builder builder(String host, String apiKey) { + return new Builder(host, apiKey); + } + + public static final class Builder { + + private static final String DEFAULT_SCHEME = "http"; + private static final int DEFAULT_PORT = 5403; + private static final String DEFAULT_API_VERSION = "api/v1"; + + private final String apiKey; + private final String host; + private int port = DEFAULT_PORT; + private String prefixPath = DEFAULT_API_VERSION; + private Duration readTimeout; + private Duration writeTimeout; + + private Builder(String host, String apiKey) { + this.apiKey = apiKey; + this.host = host; + } + + public Builder withPort(int port) { + this.port = port; + return this; + } + + public Builder withPath(String prefixPath) { + if (prefixPath != null) { + this.prefixPath = prefixPath; + } + return this; + } + + public Builder withReadTimeout(Duration duration) { + if (duration != null) { + this.readTimeout = duration; + } + return this; + } + + public Builder withWriteTimeout(Duration duration) { + if (duration != null) { + this.writeTimeout = duration; + } + return this; + } + + public SpaceClient build() { + Objects.requireNonNull(this.host, "host must not be null"); + Objects.requireNonNull(this.apiKey, "api key must not be null"); + if (apiKey.isBlank()) { + throw new IllegalArgumentException("api key must not be blank"); + } + if (host.isBlank()) { + throw new IllegalArgumentException("host must not be blank"); + } + OkHttpClient.Builder httpClientBuilder = new OkHttpClient().newBuilder(); + + if (readTimeout != null) { + httpClientBuilder.readTimeout(readTimeout); + } + + if (writeTimeout != null) { + httpClientBuilder.writeTimeout(writeTimeout); + } + + HttpUrl baseUrl = new HttpUrl.Builder() + .scheme(DEFAULT_SCHEME) + .host(host) + .port(port) + .addPathSegments(prefixPath).build(); + return new SpaceClient(httpClientBuilder.build(), baseUrl, this.apiKey); + } + + } + +} diff --git a/src/test/java/io/github/pgmarc/space/AppTest.java b/src/test/java/io/github/pgmarc/space/AppTest.java deleted file mode 100644 index a0b305d..0000000 --- a/src/test/java/io/github/pgmarc/space/AppTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.pgmarc.space; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -public class AppTest { - - @Test - void testApp() { - assertTrue(true); - } -} diff --git a/src/test/java/io/github/pgmarc/space/ConfigTest.java b/src/test/java/io/github/pgmarc/space/ConfigTest.java deleted file mode 100644 index c2625c5..0000000 --- a/src/test/java/io/github/pgmarc/space/ConfigTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.github.pgmarc.space; - -import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -class ConfigTest { - - private static final String TEST_API_KEY = "fc851e857c18a5df8ef91dd8c63a1ca3"; - private static final String TEST_HOST = "example.com"; - - @Test - void givenRequiredParametersShouldCreateConfig() { - - Config config = Config.builder(TEST_HOST, TEST_API_KEY).build(); - - assertAll( - () -> assertThat(config.getUrl()).hasToString("http://" + TEST_HOST + ":5403/api/v1"), - () -> assertThat(config.getApiKey()).isEqualTo(TEST_API_KEY)); - - } - - @Test - void givenNoHostAndPortShouldThrow() { - - Config.Builder config1 = Config.builder(null, TEST_API_KEY); - assertThatExceptionOfType(NullPointerException.class) - .isThrownBy(() -> config1.build()) - .withMessage("host must not be null"); - Config.Builder config2 = Config.builder(TEST_HOST, null); - assertThatExceptionOfType(NullPointerException.class) - .isThrownBy(() -> config2.build()) - .withMessage("api key must not be null"); - - } - - @Test - void givenOptionalParemetersShoudCreate() { - - int port = 3000; - String prefixPath = "api/v2"; - long writeTimeoutMillis = 700; - long readTimeoutMillis = 500; - - Config config = Config.builder(TEST_HOST, TEST_API_KEY) - .port(port) - .prefixPath(prefixPath) - .readTimeout(Duration.ofMillis(readTimeoutMillis)) - .writeTimeout(Duration.ofMillis(writeTimeoutMillis)) - .build(); - - assertAll( - () -> assertThat(config.getUrl()) - .hasToString("http://" + TEST_HOST + ":" + port + "/" + prefixPath), - () -> assertThat(config.getReadTimeout().toMillis()).isEqualTo(readTimeoutMillis), - () -> assertThat(config.getWriteTimeout().toMillis()).isEqualTo(writeTimeoutMillis)); - - } - - @Test - void givenNullPathShouldUseDefaultPrefixPath() { - - Config config = Config.builder(TEST_HOST, TEST_API_KEY) - .prefixPath(null) - .build(); - assertThat(config.getUrl()).hasToString("http://example.com:5403/api/v1"); - } - -} diff --git a/src/test/java/io/github/pgmarc/space/contracts/ContractsEndpointTest.java b/src/test/java/io/github/pgmarc/space/ContractsEndpointTest.java similarity index 96% rename from src/test/java/io/github/pgmarc/space/contracts/ContractsEndpointTest.java rename to src/test/java/io/github/pgmarc/space/ContractsEndpointTest.java index cce38df..61b8d1c 100644 --- a/src/test/java/io/github/pgmarc/space/contracts/ContractsEndpointTest.java +++ b/src/test/java/io/github/pgmarc/space/ContractsEndpointTest.java @@ -1,4 +1,4 @@ -package io.github.pgmarc.space.contracts; +package io.github.pgmarc.space; import java.io.IOException; import java.time.Duration; @@ -9,6 +9,10 @@ import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import io.github.pgmarc.space.contracts.Subscription; +import io.github.pgmarc.space.contracts.SubscriptionRequest; +import io.github.pgmarc.space.contracts.SubscriptionUpdateRequest; +import io.github.pgmarc.space.contracts.UserContact; import io.github.pgmarc.space.exceptions.SpaceApiException; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; diff --git a/src/test/java/io/github/pgmarc/space/SpaceClientTest.java b/src/test/java/io/github/pgmarc/space/SpaceClientTest.java new file mode 100644 index 0000000..30aa0c0 --- /dev/null +++ b/src/test/java/io/github/pgmarc/space/SpaceClientTest.java @@ -0,0 +1,96 @@ +package io.github.pgmarc.space; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.time.Duration; + +import org.junit.jupiter.api.Test; + +import okhttp3.HttpUrl; + +class SpaceClientTest { + + @Test + void givenRequiredParametersShouldCreateClient() { + + String host = "example.com"; + String apiKey = "prueba"; + + SpaceClient client = SpaceClient.builder(host, apiKey).build(); + + HttpUrl url = HttpUrl.parse("http://example.com:5403/api/v1"); + + assertThat(client).hasFieldOrPropertyWithValue("baseUrl", url); + } + + @Test + void givenOptionalParametersShouldCreate() { + + String host = "example.com"; + String alternativePath = "foo/bar"; + int port = 8080; + + Duration readTimeout = Duration.ofMillis(500); + Duration writeTimeout = Duration.ofMillis(1500); + + SpaceClient.Builder builder = SpaceClient.builder(host, "prueba") + .withPort(port) + .withPath(alternativePath) + .withReadTimeout(readTimeout) + .withWriteTimeout(writeTimeout); + + assertDoesNotThrow(builder::build); + + } + + @Test + void givenNullPathShouldCreateClient() { + + SpaceClient.Builder builder = SpaceClient.builder("example.com", "prueba"); + + assertDoesNotThrow(() -> builder.withPath(null)); + } + + @Test + void givenNullHostShouldThrow() { + + SpaceClient.Builder spaceClientBuilder = SpaceClient.builder(null, "prueba"); + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(spaceClientBuilder::build) + .withMessage("host must not be null"); + } + + @Test + void givenBlankHostShouldThrow() { + + SpaceClient.Builder spaceClientBuilder = SpaceClient.builder("", "preuba"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(spaceClientBuilder::build) + .withMessage("host must not be blank"); + } + + @Test + void givenNullApiKeyShouldThrow() { + + SpaceClient.Builder spaceClientBuilder = SpaceClient.builder("example.com", null); + + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(spaceClientBuilder::build) + .withMessage("api key must not be null"); + } + + @Test + void givenBlankApiKeyShouldThrow() { + + SpaceClient.Builder spaceClientBuilder = SpaceClient.builder("example.com", ""); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(spaceClientBuilder::build) + .withMessage("api key must not be blank"); + } + +}