diff --git a/src/main/java/io/mymetavese/metaapi/MetaAPIImpl.java b/src/main/java/io/mymetavese/metaapi/MetaAPIImpl.java
index 7ee0c54..c703639 100644
--- a/src/main/java/io/mymetavese/metaapi/MetaAPIImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/MetaAPIImpl.java
@@ -1,9 +1,11 @@
package io.mymetavese.metaapi;
import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.entities.drops.wrapper.MetaDropsWrapper;
import io.mymetavese.metaapi.api.entities.v2.GameEntity;
import io.mymetavese.metaapi.requests.RequestGenerator;
import io.mymetavese.metaapi.requests.entities.GameEntityImpl;
+import io.mymetavese.metaapi.requests.entities.drops.wrapper.MetaDropsWrapperImpl;
import io.mymetavese.metaapi.requests.routes.RouteAdapter;
import io.mymetavese.metaapi.requests.routes.V2;
import io.mymetavese.metaapi.requests.token.TokenHandler;
@@ -49,8 +51,24 @@ public MetaAPIImpl(TokenHandler tokenHandler, @Nullable RouteAdapter routeAdapte
this.routeAdapter = routeAdapter;
}
+ /**
+ * Build a new player ready to execute actions...
+ *
+ * @param playerID The player ID that the player should use.
+ * @return A {@link GameEntity} object with their possible actions.
+ */
public GameEntity buildPlayer(String playerID) {
return new GameEntityImpl(this, playerID);
}
+ /**
+ * Get an instance of a {@link MetaDropsWrapper} object.
+ *
+ * Allows to get access to the MetaDrops API.
+ * @return A {@link MetaDropsWrapper} object.
+ */
+ public MetaDropsWrapper getDropsWrapper() {
+ return new MetaDropsWrapperImpl(this);
+ }
+
}
diff --git a/src/main/java/io/mymetavese/metaapi/api/MetaAPI.java b/src/main/java/io/mymetavese/metaapi/api/MetaAPI.java
index 471b622..7fcaee2 100644
--- a/src/main/java/io/mymetavese/metaapi/api/MetaAPI.java
+++ b/src/main/java/io/mymetavese/metaapi/api/MetaAPI.java
@@ -1,6 +1,7 @@
package io.mymetavese.metaapi.api;
import io.mymetavese.metaapi.MetaAPIImpl;
+import io.mymetavese.metaapi.api.entities.drops.wrapper.MetaDropsWrapper;
import io.mymetavese.metaapi.api.entities.v2.GameEntity;
import io.mymetavese.metaapi.requests.routes.RouteAdapter;
import io.mymetavese.metaapi.requests.routes.V2;
@@ -9,13 +10,21 @@
public interface MetaAPI {
/**
- * Build a new player ready to execute actions..
+ * Build a new player ready to execute actions...
*
* @param playerID The player ID that the player should use.
- * @return A player with their possible actions.
+ * @return A {@link GameEntity} object with their possible actions.
*/
GameEntity buildPlayer(String playerID);
+ /**
+ * Get an instance of a {@link MetaDropsWrapper} object.
+ *
+ * Allows to get access to the MetaDrops API.
+ * @return A {@link MetaDropsWrapper} object.
+ */
+ MetaDropsWrapper getDropsWrapper();
+
final class Builder {
private TokenHandler tokenHandler;
diff --git a/src/main/java/io/mymetavese/metaapi/api/actions/drops/ConsumeDropAction.java b/src/main/java/io/mymetavese/metaapi/api/actions/drops/ConsumeDropAction.java
new file mode 100644
index 0000000..b20bcf1
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/actions/drops/ConsumeDropAction.java
@@ -0,0 +1,8 @@
+package io.mymetavese.metaapi.api.actions.drops;
+
+import io.mymetavese.metaapi.api.RestAction;
+import io.mymetavese.metaapi.api.entities.drops.responses.DropConsumedResponse;
+
+public interface ConsumeDropAction extends RestAction {
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetAllDropsAction.java b/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetAllDropsAction.java
new file mode 100644
index 0000000..e4e8e33
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetAllDropsAction.java
@@ -0,0 +1,10 @@
+package io.mymetavese.metaapi.api.actions.drops;
+
+import io.mymetavese.metaapi.api.RestAction;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+
+import java.util.List;
+
+public interface GetAllDropsAction extends RestAction> {
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetDropAction.java b/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetDropAction.java
new file mode 100644
index 0000000..5086a81
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/actions/drops/GetDropAction.java
@@ -0,0 +1,8 @@
+package io.mymetavese.metaapi.api.actions.drops;
+
+import io.mymetavese.metaapi.api.RestAction;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+
+public interface GetDropAction extends RestAction {
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/MetaDrop.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/MetaDrop.java
new file mode 100644
index 0000000..12f2032
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/MetaDrop.java
@@ -0,0 +1,24 @@
+package io.mymetavese.metaapi.api.entities.drops;
+
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.entities.drops.crates.DropCrateImpl;
+
+import java.util.List;
+
+public interface MetaDrop {
+
+ String getId();
+ String getName();
+ String getDescription();
+ String getSlug();
+ String getCreatorId();
+
+ List getConstraints();
+
+ List getCrates();
+
+ List getEntryRequirements();
+
+}
+
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/DropConstraint.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/DropConstraint.java
new file mode 100644
index 0000000..7d87229
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/DropConstraint.java
@@ -0,0 +1,9 @@
+package io.mymetavese.metaapi.api.entities.drops.constraints;
+
+import com.google.gson.JsonElement;
+
+public interface DropConstraint {
+
+ JsonElement toJsonElement();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/LimitedConsumptionDropConstraint.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/LimitedConsumptionDropConstraint.java
new file mode 100644
index 0000000..aff55ef
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/constraints/LimitedConsumptionDropConstraint.java
@@ -0,0 +1,7 @@
+package io.mymetavese.metaapi.api.entities.drops.constraints;
+
+public interface LimitedConsumptionDropConstraint extends DropConstraint {
+
+ int getMaxConsumptionPerUser();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrate.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrate.java
new file mode 100644
index 0000000..0c9aaac
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrate.java
@@ -0,0 +1,52 @@
+package io.mymetavese.metaapi.api.entities.drops.crates;
+
+import io.mymetavese.metaapi.requests.entities.drops.crates.DropCrateItemImpl;
+
+import java.util.List;
+
+public interface DropCrate {
+
+ /**
+ * Obtain the ID of the crate
+ * @return The ID of the crate
+ */
+ String getId();
+
+ /**
+ * Obtain the name of the crate
+ * @return The name of the crate
+ */
+ String getName();
+
+ /**
+ * Get the total supply for this crate
+ *
+ * Get the total number of tokens that will be distributed in this crate.
+ * @return The total supply of tokens in this crate
+ */
+ int getTotalSupply();
+
+ /**
+ * Get the number of tokens available in this crate
+ *
+ * Get the number of tokens that are still available in this crate.
+ * @return The number of tokens available in this crate
+ */
+ int getAvailableSupply();
+
+ /**
+ * Get the tokens available in this crate
+ *
+ * Get the tokens (its Ids and Indexes) available in this crate.
+ *
+ * @return The tokens available in this crate
+ */
+ List getTokensInCrate();
+
+ /**
+ * Get the type of this crate
+ * @return The type of this crate
+ */
+ DropCrateType getType();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateItem.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateItem.java
new file mode 100644
index 0000000..e555a40
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateItem.java
@@ -0,0 +1,6 @@
+package io.mymetavese.metaapi.api.entities.drops.crates;
+
+import io.mymetavese.metaapi.api.entities.Item;
+
+public interface DropCrateItem extends Item {
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateType.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateType.java
new file mode 100644
index 0000000..60b9811
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/crates/DropCrateType.java
@@ -0,0 +1,7 @@
+package io.mymetavese.metaapi.api.entities.drops.crates;
+
+public interface DropCrateType {
+
+ boolean isPerIndex();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/DropEntryRequirement.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/DropEntryRequirement.java
new file mode 100644
index 0000000..a3f5c52
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/DropEntryRequirement.java
@@ -0,0 +1,9 @@
+package io.mymetavese.metaapi.api.entities.drops.requirements;
+
+import com.google.gson.JsonElement;
+
+public interface DropEntryRequirement {
+
+ JsonElement toJsonElement();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/ReusableCodeDropEntryRequirement.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/ReusableCodeDropEntryRequirement.java
new file mode 100644
index 0000000..a661b12
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/ReusableCodeDropEntryRequirement.java
@@ -0,0 +1,7 @@
+package io.mymetavese.metaapi.api.entities.drops.requirements;
+
+public interface ReusableCodeDropEntryRequirement extends DropEntryRequirement {
+
+ String getReusableCode();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/SingleCodeDropEntryRequirement.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/SingleCodeDropEntryRequirement.java
new file mode 100644
index 0000000..eee1162
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/requirements/SingleCodeDropEntryRequirement.java
@@ -0,0 +1,7 @@
+package io.mymetavese.metaapi.api.entities.drops.requirements;
+
+public interface SingleCodeDropEntryRequirement extends DropEntryRequirement {
+
+ String getSingleCode();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/responses/DropConsumedResponse.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/responses/DropConsumedResponse.java
new file mode 100644
index 0000000..17f28cc
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/responses/DropConsumedResponse.java
@@ -0,0 +1,9 @@
+package io.mymetavese.metaapi.api.entities.drops.responses;
+
+public interface DropConsumedResponse {
+
+ String getDropId();
+
+ String getCrateId();
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/drops/wrapper/MetaDropsWrapper.java b/src/main/java/io/mymetavese/metaapi/api/entities/drops/wrapper/MetaDropsWrapper.java
new file mode 100644
index 0000000..344ea36
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/drops/wrapper/MetaDropsWrapper.java
@@ -0,0 +1,21 @@
+package io.mymetavese.metaapi.api.entities.drops.wrapper;
+
+import io.mymetavese.metaapi.api.ApiEntity;
+import io.mymetavese.metaapi.api.actions.drops.ConsumeDropAction;
+import io.mymetavese.metaapi.api.actions.drops.GetAllDropsAction;
+import io.mymetavese.metaapi.api.actions.drops.GetDropAction;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.api.entities.v2.GameEntity;
+
+import java.util.List;
+
+public interface MetaDropsWrapper extends ApiEntity {
+
+ GetAllDropsAction getAllDrops();
+
+ GetDropAction getDropById(String dropId);
+
+ ConsumeDropAction consumeDrop(String dropId, GameEntity dropReceiver, List dropEntryRequirements);
+
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java
new file mode 100644
index 0000000..e6a0995
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java
@@ -0,0 +1,74 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.actions.drops.ConsumeDropAction;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.api.entities.drops.responses.DropConsumedResponse;
+import io.mymetavese.metaapi.api.entities.v2.GameEntity;
+import io.mymetavese.metaapi.requests.JsonObject;
+import io.mymetavese.metaapi.requests.RestActionImpl;
+import io.mymetavese.metaapi.requests.entities.drops.responses.DropConsumedResponseImpl;
+import io.mymetavese.metaapi.requests.routes.Routes;
+import okhttp3.Response;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.List;
+import java.util.Objects;
+
+public class ConsumeDropActionImpl extends RestActionImpl implements ConsumeDropAction {
+
+ private final String dropId;
+ private final GameEntity dropReceiver;
+ private final List dropEntryRequirements;
+
+ public ConsumeDropActionImpl(MetaAPI api, String dropId, GameEntity dropReceiver, List dropEntryRequirements) {
+ super(api, Routes.CONSUME_DROP, DropConsumedResponseImpl.class);
+ this.dropId = dropId;
+ this.dropReceiver = dropReceiver;
+ this.dropEntryRequirements = dropEntryRequirements;
+ }
+
+ @Override
+ public DropConsumedResponse transform(Response response) {
+
+ if (response == null || response.body() == null) {
+ throw new NullPointerException("Response cannot be null");
+ }
+
+ Gson gson = new Gson();
+ try (Reader reader = Objects.requireNonNull(response.body()).charStream()) {
+ return gson.fromJson(reader, DropConsumedResponseImpl.class);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ return null;
+
+ }
+
+ @Override
+ protected String compileRoute() {
+ return route.compileRoute(dropId);
+ }
+
+ @Override
+ protected JsonObject buildBody() {
+
+ JsonObject body = JsonObject.JsonObjectBuilder.newBuilder().create();
+ JsonArray requirements = new JsonArray();
+
+ body.append("playerId", dropReceiver.getPlayerID());
+
+ dropEntryRequirements.stream()
+ .map(DropEntryRequirement::toJsonElement)
+ .forEach(requirements::add);
+
+ body.append("claimRequirements", requirements);
+
+ return body;
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImpl.java
new file mode 100644
index 0000000..c1bb665
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImpl.java
@@ -0,0 +1,53 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.actions.drops.GetAllDropsAction;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropConstraintDeserializer;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropEntryRequirementDeserializer;
+import io.mymetavese.metaapi.requests.RestActionImpl;
+import io.mymetavese.metaapi.requests.entities.drops.MetaDropImpl;
+import io.mymetavese.metaapi.requests.routes.Routes;
+import okhttp3.Response;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Objects;
+
+public class GetAllDropsActionImpl extends RestActionImpl> implements GetAllDropsAction {
+
+ public GetAllDropsActionImpl(MetaAPI api) {
+ super(api, Routes.GET_ALL_DROPS);
+ }
+
+ @Override
+ public List transform(Response response) {
+
+ if (response == null || response.body() == null) {
+ throw new NullPointerException("Response cannot be null");
+ }
+
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(DropEntryRequirement.class, new DropEntryRequirementDeserializer())
+ .registerTypeAdapter(DropConstraint.class, new DropConstraintDeserializer())
+ .create();
+ Type listOfMetaDropObjectsType = new TypeToken>() {}.getType();
+
+ try (Reader reader = Objects.requireNonNull(response.body()).charStream()) {
+ return gson.fromJson(reader, listOfMetaDropObjectsType);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ return null;
+
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImpl.java
new file mode 100644
index 0000000..0e33a6e
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImpl.java
@@ -0,0 +1,58 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.actions.drops.GetDropAction;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropConstraintDeserializer;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropEntryRequirementDeserializer;
+import io.mymetavese.metaapi.requests.RestActionImpl;
+import io.mymetavese.metaapi.requests.entities.drops.MetaDropImpl;
+import io.mymetavese.metaapi.requests.routes.Routes;
+import okhttp3.Response;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Objects;
+
+public class GetDropActionImpl extends RestActionImpl implements GetDropAction {
+
+ String dropId;
+
+ public GetDropActionImpl(MetaAPI api, String dropId) {
+ super(api, Routes.GET_DROP, MetaDropImpl.class);
+ this.dropId = dropId;
+ }
+
+ @Override
+ protected String compileRoute() {
+ return route.compileRoute(this.dropId);
+ }
+
+ @Override
+ public MetaDrop transform(Response response) {
+
+ if (response == null || response.body() == null) {
+ throw new NullPointerException("Response cannot be null");
+ }
+
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(DropEntryRequirement.class, new DropEntryRequirementDeserializer())
+ .registerTypeAdapter(DropConstraint.class, new DropConstraintDeserializer())
+ .create();
+
+ try (Reader reader = Objects.requireNonNull(response.body()).charStream()) {
+ return gson.fromJson(reader, MetaDropImpl.class);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ return null;
+
+ }
+
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializer.java b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializer.java
new file mode 100644
index 0000000..8f5d5a1
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializer.java
@@ -0,0 +1,40 @@
+package io.mymetavese.metaapi.requests.custom_deserializers;
+
+import com.google.gson.*;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.requests.entities.drops.constraints.LimitedConsumptionDropConstraintImpl;
+
+import java.lang.reflect.Type;
+
+public class DropConstraintDeserializer implements JsonDeserializer {
+
+ @Override
+ public DropConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+
+ if (!json.isJsonObject())
+ throw new JsonParseException("Expecting a JsonObject, but it wasn't...");
+
+ JsonObject jsonObject = json.getAsJsonObject();
+
+ if (jsonObject.has("limitedUserConsumption")) {
+
+ if (!jsonObject.get("limitedUserConsumption").isJsonObject())
+ throw new JsonParseException(String.format("Expecting 'limitedUserConsumption' value to be a JsonObject, but it was %s", jsonObject.get("limitedUserConsumption")));
+
+ JsonObject limitedUserConsumptionJsonObj = jsonObject.get("limitedUserConsumption").getAsJsonObject();
+
+ if (!limitedUserConsumptionJsonObj.has("maximumConsumptionsPerUser"))
+ throw new JsonParseException("Expecting 'maximumConsumptionsPerUser' to be present, but it wasn't...");
+
+ if (limitedUserConsumptionJsonObj.get("maximumConsumptionsPerUser").isJsonPrimitive() && limitedUserConsumptionJsonObj.get("maximumConsumptionsPerUser").getAsJsonPrimitive().isNumber())
+ return new LimitedConsumptionDropConstraintImpl(limitedUserConsumptionJsonObj.get("maximumConsumptionsPerUser").getAsInt());
+ throw new JsonParseException(String.format("Expecting 'maximumConsumptionsPerUser' value to be an Integer, but it was %s", limitedUserConsumptionJsonObj.get("maximumConsumptionsPerUser")));
+
+ }
+
+ return null;
+
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializer.java b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializer.java
new file mode 100644
index 0000000..fe2b938
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializer.java
@@ -0,0 +1,39 @@
+package io.mymetavese.metaapi.requests.custom_deserializers;
+
+import com.google.gson.*;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.entities.drops.requirements.ReusableCodeDropEntryRequirementImpl;
+import io.mymetavese.metaapi.requests.entities.drops.requirements.SingleCodeDropEntryRequirementImpl;
+
+import java.lang.reflect.Type;
+
+public class DropEntryRequirementDeserializer implements JsonDeserializer {
+
+ @Override
+ public DropEntryRequirement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+
+ if (!json.isJsonObject())
+ throw new JsonParseException("Expecting a JsonObject, but it wasn't...");
+
+ JsonObject jsonObject = json.getAsJsonObject();
+
+ if (jsonObject.has("reusableCode")) {
+
+ if (jsonObject.get("reusableCode").isJsonPrimitive())
+ return new ReusableCodeDropEntryRequirementImpl(jsonObject.get("reusableCode").getAsString());
+ return new ReusableCodeDropEntryRequirementImpl(null);
+
+ } else if (jsonObject.has("code")) {
+
+ if (jsonObject.get("code").isJsonPrimitive() && jsonObject.get("code").getAsJsonPrimitive().isString())
+ return new SingleCodeDropEntryRequirementImpl(jsonObject.get("code").getAsString());
+ return new SingleCodeDropEntryRequirementImpl(null);
+
+ }
+
+ return null;
+
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/EnjinWalletDeserializer.java b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/EnjinWalletDeserializer.java
similarity index 96%
rename from src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/EnjinWalletDeserializer.java
rename to src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/EnjinWalletDeserializer.java
index 57fa212..e2920bf 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/EnjinWalletDeserializer.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/EnjinWalletDeserializer.java
@@ -1,4 +1,4 @@
-package io.mymetavese.metaapi.requests.CustomDeserializers;
+package io.mymetavese.metaapi.requests.custom_deserializers;
import com.google.gson.*;
import io.mymetavese.metaapi.requests.entities.EnjinWalletItemImpl;
diff --git a/src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/LiveWalletDeserializer.java b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/LiveWalletDeserializer.java
similarity index 96%
rename from src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/LiveWalletDeserializer.java
rename to src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/LiveWalletDeserializer.java
index 0c652cd..068e399 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/CustomDeserializers/LiveWalletDeserializer.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/custom_deserializers/LiveWalletDeserializer.java
@@ -1,4 +1,4 @@
-package io.mymetavese.metaapi.requests.CustomDeserializers;
+package io.mymetavese.metaapi.requests.custom_deserializers;
import com.google.gson.*;
import io.mymetavese.metaapi.requests.entities.ItemIndex;
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
index ee162d2..65f5444 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
@@ -2,12 +2,15 @@
import io.mymetavese.metaapi.api.MetaAPI;
import io.mymetavese.metaapi.api.actions.*;
+import io.mymetavese.metaapi.api.actions.drops.ConsumeDropAction;
import io.mymetavese.metaapi.api.actions.p2e.AddP2EPointsAction;
import io.mymetavese.metaapi.api.actions.p2e.GetP2EPointsAction;
import io.mymetavese.metaapi.api.actions.v2.GetTransferableItems;
import io.mymetavese.metaapi.api.entities.Item;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
import io.mymetavese.metaapi.api.entities.v2.GameEntity;
import io.mymetavese.metaapi.requests.actions.*;
+import io.mymetavese.metaapi.requests.actions.drops.ConsumeDropActionImpl;
import io.mymetavese.metaapi.requests.actions.p2e.AddP2EPointsActionImpl;
import io.mymetavese.metaapi.requests.actions.p2e.GetP2EPointsActionImpl;
import io.mymetavese.metaapi.requests.actions.v2.GetTransferableItemsImpl;
@@ -76,5 +79,9 @@ public AddP2EPointsAction addP2EPoints(int points) {
public AddP2EPointsAction addP2EPoints(int points, String idempotencyKey) {
return new AddP2EPointsActionImpl(metaAPI, this, points, idempotencyKey);
}
+
+ public ConsumeDropAction consumeDrop(String dropId, List dropEntryRequirements) {
+ return new ConsumeDropActionImpl(metaAPI, dropId, this, dropEntryRequirements);
+ }
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/ItemIndex.java b/src/main/java/io/mymetavese/metaapi/requests/entities/ItemIndex.java
index a2fd495..6972f77 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/entities/ItemIndex.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/ItemIndex.java
@@ -3,11 +3,13 @@
import io.mymetavese.metaapi.api.MetaAPI;
import io.mymetavese.metaapi.api.actions.Metadata.UpdateTokenAchievementsAction;
import io.mymetavese.metaapi.requests.actions.Metadata.UpdateTokenAchievementsActionImpl;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
+@EqualsAndHashCode
public class ItemIndex {
@Getter
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImpl.java
new file mode 100644
index 0000000..58597b9
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImpl.java
@@ -0,0 +1,41 @@
+package io.mymetavese.metaapi.requests.entities.drops;
+
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.entities.drops.crates.DropCrateImpl;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.List;
+
+@Getter
+@RequiredArgsConstructor
+@EqualsAndHashCode
+public class MetaDropImpl implements MetaDrop {
+
+ private final String id;
+ private final String name;
+ private final String description;
+ private final String slug;
+ private final String creatorId;
+ private final List constraints;
+ private final List crates;
+ private final List entryRequirements;
+
+ @Override
+ public String toString() {
+ return "MetaDropImpl{" +
+ "id='" + id + '\'' +
+ ", name='" + name + '\'' +
+ ", description='" + description.substring(0, Math.min(10,description.length())) + "... (.getDescription() to see Full)" + '\'' +
+ ", slug='" + slug + '\'' +
+ ", creatorId='" + creatorId + '\'' +
+ ", entryRequirements=" + entryRequirements +
+ ", constraints=" + constraints +
+ ", crates=" + crates +
+ '}';
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImpl.java
new file mode 100644
index 0000000..ab72105
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImpl.java
@@ -0,0 +1,32 @@
+package io.mymetavese.metaapi.requests.entities.drops.constraints;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.mymetavese.metaapi.api.entities.drops.constraints.LimitedConsumptionDropConstraint;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class LimitedConsumptionDropConstraintImpl implements LimitedConsumptionDropConstraint {
+
+ private final int maxConsumptionPerUser;
+
+ @Override
+ public JsonElement toJsonElement() {
+
+ JsonObject thisAsJson = new JsonObject();
+ JsonObject innerObject = new JsonObject();
+
+ innerObject.addProperty("maximumConsumptionsPerUser", this.maxConsumptionPerUser);
+ thisAsJson.add("limitedUserConsumption", innerObject);
+
+ return thisAsJson;
+
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImpl.java
new file mode 100644
index 0000000..18ba4c1
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImpl.java
@@ -0,0 +1,33 @@
+package io.mymetavese.metaapi.requests.entities.drops.crates;
+
+import com.google.gson.annotations.SerializedName;
+import io.mymetavese.metaapi.api.entities.drops.crates.DropCrate;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+import java.util.List;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class DropCrateImpl implements DropCrate {
+
+ private final String id;
+ private final String name;
+ private final int totalSupply;
+ private final int availableSupply;
+
+ @SerializedName("tokens")
+ private final List tokensInCrate;
+
+ private final DropCrateTypeImpl type;
+
+ @Override
+ public List getTokensInCrate() {
+ return this.tokensInCrate;
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateItemImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateItemImpl.java
new file mode 100644
index 0000000..91c5236
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateItemImpl.java
@@ -0,0 +1,41 @@
+package io.mymetavese.metaapi.requests.entities.drops.crates;
+
+import com.google.gson.annotations.SerializedName;
+import io.mymetavese.metaapi.api.entities.drops.crates.DropCrateItem;
+import io.mymetavese.metaapi.requests.entities.ItemIndex;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class DropCrateItemImpl implements DropCrateItem {
+
+ @SerializedName("id")
+ private final String tokenId;
+ @SerializedName("indexes")
+ private final List tokenIndexes;
+
+ @Override
+ public boolean isNFT() {
+ return true;
+ }
+
+ @Override
+ public List getTokenIndexes() {
+ return this.tokenIndexes.stream().map(s -> new ItemIndex(null, s))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public int getAmount() {
+ return this.tokenIndexes.size();
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImpl.java
new file mode 100644
index 0000000..593d6cf
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImpl.java
@@ -0,0 +1,17 @@
+package io.mymetavese.metaapi.requests.entities.drops.crates;
+
+import io.mymetavese.metaapi.api.entities.drops.crates.DropCrateType;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class DropCrateTypeImpl implements DropCrateType {
+
+ private final boolean perIndex;
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImpl.java
new file mode 100644
index 0000000..bb0b074
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImpl.java
@@ -0,0 +1,26 @@
+package io.mymetavese.metaapi.requests.entities.drops.requirements;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.mymetavese.metaapi.api.entities.drops.requirements.ReusableCodeDropEntryRequirement;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class ReusableCodeDropEntryRequirementImpl implements ReusableCodeDropEntryRequirement {
+
+ private final String reusableCode;
+
+ @Override
+ public JsonElement toJsonElement() {
+ JsonObject thisAsJson = new JsonObject();
+ thisAsJson.addProperty("reusableCode", this.reusableCode);
+ return thisAsJson;
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImpl.java
new file mode 100644
index 0000000..10ab539
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImpl.java
@@ -0,0 +1,26 @@
+package io.mymetavese.metaapi.requests.entities.drops.requirements;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.mymetavese.metaapi.api.entities.drops.requirements.SingleCodeDropEntryRequirement;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class SingleCodeDropEntryRequirementImpl implements SingleCodeDropEntryRequirement {
+
+ private final String singleCode;
+
+ @Override
+ public JsonElement toJsonElement() {
+ JsonObject thisAsJson = new JsonObject();
+ thisAsJson.addProperty("code", this.singleCode);
+ return thisAsJson;
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImpl.java
new file mode 100644
index 0000000..388e585
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImpl.java
@@ -0,0 +1,20 @@
+package io.mymetavese.metaapi.requests.entities.drops.responses;
+
+import com.google.gson.annotations.SerializedName;
+import io.mymetavese.metaapi.api.entities.drops.responses.DropConsumedResponse;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@Getter
+@RequiredArgsConstructor
+@ToString
+@EqualsAndHashCode
+public class DropConsumedResponseImpl implements DropConsumedResponse {
+
+ @SerializedName("eventId")
+ private final String dropId;
+ private final String crateId;
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImpl.java
new file mode 100644
index 0000000..0d8484b
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImpl.java
@@ -0,0 +1,39 @@
+package io.mymetavese.metaapi.requests.entities.drops.wrapper;
+
+import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.actions.drops.ConsumeDropAction;
+import io.mymetavese.metaapi.api.actions.drops.GetAllDropsAction;
+import io.mymetavese.metaapi.api.actions.drops.GetDropAction;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.api.entities.drops.wrapper.MetaDropsWrapper;
+import io.mymetavese.metaapi.api.entities.v2.GameEntity;
+import io.mymetavese.metaapi.requests.actions.drops.ConsumeDropActionImpl;
+import io.mymetavese.metaapi.requests.actions.drops.GetAllDropsActionImpl;
+import io.mymetavese.metaapi.requests.actions.drops.GetDropActionImpl;
+import lombok.Getter;
+
+import java.util.List;
+
+
+public class MetaDropsWrapperImpl implements MetaDropsWrapper {
+
+ @Getter
+ private final MetaAPI metaAPI;
+
+ public MetaDropsWrapperImpl(MetaAPI metaAPI) {
+ this.metaAPI = metaAPI;
+ }
+
+ public GetAllDropsAction getAllDrops() {
+ return new GetAllDropsActionImpl(this.metaAPI);
+ }
+
+ public GetDropAction getDropById(String dropId) {
+ return new GetDropActionImpl(this.metaAPI, dropId);
+ }
+
+ public ConsumeDropAction consumeDrop(String dropId, GameEntity dropReceiver, List dropEntryRequirements) {
+ return new ConsumeDropActionImpl(this.metaAPI, dropId, dropReceiver, dropEntryRequirements);
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/routes/Routes.java b/src/main/java/io/mymetavese/metaapi/requests/routes/Routes.java
index 6509283..7c7d2e7 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/routes/Routes.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/routes/Routes.java
@@ -24,7 +24,13 @@ public enum Routes {
GIVE_WHITELISTED_TOKEN,
+ // Play2Earn Routes
GET_P2E_POINTS,
- ADD_P2E_POINTS
+ ADD_P2E_POINTS,
+
+ // MetaDrops Routes
+ GET_ALL_DROPS,
+ GET_DROP,
+ CONSUME_DROP
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/routes/V2.java b/src/main/java/io/mymetavese/metaapi/requests/routes/V2.java
index a4e54c8..e191dda 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/routes/V2.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/routes/V2.java
@@ -36,6 +36,10 @@ public V2() {
this.routes.put("GET_P2E_POINTS", new Route(GET, "/users/{userId}/p2e/points"));
this.routes.put("ADD_P2E_POINTS", new Route(POST, "/users/{userId}/p2e/points"));
+ this.routes.put("GET_ALL_DROPS", new Route(GET, "/metadrops"));
+ this.routes.put("GET_DROP", new Route(GET, "/metadrops/{dropId}"));
+ this.routes.put("CONSUME_DROP", new Route(POST, "/metadrops/{dropId}/consume"));
+
}
}
diff --git a/src/test/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImplTest.java
new file mode 100644
index 0000000..0cbd79e
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImplTest.java
@@ -0,0 +1,98 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.mymetavese.metaapi.MetaAPIImpl;
+import io.mymetavese.metaapi.api.entities.v2.GameEntity;
+import io.mymetavese.metaapi.requests.entities.drops.requirements.ReusableCodeDropEntryRequirementImpl;
+import io.mymetavese.metaapi.requests.routes.RouteAdapter;
+import io.mymetavese.metaapi.requests.routes.V2;
+import okhttp3.MediaType;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class ConsumeDropActionImplTest {
+
+ @Mock
+ MetaAPIImpl metaAPIMock;
+
+ @Mock
+ GameEntity gameEntityMock;
+
+ @Mock
+ private Response response;
+
+ private ConsumeDropActionImpl consumeDropActionImpl;
+
+ @BeforeEach
+ void setUp() {
+
+ ReusableCodeDropEntryRequirementImpl reusableCodeDropEntryRequirementStub = new ReusableCodeDropEntryRequirementImpl("my_reusable_code");
+ RouteAdapter routeAdapter = new V2();
+
+ when(metaAPIMock.getRouteAdapter()).thenReturn(routeAdapter);
+
+ consumeDropActionImpl = new ConsumeDropActionImpl(metaAPIMock,
+ "MyStubDrop",
+ gameEntityMock,
+ Collections.singletonList(reusableCodeDropEntryRequirementStub));
+
+ }
+
+ @Test
+ void transform() {
+
+ String json = "{\"eventId\": \"63ec9c2589adf4e1aca2687f\"," + "\"crateId\": \"cr_123456\"}";
+ ResponseBody responseBodyStub = ResponseBody.create(json, MediaType.get("application/json"));
+
+ when(response.body()).thenReturn(responseBodyStub);
+
+ assertThat(consumeDropActionImpl.transform(response))
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("dropId", "63ec9c2589adf4e1aca2687f")
+ .hasFieldOrPropertyWithValue("crateId", "cr_123456");
+
+ }
+
+ @Test
+ void compileRoute() {
+ assertThat(consumeDropActionImpl.compileRoute())
+ .isNotNull()
+ .isEqualTo(String.format("/metadrops/%s/consume", "MyStubDrop"));
+ }
+
+ @Test
+ void buildBody() {
+
+ String expectedBody = "{\n" +
+ " \"playerId\": \"cdbc3194-b76c-483d-b644-035904423dbe\",\n" +
+ " \"claimRequirements\": [\n" +
+ " {\n" +
+ " \"reusableCode\": \"my_reusable_code\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ when(gameEntityMock.getPlayerID()).thenReturn("cdbc3194-b76c-483d-b644-035904423dbe");
+
+ JsonObject expectedBodyAsJson = JsonParser.parseString(expectedBody).getAsJsonObject();
+ JsonObject actualBodyAsJson = JsonParser.parseString(consumeDropActionImpl.buildBody().toJson()).getAsJsonObject();
+
+ assertThat(actualBodyAsJson)
+ .isNotNull()
+ .isEqualTo(expectedBodyAsJson);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImplTest.java
new file mode 100644
index 0000000..e38794b
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetAllDropsActionImplTest.java
@@ -0,0 +1,113 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import io.mymetavese.metaapi.MetaAPIImpl;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+import io.mymetavese.metaapi.requests.routes.RouteAdapter;
+import okhttp3.MediaType;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class GetAllDropsActionImplTest {
+
+ @Mock
+ MetaAPIImpl metaAPIMock;
+
+ @Mock
+ private Response responseMock;
+
+ private GetAllDropsActionImpl getAllDropsActionImpl;
+
+ @BeforeEach
+ void setUp() {
+
+ when(metaAPIMock.getRouteAdapter()).thenReturn(mock(RouteAdapter.class));
+ getAllDropsActionImpl = new GetAllDropsActionImpl(metaAPIMock);
+
+ }
+
+ @Test
+ void transform() {
+
+ String json = "[\n" +
+ " {\n" +
+ " \"id\": \"63ca42a6e36aea1021a4a728\",\n" +
+ " \"name\": \"Honey Bear\",\n" +
+ " \"description\": \"Introducing the Honey Bear artefact\",\n" +
+ " \"slug\": \"honeybear\",\n" +
+ " \"creatorId\": \"ct_VF03rFw18LA2FpTRBlChd\",\n" +
+ " \"entryRequirements\": [\n" +
+ " {\n" +
+ " \"reusableCode\": {}\n" +
+ " }\n" +
+ " ],\n" +
+ " \"constraints\": [],\n" +
+ " \"crates\": [\n" +
+ " {\n" +
+ " \"id\": \"cr_I2MIE69I\",\n" +
+ " \"name\": \"Crate\",\n" +
+ " \"totalSupply\": 50000,\n" +
+ " \"availableSupply\": 50000,\n" +
+ " \"tokens\": [\n" +
+ " {\n" +
+ " \"id\": \"a800000000000001\",\n" +
+ " \"indexes\": [\n" +
+ " \"0000000000000002\",\n" +
+ " \"0000000000000003\",\n" +
+ " \"0000000000000004\",\n" +
+ " \"0000000000050001\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"type\": {\n" +
+ " \"perIndex\": true\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "]";
+
+ ResponseBody responseBodyStub = ResponseBody.create(json, MediaType.get("application/json"));
+
+ when(responseMock.body()).thenReturn(responseBodyStub);
+
+ List transformedEntities = getAllDropsActionImpl.transform(responseMock);
+
+ assertThat(transformedEntities)
+ .isNotNull()
+ .hasSize(1);
+
+ assertThat(transformedEntities)
+ .first()
+ .hasFieldOrPropertyWithValue("id", "63ca42a6e36aea1021a4a728")
+ .hasFieldOrPropertyWithValue("name", "Honey Bear")
+ .hasFieldOrPropertyWithValue("description", "Introducing the Honey Bear artefact")
+ .hasFieldOrPropertyWithValue("slug", "honeybear")
+ .hasFieldOrPropertyWithValue("creatorId", "ct_VF03rFw18LA2FpTRBlChd");
+
+ assertThat(transformedEntities.get(0).getEntryRequirements())
+ .isNotNull()
+ .hasSize(1);
+
+ assertThat(transformedEntities.get(0).getConstraints())
+ .isNotNull()
+ .hasSize(0);
+
+ assertThat(transformedEntities.get(0).getCrates())
+ .isNotNull()
+ .hasSize(1);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImplTest.java
new file mode 100644
index 0000000..dbee037
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/actions/drops/GetDropActionImplTest.java
@@ -0,0 +1,114 @@
+package io.mymetavese.metaapi.requests.actions.drops;
+
+import io.mymetavese.metaapi.MetaAPIImpl;
+import io.mymetavese.metaapi.api.entities.drops.MetaDrop;
+import io.mymetavese.metaapi.requests.routes.V2;
+import okhttp3.MediaType;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class GetDropActionImplTest {
+
+ @Mock
+ MetaAPIImpl metaAPIMock;
+
+ @Mock
+ private Response responseMock;
+
+ private GetDropActionImpl getDropAction;
+
+ @BeforeEach
+ void setUp() {
+
+ when(metaAPIMock.getRouteAdapter()).thenReturn(new V2());
+ getDropAction = new GetDropActionImpl(metaAPIMock, "myDropId");
+
+ }
+
+ @Test
+ void compileRoute() {
+ assertThat(getDropAction.compileRoute())
+ .isNotNull()
+ .isEqualTo(String.format("/metadrops/%s", "myDropId"));
+ }
+
+ @Test
+ void transform() {
+
+ String json = "{\n" +
+ " \"id\": \"63ca42a6e36aea1021a4a728\",\n" +
+ " \"name\": \"Honey Bear\",\n" +
+ " \"description\": \"Introducing the Honey Bear artefact\",\n" +
+ " \"slug\": \"honeybear\",\n" +
+ " \"creatorId\": \"ct_VF03rFw18LA2FpTRBlChd\",\n" +
+ " \"entryRequirements\": [\n" +
+ " {\n" +
+ " \"reusableCode\": {}\n" +
+ " }\n" +
+ " ],\n" +
+ " \"constraints\": [],\n" +
+ " \"crates\": [\n" +
+ " {\n" +
+ " \"id\": \"cr_I2MIE69I\",\n" +
+ " \"name\": \"Crate\",\n" +
+ " \"totalSupply\": 50000,\n" +
+ " \"availableSupply\": 50000,\n" +
+ " \"tokens\": [\n" +
+ " {\n" +
+ " \"id\": \"a800000000000001\",\n" +
+ " \"indexes\": [\n" +
+ " \"0000000000000002\",\n" +
+ " \"0000000000000003\",\n" +
+ " \"0000000000000004\",\n" +
+ " \"0000000000050001\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"type\": {\n" +
+ " \"perIndex\": true\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n";
+
+ ResponseBody responseBodyStub = ResponseBody.create(json, MediaType.get("application/json"));
+
+ when(responseMock.body()).thenReturn(responseBodyStub);
+
+ MetaDrop transformedEntity = getDropAction.transform(responseMock);
+
+ assertThat(transformedEntity)
+ .isNotNull();
+
+ assertThat(transformedEntity)
+ .hasFieldOrPropertyWithValue("id", "63ca42a6e36aea1021a4a728")
+ .hasFieldOrPropertyWithValue("name", "Honey Bear")
+ .hasFieldOrPropertyWithValue("description", "Introducing the Honey Bear artefact")
+ .hasFieldOrPropertyWithValue("slug", "honeybear")
+ .hasFieldOrPropertyWithValue("creatorId", "ct_VF03rFw18LA2FpTRBlChd");
+
+ assertThat(transformedEntity.getEntryRequirements())
+ .isNotNull()
+ .hasSize(1);
+
+ assertThat(transformedEntity.getConstraints())
+ .isNotNull()
+ .hasSize(0);
+
+ assertThat(transformedEntity.getCrates())
+ .isNotNull()
+ .hasSize(1);
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializerTest.java b/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializerTest.java
new file mode 100644
index 0000000..58b3412
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropConstraintDeserializerTest.java
@@ -0,0 +1,35 @@
+package io.mymetavese.metaapi.requests.custom_deserializers;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.requests.entities.drops.constraints.LimitedConsumptionDropConstraintImpl;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+class DropConstraintDeserializerTest {
+
+ @Test
+ @DisplayName("Deserialize Limited User Consumption Constraint type.")
+ void deserialize_limitedUserConsumptionConstraint() {
+
+ String json = "{\"limitedUserConsumption\": {\"maximumConsumptionsPerUser\": 1}}";
+
+ Gson gsonInstance = new GsonBuilder()
+ .registerTypeAdapter(DropConstraint.class, new DropConstraintDeserializer())
+ .create();
+
+ DropConstraint dropConstraints = gsonInstance.fromJson(json, DropConstraint.class);
+
+ assertThat(dropConstraints)
+ .isNotNull()
+ .isInstanceOf(LimitedConsumptionDropConstraintImpl.class)
+ .hasFieldOrPropertyWithValue("maxConsumptionPerUser", 1);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializerTest.java b/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializerTest.java
new file mode 100644
index 0000000..64e931f
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/custom_deserializers/DropEntryRequirementDeserializerTest.java
@@ -0,0 +1,88 @@
+package io.mymetavese.metaapi.requests.custom_deserializers;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.entities.drops.constraints.LimitedConsumptionDropConstraintImpl;
+import io.mymetavese.metaapi.requests.entities.drops.requirements.ReusableCodeDropEntryRequirementImpl;
+import io.mymetavese.metaapi.requests.entities.drops.requirements.SingleCodeDropEntryRequirementImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+class DropEntryRequirementDeserializerTest {
+
+ Gson gsonInstance;
+
+ @BeforeEach
+ void setUp() {
+ gsonInstance = new GsonBuilder()
+ .registerTypeAdapter(DropEntryRequirement.class, new DropEntryRequirementDeserializer())
+ .create();
+ }
+
+ @Test
+ @DisplayName("Deserialize Reusable Code Drop Requirement if empty.")
+ void deserialize_reusableCodeDropEntryRequirement_empty() {
+
+ String json = "{\"reusableCode\": {}}";
+
+ DropEntryRequirement dropRequirement = gsonInstance.fromJson(json, DropEntryRequirement.class);
+
+ assertThat(dropRequirement)
+ .isNotNull()
+ .isInstanceOf(ReusableCodeDropEntryRequirementImpl.class)
+ .hasFieldOrPropertyWithValue("reusableCode", null);
+
+ }
+
+ @Test
+ @DisplayName("Deserialize Reusable Code Drop Requirement if it has a value.")
+ void deserialize_reusableCodeDropEntryRequirement_withValue() {
+
+ String json = "{\"reusableCode\": \"reusable_code_123456\"}";
+
+ DropEntryRequirement dropRequirement = gsonInstance.fromJson(json, DropEntryRequirement.class);
+
+ assertThat(dropRequirement)
+ .isNotNull()
+ .isInstanceOf(ReusableCodeDropEntryRequirementImpl.class)
+ .hasFieldOrPropertyWithValue("reusableCode", "reusable_code_123456");
+
+ }
+
+ @Test
+ @DisplayName("Deserialize Single Code Drop Requirement if empty.")
+ void deserialize_singleCodeDropEntryRequirement_empty() {
+
+ String json = "{\"code\": {}}";
+
+ DropEntryRequirement dropRequirement = gsonInstance.fromJson(json, DropEntryRequirement.class);
+
+ assertThat(dropRequirement)
+ .isNotNull()
+ .isInstanceOf(SingleCodeDropEntryRequirementImpl.class)
+ .hasFieldOrPropertyWithValue("singleCode", null);
+
+ }
+
+ @Test
+ @DisplayName("Deserialize Single Code Drop Requirement if it has a value.")
+ void deserialize_singleCodeDropEntryRequirement_withValue() {
+
+ String json = "{\"code\": \"single_code_123456\"}";
+
+ DropEntryRequirement dropRequirement = gsonInstance.fromJson(json, DropEntryRequirement.class);
+
+ assertThat(dropRequirement)
+ .isNotNull()
+ .isInstanceOf(SingleCodeDropEntryRequirementImpl.class)
+ .hasFieldOrPropertyWithValue("singleCode", "single_code_123456");
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImplTest.java
new file mode 100644
index 0000000..dd7ac07
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/MetaDropImplTest.java
@@ -0,0 +1,84 @@
+package io.mymetavese.metaapi.requests.entities.drops;
+
+import com.google.gson.GsonBuilder;
+import io.mymetavese.metaapi.api.entities.drops.constraints.DropConstraint;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropConstraintDeserializer;
+import io.mymetavese.metaapi.requests.custom_deserializers.DropEntryRequirementDeserializer;
+import io.mymetavese.metaapi.requests.entities.drops.crates.DropCrateImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class MetaDropImplTest {
+
+ @Test
+ void testDeserialization() {
+
+ String json = "{\n" +
+ " \"id\": \"63ca42a6e36aea1021a4a728\",\n" +
+ " \"name\": \"Honey Bear\",\n" +
+ " \"description\": \"Introducing the Honey Bear artefact - the ultimate digital companion!\",\n" +
+ " \"slug\": \"honeybear\",\n" +
+ " \"creatorId\": \"ct_VF03rFw18LA2FpTRBlChd\",\n" +
+ " \"entryRequirements\": [\n" +
+ " {\n" +
+ " \"reusableCode\": {}\n" +
+ " }\n" +
+ " ],\n" +
+ " \"constraints\": [],\n" +
+ " \"crates\": [\n" +
+ " {\n" +
+ " \"id\": \"cr_I2MIE69I\",\n" +
+ " \"name\": \"Crate\",\n" +
+ " \"totalSupply\": 50000,\n" +
+ " \"availableSupply\": 50000,\n" +
+ " \"tokens\": [\n" +
+ " {\n" +
+ " \"id\": \"a800000000000001\",\n" +
+ " \"indexes\": [\n" +
+ " \"0000000000000002\",\n" +
+ " \"0000000000000003\",\n" +
+ " \"0000000000000004\",\n" +
+ " \"0000000000050001\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"type\": {\n" +
+ " \"perIndex\": true\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }";
+
+ MetaDropImpl deserializedDrop = new GsonBuilder()
+ .registerTypeAdapter(DropEntryRequirement.class, new DropEntryRequirementDeserializer())
+ .registerTypeAdapter(DropConstraint.class, new DropConstraintDeserializer())
+ .create()
+ .fromJson(json, MetaDropImpl.class);
+
+ assertThat(deserializedDrop)
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("id", "63ca42a6e36aea1021a4a728")
+ .hasFieldOrPropertyWithValue("name", "Honey Bear")
+ .hasFieldOrPropertyWithValue("description", "Introducing the Honey Bear artefact - the ultimate digital companion!");
+
+ assertThat(deserializedDrop.getEntryRequirements())
+ .isNotNull()
+ .hasSize(1)
+ .first()
+ .isInstanceOf(DropEntryRequirement.class);
+
+ assertThat(deserializedDrop.getConstraints())
+ .isNotNull()
+ .hasSize(0);
+
+ assertThat(deserializedDrop.getCrates())
+ .isNotNull()
+ .hasSize(1)
+ .first()
+ .isInstanceOf(DropCrateImpl.class);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImplTest.java
new file mode 100644
index 0000000..c6cad51
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/constraints/LimitedConsumptionDropConstraintImplTest.java
@@ -0,0 +1,41 @@
+package io.mymetavese.metaapi.requests.entities.drops.constraints;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class LimitedConsumptionDropConstraintImplTest {
+
+ LimitedConsumptionDropConstraintImpl limitedConsumptionDropConstraintStub;
+
+ @BeforeEach
+ void setUp() {
+ limitedConsumptionDropConstraintStub = new LimitedConsumptionDropConstraintImpl(1);
+ }
+
+ @Test
+ @DisplayName("toJsonElement() should return a JsonElement with the correct max consumptions per user & structure")
+ void toJsonElement() {
+
+ String expectedJson = "{\"limitedUserConsumption\":{\"maximumConsumptionsPerUser\":1}}";
+ JsonElement jsonElement = JsonParser.parseString(expectedJson);
+
+ assertThat(limitedConsumptionDropConstraintStub.toJsonElement())
+ .isEqualTo(jsonElement);
+
+ }
+
+ @Test
+ @DisplayName("getMaxConsumptionPerUser() should return the correct max consumptions per user")
+ void getMaxConsumptionPerUser() {
+
+ assertThat(limitedConsumptionDropConstraintStub.getMaxConsumptionPerUser())
+ .isEqualTo(1);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImplTest.java
new file mode 100644
index 0000000..924f3bc
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateImplTest.java
@@ -0,0 +1,76 @@
+package io.mymetavese.metaapi.requests.entities.drops.crates;
+
+import com.google.gson.Gson;
+import io.mymetavese.metaapi.api.entities.Item;
+import io.mymetavese.metaapi.requests.entities.ItemIndex;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DropCrateImplTest {
+
+ @Test
+ void testDeserialization() {
+
+ // This is a JSON string comes from Postman docs.
+ String crateJson = "{\n" +
+ " \"id\": \"cr_I2MIE69I\",\n" +
+ " \"name\": \"Crate\",\n" +
+ " \"totalSupply\": 50000,\n" +
+ " \"availableSupply\": 49661,\n" +
+ " \"tokens\": [\n" +
+ " {\n" +
+ " \"id\": \"a800000000000001\",\n" +
+ " \"indexes\": [\n" +
+ " \"0000000000000341\",\n" +
+ " \"0000000000000342\",\n" +
+ " \"0000000000000343\",\n" +
+ " \"0000000000050001\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ],\n" +
+ " \"type\": {\n" +
+ " \"perIndex\": true\n" +
+ " }\n" +
+ " }";
+
+ // Deserialize the JSON string to DropCrateImpl object and check if all the fields are correct.
+
+ DropCrateImpl deserializedDropCrate = new Gson().fromJson(crateJson, DropCrateImpl.class);
+
+ assertThat(deserializedDropCrate)
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("id", "cr_I2MIE69I")
+ .hasFieldOrPropertyWithValue("name", "Crate")
+ .hasFieldOrPropertyWithValue("totalSupply", 50000)
+ .hasFieldOrPropertyWithValue("availableSupply", 49661)
+ .hasFieldOrProperty("tokensInCrate");
+
+ assertThat(deserializedDropCrate.getTokensInCrate())
+ .isNotNull()
+ .hasSize(1);
+
+ Item firstToken = deserializedDropCrate.getTokensInCrate().get(0);
+
+ assertThat(firstToken)
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("tokenId", "a800000000000001")
+ .hasFieldOrProperty("tokenIndexes");
+
+ assertThat(firstToken.getTokenIndexes())
+ .isNotNull()
+ .hasSize(4)
+ .containsExactly(
+ new ItemIndex(null, "0000000000000341"),
+ new ItemIndex(null, "0000000000000342"),
+ new ItemIndex(null, "0000000000000343"),
+ new ItemIndex(null, "0000000000050001")
+ );
+
+ assertThat(deserializedDropCrate.getType())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("perIndex", true);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImplTest.java
new file mode 100644
index 0000000..ae9e890
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/crates/DropCrateTypeImplTest.java
@@ -0,0 +1,24 @@
+package io.mymetavese.metaapi.requests.entities.drops.crates;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+class DropCrateTypeImplTest {
+
+ @Test
+ void testDeserialization() {
+
+ String json = "{\n" + "\"perIndex\": true\n" + "}";
+
+ DropCrateTypeImpl deserializedDropCrateType = new Gson().fromJson(json, DropCrateTypeImpl.class);
+
+ assertThat(deserializedDropCrateType)
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("perIndex", true);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImplTest.java
new file mode 100644
index 0000000..44d9133
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/ReusableCodeDropEntryRequirementImplTest.java
@@ -0,0 +1,42 @@
+package io.mymetavese.metaapi.requests.entities.drops.requirements;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+class ReusableCodeDropEntryRequirementImplTest {
+
+ ReusableCodeDropEntryRequirementImpl reusableCodeDropEntryRequirementStub;
+
+ @BeforeEach
+ void setUp() {
+ reusableCodeDropEntryRequirementStub = new ReusableCodeDropEntryRequirementImpl("testReusableCode");
+ }
+
+ @Test
+ @DisplayName("toJsonElement() should return a JsonElement with the correct reusable code & structure")
+ void toJsonElement() {
+
+ String entryRequirementJson = "{\"reusableCode\":\"testReusableCode\"}";
+ JsonElement entryRequirementJsonElement = JsonParser.parseString(entryRequirementJson);
+
+ assertThat(reusableCodeDropEntryRequirementStub.toJsonElement())
+ .isEqualTo(entryRequirementJsonElement);
+
+ }
+
+ @Test
+ @DisplayName("getReusableCode() should return the correct reusable code")
+ void getReusableCode() {
+
+ assertThat(reusableCodeDropEntryRequirementStub.getReusableCode())
+ .isEqualTo("testReusableCode");
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImplTest.java
new file mode 100644
index 0000000..aedbe47
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/requirements/SingleCodeDropEntryRequirementImplTest.java
@@ -0,0 +1,42 @@
+package io.mymetavese.metaapi.requests.entities.drops.requirements;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+class SingleCodeDropEntryRequirementImplTest {
+
+ SingleCodeDropEntryRequirementImpl singleCodeDropEntryRequirementStub;
+
+ @BeforeEach
+ void setUp() {
+ singleCodeDropEntryRequirementStub = new SingleCodeDropEntryRequirementImpl("testSingleCode");
+ }
+
+ @Test
+ @DisplayName("toJsonElement() should return a JsonElement with the correct single code & structure")
+ void toJsonElement() {
+
+ String entryRequirementJson = "{\"code\":\"testSingleCode\"}";
+ JsonElement entryRequirementJsonElement = JsonParser.parseString(entryRequirementJson);
+
+ assertThat(singleCodeDropEntryRequirementStub.toJsonElement())
+ .isEqualTo(entryRequirementJsonElement);
+
+ }
+
+ @Test
+ @DisplayName("getSingleCode() should return the correct single code")
+ void getSingleCode() {
+
+ assertThat(singleCodeDropEntryRequirementStub.getSingleCode())
+ .isEqualTo("testSingleCode");
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImplTest.java
new file mode 100644
index 0000000..f5e5301
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/responses/DropConsumedResponseImplTest.java
@@ -0,0 +1,28 @@
+package io.mymetavese.metaapi.requests.entities.drops.responses;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DropConsumedResponseImplTest {
+
+ @Test
+ @DisplayName("Deserialization of API response should work correctly")
+ void testDeserialization() {
+
+ String jsonProvidedByAPI = "{\"eventId\":\"testDropId\",\"crateId\":\"cr_123456\"}";
+
+ DropConsumedResponseImpl deserializedDropConsumedResponse = new Gson()
+ .fromJson(jsonProvidedByAPI, DropConsumedResponseImpl.class);
+
+ assertThat(deserializedDropConsumedResponse.getDropId())
+ .isEqualTo("testDropId");
+
+ assertThat(deserializedDropConsumedResponse.getCrateId())
+ .isEqualTo("cr_123456");
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImplTest.java b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImplTest.java
new file mode 100644
index 0000000..2bb3e99
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/entities/drops/wrapper/MetaDropsWrapperImplTest.java
@@ -0,0 +1,85 @@
+package io.mymetavese.metaapi.requests.entities.drops.wrapper;
+
+import io.mymetavese.metaapi.MetaAPIImpl;
+import io.mymetavese.metaapi.api.MetaAPI;
+import io.mymetavese.metaapi.api.entities.drops.requirements.DropEntryRequirement;
+import io.mymetavese.metaapi.api.entities.v2.GameEntity;
+import io.mymetavese.metaapi.requests.Route;
+import io.mymetavese.metaapi.requests.actions.drops.ConsumeDropActionImpl;
+import io.mymetavese.metaapi.requests.actions.drops.GetAllDropsActionImpl;
+import io.mymetavese.metaapi.requests.actions.drops.GetDropActionImpl;
+import io.mymetavese.metaapi.requests.entities.GameEntityImpl;
+import io.mymetavese.metaapi.requests.routes.RouteAdapter;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class MetaDropsWrapperImplTest {
+
+ @Mock
+ MetaAPIImpl metaAPIMock;
+
+ MetaDropsWrapperImpl metaDropsWrapperStub;
+
+ @BeforeEach
+ void setUp() {
+
+ RouteAdapter routeAdapterMock = mock(RouteAdapter.class);
+
+ metaDropsWrapperStub = new MetaDropsWrapperImpl(metaAPIMock);
+
+ when(metaAPIMock.getRouteAdapter()).thenReturn(routeAdapterMock);
+
+ }
+
+ @Test
+ void getAllDrops() {
+ assertThat(metaDropsWrapperStub.getAllDrops())
+ .isNotNull()
+ .isInstanceOf(GetAllDropsActionImpl.class)
+ .hasFieldOrPropertyWithValue("metaAPI", metaAPIMock);
+ }
+
+ @Test
+ void getDropById() {
+ assertThat(metaDropsWrapperStub.getDropById("testId"))
+ .isNotNull()
+ .isInstanceOf(GetDropActionImpl.class)
+ .hasFieldOrPropertyWithValue("metaAPI", metaAPIMock)
+ .hasFieldOrPropertyWithValue("dropId", "testId");
+ }
+
+ @Test
+ void consumeDrop() {
+
+ GameEntityImpl gameEntityMock = mock(GameEntityImpl.class);
+
+ List dropEntryRequirementList = Arrays.asList(
+ mock(DropEntryRequirement.class),
+ mock(DropEntryRequirement.class)
+ );
+
+ when(metaAPIMock.getRouteAdapter()).thenReturn(mock(RouteAdapter.class));
+
+ assertThat(metaDropsWrapperStub.consumeDrop("testId", gameEntityMock, dropEntryRequirementList))
+ .isNotNull()
+ .isInstanceOf(ConsumeDropActionImpl.class)
+ .hasFieldOrPropertyWithValue("metaAPI", metaAPIMock)
+ .hasFieldOrPropertyWithValue("dropId", "testId")
+ .hasFieldOrPropertyWithValue("dropReceiver", gameEntityMock)
+ .hasFieldOrPropertyWithValue("dropEntryRequirements", dropEntryRequirementList);
+ }
+
+}
\ No newline at end of file