Skip to content

Commit

Permalink
Fixed item removal. Added unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
tastybento committed Nov 19, 2018
1 parent ac80a7e commit 326b8ca
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 14 deletions.
43 changes: 29 additions & 14 deletions src/main/java/bentobox/addon/challenges/panel/TryToComplete.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,24 +241,39 @@ private ChallengeResult checkInventory() {
}
// If remove items, then remove them
if (challenge.isTakeItems()) {
for (ItemStack req : required) {
int amountToBeRemoved = req.getAmount();
List<ItemStack> itemsInInv = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).collect(Collectors.toList());
for (ItemStack i : itemsInInv) {
if (amountToBeRemoved > 0) {
// Remove all of this item
HashMap<Integer, ItemStack> remaining = user.getInventory().removeItem(i);
if (!remaining.isEmpty()) {
remaining.forEach((k,v) -> addon.logError("Could not remove items: " + v));
} else {
amountToBeRemoved -= i.getAmount();
}
removeItems(required);

}
// Return the result
return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world));
}

/**
* Removes items from a user's inventory
* @param required - a list of item stacks to be removed
* @return Map of item type and quantity that were successfully removed from the user's inventory
*/
public Map<Material, Integer> removeItems(List<ItemStack> required) {
Map<Material, Integer> removed = new HashMap<>();
for (ItemStack req : required) {
int amountToBeRemoved = req.getAmount();
List<ItemStack> itemsInInv = Arrays.stream(user.getInventory().getContents()).filter(Objects::nonNull).filter(i -> i.getType().equals(req.getType())).collect(Collectors.toList());
for (ItemStack i : itemsInInv) {
if (amountToBeRemoved > 0) {
// Remove either the full amount or the remaining amount
i.setAmount(Math.min(i.getAmount(), amountToBeRemoved));
// Remove all of this item
HashMap<Integer, ItemStack> remaining = user.getInventory().removeItem(i);
if (!remaining.isEmpty()) {
remaining.forEach((k,v) -> addon.logError("Could not remove items: " + v.getType() + " x " + v.getAmount()));
} else {
amountToBeRemoved -= i.getAmount();
removed.merge(i.getType(), i.getAmount(), Integer::sum);
}
}
}
}
// Return the result
return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world));
return removed;
}

private ChallengeResult checkLevel() {
Expand Down
166 changes: 166 additions & 0 deletions src/test/java/bentobox/addon/challenges/panel/TryToCompleteTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
*
*/
package bentobox.addon.challenges.panel;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;

import bentobox.addon.challenges.ChallengesAddon;
import world.bentobox.bentobox.api.user.User;

/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
public class TryToCompleteTest {

private User user;
ItemStack[] stacks = { new ItemStack(Material.PAPER, 32),
new ItemStack(Material.ACACIA_BOAT),
null,
null,
new ItemStack(Material.CACTUS, 32),
new ItemStack(Material.CACTUS, 32),
new ItemStack(Material.CACTUS, 32),
new ItemStack(Material.GOLD_BLOCK, 32)
};
List<ItemStack> required;
private ChallengesAddon addon;
private PlayerInventory inv;

/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
user = mock(User.class);
inv = mock(PlayerInventory.class);
when(inv.getContents()).thenReturn(stacks);
when(user.getInventory()).thenReturn(inv);
addon = mock(ChallengesAddon.class);
required = new ArrayList<>();
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsSuccess() {
Material reqMat = Material.PAPER;
int reqQty = 21;
required.add(new ItemStack(reqMat, reqQty));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.get(reqMat) == reqQty);
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsMax() {
Material reqMat = Material.PAPER;
int reqQty = 50;
required.add(new ItemStack(reqMat, reqQty));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.get(reqMat) == 32);
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsZero() {
Material reqMat = Material.PAPER;
int reqQty = 0;
required.add(new ItemStack(reqMat, reqQty));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.get(reqMat) == null);
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsSuccessMultiple() {
required.add(new ItemStack(Material.PAPER, 11));
required.add(new ItemStack(Material.PAPER, 5));
required.add(new ItemStack(Material.PAPER, 5));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.get(Material.PAPER) == 21);
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsSuccessMultipleOther() {
required.add(new ItemStack(Material.CACTUS, 5));
required.add(new ItemStack(Material.PAPER, 11));
required.add(new ItemStack(Material.PAPER, 5));
required.add(new ItemStack(Material.PAPER, 5));
required.add(new ItemStack(Material.CACTUS, 5));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.get(Material.PAPER) == 21);
assertTrue(removed.get(Material.CACTUS) == 10);
}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsMultipleOtherFail() {
required.add(new ItemStack(Material.ACACIA_FENCE, 5));
required.add(new ItemStack(Material.ARROW, 11));
required.add(new ItemStack(Material.STONE, 5));
required.add(new ItemStack(Material.BAKED_POTATO, 5));
required.add(new ItemStack(Material.GHAST_SPAWN_EGG, 5));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.isEmpty());

}

/**
* Test method for {@link bentobox.addon.challenges.panel.TryToComplete#removeItems(java.util.List)}.
*/
@Test
public void testRemoveItemsFail() {
HashMap<Integer, ItemStack> unremovable = new HashMap<>();
unremovable.put(0, new ItemStack(Material.GOLD_BLOCK, 2));
when(inv.removeItem(Mockito.any(ItemStack.class))).thenReturn(unremovable);
required.add(new ItemStack(Material.GOLD_BLOCK, 5));
TryToComplete x = new TryToComplete(addon);
x.user(user);
Map<Material, Integer> removed = x.removeItems(required);
assertTrue(removed.isEmpty());
Mockito.verify(addon, Mockito.times(1)).logError(Mockito.anyString());
}
}

0 comments on commit 326b8ca

Please sign in to comment.