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
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ public void testFileUpload() throws ApiException, IOException {
String imgPath = Paths.get(System.getProperty("user.dir").toString(), "src/test/resources/square.png")
.toString();
File imageFile = new File(imgPath);

// Skip test if test image is not available
org.junit.Assume.assumeTrue("Test image file not found: " + imgPath, imageFile.exists());

CreateCatalogImageResponse result = api.createCatalogImage(request, new FileWrapper(imageFile, "image/jpeg"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

import com.squareup.square.legacy.SquareClient;
import com.squareup.square.legacy.exceptions.ApiException;
import com.squareup.square.legacy.models.ListLocationsResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class LocationsApiTest extends BaseApiTest {

private static final int MAX_RETRIES = 5;
private static final long INITIAL_RETRY_DELAY_MS = 2000;

/**
* Client instance.
*/
Expand Down Expand Up @@ -38,6 +42,58 @@ public static void tearDownClass() {
controller = null;
}

private interface ApiCall<T> {
T execute() throws ApiException;
}

private <T> T withRetry(ApiCall<T> apiCall) throws ApiException {
ApiException lastException = null;

for (int attempt = 0; attempt < MAX_RETRIES; attempt++) {
try {
if (attempt > 0) {
// Calculate exponential backoff delay
long delayMs = INITIAL_RETRY_DELAY_MS * (long) Math.pow(2, attempt - 1);
System.out.printf("Retry attempt %d after %d ms delay%n", attempt + 1, delayMs);
Thread.sleep(delayMs);
}

return apiCall.execute();

} catch (ApiException e) {
lastException = e;

// Check if it's a rate limit error
if (e.getMessage() != null &&
(e.getMessage().contains("RATE_LIMITED") ||
e.getMessage().contains("rate limit"))) {
System.out.printf("Rate limited on attempt %d%n", attempt + 1);
continue;
}

// For authentication errors, throw immediately
if (e.getMessage() != null &&
(e.getMessage().contains("UNAUTHORIZED") ||
e.getMessage().contains("UNAUTHENTICATED"))) {
throw e;
}

// For other errors, retry
System.out.printf("API error on attempt %d: %s%n", attempt + 1, e.getMessage());

if (attempt == MAX_RETRIES - 1) {
throw e;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted during retry delay", e);
}
}

// If we've exhausted all retries, throw the last exception
throw lastException;
}

/**
* Provides details about all of the seller's
* [locations](https://developer.squareup.com/docs/locations-api), including those with an
Expand All @@ -46,17 +102,29 @@ public static void tearDownClass() {
*/
@Test
public void testListLocations() throws Exception {

// Set callback and perform API call
try {
controller.listLocations();
ListLocationsResponse response = withRetry(() -> {
System.out.println("Attempting to list locations...");
return controller.listLocations();
});

// Test whether the response is null
assertNotNull("Response is null", response);
assertNotNull("Response context is null", response.getContext());
assertNotNull("Response context response is null", response.getContext().getResponse());

// Test response code
int statusCode = response.getContext().getResponse().getStatusCode();
assertEquals("Status is not 200", 200, statusCode);

} catch (ApiException e) {
// Empty block
System.err.println("API Exception occurred: " + e.getMessage());
if (e.getMessage() != null &&
(e.getMessage().contains("UNAUTHORIZED") ||
e.getMessage().contains("UNAUTHENTICATED"))) {
System.err.println("Authentication error - check your credentials");
}
throw e;
}

// Test whether the response is null
assertNotNull("Response is null", httpResponse.getResponse());
// Test response code
assertEquals("Status is not 200", 200, httpResponse.getResponse().getStatusCode());
}
}
}
150 changes: 113 additions & 37 deletions src/test/java/com/squareup/square/integration/CustomerGroupsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

public final class CustomerGroupsTest {

private static final int MAX_RETRIES = 5;
private static final long INITIAL_RETRY_DELAY_MS = 2000;
private static final long DELAY_BETWEEN_OPERATIONS_MS = 2000;

private SquareClient client;
private String groupId;

Expand All @@ -32,78 +36,150 @@ public void before() {

@AfterEach
public void deleteTestCustomerGroup() {
client.customers()
.groups()
.delete(DeleteGroupsRequest.builder().groupId(groupId).build());
try {
// Add delay before cleanup
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);
withRetry(() -> client.customers()
.groups()
.delete(DeleteGroupsRequest.builder().groupId(groupId).build()));
} catch (Exception e) {
System.out.println("Warning: Failed to delete test customer group: " + e.getMessage());
}
}

@Test
public void testCreateAndListCustomerGroup() {
SyncPagingIterable<CustomerGroup> response = client.customers().groups().list();
public void testCreateAndListCustomerGroup() throws InterruptedException {
// Add delay before test
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);

SyncPagingIterable<CustomerGroup> response = withRetry(() ->
client.customers().groups().list());

Assertions.assertNotNull(response);
List<CustomerGroup> groups = response.getItems();
Assertions.assertFalse(groups.isEmpty());
}

@Test
public void testRetrieveCustomerGroup() {
GetCustomerGroupResponse response = client.customers()
.groups()
.get(GetGroupsRequest.builder().groupId(groupId).build());
public void testRetrieveCustomerGroup() throws InterruptedException {
// Add delay before test
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);

GetCustomerGroupResponse response = withRetry(() ->
client.customers()
.groups()
.get(GetGroupsRequest.builder().groupId(groupId).build()));

Assertions.assertTrue(response.getGroup().isPresent());
Assertions.assertEquals(groupId, response.getGroup().get().getId().get());
}

@Test
public void testUpdateCustomerGroup() {
public void testUpdateCustomerGroup() throws InterruptedException {
// Add delay before test
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);

String newName = "Updated-" + UUID.randomUUID();
UpdateCustomerGroupResponse response = client.customers()
.groups()
.update(UpdateCustomerGroupRequest.builder()
.groupId(groupId)
.group(CustomerGroup.builder().name(newName).build())
.build());
UpdateCustomerGroupResponse response = withRetry(() ->
client.customers()
.groups()
.update(UpdateCustomerGroupRequest.builder()
.groupId(groupId)
.group(CustomerGroup.builder().name(newName).build())
.build()));

Assertions.assertTrue(response.getGroup().isPresent());
Assertions.assertEquals(newName, response.getGroup().get().getName());
}

@Test
public void testRetrieveNonExistentGroup() {
public void testRetrieveNonExistentGroup() throws InterruptedException {
// Add delay before test
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);

Assertions.assertThrows(SquareApiException.class, () -> {
client.customers()
.groups()
.get(GetGroupsRequest.builder().groupId("not existent id").build());
withRetry(() ->
client.customers()
.groups()
.get(GetGroupsRequest.builder().groupId("not existent id").build()));
});
}

@Test
public void testCreateGroupWithInvalidData() {
public void testCreateGroupWithInvalidData() throws InterruptedException {
// Add delay before test
Thread.sleep(DELAY_BETWEEN_OPERATIONS_MS);

Assertions.assertThrows(SquareApiException.class, () -> {
withRetry(() ->
client.customers()
.groups()
.create(CreateCustomerGroupRequest.builder()
.group(CustomerGroup.builder()
// Empty name should be invalid
.name("")
.build())
.idempotencyKey(UUID.randomUUID().toString())
.build()));
});
}

private String createTestCustomerGroup() {
CreateCustomerGroupResponse response = withRetry(() ->
client.customers()
.groups()
.create(CreateCustomerGroupRequest.builder()
.group(CustomerGroup.builder()
// Empty name should be invalid
.name("")
.name("Default-" + UUID.randomUUID())
.build())
.idempotencyKey(UUID.randomUUID().toString())
.build());
});
}

private String createTestCustomerGroup() {
CreateCustomerGroupResponse response = client.customers()
.groups()
.create(CreateCustomerGroupRequest.builder()
.group(CustomerGroup.builder()
.name("Default-" + UUID.randomUUID())
.build())
.idempotencyKey(UUID.randomUUID().toString())
.build());
.build()));

Optional<CustomerGroup> group = response.getGroup();
if (!group.isPresent()) {
throw new RuntimeException("Failed to create test customer group.");
}
return group.get().getId().get();
}
}

private interface ApiCall<T> {
T execute() throws SquareApiException;
}

private <T> T withRetry(ApiCall<T> apiCall) {
int attempt = 0;
SquareApiException lastException = null;

while (attempt < MAX_RETRIES) {
try {
if (attempt > 0) {
// Calculate exponential backoff delay
long delayMs = INITIAL_RETRY_DELAY_MS * (long) Math.pow(2, attempt - 1);
System.out.printf("Retry attempt %d after %d ms delay%n", attempt + 1, delayMs);
Thread.sleep(delayMs);
}

return apiCall.execute();

} catch (SquareApiException e) {
lastException = e;

// Check if it's a rate limit error
if (e.statusCode() == 429) {
System.out.printf("Rate limited on attempt %d%n", attempt + 1);
attempt++;
continue;
}

// For other API errors, throw immediately
throw e;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted during retry delay", e);
}
}

// If we've exhausted all retries, throw the last exception
throw lastException;
}
}
Loading
Loading