Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.abacatepay.AbacatePay</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
Expand Down
69 changes: 37 additions & 32 deletions src/main/java/com/abacatepay/AbacatePay.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
package com.abacatepay;

import com.abacatepay.clients.AbacatePayClient;
import com.abacatepay.clients.factories.AbacatePayClientFactory;
import com.abacatepay.model.AbacatePayBilling;
import com.abacatepay.model.IAbacatePay;
import com.abacatepay.model.IAbacatePayBilling;
import com.abacatepay.model.billing.CreateBillingData;
import com.abacatepay.model.billing.CreateBillingResponse;
import com.abacatepay.model.billing.ListBillingResponse;
import feign.FeignException;
import feign.RequestInterceptor;

public class AbacatePay implements IAbacatePay {

private static final String API_BASE_URL = "https://api.abacatepay.com/v1";
private static final String SDK_NAME = "abacatepay-java-sdk";
private static final String SDK_VERSION = resolveVersion();

private final AbacatePayClient client;
private final String apiKey;
private final String userAgent;
private final IAbacatePayBilling billing;

public AbacatePay(String apiKey) {
this.apiKey = apiKey;
this.client = AbacatePayClientFactory.create(API_BASE_URL, requestInterceptor());
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalArgumentException("API key not provided");
}

//TODO: Pegar a versão do SDK dinamicamente
this.userAgent = "Java SDK (1.0.0)";
this.apiKey = apiKey;
this.userAgent = buildUserAgent();
this.billing = new AbacatePayBilling(
AbacatePayClientFactory.create(
API_BASE_URL,
requestInterceptor()
)
);
}

private RequestInterceptor requestInterceptor() {
return template -> {
if (apiKey == null || apiKey.isEmpty()) {
throw new IllegalArgumentException("API key not provided");
}

template.header("Authorization", "Bearer " + apiKey);
template.header("Content-Type", "application/json");
template.header("User-Agent", userAgent);
Expand All @@ -40,28 +41,32 @@ private RequestInterceptor requestInterceptor() {

@Override
public IAbacatePayBilling billing() {
return billing;
}

class AbacatePayBilling implements IAbacatePayBilling {
private static String resolveVersion() {
Package pkg = AbacatePay.class.getPackage();
String version = null;

@Override
public CreateBillingResponse create(CreateBillingData data) {
try {
return client.create(data);
} catch (IllegalArgumentException | FeignException e) {
return new CreateBillingResponse(e.getMessage());
}
}
if (pkg != null) {
version = pkg.getImplementationVersion();
}

@Override
public ListBillingResponse list() {
try {
return client.list();
} catch (IllegalArgumentException | FeignException e) {
return new ListBillingResponse(e.getMessage());
}
}
if (version == null || version.isBlank()) {
version = "dev";
}

return new AbacatePayBilling();
return version;
}

private static String buildUserAgent() {
return String.format(
"%s/%s Java/%s (%s %s)",
SDK_NAME,
SDK_VERSION,
System.getProperty("java.version"),
System.getProperty("os.name"),
System.getProperty("os.version")
);
}
}
34 changes: 34 additions & 0 deletions src/main/java/com/abacatepay/model/AbacatePayBilling.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.abacatepay.model;

import com.abacatepay.clients.AbacatePayClient;
import com.abacatepay.model.billing.CreateBillingData;
import com.abacatepay.model.billing.CreateBillingResponse;
import com.abacatepay.model.billing.ListBillingResponse;
import feign.FeignException;

public class AbacatePayBilling implements IAbacatePayBilling {

private final AbacatePayClient client;

public AbacatePayBilling(AbacatePayClient client) {
this.client = client;
}

@Override
public CreateBillingResponse create(CreateBillingData data) {
try {
return client.create(data);
} catch (IllegalArgumentException | FeignException e) {
return new CreateBillingResponse(e.getMessage());
}
}

@Override
public ListBillingResponse list() {
try {
return client.list();
} catch (IllegalArgumentException | FeignException e) {
return new ListBillingResponse(e.getMessage());
}
}
}
89 changes: 67 additions & 22 deletions src/test/java/com/abacatepay/AbacatePayTest.java
Original file line number Diff line number Diff line change
@@ -1,85 +1,130 @@
package com.abacatepay;

import com.abacatepay.clients.AbacatePayClient;
import com.abacatepay.model.AbacatePayBilling;
import com.abacatepay.model.IAbacatePayBilling;
import com.abacatepay.model.billing.CreateBillingData;
import com.abacatepay.model.billing.CreateBillingResponse;
import com.abacatepay.model.billing.ListBillingResponse;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import static org.mockito.Mockito.*;

class AbacatePayTest {

@Mock
private AbacatePayClient abacatePayClient;
private AbacatePayClient mockClient;

@InjectMocks
private AbacatePay abacatePay;

@BeforeEach
public void setUp() throws Exception {
void setUp() throws Exception {
MockitoAnnotations.openMocks(this);

abacatePay = new AbacatePay("apiKey");
setClientMock(abacatePay, abacatePayClient);

IAbacatePayBilling realBilling = new AbacatePayBilling(mockClient);

setClientMock(abacatePay, realBilling);
}

private void setClientMock(AbacatePay abacatePay, AbacatePayClient mockClient) throws Exception {
Field clientField = AbacatePay.class.getDeclaredField("client");
private void setClientMock(AbacatePay abacatePay, IAbacatePayBilling realBilling) throws Exception {
Field clientField = AbacatePay.class.getDeclaredField("billing");
clientField.setAccessible(true);
clientField.set(abacatePay, mockClient);
clientField.set(abacatePay, realBilling);
}

@Test
void shouldReturnCreateBillingResponseOnSuccess() {
CreateBillingData data = CreateBillingData.builder().build();
CreateBillingResponse expectedResponse = new CreateBillingResponse();

when(abacatePayClient.create(data)).thenReturn(expectedResponse);
when(mockClient.create(data)).thenReturn(expectedResponse);

CreateBillingResponse result = abacatePay.billing().create(data);
verify(abacatePayClient, atMostOnce()).create(data);

verify(mockClient, atMostOnce()).create(data);
Assertions.assertEquals(expectedResponse, result, "Should return the expected response");
}

@Test
void shouldCreateBillingThrowsAnException() {
void shouldCreateBillingReturnErrorResponseWhenClientFails() {
CreateBillingData data = CreateBillingData.builder().build();
CreateBillingResponse expectedResponse = new CreateBillingResponse("API key not provided");
String errorMessage = "Internal Server Error";

when(abacatePayClient.create(data)).thenThrow(new IllegalArgumentException("API key not provided"));
when(mockClient.create(data)).thenThrow(new IllegalArgumentException(errorMessage));

CreateBillingResponse result = abacatePay.billing().create(data);
verify(abacatePayClient, atMostOnce()).create(data);
Assertions.assertEquals(expectedResponse, result, "Should return the expected response");

verify(mockClient, atMostOnce()).create(data);
Assertions.assertNotNull(result, "Should not return null");
Assertions.assertEquals(errorMessage, result.getError());
}

@Test
void shouldReturnBillingListResponseOnSucess() {
ListBillingResponse expectedResponse = new ListBillingResponse();

when(abacatePayClient.list()).thenReturn(expectedResponse);
when(mockClient.list()).thenReturn(expectedResponse);

ListBillingResponse result = abacatePay.billing().list();
verify(abacatePayClient, atMostOnce()).list();
verify(mockClient, atMostOnce()).list();
Assertions.assertEquals(expectedResponse, result, "Should return the expected response");
}

@Test
void shouldListBillingThrowsAnException() {
ListBillingResponse expectedResponse = new ListBillingResponse("API key not provided");
void shouldListBillingReturnErrorResponseWhenClientFails() {
String errorMessage = "Internal Server Error";

when(abacatePayClient.list()).thenThrow(new IllegalArgumentException("API key not provided"));
when(mockClient.list()).thenThrow(new IllegalArgumentException(errorMessage));

ListBillingResponse result = abacatePay.billing().list();
verify(abacatePayClient, atMostOnce()).list();
Assertions.assertEquals(expectedResponse, result, "Should return the expected response");

verify(mockClient, atMostOnce()).list();
Assertions.assertNotNull(result, "Should not return null");
Assertions.assertEquals(errorMessage, result.getError());
}

@Test
void shouldThrowExceptionWhenApiKeyIsMissing() {
IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
new AbacatePay("");
});

Assertions.assertEquals("API key not provided", exception.getMessage());
}

@Test
void testResolveVersionDirectly() throws Exception {
Method method = AbacatePay.class.getDeclaredMethod("resolveVersion");
method.setAccessible(true);

String version = (String) method.invoke(null);

Assertions.assertNotNull(version);
Assertions.assertEquals("dev", version, "local environment should return 'dev' as version");
}

@Test
void testBuildUserAgentDirectly() throws Exception {
Method method = AbacatePay.class.getDeclaredMethod("buildUserAgent");
method.setAccessible(true);

String userAgent = (String) method.invoke(null);

String currentJava = System.getProperty("java.version");
String currentOs = System.getProperty("os.name");

Assertions.assertNotNull(userAgent);
Assertions.assertTrue(userAgent.startsWith("abacatepay-java-sdk/"), "Should start with the SDK name");
Assertions.assertTrue(userAgent.contains("Java/" + currentJava), "Should contain the Java tag version");
Assertions.assertTrue(userAgent.contains(currentOs), "Should contain the OS name");
}
}
Loading