From a2554d2dbc31ff2a9f9a55e3fa00047d166eed41 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sun, 12 May 2019 19:36:23 +0300 Subject: [PATCH] Test against duplicate columns in players table --- Plan/common/build.gradle | 1 + .../tables/PlayersTableJSONParserTest.java | 184 ++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParserTest.java diff --git a/Plan/common/build.gradle b/Plan/common/build.gradle index f73416109..d0c32da94 100644 --- a/Plan/common/build.gradle +++ b/Plan/common/build.gradle @@ -15,6 +15,7 @@ dependencies { compileOnly "com.google.guava:guava:$guavaVersion" testCompile project(":api") + testCompile "com.google.code.gson:gson:2.8.5" } shadowJar { diff --git a/Plan/common/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParserTest.java b/Plan/common/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParserTest.java new file mode 100644 index 000000000..850901e65 --- /dev/null +++ b/Plan/common/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParserTest.java @@ -0,0 +1,184 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.utilities.html.tables; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.db.Database; +import com.djrapitops.plan.db.access.queries.containers.ServerPlayersTableContainersQuery; +import com.djrapitops.plan.db.access.transactions.Transaction; +import com.djrapitops.plan.db.access.transactions.events.PlayerRegisterTransaction; +import com.djrapitops.plan.db.access.transactions.events.PlayerServerRegisterTransaction; +import com.djrapitops.plan.db.access.transactions.events.SessionEndTransaction; +import com.djrapitops.plan.db.access.transactions.events.WorldNameStoreTransaction; +import com.djrapitops.plan.extension.CallEvents; +import com.djrapitops.plan.extension.DataExtension; +import com.djrapitops.plan.extension.ExtensionService; +import com.djrapitops.plan.extension.ExtensionServiceImplementation; +import com.djrapitops.plan.extension.annotation.*; +import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionServerPlayerDataTableQuery; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.paths.WebserverSettings; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.google.gson.Gson; +import org.junit.Assume; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import utilities.RandomData; +import utilities.TestConstants; +import utilities.mocks.PluginMockComponent; + +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * Test against PlayersTableJSONParser JSON issues as well as other issues. + * + * @author Rsl1122 + */ +@RunWith(JUnitPlatform.class) +class PlayersTableJSONParserTest { + + private static final int TEST_PORT_NUMBER = RandomData.randomInt(9005, 9500); + + private Database db; + private PlanSystem system; + + private UUID serverUUID; + private UUID playerUUID = TestConstants.PLAYER_ONE_UUID; + private UUID player2UUID = TestConstants.PLAYER_TWO_UUID; + + @BeforeEach + void setUp(@TempDir Path tempDir) throws Exception { + Assume.assumeTrue(false); // TODO Skipped due to problems with Gson, parsed 'columns' is null even though it's not. + + PluginMockComponent component = new PluginMockComponent(tempDir); + system = component.getPlanSystem(); + PlanConfig config = system.getConfigSystem().getConfig(); + config.set(WebserverSettings.PORT, TEST_PORT_NUMBER); + + system.enable(); + db = system.getDatabaseSystem().getDatabase(); + serverUUID = system.getServerInfo().getServerUUID(); + storePlayerData(); + } + + private void storePlayerData() throws Exception { + db.executeTransaction(new WorldNameStoreTransaction(serverUUID, "World")); + + db.executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> 1000L, TestConstants.PLAYER_ONE_NAME, serverUUID)); + db.executeTransaction(new PlayerRegisterTransaction(player2UUID, () -> 123456789L, TestConstants.PLAYER_TWO_NAME)); + + Session session = new Session(playerUUID, serverUUID, 12345L, "World", "SURVIVAL"); + session.endSession(22345L); + db.executeTransaction(new SessionEndTransaction(session)); + Session session2 = new Session(player2UUID, serverUUID, 12345L, "World", "SURVIVAL"); + session2.endSession(22345L); + db.executeTransaction(new SessionEndTransaction(session2)); + + ExtensionService extensionService = ExtensionService.getInstance(); + extensionService.register(new PlayerExtension()); + ((ExtensionServiceImplementation) extensionService).updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL); + ((ExtensionServiceImplementation) extensionService).updatePlayerValues(player2UUID, TestConstants.PLAYER_TWO_NAME, CallEvents.MANUAL); + + db.executeTransaction(new Transaction() { + @Override + protected void performOperations() { + + } + }).get(); // Wait for transactions to finish + } + + @Test + void playersTableJSONDoesNotContainDuplicateColumns() { + PlayersTableJSONParser parser = createParser(); + class Column { + String title; + } + + class Table { + Column[] columns; + } + + String json = parser.toJSONString(); + System.out.println("Parsed: " + json); + Table table = new Gson().fromJson(json, Table.class); + + Set foundColumnNames = new HashSet<>(); + for (Column column : table.columns) { + assertFalse(foundColumnNames.contains(column.title), () -> "Duplicate column title: '" + column.title + "'"); + foundColumnNames.add(column.title); + } + } + + private PlayersTableJSONParser createParser() { + int xMostRecentPlayers = 5; + int loginThreshold = 5; + long playtimeThreshold = TimeUnit.DAYS.toMillis(1L); + boolean openPlayerLinksInNewTab = false; + + return new PlayersTableJSONParser( + db.query(new ServerPlayersTableContainersQuery(serverUUID)), + db.query(new ExtensionServerPlayerDataTableQuery(serverUUID, xMostRecentPlayers)), + xMostRecentPlayers, playtimeThreshold, loginThreshold, openPlayerLinksInNewTab, + new Formatters(system.getConfigSystem().getConfig(), new Locale()) + ); + } + + @AfterEach + void tearDown() { + system.disable(); + } + + @PluginInfo(name = "PlayerExtension") + public class PlayerExtension implements DataExtension { + @NumberProvider(text = "a number", showInPlayerTable = true) + public long value(UUID playerUUD) { + return 5L; + } + + @BooleanProvider(text = "a boolean", showInPlayerTable = true) + public boolean boolVal(UUID playerUUID) { + return false; + } + + @DoubleProvider(text = "a double", showInPlayerTable = true) + public double doubleVal(UUID playerUUID) { + return 0.5; + } + + @PercentageProvider(text = "a percentage", showInPlayerTable = true) + public double percentageVal(UUID playerUUID) { + return 0.5; + } + + @StringProvider(text = "a string", showInPlayerTable = true) + public String stringVal(UUID playerUUID) { + return "Something"; + } + } +} \ No newline at end of file