package com.nicewuerfel.blockown.protection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.nicewuerfel.blockown.Material;
import com.nicewuerfel.blockown.Setting;
import com.nicewuerfel.blockown.User;
import org.apache.commons.io.FileUtils;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.UUID;
public class TestProtection {
private static final int USER_COUNT = 10;
private static final String TEST_CONFIG_LOCATION = "/testConfig.yml";
@Rule
public ExpectedException expected = ExpectedException.none();
static File testFolder;
static Protection protection;
static Setting setting;
static User[] testUsers;
@BeforeClass
public static void init() {
InputStream stream = TestProtection.class.getClass().getResourceAsStream(TEST_CONFIG_LOCATION);
// Read-only, set() can't be used!
setting = Setting.load(new TestOutput(),
YamlConfiguration.loadConfiguration(new InputStreamReader(stream)));
try {
testFolder = new File("protectionTest");
if (testFolder.exists()) {
FileUtils.deleteDirectory(testFolder);
}
testFolder.mkdir();
protection = new Protection(setting, testFolder);
} catch (IOException e) {
fail(e.getMessage());
}
}
@BeforeClass
public static void createTestUsers() {
testUsers = new User[USER_COUNT];
for (int i = 0; i < USER_COUNT; i++) {
testUsers[i] = User.getInstance(UUID.randomUUID());
}
}
@After
public void dropUsers() {
for (User user : testUsers) {
protection.enqueue(new ProtectAction.Builder(user).drop().build());
}
waitForLock();
}
@Test
public void testInvalidAction() {
expected.expect(IllegalStateException.class);
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).build();
protection.enqueue(protectAction);
}
@Test
public void testProtect() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).protect(log).build();
protection.enqueue(protectAction);
Material torch = Material.parseMaterial("TORCH");
protectAction = new ProtectAction.Builder(testUsers[0]).protect(torch).build();
protection.enqueue(protectAction);
Material stone = Material.parseMaterial("STONE");
protectAction = new ProtectAction.Builder(testUsers[0]).protect(stone).build();
protection.enqueue(protectAction);
Material dirt = Material.parseMaterial("DIRT");
waitForLock();
assertTrue(protection.isListed(testUsers[0], log));
assertFalse("Torch should not be protected since it's not allowed",
protection.isListed(testUsers[0], torch));
assertFalse("Stone should not be protected since it's disallowed",
protection.isListed(testUsers[0], stone));
assertTrue("Dirt should be protected automatically", protection.isListed(testUsers[0], dirt));
assertEquals(ProtectionCause.AUTO_PROTECTED,
protection.getAccess(testUsers[0], dirt, testUsers[2]));
}
@Test
public void testUnprotect() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).protect(log).build();
protection.enqueue(protectAction);
waitForLock();
assertTrue(protection.isListed(testUsers[0], log));
protectAction = new ProtectAction.Builder(testUsers[0]).unprotect(log).build();
protection.enqueue(protectAction);
Material dirt = Material.parseMaterial("DIRT");
protectAction = new ProtectAction.Builder(testUsers[1]).unprotect(dirt).build();
protection.enqueue(protectAction);
waitForLock();
assertFalse(protection.isListed(testUsers[0], log));
assertTrue("Dirt should still be protected automatically",
protection.isListed(testUsers[1], dirt));
}
@Test
public void testFriend() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).protect(log).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).friend(testUsers[1]).build();
protection.enqueue(protectAction);
waitForLock();
assertTrue(protection.isFriend(testUsers[0], testUsers[1]));
assertFalse(protection.isFriend(testUsers[1], testUsers[0]));
assertFalse(protection.isFriend(testUsers[0], testUsers[2]));
assertEquals(ProtectionCause.NONE, protection.getAccess(testUsers[0], log, testUsers[1]));
assertEquals(ProtectionCause.PROTECTED, protection.getAccess(testUsers[0], log, testUsers[2]));
}
@Test
public void testUnfriend() {
ProtectAction protectAction =
new ProtectAction.Builder(testUsers[0]).friend(testUsers[1]).build();
protection.enqueue(protectAction);
waitForLock();
assertTrue(protection.isFriend(testUsers[0], testUsers[1]));
assertFalse(protection.isFriend(testUsers[1], testUsers[0]));
assertFalse(protection.isFriend(testUsers[2], testUsers[3]));
protectAction = new ProtectAction.Builder(testUsers[0]).unfriend(testUsers[1]).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[2]).unfriend(testUsers[3]).build();
protection.enqueue(protectAction);
assertFalse(protection.isFriend(testUsers[0], testUsers[1]));
assertFalse(protection.isFriend(testUsers[1], testUsers[0]));
assertFalse(protection.isFriend(testUsers[2], testUsers[3]));
}
@Test
public void testLock() {
Material log = Material.parseMaterial("LOG");
Material stone = Material.parseMaterial("STONE");
Material torch = Material.parseMaterial("TORCH");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).lock(log).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).lock(torch).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).lock(stone).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).friend(testUsers[1]).build();
protection.enqueue(protectAction);
waitForLock();
assertTrue(protection.isListed(testUsers[0], log));
assertFalse("Torch should not be locked since it's not allowed",
protection.isListed(testUsers[0], torch));
assertFalse("Stone should not be locked since it's disallowed",
protection.isListed(testUsers[0], stone));
assertEquals(ProtectionCause.LOCKED, protection.getAccess(testUsers[0], log, testUsers[1]));
}
@Test
public void testUnlock() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[1]).unlock(log).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).lock(log).build();
protection.enqueue(protectAction);
waitForLock();
assertFalse(protection.isListed(testUsers[1], log));
assertTrue(protection.isListed(testUsers[0], log));
protectAction = new ProtectAction.Builder(testUsers[0]).unlock(log).build();
protection.enqueue(protectAction);
assertFalse(protection.isListed(testUsers[0], log));
}
@Test
public void testAnyProtect() {
ProtectAction protectAction =
new ProtectAction.Builder(testUsers[0]).protect(Material.ANY).build();
protection.enqueue(protectAction);
Material log = Material.parseMaterial("LOG");
Material torch = Material.parseMaterial("TORCH");
Material stone = Material.parseMaterial("STONE");
waitForLock();
assertTrue(protection.isListed(testUsers[0], log));
assertFalse("Torch should not be protected since it's not allowed",
protection.isListed(testUsers[0], torch));
assertFalse("Stone should not be protected since it's disallowed",
protection.isListed(testUsers[0], stone));
}
@Test
public void testAnyLock() {
ProtectAction protectAction =
new ProtectAction.Builder(testUsers[0]).lock(Material.ANY).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).friend(testUsers[1]).build();
protection.enqueue(protectAction);
Material log = Material.parseMaterial("LOG");
Material torch = Material.parseMaterial("TORCH");
Material stone = Material.parseMaterial("STONE");
waitForLock();
assertTrue(protection.isListed(testUsers[0], log));
assertFalse("Torch should not be locked since it's not allowed",
protection.isListed(testUsers[0], torch));
assertFalse("Stone should not be locked since it's disallowed",
protection.isListed(testUsers[0], stone));
assertEquals(ProtectionCause.LOCKED, protection.getAccess(testUsers[0], log, testUsers[1]));
}
@Test
public void testDrop() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).protect(log).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).lock(log).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[0]).friend(testUsers[1]).build();
protection.enqueue(protectAction);
protectAction = new ProtectAction.Builder(testUsers[2]).friend(testUsers[0]).build();
protection.enqueue(protectAction);
waitForLock();
protectAction = new ProtectAction.Builder(testUsers[0]).drop().build();
protection.enqueue(protectAction);
waitForLock();
assertFalse(protection.isListed(testUsers[0], log));
assertFalse(protection.isListed(testUsers[0], log));
assertFalse(protection.isFriend(testUsers[0], testUsers[1]));
assertFalse(protection.isFriend(testUsers[2], testUsers[0]));
}
@Test
public void testHasAccess() {
Material log = Material.parseMaterial("LOG");
ProtectAction protectAction = new ProtectAction.Builder(testUsers[0]).protect(log).build();
protection.enqueue(protectAction);
Material stone = Material.parseMaterial("STONE");
protectAction = new ProtectAction.Builder(testUsers[0]).protect(stone).build();
protection.enqueue(protectAction);
Material dirt = Material.parseMaterial("DIRT");
Material boat = Material.parseMaterial("BOAT");
waitForLock();
assertFalse(protection.getAccess(testUsers[0], log, testUsers[1]) == ProtectionCause.NONE);
assertTrue(protection.getAccess(testUsers[1], stone, testUsers[0]) == ProtectionCause.NONE);
assertFalse("Dirt should be protected automatically",
protection.getAccess(testUsers[1], dirt, testUsers[0]) == ProtectionCause.NONE);
assertTrue(protection.getAccess(testUsers[3], boat, testUsers[2]) == ProtectionCause.NONE);
assertTrue(protection.getAccess(testUsers[1], boat, testUsers[2]) == ProtectionCause.NONE);
}
@Test
public void testGetFriends() {
Set<User> result = protection.getFriends(testUsers[5]);
assertNotNull(result);
assertEquals(result, protection.getFriends(testUsers[5]));
}
@Test
public void testGetProtections() {
Set<Material> result = protection.getProtections(testUsers[5]);
assertNotNull(result);
assertEquals(result, protection.getProtections(testUsers[5]));
}
@Test
public void testGetLocks() {
Set<Material> result = protection.getLocks(testUsers[5]);
assertNotNull(result);
assertEquals(result, protection.getLocks(testUsers[5]));
}
@Test
public void testGetDecayer() {
Server server = mock(Server.class);
when(server.getOfflinePlayers()).thenReturn(new OfflinePlayer[3]);
Plugin plugin = mock(Plugin.class);
when(plugin.getServer()).thenReturn(server);
final ProtectionDecayer decayer = protection.getDecayer(plugin);
assertTrue(decayer == protection.getDecayer(plugin));
}
@AfterClass
public static void disable() throws IOException {
protection.disable();
FileUtils.deleteDirectory(testFolder);
}
private static void waitForLock() {
/*
* try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); }
* protection.resetThreadPool();
*/
// Nothing to do, because ProtectActions aren't performed asynchronous
}
}