/** Test a source under another player. */
  @Test
  public void testIsValidNonContainedBelowPlayer() {
    MockStendlRPWorld.get();
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final Player alice = PlayerTestHelper.createPlayer("alice");
    alice.setPosition(0, 1);
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = ItemTestHelper.createItem();
    zone.add(dropitem);
    zone.add(bob);
    zone.add(alice);
    assertNotNull(dropitem.getID().getObjectID());
    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());
    MockStendlRPWorld.get().addRPZone(zone);
    assertNotNull(bob.getZone());

    SourceObject so = SourceObject.createSourceObject(action, alice);
    assertFalse("Picking an item below another player", so.isValid());

    // Bind it to alice. She should be able to pick it up
    dropitem.setBoundTo("alice");
    so = SourceObject.createSourceObject(action, alice);
    assertTrue("Picking an item belonging to player herself", so.isValid());

    // Sanity check. Should be still valid to bob
    so = SourceObject.createSourceObject(action, bob);
    assertTrue("Accessing bound object below oneself", so.isValid());
    // ... unless it's under alice
    dropitem.setPosition(0, 1);
    so = SourceObject.createSourceObject(action, bob);
    assertFalse("Picking an item below another player", so.isValid());
  }
  /** Tests for isValidStackableDropTooMany. */
  @Test
  public void testIsValidStackableDropTooMany() {
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = ItemTestHelper.createItem("drops", 5);
    zone.add(dropitem);
    zone.add(bob);
    MockStendlRPWorld.get().addRPZone(zone);

    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());
    action.put(EquipActionConsts.QUANTITY, dropitem.getQuantity() + 3);
    final SourceObject so = SourceObject.createSourceObject(action, bob);
    assertTrue(so.isValid());
    assertEquals("too many are reduced to all", dropitem.getQuantity(), so.getQuantity());
  }
  /** Tests for isValidNonContained. */
  @Test
  public void testIsValidNonContained() {
    MockStendlRPWorld.get();
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = ItemTestHelper.createItem();
    zone.add(dropitem);
    zone.add(bob);
    assertNotNull(dropitem.getID().getObjectID());
    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());
    MockStendlRPWorld.get().addRPZone(zone);
    assertNotNull(bob.getZone());

    final SourceObject so = SourceObject.createSourceObject(action, bob);
    assertTrue(so.isValid());
  }
  /** Tests for isValidStackableDropAFew. */
  @Test
  public void testIsValidStackableDropAFew() {
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = ItemTestHelper.createItem("drops", 5);
    zone.add(dropitem);
    zone.add(bob);
    MockStendlRPWorld.get().addRPZone(zone);

    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());
    final int amounttodrop = 3;
    action.put(EquipActionConsts.QUANTITY, amounttodrop);
    final SourceObject so = SourceObject.createSourceObject(action, bob);
    assertTrue(so.isValid());
    assertEquals("return the amount to be dropped", amounttodrop, so.getQuantity());
  }
  /** Tests for isValidStackable. */
  @Test
  public void testIsValidStackable() {
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = ItemTestHelper.createItem("drops", 5);
    zone.add(dropitem);
    zone.add(bob);
    assertNotNull(dropitem.getID().getObjectID());
    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());
    MockStendlRPWorld.get().addRPZone(zone);
    assertNotNull(bob.getZone());

    final SourceObject so = SourceObject.createSourceObject(action, bob);
    assertTrue(so.isValid());
    assertEquals("stackable returns full quantity", dropitem.getQuantity(), so.getQuantity());
  }
  /** Tests for isValidContained. */
  @Test
  public void testIsValidContained() {
    MockStendlRPWorld.get();
    final Player bob = PlayerTestHelper.createPlayer("bob");
    final StendhalRPZone zone = new StendhalRPZone("dropzone");
    final Item dropitem = SingletonRepository.getEntityManager().getItem("money");
    assertNotNull(dropitem);
    zone.add(bob);
    assertTrue(bob.equipToInventoryOnly(dropitem));
    assertNotNull(dropitem.getID().getObjectID());
    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, dropitem.getID().getObjectID());

    action.put(EquipActionConsts.BASE_OBJECT, bob.getID().getObjectID());
    action.put(EquipActionConsts.BASE_SLOT, "bag");
    MockStendlRPWorld.get().addRPZone(zone);
    assertNotNull(bob.getZone());

    final SourceObject so = SourceObject.createSourceObject(action, bob);
    assertTrue("Unreachable slot", so.isValid());
  }
  /** Tests for isNotValid. */
  @Test
  public void testIsNotValid() {
    SourceObject so = SourceObject.createSourceObject(null, null);
    assertFalse("null null does not make a valid source", so.isValid());

    so = SourceObject.createSourceObject(new RPAction(), PlayerTestHelper.createPlayer("bob"));
    assertFalse("empty action does not make a valid source", so.isValid());

    final RPAction action = new RPAction();
    action.put(EquipActionConsts.BASE_ITEM, 1);
    so = SourceObject.createSourceObject(action, PlayerTestHelper.createPlayer("bob"));
    assertFalse("Player is not in zone", so.isValid());
  }