Skip to content

Commit

Permalink
Added Async to Beancoins Endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
beanbeanjuice committed Jun 24, 2024
1 parent 4fae2f0 commit e997786
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
import com.beanbeanjuice.cafeapi.wrapper.CafeAPI;
import com.beanbeanjuice.cafeapi.wrapper.endpoints.CafeEndpoint;
import com.beanbeanjuice.cafeapi.wrapper.generic.CafeGeneric;
import com.beanbeanjuice.cafeapi.wrapper.requests.Request;
import com.beanbeanjuice.cafeapi.wrapper.requests.RequestBuilder;
import com.beanbeanjuice.cafeapi.wrapper.requests.RequestRoute;
import com.beanbeanjuice.cafeapi.wrapper.requests.RequestType;
import com.beanbeanjuice.cafeapi.wrapper.exception.api.*;
import com.fasterxml.jackson.databind.JsonNode;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

/**
* A class used to make {@link DonationUsersEndpoint} requests to the {@link CafeAPI CafeAPI}.
Expand All @@ -21,85 +20,62 @@
*/
public class DonationUsersEndpoint extends CafeEndpoint {

/**
* Retrieves all {@link Timestamp} from the {@link CafeAPI CafeAPI} containing when a specified {@link String userID} can be donated to again.
* @return A {@link HashMap} with keys of {@link String userID} and values of {@link Timestamp timeUntilNextDonation}.
* @throws AuthorizationException Thrown when the {@link String apiKey} is invalid.
* @throws ResponseException Thrown when there is a generic server-side {@link CafeException}.
*/
public HashMap<String, Timestamp> getAllUserDonationTimes()
throws AuthorizationException, ResponseException {
HashMap<String, Timestamp> donationUsers = new HashMap<>();

Request request = RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.GET)
public CompletableFuture<HashMap<String, Timestamp>> getAllUserDonationTimes() {
return RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.GET)
.setRoute("/beanCoin/donation_users")
.setAuthorization(apiKey)
.build().orElseThrow();
.buildAsync()
.thenApply((optionalRequest) -> {
HashMap<String, Timestamp> donationUsers = new HashMap<>();

if (optionalRequest.isEmpty()) throw new CompletionException("Unable to get donation user times. Request is empty.", null);

for (JsonNode user : request.getData().get("users")) {
String userID = user.get("user_id").asText();
Timestamp timeUntilNextDonation = CafeGeneric.parseTimestampFromAPI(user.get("time_until_next_donation").asText()).orElse(null);
optionalRequest.get().getData().get("users").forEach((userNode) -> {
String userID = userNode.get("user_id").asText();
Timestamp timeUntilNextDonation = CafeGeneric.parseTimestampFromAPI(userNode.get("time_until_next_donation").asText()).orElse(null);

donationUsers.put(userID, timeUntilNextDonation);
}
donationUsers.put(userID, timeUntilNextDonation);
});

return donationUsers;
return donationUsers;
});
}

/**
* Retrieves the {@link Timestamp timeUntilNextDonation} for a specified {@link String userID}.
* @param userID The specified {@link String userID}.
* @return The {@link Timestamp timeUntilNextDonation} for the specified {@link String userID}.
* @throws AuthorizationException Thrown when the {@link String apiKey} is invalid.
* @throws ResponseException Thrown when there is a generic server-side {@link CafeException}.
* @throws NotFoundException Thrown when the {@link Timestamp timeUntilNextDonation} does not exist for the specified {@link String userID}.
*/
public Optional<Timestamp> getUserDonationTime(final String userID)
throws AuthorizationException, ResponseException, NotFoundException {
Request request = RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.GET)
public CompletableFuture<Optional<Timestamp>> getUserDonationTime(final String userID) {
return RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.GET)
.setRoute("/beanCoin/donation_users/" + userID)
.setAuthorization(apiKey)
.build().orElseThrow();
.buildAsync()
.thenApply((optionalRequest) -> {
if (optionalRequest.isEmpty()) throw new CompletionException("Unable to get user donation time. Request is empty.", null);

return CafeGeneric.parseTimestampFromAPI(request.getData().get("user").get("time_until_next_donation").asText());
return CafeGeneric.parseTimestampFromAPI(optionalRequest.get().getData().get("user").get("time_until_next_donation").asText());
});
}

/**
* Creates a new {@link Timestamp timeUntilNextDonation} for a specified {@link String userID}.
* @param userID The specified {@link String userID}.
* @param timeUntilNextDonation The new {@link Timestamp timeUntilNextDonation}.
* @return True, if the {@link Timestamp timeUntilNextDonation} was successfully created in the {@link CafeAPI CafeAPI}.
* @throws AuthorizationException Thrown when the {@link String apiKey} is invalid.
* @throws ResponseException Thrown when there is a generic server-side {@link CafeException}.
* @throws ConflictException Thrown when the {@link Timestamp timeUntilNextDonation} already exists for the specified {@link String userID}.
* @throws UndefinedVariableException Thrown when a variable is undefined.
*/
public Boolean addDonationUser(final String userID, final Timestamp timeUntilNextDonation)
throws AuthorizationException, ResponseException, ConflictException, UndefinedVariableException {
Request request = RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.POST)
public CompletableFuture<Boolean> addDonationUser(final String userID, final Timestamp timeUntilNextDonation) {
return RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.POST)
.setRoute("/beanCoin/donation_users/" + userID)
.addParameter("time_stamp", timeUntilNextDonation.toString())
.setAuthorization(apiKey)
.build().orElseThrow();
.buildAsync()
.thenApply((optionalRequest) -> {
if (optionalRequest.isEmpty()) throw new CompletionException("Unable to add donation user. Request is empty.", null);

return request.getStatusCode() == 201;
return optionalRequest.get().getStatusCode() == 201;
});
}

/**
* Deletes a {@link Timestamp timeUntilNextDonation} for a specified {@link String userID}.
* @param userID The specified {@link String userID}.
* @return True, if the {@link Timestamp timeUntilNextDonation} was successfully deleted for the specified {@link String userID}.
* @throws AuthorizationException Thrown when the {@link String apiKey} is invalid.
* @throws ResponseException Thrown when there is a generic server-side {@link CafeException}.
*/
public Boolean deleteDonationUser(final String userID)
throws AuthorizationException, ResponseException {
Request request = RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.DELETE)
public CompletableFuture<Boolean> deleteDonationUser(final String userID) {
return RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.DELETE)
.setRoute("/beanCoin/donation_users/" + userID)
.setAuthorization(apiKey)
.build().orElseThrow();
.buildAsync()
.thenApply((optionalRequest) -> {
if (optionalRequest.isEmpty()) throw new CompletionException("Unable to delete donation user. Request is empty.", null);

return request.getStatusCode() == 200;
return optionalRequest.get().getStatusCode() == 200;
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public CompletableFuture<HashMap<String, Birthday>> getAllBirthdays() throws Aut
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return requestToBirthdayMap(optionalRequest.get());
throw new CompletionException("Error getting all birthdays. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error getting all birthdays. Request is empty.", null);
return requestToBirthdayMap(optionalRequest.get());
});
}

Expand All @@ -60,8 +60,8 @@ public CompletableFuture<Optional<Birthday>> getUserBirthday(final String userID
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return parseBirthday(optionalRequest.get().getData().get("birthday"));
throw new CompletionException("Error getting user birthday. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error getting user birthday. Request is empty.", null);
return parseBirthday(optionalRequest.get().getData().get("birthday"));
});
}

Expand All @@ -82,8 +82,8 @@ public CompletableFuture<Boolean> updateUserBirthday(final String userID, final
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return optionalRequest.get().getStatusCode() == 200;
throw new CompletionException("Error updating user birthday. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error updating user birthday. Request is empty.", null);
return optionalRequest.get().getStatusCode() == 200;
});
}

Expand All @@ -100,8 +100,8 @@ public CompletableFuture<Boolean> updateUserBirthdayMention(final String userID,
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return optionalRequest.get().getStatusCode() == 200;
throw new CompletionException("Error updating user mention. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error updating user mention. Request is empty.", null);
return optionalRequest.get().getStatusCode() == 200;
});
}

Expand All @@ -122,32 +122,22 @@ public CompletableFuture<Boolean> createUserBirthday(final String userID, final
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return optionalRequest.get().getStatusCode() == 201;
throw new CompletionException("Error creating user birthday. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error creating user birthday. Request is empty.", null);
return optionalRequest.get().getStatusCode() == 201;
});
}

/**
* Removes a {@link Birthday} for a specified {@link String userID}.
* @param userID The specified {@link String userID}.
* @return True, if the {@link Birthday} has been successfully removed from the {@link CafeAPI CafeAPI}.
*/
public CompletableFuture<Boolean> removeUserBirthday(final String userID) {
return RequestBuilder.create(RequestRoute.CAFEBOT, RequestType.DELETE)
.setRoute("/birthdays/" + userID)
.setAuthorization(apiKey)
.buildAsync()
.thenApplyAsync((optionalRequest) -> {
if (optionalRequest.isPresent()) return optionalRequest.get().getStatusCode() == 200;
throw new CompletionException("Error removing user birthday. Request is empty.", null);
if (optionalRequest.isEmpty()) throw new CompletionException("Error removing user birthday. Request is empty.", null);
return optionalRequest.get().getStatusCode() == 200;
});
}

/**
* Parses a {@link Birthday} from a {@link JsonNode}.
* @param birthday The {@link JsonNode} to parse.
* @return The parsed {@link Birthday}.
*/
private Optional<Birthday> parseBirthday(final JsonNode birthday) {
String unformattedDate = birthday.get("birth_date").asText();
String timeZoneString = birthday.get("time_zone").asText();
Expand All @@ -166,11 +156,6 @@ private Optional<Birthday> parseBirthday(final JsonNode birthday) {
}
}

/**
* Retrieves the {@link BirthdayMonth} from the {@link Integer index}.
* @param index The {@link Integer index} of the month. January is 0.
* @return The {@link BirthdayMonth} from the {@link Integer index}.
*/
private BirthdayMonth getBirthdayMonth(final int index) {
for (BirthdayMonth month : BirthdayMonth.values()) {
if (month.getMonthNumber() == index)
Expand All @@ -180,22 +165,11 @@ private BirthdayMonth getBirthdayMonth(final int index) {
return BirthdayMonth.ERROR;
}

/**
* Parses a number and adds a 0 to the {@link String}.
* @param number The {@link Integer number} to parse.
* @return The parsed {@link String number}. Double-digit numbers don't have a 0 added.
*/
private String parseNumber(final int number) { // TODO: There MUST be a better way to do this.
if (number <= 9) return "0" + number;
return String.valueOf(number);
}

/**
* Gets the birthday {@link String} to send to the {@link CafeAPI CafeAPI}.
* @param month The {@link BirthdayMonth montH} of the {@link Birthday}.
* @param day The {@link Integer day} in the {@link BirthdayMonth month} of the {@link Birthday}.
* @return The birthday {@link String} to send to the {@link CafeAPI CafeAPI}.
*/
private String getBirthdayString(final BirthdayMonth month, final int day) {
return parseNumber(month.getMonthNumber()) + "-" + parseNumber(day);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.util.Optional;
import java.util.concurrent.ExecutionException;

public class BirthdayTest {
public class BirthdaysEndpointTests {

@Test
@DisplayName("Birthdays Endpoint Test")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.beanbeanjuice.cafeapi.beta;

import com.beanbeanjuice.cafeapi.wrapper.CafeAPI;
import com.beanbeanjuice.cafeapi.wrapper.exception.api.ConflictException;
import com.beanbeanjuice.cafeapi.wrapper.exception.api.NotFoundException;
import com.beanbeanjuice.cafeapi.wrapper.generic.CafeGeneric;
import com.beanbeanjuice.cafeapi.wrapper.requests.RequestLocation;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.sql.Timestamp;
import java.util.concurrent.ExecutionException;

public class DonationUsersEndpointTests {

@Test
@DisplayName("Donation Users Endpoint Test")
public void testDonationUsersEndpoint() throws ExecutionException, InterruptedException {
CafeAPI cafeAPI = new CafeAPI("beanbeanjuice", System.getenv("API_PASSWORD"), RequestLocation.BETA);

Assertions.assertTrue(cafeAPI.getDonationUsersEndpoint().deleteDonationUser("738590591767543921").get());

try {
cafeAPI.getDonationUsersEndpoint().getUserDonationTime("738590591767543921").get();
Assertions.fail();
} catch (Exception e) {
Assertions.assertInstanceOf(NotFoundException.class, e.getCause());
}

Timestamp currentTimestamp = CafeGeneric.parseTimestamp((new Timestamp(System.currentTimeMillis())).toString()).orElse(null);
Assertions.assertTrue(cafeAPI.getDonationUsersEndpoint().addDonationUser("738590591767543921", currentTimestamp).get());

try {
cafeAPI.getDonationUsersEndpoint().addDonationUser("738590591767543921", currentTimestamp).get();
Assertions.fail();
} catch (Exception e) {
Assertions.assertInstanceOf(ConflictException.class, e.getCause());
}
Assertions.assertEquals(currentTimestamp, cafeAPI.getDonationUsersEndpoint().getAllUserDonationTimes().get().get("738590591767543921"));
Assertions.assertEquals(currentTimestamp, cafeAPI.getDonationUsersEndpoint().getUserDonationTime("738590591767543921").get().orElse(null));

Assertions.assertTrue(cafeAPI.getDonationUsersEndpoint().deleteDonationUser("738590591767543921").get());

try {
cafeAPI.getDonationUsersEndpoint().getUserDonationTime("738590591767543921").get();
Assertions.fail();
} catch (Exception e) {
Assertions.assertInstanceOf(NotFoundException.class, e.getCause());
}
}

}

0 comments on commit e997786

Please sign in to comment.