From 2510cb278eb16a0ab228b079d5e09e96bb5e7b9f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:37:48 -0300 Subject: [PATCH 01/56] test: Add permssions tests --- .../telegrambridge/PermissionsTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/PermissionsTest.java diff --git a/src/test/java/org/altart/telegrambridge/PermissionsTest.java b/src/test/java/org/altart/telegrambridge/PermissionsTest.java new file mode 100644 index 0000000..a3502ad --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/PermissionsTest.java @@ -0,0 +1,39 @@ +package org.altart.telegrambridge; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PermissionsTest { + + static final String[] PERMISSIONS = {"DEFAULT_TRANSLATION_CONFIG", "TRANSLATION_CONFIG", "REPLY_COMMAND", "RECEIVE", "SEND"}; + + @Test + @DisplayName("Permissions getString method") + void getString() { + assertEquals("telegrambridge.commands.config.default-language", Permissions.DEFAULT_TRANSLATION_CONFIG.getString()); + assertEquals("telegrambridge.commands.config.language", Permissions.TRANSLATION_CONFIG.getString()); + assertEquals("telegrambridge.commands.reply", Permissions.REPLY_COMMAND.getString()); + assertEquals("telegrambridge.receive", Permissions.RECEIVE.getString()); + assertEquals("telegrambridge.send", Permissions.SEND.getString()); + } + + @Test + @DisplayName("Permissions values method") + void values() { + Permissions[] perms = Permissions.values(); + for (int i = 0; i < perms.length; i++) { + assertEquals(PERMISSIONS[i], perms[i].name()); + } + assertEquals(PERMISSIONS.length, perms.length); + } + + @Test + @DisplayName("Permissions valueOf method") + void valueOf() { + for (String perm : PERMISSIONS) { + assertEquals(perm, Permissions.valueOf(perm).name()); + } + } +} From 91c728207d2c548bc7ae31135ade914a1be77287 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:39:03 -0300 Subject: [PATCH 02/56] test: Add time converter tests --- .../utils/TimeConverterTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/utils/TimeConverterTest.java diff --git a/src/test/java/org/altart/telegrambridge/utils/TimeConverterTest.java b/src/test/java/org/altart/telegrambridge/utils/TimeConverterTest.java new file mode 100644 index 0000000..6cc7270 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/utils/TimeConverterTest.java @@ -0,0 +1,64 @@ +package org.altart.telegrambridge.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class TimeConverterTest { + + @Test + @DisplayName("TimeConverter ticksToDays method") + void daysToMonthsAndYears() { + int[] oneDay = TimeConverter.daysToMonthsAndYears(1); + assertEquals(1, oneDay[0]); + assertEquals(0, oneDay[1]); + assertEquals(0, oneDay[2]); + + int[] oneMonth = TimeConverter.daysToMonthsAndYears(32); + assertEquals(1, oneMonth[0]); + assertEquals(1, oneMonth[1]); + assertEquals(0, oneMonth[2]); + + int[] twelveMonths = TimeConverter.daysToMonthsAndYears(365); + assertEquals(30, twelveMonths[0]); + assertEquals(11, twelveMonths[1]); + assertEquals(0, twelveMonths[2]); + + int[] oneYear = TimeConverter.daysToMonthsAndYears(367); + assertEquals(1, oneYear[0]); + assertEquals(0, oneYear[1]); + assertEquals(1, oneYear[2]); + + int[] fourtyYears = TimeConverter.daysToMonthsAndYears(14611); + assertEquals(1, fourtyYears[0]); + assertEquals(0, fourtyYears[1]); + assertEquals(40, fourtyYears[2]); + } + + @Test + @DisplayName("TimeConverter ticksToTime method") + void ticksToTime() { + String zero = TimeConverter.ticksToTime(0); + assertEquals("00:00", zero); + String midday = TimeConverter.ticksToTime(6000); + assertEquals("06:00", midday); + String midnight = TimeConverter.ticksToTime(18000); + assertEquals("18:00", midnight); + String end = TimeConverter.ticksToTime(24000); + assertEquals("24:00", end); + } + + @Test + @DisplayName("TimeConverter getTimeCycleEmoji method") + void getTimeCycleEmoji() { + String dawn = TimeConverter.getTimeCycleEmoji(0); + assertEquals("\uD83C\uDF05", dawn); + String morning = TimeConverter.getTimeCycleEmoji(12000); + assertEquals("\uD83C\uDF07", morning); + String noon = TimeConverter.getTimeCycleEmoji(13000); + assertEquals("\uD83C\uDF03", noon); + String evening = TimeConverter.getTimeCycleEmoji(23000); + assertEquals("\uD83C\uDF05", evening); + } +} From 1e841a0141ad54e9f61a4c08cbfbaadd91bde89e Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:41:42 -0300 Subject: [PATCH 03/56] test: Add format place holder test --- .../telegrambridge/utils/FormatTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/utils/FormatTest.java diff --git a/src/test/java/org/altart/telegrambridge/utils/FormatTest.java b/src/test/java/org/altart/telegrambridge/utils/FormatTest.java new file mode 100644 index 0000000..aace772 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/utils/FormatTest.java @@ -0,0 +1,20 @@ +package org.altart.telegrambridge.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; + +class FormatTest { + @Test + @DisplayName("Format string method") + void string() { + assertEquals("Hello, world!", Format.string("Hello, %name%!", "name", "world")); + assertEquals("\n", Format.string("\\n", "name", "world")); + HashMap values = new HashMap<>(); + values.put("name", "world"); + assertEquals("Hello, world!", Format.string("Hello, %name%!", values)); + } +} From a8771d5d6497b528bbbcc1eab1c08a100302b3cf Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:49:36 -0300 Subject: [PATCH 04/56] test: Add game event test --- .../telegrambridge/StandardMockTest.java | 19 + .../telegrambridge/events/GameEventTest.java | 359 ++++++++++++++++++ src/test/resources/config.yml | 3 + src/test/resources/lang/en.yml | 36 ++ src/test/resources/lang/tt.yml | 36 ++ 5 files changed, 453 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/StandardMockTest.java create mode 100644 src/test/java/org/altart/telegrambridge/events/GameEventTest.java create mode 100644 src/test/resources/config.yml create mode 100644 src/test/resources/lang/en.yml create mode 100644 src/test/resources/lang/tt.yml diff --git a/src/test/java/org/altart/telegrambridge/StandardMockTest.java b/src/test/java/org/altart/telegrambridge/StandardMockTest.java new file mode 100644 index 0000000..4dd5a54 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/StandardMockTest.java @@ -0,0 +1,19 @@ +package org.altart.telegrambridge; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.MockitoAnnotations; + +public abstract class StandardMockTest { + AutoCloseable closeable; + + @BeforeEach + public void openMocks() { + closeable = MockitoAnnotations.openMocks(this); + } + + @AfterEach + public void releaseMocks() throws Exception { + closeable.close(); + } +} diff --git a/src/test/java/org/altart/telegrambridge/events/GameEventTest.java b/src/test/java/org/altart/telegrambridge/events/GameEventTest.java new file mode 100644 index 0000000..7192df0 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/events/GameEventTest.java @@ -0,0 +1,359 @@ +package org.altart.telegrambridge.events; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.bot.feature.PinMessage; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.bukkit.*; +import org.bukkit.advancement.Advancement; +import org.bukkit.block.*; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerAdvancementDoneEvent; +import org.bukkit.event.player.PlayerBedEnterEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.*; + +class GameEventTest extends StandardMockTest { + @Mock + Plugin mockPlugin; + + @Mock + Config mockConfig; + + @Mock + Player mockPlayer; + + @Mock + TelegramBot mockTelegramBot; + + @Mock + PinMessage mockPinMessage; + + final GameEvent gameEvent = new GameEvent(); + + @Test + @DisplayName("Test onPlayerJoin() method") + void onPlayerJoin() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.joinAndLeaveEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + TelegramBridge.telegramBot.pinMessageFeature = mockPinMessage; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + + PlayerJoinEvent event = new PlayerJoinEvent(mockPlayer, "Player joined the game"); + gameEvent.onPlayerJoin(event); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick joined the game!"); + verify(mockPinMessage, times(1)).addPlayer("playerNick"); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerJoin() method with joinAndLeaveEvent disabled") + void onPlayerJoinNoEvent() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.joinAndLeaveEvent = false; + + PlayerJoinEvent event = new PlayerJoinEvent(mockPlayer, "Player joined the game"); + gameEvent.onPlayerJoin(event); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPinMessage, never()).addPlayer(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerJoin() method with sendToTelegram disabled") + void onPlayerJoinNoTelegram() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + TelegramBridge.config.joinAndLeaveEvent = true; + + PlayerJoinEvent event = new PlayerJoinEvent(mockPlayer, "Player joined the game"); + gameEvent.onPlayerJoin(event); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPinMessage, never()).addPlayer(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerLeave() method") + void onPlayerLeave() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.joinAndLeaveEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + TelegramBridge.telegramBot.pinMessageFeature = mockPinMessage; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + + PlayerQuitEvent leaveEvent = new PlayerQuitEvent(mockPlayer, "Player left the game"); + gameEvent.onPlayerLeave(leaveEvent); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick left the game!"); + verify(mockPinMessage, times(1)).removePlayer("playerNick"); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerLeave() method with joinAndLeaveEvent disabled") + void onPlayerLeaveNoEvent() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.joinAndLeaveEvent = false; + + PlayerQuitEvent leaveEvent = new PlayerQuitEvent(mockPlayer, "Player left the game"); + gameEvent.onPlayerLeave(leaveEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPinMessage, never()).removePlayer(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerLeave() method with sendToTelegram disabled") + void onPlayerLeaveNoTelegram() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + TelegramBridge.config.joinAndLeaveEvent = true; + + PlayerQuitEvent leaveEvent = new PlayerQuitEvent(mockPlayer, "Player left the game"); + gameEvent.onPlayerLeave(leaveEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPinMessage, never()).removePlayer(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerDeath() method") + void onPlayerDeath() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.deathEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + when(mockPlayer.isDead()).thenReturn(true); + + List items = Collections.singletonList(new ItemStack(Material.STICK)); + PlayerDeathEvent deathEvent = new PlayerDeathEvent(mockPlayer, items, 0, "Player died"); + + gameEvent.onPlayerDeath(deathEvent); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick died! Player died"); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerDeath() method with deathEvent disabled") + void onPlayerDeathNoEvent() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.deathEvent = false; + + List items = Collections.singletonList(new ItemStack(Material.STICK)); + PlayerDeathEvent deathEvent = new PlayerDeathEvent(mockPlayer, items, 0, "Player died"); + gameEvent.onPlayerDeath(deathEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerDeath() method with sendToTelegram disabled") + void onPlayerDeathNoTelegram() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + TelegramBridge.config.deathEvent = true; + + List items = Collections.singletonList(new ItemStack(Material.STICK)); + PlayerDeathEvent deathEvent = new PlayerDeathEvent(mockPlayer, items, 0, "Player died"); + gameEvent.onPlayerDeath(deathEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerAsleep() method") + void onPlayerAsleep() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.sleepEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + + PlayerBedEnterEvent.BedEnterResult bedEnterResult = PlayerBedEnterEvent.BedEnterResult.OK; + PlayerBedEnterEvent sleepEvent = new PlayerBedEnterEvent(mockPlayer, mock(Block.class), bedEnterResult); + gameEvent.onPlayerAsleep(sleepEvent); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick went to bed!"); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerAsleep() method with sleepEvent disabled") + void onPlayerAsleepNoEvent() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.sleepEvent = false; + + PlayerBedEnterEvent.BedEnterResult bedEnterResult = PlayerBedEnterEvent.BedEnterResult.OK; + PlayerBedEnterEvent sleepEvent = new PlayerBedEnterEvent(mockPlayer, mock(Block.class), bedEnterResult); + gameEvent.onPlayerAsleep(sleepEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onPlayerAsleep() method with sendToTelegram disabled") + void onPlayerAsleepNoTelegram() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + TelegramBridge.config.sleepEvent = true; + + PlayerBedEnterEvent.BedEnterResult bedEnterResult = PlayerBedEnterEvent.BedEnterResult.OK; + PlayerBedEnterEvent sleepEvent = new PlayerBedEnterEvent(mockPlayer, mock(Block.class), bedEnterResult); + gameEvent.onPlayerAsleep(sleepEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onAdvancement() method") + void onAdvancement() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.advancementEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + + Advancement mockAdvancement = mock(Advancement.class); + when(mockAdvancement.getKey()).thenReturn(NamespacedKey.minecraft("story/root")); + PlayerAdvancementDoneEvent advancementEvent = new PlayerAdvancementDoneEvent(mockPlayer, mockAdvancement); + gameEvent.onAdvancement(advancementEvent); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick made an advancement! Minecraft: The heart and story of the game"); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Test onAdvancement() method with advancementEvent disabled") + void onAdvancementNoEvent() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.advancementEvent = false; + + Advancement mockAdvancement = mock(Advancement.class); + when(mockAdvancement.getKey()).thenReturn(NamespacedKey.minecraft("story/root")); + PlayerAdvancementDoneEvent advancementEvent = new PlayerAdvancementDoneEvent(mockPlayer, mockAdvancement); + gameEvent.onAdvancement(advancementEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onAdvancement() method with sendToTelegram disabled") + void onAdvancementNoTelegram() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + TelegramBridge.config.advancementEvent = true; + + Advancement mockAdvancement = mock(Advancement.class); + when(mockAdvancement.getKey()).thenReturn(NamespacedKey.minecraft("story/root")); + PlayerAdvancementDoneEvent advancementEvent = new PlayerAdvancementDoneEvent(mockPlayer, mockAdvancement); + gameEvent.onAdvancement(advancementEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onAdvancement() method with a recipe advancement") + void onAdvancementRecipes() { + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.advancementEvent = true; + + Advancement mockAdvancement = mock(Advancement.class); + when(mockAdvancement.getKey()).thenReturn(NamespacedKey.minecraft("recipes/root")); + PlayerAdvancementDoneEvent advancementEvent = new PlayerAdvancementDoneEvent(mockPlayer, mockAdvancement); + gameEvent.onAdvancement(advancementEvent); + + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + verify(mockPlayer, never()).getDisplayName(); + } + + @Test + @DisplayName("Test onAdvancement() method with a dummy advancement key") + void onAdvancementDummyKey() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.config.advancementEvent = true; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations(null); + TelegramBridge.telegramBot = mockTelegramBot; + + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + + Advancement mockAdvancement = mock(Advancement.class); + when(mockAdvancement.getKey()).thenReturn(NamespacedKey.minecraft("dummy/root")); + PlayerAdvancementDoneEvent advancementEvent = new PlayerAdvancementDoneEvent(mockPlayer, mockAdvancement); + gameEvent.onAdvancement(advancementEvent); + + verify(mockTelegramBot, times(1)).broadcastMessage("Player playerNick made an advancement! advancements.dummy.root.title: advancements.dummy.root.description"); + verify(mockPlayer, times(1)).getDisplayName(); + } +} diff --git a/src/test/resources/config.yml b/src/test/resources/config.yml new file mode 100644 index 0000000..0404d69 --- /dev/null +++ b/src/test/resources/config.yml @@ -0,0 +1,3 @@ +botToken: BT +chats: +- id: '123456789' diff --git a/src/test/resources/lang/en.yml b/src/test/resources/lang/en.yml new file mode 100644 index 0000000..dbd69ea --- /dev/null +++ b/src/test/resources/lang/en.yml @@ -0,0 +1,36 @@ +# Author: @alt-art + +# Month names for the /time command +months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] +# Media types for the type of media that is sent to the chat +mediaTypes: [ 'an image', 'a video', 'a document', 'an audio', 'a voice', 'a sticker', 'a contact', 'a location', 'a poll', 'a media' ] + +# When a player joins the server +join: 'Player %playername% joined the game!' +# When a player leaves the server +leave: 'Player %playername% left the game!' +# When a player dies +death: 'Player %playername% died! %deathmessage%' +# When a player makes an achievement +advancement: 'Player %playername% made an advancement! %advancement%' +# When a player sleeps +sleep: 'Player %playername% went to bed!' + +# When a minecraft player sends a message +chatMessage: '[%playername%]: %message%' +# When a telegram user sends a message +telegramMessage: '§7[§bTelegram§7] §f[%user%] %message%' +# When a telegram user sends a media +telegramMedia: '§7[§bTelegram§7] §f[%user%] sent %type%%caption%' +# When player or telegram user sends a reply +telegramReply: '- §breply to §7%user%: %message%§r -\n' + +# /online command +online: 'There are %count% players online%players%' +# /time command +time: 'Time is %time% %emoji%\nDate is %month% %day%, Year %year%' + +# Reply button in chat +replyButton: 'Reply' +# Message when hovering over the reply button +replyHint: 'Click to reply' diff --git a/src/test/resources/lang/tt.yml b/src/test/resources/lang/tt.yml new file mode 100644 index 0000000..cc5139a --- /dev/null +++ b/src/test/resources/lang/tt.yml @@ -0,0 +1,36 @@ +# Author: @alt-art + +# Nome dos meses para o comando /time +months: ['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'M11', 'M12' ] +# Tipos de mídia para o tipo de mídia que é enviada para o chat +mediaTypes: [ 'MI', 'MV', 'MD', 'MM', 'MA', 'MS', 'MC', 'ML', 'ME', 'M?' ] + +# Quando um jogador entra no servidor +join: 'JE' +# Quando um jogador sai do servidor +leave: 'JS' +# Quando um jogador morre +death: 'JM' +# Quando um jogador faz uma conquista +advancement: 'JC' +# Quando um jogador dorme +sleep: 'JD' + +# Quando um jogador envia uma mensagem +chatMessage: 'CM' +# Quando um usuário do Telegram envia uma mensagem +telegramMessage: 'TM' +# Quando um usuário do Telegram envia uma mídia +telegramMedia: 'TMM' +# Quando um jogador ou usuário do Telegram envia uma resposta +telegramReply: 'TR' + +# Comando /online +online: 'JO' +# Comando /time +time: 'JT' + +# Botão de resposta no chat +replyButton: 'RB' +# Mensagem ao colocar o mouse sobre o botão de resposta +replyHint: 'RA' From 621ac2199f585d4d931e0a653d3b58be60887349 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:53:31 -0300 Subject: [PATCH 05/56] test: Add chat event tests --- .../telegrambridge/events/ChatEventTest.java | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/events/ChatEventTest.java diff --git a/src/test/java/org/altart/telegrambridge/events/ChatEventTest.java b/src/test/java/org/altart/telegrambridge/events/ChatEventTest.java new file mode 100644 index 0000000..7b2bd80 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/events/ChatEventTest.java @@ -0,0 +1,163 @@ +package org.altart.telegrambridge.events; + +import org.altart.telegrambridge.Permissions; +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.bukkit.entity.*; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.mockito.Mock; + +class ChatEventTest extends StandardMockTest { + @Mock + Player mockPlayer; + + @Mock + Config mockConfig; + + @Mock + TelegramBot mockTelegramBot; + + @Mock + Plugin mockPlugin; + + @BeforeEach + void setUp() { + when(mockPlayer.getDisplayName()).thenReturn("playerNick"); + } + + @Test + @DisplayName("Chat event test") + void onChat() { + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + ChatEvent chatEvent = new ChatEvent(); + Set players = new HashSet<>(); + players.add(mockPlayer); + + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(true, mockPlayer, "message", players); + assertEquals("message", event.getMessage()); + + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + doNothing().when(mockTelegramBot).broadcastMessage(anyString()); + doNothing().when(mockConfig).load(); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.telegramBot = mockTelegramBot; + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + TelegramBridge.translations = new Translations(null); + + chatEvent.onChat(event); + + verify(mockTelegramBot, times(1)).broadcastMessage("[playerNick]: message"); + verify(mockPlayer, times(1)).hasPermission(Permissions.SEND.getString()); + verify(mockPlayer, times(1)).getDisplayName(); + } + + @Test + @DisplayName("Chat event test with no permissions") + void onChatNoPermission() { + when(mockPlayer.hasPermission(anyString())).thenReturn(false); + ChatEvent chatEvent = new ChatEvent(); + Set players = new HashSet<>(); + players.add(mockPlayer); + + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(true, mockPlayer, "message", players); + assertEquals("message", event.getMessage()); + + doNothing().when(mockConfig).load(); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + + chatEvent.onChat(event); + + verify(mockPlayer, times(1)).hasPermission(Permissions.SEND.getString()); + verify(mockPlayer, never()).getDisplayName(); + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + } + + @Test + @DisplayName("Chat event test with sendToTelegram false") + void onChatDoNotSendToTelegram() { + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + ChatEvent chatEvent = new ChatEvent(); + Set players = new HashSet<>(); + players.add(mockPlayer); + + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(true, mockPlayer, "message", players); + assertEquals("message", event.getMessage()); + + doNothing().when(mockConfig).load(); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = false; + + chatEvent.onChat(event); + + verify(mockPlayer, times(1)).hasPermission(Permissions.SEND.getString()); + verify(mockPlayer, never()).getDisplayName(); + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + } + + @Test + @DisplayName("Chat event test with empty message") + void onChatEmptyMessage() { + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + ChatEvent chatEvent = new ChatEvent(); + Set players = new HashSet<>(); + players.add(mockPlayer); + + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(true, mockPlayer, "", players); + assertEquals("", event.getMessage()); + + doNothing().when(mockConfig).load(); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + + chatEvent.onChat(event); + + verify(mockPlayer, times(1)).hasPermission(Permissions.SEND.getString()); + verify(mockPlayer, times(1)).getDisplayName(); + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + } + + @Test + @DisplayName("Chat event test with command") + void onChatCommand() { + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + ChatEvent chatEvent = new ChatEvent(); + Set players = new HashSet<>(); + players.add(mockPlayer); + + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(true, mockPlayer, "/command", players); + assertEquals("/command", event.getMessage()); + + doNothing().when(mockConfig).load(); + + TelegramBridge.config = mockConfig; + TelegramBridge.config.sendToTelegram = true; + + chatEvent.onChat(event); + + verify(mockPlayer, never()).hasPermission(anyString()); + verify(mockPlayer, never()).getDisplayName(); + verify(mockTelegramBot, never()).broadcastMessage(anyString()); + } +} From 90435705d954a6c5e5b75e032db4bcbc1d48f5d1 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:54:55 -0300 Subject: [PATCH 06/56] test: Add sqlite tests --- .../telegrambridge/database/SQLiteTest.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/database/SQLiteTest.java diff --git a/src/test/java/org/altart/telegrambridge/database/SQLiteTest.java b/src/test/java/org/altart/telegrambridge/database/SQLiteTest.java new file mode 100644 index 0000000..18ddd3c --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/database/SQLiteTest.java @@ -0,0 +1,72 @@ +package org.altart.telegrambridge.database; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.io.File; +import java.util.UUID; +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class SQLiteTest extends StandardMockTest { + @Mock + Plugin mockPlugin; + + @BeforeEach + public void setUp() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + TelegramBridge.plugin = mockPlugin; + } + + @AfterEach + void removeDatabase() { + File database = new File("src/test/resources/database.db"); + boolean delete = database.delete(); + assertTrue(delete); + } + + @Test + @DisplayName("Test sqlite getLang() and setLang() methods") + void getLang() { + SQLite sqlite = new SQLite(); + UUID uuid = UUID.randomUUID(); + sqlite.setLang(uuid, "en"); + assertEquals("en", sqlite.getLang(uuid)); + sqlite.close(); + } + + @Test + @DisplayName("Test sqlite setLang() method with invalid language") + void invalidLang() { + SQLite sqlite = new SQLite(); + UUID uuid = UUID.randomUUID(); + assertThrows(IllegalArgumentException.class, () -> sqlite.setLang(uuid, "eng")); + sqlite.close(); + } + + @Test + @DisplayName("Test sqlite methods with SQLite connection closed to trigger SQLiteException") + void sqliteException() { + TelegramBridge.log = mock(Logger.class); + + SQLite sqlite = new SQLite(); + sqlite.close(); + UUID uuid = UUID.randomUUID(); + assertNull(sqlite.getLang(uuid)); + verify(TelegramBridge.log, times(92)).severe(anyString()); + + SQLite sqlite2 = new SQLite(); + sqlite2.close(); + sqlite2.setLang(uuid, "en"); + verify(TelegramBridge.log, times(184)).severe(anyString()); + } +} From cfdc18cb0d46178d1dadbb9473f1097c7d76e100 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:55:39 -0300 Subject: [PATCH 07/56] test: Add config tests --- .../telegrambridge/config/ConfigTest.java | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/config/ConfigTest.java diff --git a/src/test/java/org/altart/telegrambridge/config/ConfigTest.java b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java new file mode 100644 index 0000000..23c82c9 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java @@ -0,0 +1,191 @@ +package org.altart.telegrambridge.config; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.List; +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ConfigTest extends StandardMockTest { + + @Mock + Plugin mockPlugin; + + @Test + @DisplayName("Load config") + void load() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + + Config config = new Config(); + verify(mockPlugin, times(1)).getDataFolder(); + assertEquals("BT", config.botToken); + assertEquals("123456789", config.chats.get(0).id); + } + + @Test + @DisplayName("Create config") + void create() { + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + Logger log = mock(Logger.class); + TelegramBridge.log = log; + + Config config = new Config(); + verify(mockPlugin, times(1)).getDataFolder(); + assertEquals("YOUR_BOT_TOKEN", config.botToken); + assertEquals("YOUR_CHAT_ID", config.chats.get(0).id); + verify(log, times(1)).warning(anyString()); + verify(log, times(1)).info(anyString()); + + assertTrue(new File("src/test/resources/empty/config.yml").delete()); + } + + @Test + @DisplayName("Save config") + void save() { + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + Logger log = mock(Logger.class); + TelegramBridge.log = log; + + Config config = new Config(); + config.botToken = "BT"; + config.chats.get(0).id = "ID"; + config.chats.get(0).thread = 77; + config.chats.get(0).pinnedMessageId = 77; + config.sendToTelegram = !config.sendToTelegram; + config.sendToChat = !config.sendToChat; + config.joinAndLeaveEvent = !config.joinAndLeaveEvent; + config.deathEvent = !config.deathEvent; + config.sleepEvent = !config.sleepEvent; + config.advancementEvent = !config.advancementEvent; + config.lang = "LANG"; + config.pinned = "PINNED"; + config.save(); + + YamlConfiguration yaml = YamlConfiguration.loadConfiguration(new File("src/test/resources/empty/config.yml")); + Field[] fields = config.getClass().getDeclaredFields(); + for (Field field : fields) { + try { + if (yaml.contains(field.getName())) { + if (field.getType().equals(String.class)) { + assertEquals(field.get(config), yaml.get(field.getName())); + } else if (field.getType().equals(Boolean.class)) { + assertEquals(field.get(config), yaml.getBoolean(field.getName())); + } else if (field.getType().equals(Integer.class)) { + assertEquals(field.get(config), yaml.getInt(field.getName())); + } else if (field.getType().equals(List.class)) { + Config.Chat chat = Config.Chat.chatsFrom(yaml.getMapList(field.getName())).get(0); + assertEquals(chat.id, config.chats.get(0).id); + assertEquals(chat.thread, config.chats.get(0).thread); + assertEquals(chat.pinnedMessageId, config.chats.get(0).pinnedMessageId); + } + } + } catch (Exception e) { + fail(); + } + } + verify(log, times(1)).warning(anyString()); + verify(log, times(1)).info(anyString()); + assertTrue(new File("src/test/resources/empty/config.yml").delete()); + } + + @Test + @DisplayName("Set PinnedMessageId") + void setPinnedMessageId() { + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + Logger log = mock(Logger.class); + TelegramBridge.log = log; + + Config config = new Config(); + + config.chats.get(0).id = "ID"; + config.setPinnedMessageId("ID", 77); + assertEquals(77, config.chats.get(0).pinnedMessageId); + + config.setPinnedMessageId("BANANA", 66); + assertNotEquals(66, config.chats.get(0).pinnedMessageId); + + YamlConfiguration yaml = YamlConfiguration.loadConfiguration(new File("src/test/resources/empty/config.yml")); + Config.Chat chat = Config.Chat.chatsFrom(yaml.getMapList("chats")).get(0); + assertEquals(77, chat.pinnedMessageId); + assertEquals("ID", chat.id); + + verify(log, times(1)).warning(anyString()); + verify(log, times(1)).info(anyString()); + assertTrue(new File("src/test/resources/empty/config.yml").delete()); + } + + @Test + @DisplayName("Set Lang") + void setLang() { + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + Logger log = mock(Logger.class); + TelegramBridge.log = log; + + Config config = new Config(); + + config.setLang("LANG"); + assertEquals("LANG", config.lang); + + YamlConfiguration yaml = YamlConfiguration.loadConfiguration(new File("src/test/resources/empty/config.yml")); + assertEquals("LANG", yaml.get("lang")); + + verify(log, times(1)).warning(anyString()); + verify(log, times(1)).info(anyString()); + assertTrue(new File("src/test/resources/empty/config.yml").delete()); + } + + @Test + @DisplayName("Set Thread") + void setThread() { + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + Logger log = mock(Logger.class); + TelegramBridge.log = log; + + Config config = new Config(); + + config.chats.get(0).id = "ID"; + config.setThread("ID", 77); + assertEquals(77, config.chats.get(0).thread); + + config.setThread("BANANA", 66); + assertNotEquals(66, config.chats.get(0).thread); + + YamlConfiguration yaml = YamlConfiguration.loadConfiguration(new File("src/test/resources/empty/config.yml")); + Config.Chat chat = Config.Chat.chatsFrom(yaml.getMapList("chats")).get(0); + assertEquals(77, chat.thread); + assertEquals("ID", chat.id); + + verify(log, times(1)).warning(anyString()); + verify(log, times(1)).info(anyString()); + assertTrue(new File("src/test/resources/empty/config.yml").delete()); + } +} From 1cb9edbbfd8ac92d3ed0448928c54be1855cb5c9 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 14:56:03 -0300 Subject: [PATCH 08/56] test: Add translations tests --- .../config/TranslationsTest.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/config/TranslationsTest.java diff --git a/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java new file mode 100644 index 0000000..086dbe5 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java @@ -0,0 +1,149 @@ +package org.altart.telegrambridge.config; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class TranslationsTest extends StandardMockTest { + @Mock + Plugin mockPlugin; + + @Test + @DisplayName("Get translation") + void getTranslation() { + File resourseFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + + TelegramBridge.plugin = mockPlugin; + + Translations translations = new Translations("en"); + List languageCodes = translations.getLoadedLanguages(); + List expectedLanguageCodes = Arrays.asList("en", "es", "jp", "pt", "ru", "uk", "tt"); + assertEquals(expectedLanguageCodes.size(), languageCodes.size()); + for (String lang : expectedLanguageCodes) { + assertTrue(languageCodes.contains(lang)); + } + Translations.Translation translation = translations.get(null); + assertNotNull(translation); + verify(mockPlugin, times(1)).getDataFolder(); + Field[] fields = translation.getClass().getDeclaredFields(); + YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourseFolder, "lang/en.yml")); + for (Field field : fields) { + field.setAccessible(true); + try { + if (field.getName().equals("__$hits$__")) { + continue; + } + assertEquals(yamlConfiguration.get(field.getName()), field.get(translation)); + } catch (IllegalAccessException e) { + System.out.println(e.getMessage()); + fail(); + } + } + } + + @Test + @DisplayName("Set default language") + void setDefaultLang() { + File resourseFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + + TelegramBridge.plugin = mockPlugin; + + Translations translations = new Translations(null); + try { + translations.setDefaultLang("pt"); + } catch (Exception e) { + fail(); + } + + Field[] fields = translations.get().getClass().getDeclaredFields(); + YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourseFolder, "lang/pt.yml")); + for (Field field : fields) { + field.setAccessible(true); + try { + if (field.getName().equals("__$hits$__")) { + continue; + } + assertEquals(yamlConfiguration.get(field.getName()), field.get(translations.get())); + } catch (IllegalAccessException e) { + System.out.println(e.getMessage()); + fail(); + } + } + } + + @Test + @DisplayName("Set default language with invalid language and non-existent file") + void translationExceptions() { + File resourseFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + + TelegramBridge.plugin = mockPlugin; + + Translations translations = new Translations(null); + assertThrows(Exception.class, () -> translations.setDefaultLang("fr")); + + File mockFile = mock(File.class); + when(mockFile.exists()).thenReturn(false); + new Translations.Translation(mockFile); + verify(mockFile, times(1)).exists(); + } + + @Test + @DisplayName("Empty translations directory") + void emptyTranslationsDirectory() { + File resourseFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + + TelegramBridge.plugin = mockPlugin; + + new Translations(null); + + verify(mockPlugin, times(1)).getDataFolder(); + List languageCodes = new Translations(null).getLoadedLanguages(); + for (String lang : languageCodes) { + verify(mockPlugin, times(1)).saveResource("lang/" + lang + ".yml", false); + } + + File langDir = new File(resourseFolder, "lang"); + assertTrue(langDir.delete()); + assertTrue(resourseFolder.delete()); + } + + @Test + @DisplayName("File passed as directory") + void nullTranslationsDirectory() { + File fileAsDir = new File("src/test/resources/lang/lang"); + try { + assertTrue(fileAsDir.createNewFile()); + } catch (IOException e) { + fail(); + } + + File translationsFolder = new File("src/test/resources/lang"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.plugin = mockPlugin; + + new Translations(null); + + verify(mockPlugin, times(1)).getDataFolder(); + verify(mockPlugin, never()).saveResource("lang/tt.yml", false); + + assertTrue(fileAsDir.delete()); + } +} From 762cc9b8122f71e4f9d0c44c75542bc8d8abea2f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:01:45 -0300 Subject: [PATCH 09/56] test: Add telegram bot class tests --- .../telegrambridge/bot/TelegramBotTest.java | 489 ++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/bot/TelegramBotTest.java diff --git a/src/test/java/org/altart/telegrambridge/bot/TelegramBotTest.java b/src/test/java/org/altart/telegrambridge/bot/TelegramBotTest.java new file mode 100644 index 0000000..18d4ced --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/bot/TelegramBotTest.java @@ -0,0 +1,489 @@ +package org.altart.telegrambridge.bot; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.feature.MessageListener; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.User; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class TelegramBotTest extends StandardMockTest { + @Mock + Plugin mockPlugin; + @Mock + Update mockUpdate; + @Mock + Message mockMessage; + @Mock + User mockUser; + @Mock + Server mockServer; + @Mock + Player mockPlayer; + @Mock + Player mockPlayer2; + + @Test + @DisplayName("Message received") + void onUpdateReceivedMessage() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/test command"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, times(2)).getText(); + } + + @Test + @DisplayName("Message received null") + void onUpdateReceivedMessageNull() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(null); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, never()).onUpdateReceived(any()); + verify(mockMessage, never()).getText(); + } + + @Test + @DisplayName("Message received from bot") + void onUpdateReceivedMessageFromBot() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getIsBot()).thenReturn(true); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, never()).onUpdateReceived(any()); + verify(mockMessage, never()).getText(); + } + + @Test + @DisplayName("Message received chat id not in config") + void onUpdateReceivedMessageChatIdNotInConfig() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getIsBot()).thenReturn(false); + when(mockMessage.getChatId()).thenReturn(987654321L); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, never()).onUpdateReceived(any()); + verify(mockMessage, never()).getText(); + } + + @Test + @DisplayName("Message received not a command") + void onUpdateReceivedMessageNotACommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("test message"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getIsBot()).thenReturn(false); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, times(1)).getText(); + } + + @Test + @DisplayName("Message received has text false") + void onUpdateReceivedHasTextFalse() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getIsBot()).thenReturn(false); + when(mockMessage.hasText()).thenReturn(false); + when(mockMessage.getChatId()).thenReturn(123456789L); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + telegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + telegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, never()).getText(); + } + + @Test + @DisplayName("Message received no features") + void getBotUsername() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.config = new Config(); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + assertEquals("TelegramBridgeBot", telegramBot.getBotUsername()); + } + + @Test + @DisplayName("Online command") + void onlineCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + when(mockPlugin.getServer()).thenReturn(mockServer); + + List players = new ArrayList<>(); + players.add(mockPlayer); + players.add(mockPlayer2); + + when(mockServer.getOnlinePlayers()).thenAnswer(invocation -> players); + when(mockPlayer.getDisplayName()).thenReturn("Player1"); + when(mockPlayer2.getDisplayName()).thenReturn("Player2"); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/online"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot spyTelegramBot = spy(telegramBot); + doReturn(false).when(spyTelegramBot).isNotAdmin(any(),any()); + spyTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + spyTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, times(2)).getText(); + verify(spyTelegramBot, times(1)).reply("There are 2 players online\nPlayer1\nPlayer2", "123456789", 314159265); + verify(spyTelegramBot, never()).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Online command no players") + void onlineCommandNoPlayers() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + when(mockPlugin.getServer()).thenReturn(mockServer); + + List players = new ArrayList<>(); + + when(mockServer.getOnlinePlayers()).thenAnswer(invocation -> players); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/online"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot spyTelegramBot = spy(telegramBot); + doReturn(false).when(spyTelegramBot).isNotAdmin(any(),any()); + spyTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + spyTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, times(2)).getText(); + verify(spyTelegramBot, times(1)).reply("There are 0 players online", "123456789", 314159265); + verify(spyTelegramBot, never()).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Set pin command") + void setPinCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + when(mockPlugin.getServer()).thenReturn(mockServer); + + List players = new ArrayList<>(); + players.add(mockPlayer); + players.add(mockPlayer2); + + when(mockServer.getOnlinePlayers()).thenAnswer(invocation -> players); + when(mockPlayer.getDisplayName()).thenReturn("Player1"); + when(mockPlayer2.getDisplayName()).thenReturn("Player2"); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/setpin"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot mockTelegramBot = spy(telegramBot); + doReturn(false).when(mockTelegramBot).isNotAdmin(any(),any()); + doReturn(mockMessage).when(mockTelegramBot).sendSystemMessage(any(), any(), any()); + mockTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + mockTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockTelegramBot, times(1)).sendSystemMessage("Hey welcome to the chat!\nThere are 0 players online", "123456789", 0); + verify(mockTelegramBot, times(1)).pinMessage("123456789", 314159265); + verify(mockTelegramBot, times(1)).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Set pin command no players") + void unsetPinCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.config.chats.get(0).pinnedMessageId = 314159265; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/unsetpin"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot mockTelegramBot = spy(telegramBot); + doReturn(false).when(mockTelegramBot).isNotAdmin(any(),any()); + mockTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockTelegramBot, times(1)).unpinMessage("123456789", 314159265); + verify(mockTelegramBot, times(1)).deleteMessage("123456789", 314159265); + assertNull(TelegramBridge.config.chats.get(0).pinnedMessageId); + verify(mockTelegramBot, times(1)).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Time command") + void timeCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + when(mockPlugin.getServer()).thenReturn(mockServer); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/time"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + List worlds = new ArrayList<>(); + World world = mock(World.class); + worlds.add(world); + when(mockServer.getWorlds()).thenReturn(worlds); + when(world.getTime()).thenReturn(24000L); + when(world.getFullTime()).thenReturn(24000L*1000); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot spyTelegramBot = spy(telegramBot); + doReturn(false).when(spyTelegramBot).isNotAdmin(any(),any()); + spyTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + spyTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockMessageListener, times(1)).onUpdateReceived(any()); + verify(mockMessage, times(2)).getText(); + verify(spyTelegramBot, times(1)).reply( + "Time is 24:00 \n"+ + "Date is September 26, Year 2", + "123456789", + 314159265 + ); + verify(spyTelegramBot, never()).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Set thread command") + void setThreadCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.translations = new Translations("en"); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/setthread"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot mockTelegramBot = spy(telegramBot); + doReturn(false).when(mockTelegramBot).isNotAdmin(any(),any()); + doReturn(mockMessage).when(mockTelegramBot).sendSystemMessage(any(), any(), any()); + mockTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + mockTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockTelegramBot, times(1)).reply("Thread set", "123456789", 314159265); + verify(mockTelegramBot, times(1)).isNotAdmin(any(), any()); + } + + @Test + @DisplayName("Unset thread command") + void unsetThreadCommand() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.log = mock(Logger.class); + TelegramBridge.config = new Config(); + TelegramBridge.config.chats.get(0).id = "123456789"; + TelegramBridge.config.chats.get(0).thread = 123456789; + TelegramBridge.translations = new Translations("en"); + + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + + when(mockMessage.getText()).thenReturn("/unsetthread"); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockMessage.hasText()).thenReturn(true); + when(mockMessage.getChatId()).thenReturn(123456789L); + when(mockMessage.getMessageId()).thenReturn(314159265); + + MessageListener mockMessageListener = mock(MessageListener.class); + + TelegramBot telegramBot = new TelegramBot(mockPlugin); + TelegramBot mockTelegramBot = spy(telegramBot); + doReturn(false).when(mockTelegramBot).isNotAdmin(any(),any()); + mockTelegramBot.features = new ArrayList<>(Collections.singletonList(mockMessageListener)); + mockTelegramBot.onUpdateReceived(mockUpdate); + + verify(mockTelegramBot, times(1)).reply("Thread unset", "123456789", 314159265); + verify(mockTelegramBot, times(1)).isNotAdmin(any(), any()); + assertNull(TelegramBridge.config.chats.get(0).thread); + } +} From 43c4e57b5a657d16a8e32dc0e01223593872f62b Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:02:52 -0300 Subject: [PATCH 10/56] test: Add message listener feature tests --- .../bot/feature/MessageListenerTest.java | 319 ++++++++++++++++++ .../utils/ComponentMatcher.java | 203 +++++++++++ 2 files changed, 522 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/bot/feature/MessageListenerTest.java create mode 100644 src/test/java/org/altart/telegrambridge/utils/ComponentMatcher.java diff --git a/src/test/java/org/altart/telegrambridge/bot/feature/MessageListenerTest.java b/src/test/java/org/altart/telegrambridge/bot/feature/MessageListenerTest.java new file mode 100644 index 0000000..d468ade --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/bot/feature/MessageListenerTest.java @@ -0,0 +1,319 @@ +package org.altart.telegrambridge.bot.feature; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.hover.content.Text; +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.altart.telegrambridge.database.SQLite; +import org.altart.telegrambridge.utils.ComponentMatcher; +import org.apache.commons.lang.RandomStringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.User; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import static org.mockito.Mockito.*; + +class MessageListenerTest extends StandardMockTest { + @Mock + Plugin mockPlugin; + @Mock + TelegramBot mockTelegramBot; + @Mock + Update mockUpdate; + @Mock + Message mockMessage; + @Mock + Message mockReplyToMessage; + @Mock + Config mockConfig; + @Mock + User mockUser; + @Mock + Logger mockLogger; + @Mock + Server mockServer; + @Mock + SQLite mockSQLite; + @Mock + Player mockPlayer; + @Mock + Player.Spigot mockPlayerSpigot; + @Mock + Player mockPlayerNoReceivePerm; + @Mock + Player.Spigot mockPlayerNoReceivePermSpigot; + @Mock + Player mockPlayerNoReplyPerm; + @Mock + Player.Spigot mockPlayerNoReplyPermSpigot; + final MockedStatic utils = mockStatic(RandomStringUtils.class); + + @BeforeEach + void setUp() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockReplyToMessage.getFrom()).thenReturn(mockUser); + + TelegramBridge.config = mockConfig; + TelegramBridge.log = mockLogger; + TelegramBridge.database = mockSQLite; + TelegramBridge.plugin = mockPlugin; + TelegramBridge.translations = new Translations("en"); + + utils.when(() -> RandomStringUtils.random(anyInt(), anyBoolean(), anyBoolean())).thenReturn("asdf", "asdf", "aaaa"); + + List players = new ArrayList<>(); + + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + when(mockPlayer.spigot()).thenReturn(mockPlayerSpigot); + players.add(mockPlayer); + + when(mockPlayerNoReceivePerm.hasPermission(anyString())).thenReturn(false); + when(mockPlayerNoReceivePerm.spigot()).thenReturn(mockPlayerNoReceivePermSpigot); + players.add(mockPlayerNoReceivePerm); + + when(mockPlayerNoReplyPerm.hasPermission("telegrambridge.receive")).thenReturn(true); + when(mockPlayerNoReplyPerm.spigot()).thenReturn(mockPlayerNoReplyPermSpigot); + players.add(mockPlayerNoReplyPerm); + + when(mockServer.getOnlinePlayers()).thenAnswer(invocation -> players); + when(mockServer.getLogger()).thenReturn(mockLogger); + + setServerMock(mockServer); + } + + @AfterEach + void tearDown() { + utils.close(); + } + + private void setServerMock(Server mock) { + try { + Field server = Bukkit.class.getDeclaredField("server"); + server.setAccessible(true); + server.set(server, mock); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + @DisplayName("Update received") + void onUpdateReceived() { + when(mockMessage.getText()).thenReturn("test"); + when(mockReplyToMessage.getText()).thenReturn("test reply"); + when(mockReplyToMessage.hasText()).thenReturn(true); + when(mockMessage.getReplyToMessage()).thenReturn(mockReplyToMessage); + when(mockUser.getUserName()).thenReturn("testUser"); + + TelegramBridge.config.sendToChat = true; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + BaseComponent finalComponent = new TextComponent(""); + TextComponent replyComponent = new TextComponent("- §breply to §7testUser: test reply...§r -\n"); + replyComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("test reply"))); + finalComponent.addExtra(replyComponent); + finalComponent.addExtra(new TextComponent("§7[§bTelegram§7] §f[testUser] test")); + + + verify(mockPlayerNoReplyPermSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + utils.verify(() -> RandomStringUtils.random(8, true, true), times(1)); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + + TextComponent replyButtonComponent = new TextComponent(" [Reply]"); + replyButtonComponent.setColor(ChatColor.AQUA); + replyButtonComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to reply"))); + replyButtonComponent.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tbr asdf ")); + finalComponent.addExtra(replyButtonComponent); + verify(mockPlayerSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + + verify(mockMessage, times(2)).getText(); + + messageListener.onUpdateReceived(mockUpdate); + utils.verify(() -> RandomStringUtils.random(8, true, true), times(3)); + } + + @Test + @DisplayName("Update received no text") + void onUpdateReceivedNoText() { + when(mockMessage.getText()).thenReturn(null); + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + verify(mockMessage, times(1)).getText(); + verify(mockPlayerSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReplyPermSpigot, never()).sendMessage(any(BaseComponent.class)); + } + + @Test + @DisplayName("Update received no send to chat") + void onUpdateReceivedNoSendToChat() { + when(mockMessage.getText()).thenReturn("test"); + + TelegramBridge.config.sendToChat = false; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + verify(mockMessage, times(1)).getText(); + verify(mockPlayerSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReplyPermSpigot, never()).sendMessage(any(BaseComponent.class)); + } + + @Test + @DisplayName("Update received command") + void onUpdateReceivedCommand() { + when(mockMessage.getText()).thenReturn("/command"); + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + verify(mockMessage, times(1)).getText(); + verify(mockPlayerSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReplyPermSpigot, never()).sendMessage(any(BaseComponent.class)); + } + + @Test + @DisplayName("Update received no reply to message") + void onUpdateReceivedNoReplyToMessage() { + when(mockMessage.getText()).thenReturn("test"); + when(mockUser.getUserName()).thenReturn("testUser"); + + TelegramBridge.config.sendToChat = true; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + BaseComponent finalComponent = new TextComponent(""); + finalComponent.addExtra(new TextComponent("§7[§bTelegram§7] §f[testUser] test")); + + verify(mockPlayerNoReplyPermSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + + TextComponent replyButtonComponent = new TextComponent(" [Reply]"); + replyButtonComponent.setColor(ChatColor.AQUA); + replyButtonComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to reply"))); + replyButtonComponent.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tbr asdf ")); + finalComponent.addExtra(replyButtonComponent); + + verify(mockPlayerSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + + verify(mockMessage, times(2)).getText(); + } + + @Test + @DisplayName("Update received no reply to message no text") + void onUpdateReceivedNoReplyToMessageNoText() { + when(mockMessage.getText()).thenReturn("test"); + when(mockUser.getUserName()).thenReturn("testUser"); + when(mockReplyToMessage.hasText()).thenReturn(false); + when(mockMessage.getReplyToMessage()).thenReturn(mockReplyToMessage); + + TelegramBridge.config.sendToChat = true; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + BaseComponent finalComponent = new TextComponent(""); + finalComponent.addExtra(new TextComponent("§7[§bTelegram§7] §f[testUser] test")); + + verify(mockPlayerNoReplyPermSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + + TextComponent replyButtonComponent = new TextComponent(" [Reply]"); + replyButtonComponent.setColor(ChatColor.AQUA); + replyButtonComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to reply"))); + replyButtonComponent.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tbr asdf ")); + finalComponent.addExtra(replyButtonComponent); + + verify(mockPlayerSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + verify(mockPlayerNoReceivePermSpigot, never()).sendMessage(any(BaseComponent.class)); + + verify(mockMessage, times(2)).getText(); + } + + @Test + @DisplayName("Reply") + void reply() { + when(mockMessage.getText()).thenReturn("test"); + when(mockReplyToMessage.getText()).thenReturn("test reply"); + when(mockReplyToMessage.hasText()).thenReturn(true); + when(mockMessage.getReplyToMessage()).thenReturn(mockReplyToMessage); + when(mockUser.getUserName()).thenReturn("testUser"); + + TelegramBridge.config.sendToChat = true; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + messageListener.reply("asdf", "TEST MESSAGE"); + + BaseComponent finalComponent = new TextComponent(""); + TextComponent replyComponent = new TextComponent("- §breply to §7testUser: test...§r -\n"); + replyComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("test"))); + finalComponent.addExtra(replyComponent); + finalComponent.addExtra(new TextComponent("TEST MESSAGE")); + + verify(mockPlayerNoReplyPermSpigot, times(1)).sendMessage(argThat(new ComponentMatcher(finalComponent))); + verify(mockPlayerNoReplyPermSpigot, times(2)).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReplyPerm, times(2)).hasPermission("telegrambridge.receive"); + } + + @Test + @DisplayName("Reply no message to reply to") + void replyNoMessageToReplyTo() { + when(mockMessage.getText()).thenReturn("test"); + when(mockReplyToMessage.getText()).thenReturn("test reply"); + when(mockReplyToMessage.hasText()).thenReturn(true); + when(mockMessage.getReplyToMessage()).thenReturn(mockReplyToMessage); + when(mockUser.getUserName()).thenReturn("testUser"); + + TelegramBridge.config.sendToChat = true; + + MessageListener messageListener = new MessageListener(mockTelegramBot); + messageListener.onUpdateReceived(mockUpdate); + + messageListener.reply("dddd", "TEST MESSAGE"); + + BaseComponent finalComponent = new TextComponent(""); + TextComponent replyComponent = new TextComponent("- §breply to §7testUser: test...§r -\n"); + replyComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("test"))); + finalComponent.addExtra(replyComponent); + finalComponent.addExtra(new TextComponent("TEST MESSAGE")); + + verify(mockPlayerNoReplyPermSpigot, never()).sendMessage(argThat(new ComponentMatcher(finalComponent))); + verify(mockPlayerNoReplyPermSpigot, times(1)).sendMessage(any(BaseComponent.class)); + verify(mockPlayerNoReplyPerm, times(1)).hasPermission("telegrambridge.receive"); + } +} diff --git a/src/test/java/org/altart/telegrambridge/utils/ComponentMatcher.java b/src/test/java/org/altart/telegrambridge/utils/ComponentMatcher.java new file mode 100644 index 0000000..687474b --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/utils/ComponentMatcher.java @@ -0,0 +1,203 @@ +package org.altart.telegrambridge.utils; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.hover.content.Content; +import org.mockito.ArgumentMatcher; + +import java.util.List; +import java.util.Objects; + +public class ComponentMatcher implements ArgumentMatcher { + private final BaseComponent right; + + public ComponentMatcher(BaseComponent right) { + this.right = right; + } + + @Override + public boolean matches(BaseComponent left) { + try { + deepAssert(left, right); + } catch (AssertionError e) { + return false; + } + return true; + } + + private void deepAssert(BaseComponent left, BaseComponent right) { + assertPlainText(left, right); + assertInsertion(left, right); + assertColor(left, right); + assertBold(left, right); + assertItalic(left, right); + assertUnderline(left, right); + assertStrikethrough(left, right); + assertObfuscated(left, right); + assertHoverEvent(left, right); + assertClickEvent(left, right); + assertExtra(left, right); + } + + private void assertExtra(BaseComponent left, BaseComponent right) { + List leftExtra = left.getExtra(); + List rightExtra = right.getExtra(); + + if (rightExtra == null) { + if (leftExtra != null) { + throw new AssertionError("Expected no extra but got \"" + leftExtra + "\""); + } + } else { + if (leftExtra == null) { + throw new AssertionError("Expected extra \"" + rightExtra + "\" but got none"); + } + if (leftExtra.size() != rightExtra.size()) { + throw new AssertionError("Expected extra size \"" + rightExtra.size() + "\" but got \"" + leftExtra.size() + "\""); + } + for (int i = 0; i < leftExtra.size(); i++) { + deepAssert(leftExtra.get(i), rightExtra.get(i)); + } + } + } + + private void assertPlainText(BaseComponent left, BaseComponent right) { + String leftText = left.toPlainText(); + String rightText = right.toPlainText(); + if (!rightText.equals(leftText)) { + throw new AssertionError("Expected text \"" + rightText + "\" but got \"" + leftText + "\""); + } + } + + private void assertObfuscated(BaseComponent left, BaseComponent right) { + boolean leftObfuscated = left.isObfuscated(); + boolean rightObfuscated = right.isObfuscated(); + if (leftObfuscated != rightObfuscated) { + throw new AssertionError("Expected obfuscated \"" + rightObfuscated + "\" but got \"" + leftObfuscated + "\""); + } + } + + private void assertStrikethrough(BaseComponent left, BaseComponent right) { + boolean leftStrikethrough = left.isStrikethrough(); + boolean rightStrikethrough = right.isStrikethrough(); + if (leftStrikethrough != rightStrikethrough) { + throw new AssertionError("Expected strikethrough \"" + rightStrikethrough + "\" but got \"" + leftStrikethrough + "\""); + } + } + + private void assertUnderline(BaseComponent left, BaseComponent right) { + boolean leftUnderlined = left.isUnderlined(); + boolean rightUnderlined = right.isUnderlined(); + if (leftUnderlined != rightUnderlined) { + throw new AssertionError("Expected underlined \"" + rightUnderlined + "\" but got \"" + leftUnderlined + "\""); + } + } + + private void assertItalic(BaseComponent left, BaseComponent right) { + boolean leftItalic = left.isItalic(); + boolean rightItalic = right.isItalic(); + if (leftItalic != rightItalic) { + throw new AssertionError("Expected italic \"" + rightItalic + "\" but got \"" + leftItalic + "\""); + } + } + + private void assertBold(BaseComponent left, BaseComponent right) { + boolean leftBold = left.isBold(); + boolean rightBold = right.isBold(); + if (leftBold != rightBold) { + throw new AssertionError("Expected bold \"" + rightBold + "\" but got \"" + leftBold + "\""); + } + } + + private void assertColor(BaseComponent left, BaseComponent right) { + ChatColor leftColor = left.getColor(); + ChatColor rightColor = right.getColor(); + if (!right.getColor().equals(left.getColor())) { + throw new AssertionError("Expected color \"" + rightColor + "\" but got \"" + leftColor + "\""); + } + } + + private void assertClickEvent(BaseComponent left, BaseComponent right) { + ClickEvent leftClickEvent = left.getClickEvent(); + ClickEvent rightClickEvent = right.getClickEvent(); + if (rightClickEvent == null) { + if (leftClickEvent != null) { + throw new AssertionError("Expected no click event but got \"" + leftClickEvent + "\""); + } + } else { + if (leftClickEvent == null) { + throw new AssertionError("Expected click event \"" + rightClickEvent + "\" but got none"); + } + ClickEvent.Action leftClickAction = leftClickEvent.getAction(); + ClickEvent.Action rightClickAction = rightClickEvent.getAction(); + if (!Objects.equals(leftClickAction, rightClickAction)) { + throw new AssertionError("Expected click action \"" + rightClickAction + "\" but got \"" + leftClickAction + "\""); + } + String leftClickValue = leftClickEvent.getValue(); + String rightClickValue = rightClickEvent.getValue(); + if (!Objects.equals(leftClickValue, rightClickValue)) { + throw new AssertionError("Expected click value \"" + rightClickValue + "\" but got \"" + leftClickValue + "\""); + } + } + } + + private void assertHoverEvent(BaseComponent left, BaseComponent right) { + HoverEvent leftHoverEvent = left.getHoverEvent(); + HoverEvent rightHoverEvent = right.getHoverEvent(); + if (rightHoverEvent == null) { + if (leftHoverEvent != null) { + throw new AssertionError("Expected no hover event but got \"" + leftHoverEvent + "\""); + } + } else { + if (leftHoverEvent == null) { + throw new AssertionError("Expected hover event \"" + rightHoverEvent + "\" but got none"); + } + HoverEvent.Action leftAction = leftHoverEvent.getAction(); + HoverEvent.Action rightAction = rightHoverEvent.getAction(); + if (!leftAction.equals(rightAction)) { + throw new AssertionError("Expected hover action \"" + rightAction + "\" but got \"" + leftAction + "\""); + } + List leftContents = leftHoverEvent.getContents(); + List rightContents = rightHoverEvent.getContents(); + for (int i = 0; i < leftContents.size(); i++) { + String leftContent = leftContents.get(i).toString(); + String rightContent = rightContents.get(i).toString(); + if (!leftContent.equals(rightContent)) { + throw new AssertionError("Expected hover content \"" + rightContent + "\" but got \"" + leftContent + "\""); + } + } + boolean leftLegacy = leftHoverEvent.isLegacy(); + boolean rightLegacy = rightHoverEvent.isLegacy(); + if (leftLegacy != rightLegacy) { + throw new AssertionError("Expected hover legacy \"" + rightLegacy + "\" but got \"" + leftLegacy + "\""); + } + } + } + + private void assertInsertion(BaseComponent left, BaseComponent right) { + String leftInsertion = left.getInsertion(); + String rightInsertion = right.getInsertion(); + if (rightInsertion == null) { + if (leftInsertion != null) { + throw new AssertionError("Expected no insertion but got \"" + leftInsertion + "\""); + } + } else { + if (leftInsertion == null) { + throw new AssertionError("Expected insertion \"" + rightInsertion + "\" but got none"); + } + if (!leftInsertion.equals(rightInsertion)) { + throw new AssertionError("Expected insertion \"" + rightInsertion + "\" but got \"" + leftInsertion + "\""); + } + } + } + + @Override + public String toString() { + return right.toLegacyText(); + } + + public Class type() { + return ComponentMatcher.class; + } +} From 8c2df5ef2daf8637300aca864f09c64477bb562f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:11:05 -0300 Subject: [PATCH 11/56] test: Add pin message feature tests --- .../bot/feature/PinMessageTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/bot/feature/PinMessageTest.java diff --git a/src/test/java/org/altart/telegrambridge/bot/feature/PinMessageTest.java b/src/test/java/org/altart/telegrambridge/bot/feature/PinMessageTest.java new file mode 100644 index 0000000..5805f1a --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/bot/feature/PinMessageTest.java @@ -0,0 +1,50 @@ +package org.altart.telegrambridge.bot.feature; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.config.Config; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class PinMessageTest extends StandardMockTest { + + @Mock + TelegramBot mockTelegramBot; + + @Test + @DisplayName("Build pinned message") + void buildPinnedMessage() { + TelegramBridge.config = mock(Config.class); + TelegramBridge.config.pinned = "Players: %players%\nCount: %count%"; + doNothing().when(mockTelegramBot).editSystemMessage(anyString(), anyString(), anyInt()); + + ArrayList chatArrayList = new ArrayList<>(); + chatArrayList.add(new Config.Chat("id", 1, 1)); + chatArrayList.add(new Config.Chat("id2", 2, null)); + TelegramBridge.config.chats = chatArrayList; + + PinMessage pinMessage = new PinMessage(mockTelegramBot); + pinMessage.addPlayer("Player1"); + verify(mockTelegramBot, times(1)).editSystemMessage("Players: \nPlayer1\nCount: 1", "id", 1); + pinMessage.addPlayer("Player2"); + verify(mockTelegramBot, times(1)).editSystemMessage("Players: \nPlayer2\nPlayer1\nCount: 2", "id", 1); + assertEquals("Players: \nPlayer2\nPlayer1\nCount: 2", PinMessage.buildPinnedMessage()); + + pinMessage.removePlayer("Player1"); + verify(mockTelegramBot, times(1)).editSystemMessage("Players: \nPlayer2\nCount: 1", "id", 1); + assertEquals("Players: \nPlayer2\nCount: 1", PinMessage.buildPinnedMessage()); + + pinMessage.removePlayer("Player2"); + verify(mockTelegramBot, times(1)).editSystemMessage("Players: \nCount: 0", "id", 1); + assertEquals("Players: \nCount: 0", PinMessage.buildPinnedMessage()); + + verify(mockTelegramBot, times(4)).editSystemMessage(anyString(), anyString(), anyInt()); + } +} From d91eb1af7bd94b3372ec034465db2e26dfe39bec Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:11:59 -0300 Subject: [PATCH 12/56] test: Add sent media feature tests --- .../bot/feature/SentMediaTest.java | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/bot/feature/SentMediaTest.java diff --git a/src/test/java/org/altart/telegrambridge/bot/feature/SentMediaTest.java b/src/test/java/org/altart/telegrambridge/bot/feature/SentMediaTest.java new file mode 100644 index 0000000..45182df --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/bot/feature/SentMediaTest.java @@ -0,0 +1,262 @@ +package org.altart.telegrambridge.bot.feature; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.altart.telegrambridge.database.SQLite; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.User; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.logging.Logger; + +import static org.mockito.Mockito.*; + +class SentMediaTest extends StandardMockTest { + @Mock + Logger mockLogger; + @Mock + Plugin mockPlugin; + @Mock + Server mockServer; + @Mock + TelegramBot mockTelegramBot; + @Mock + Update mockUpdate; + @Mock + Message mockMessage; + @Mock + User mockUser; + @Mock + SQLite mockDatabase; + @Mock + Player mockPlayer; + @Mock + Player mockPlayerNoPerm; + + @BeforeEach + void setUp() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.config = new Config(); + TelegramBridge.database = mockDatabase; + TelegramBridge.translations = new Translations("en"); + + when(mockServer.getLogger()).thenReturn(mockLogger); + + setServerMock(mockServer); + + when(mockPlayer.hasPermission(anyString())).thenReturn(true); + + when(mockPlayerNoPerm.hasPermission(anyString())).thenReturn(false); + + ArrayList players = new ArrayList<>(); + players.add(mockPlayer); + players.add(mockPlayerNoPerm); + + when(mockServer.getOnlinePlayers()).thenAnswer(invocation -> players); + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + when(mockMessage.getFrom()).thenReturn(mockUser); + } + + private void setServerMock(Server mock) { + try { + Field server = Bukkit.class.getDeclaredField("server"); + server.setAccessible(true); + server.set(server, mock); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + @DisplayName("Update received") + void onUpdateReceived() { + when(mockMessage.hasPhoto()).thenReturn(true); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockMessage, times(2)).hasPhoto(); + verify(mockDatabase, times(1)).getLang(any()); + verify(mockPlayer, times(1)).hasPermission("telegrambridge.receive"); + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent an image"); + verify(mockPlayer, times(1)).getUniqueId(); + verify(mockPlayerNoPerm, times(1)).hasPermission("telegrambridge.receive"); + verify(mockPlayerNoPerm, never()).sendMessage(anyString()); + verify(mockPlayerNoPerm, never()).getUniqueId(); + + when(mockMessage.getCaption()).thenReturn("caption"); + sentMedia.onUpdateReceived(mockUpdate); + verify(mockMessage, times(4)).hasPhoto(); + verify(mockDatabase, times(2)).getLang(any()); + verify(mockPlayer, times(2)).hasPermission("telegrambridge.receive"); + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent an image\ncaption"); + verify(mockPlayer, times(2)).getUniqueId(); + verify(mockPlayerNoPerm, times(2)).hasPermission("telegrambridge.receive"); + verify(mockPlayerNoPerm, never()).sendMessage(anyString()); + verify(mockPlayerNoPerm, never()).getUniqueId(); + } + + @Test + @DisplayName("Update received with no photo") + void onUpdateReceivedPhoto() { + when(mockMessage.hasPhoto()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent an image\ncaption"); + } + + @Test + @DisplayName("Update received with video") + void onUpdateReceivedVideo() { + when(mockMessage.hasVideo()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a video\ncaption"); + } + + @Test + @DisplayName("Update received with document") + void onUpdateReceivedDocument() { + when(mockMessage.hasDocument()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a document\ncaption"); + } + + @Test + @DisplayName("Update received with audio") + void onUpdateReceivedAudio() { + when(mockMessage.hasAudio()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent an audio\ncaption"); + } + + @Test + @DisplayName("Update received with voice") + void onUpdateReceivedVoice() { + when(mockMessage.hasVoice()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a voice\ncaption"); + } + + @Test + @DisplayName("Update received with sticker") + void onUpdateReceivedSticker() { + when(mockMessage.hasSticker()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a sticker\ncaption"); + } + + @Test + @DisplayName("Update received with contact") + void onUpdateReceivedContact() { + when(mockMessage.hasContact()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a contact\ncaption"); + } + + @Test + @DisplayName("Update received with location") + void onUpdateReceivedLocation() { + when(mockMessage.hasLocation()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a location\ncaption"); + } + + @Test + @DisplayName("Update received with poll") + void onUpdateReceivedPoll() { + when(mockMessage.hasPoll()).thenReturn(true); + when(mockMessage.getCaption()).thenReturn("caption"); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockPlayer, times(1)).sendMessage("§7[§bTelegram§7] §f[] sent a poll\ncaption"); + } + + @Test + @DisplayName("Update received is not media") + void onUpdateReceivedIsNotMedia() { + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockMessage, times(1)).hasPhoto(); + } + + @Test + @DisplayName("Update received with send to chat false") + void onUpdateReceivedSendToChatFalse() { + File resourceFolder = new File("src/test/resources/"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.config = new Config(); + TelegramBridge.translations = new Translations("en"); + TelegramBridge.config.sendToChat = false; + + when(mockUpdate.getMessage()).thenReturn(mockMessage); + when(mockMessage.hasPhoto()).thenReturn(true); + when(mockMessage.getFrom()).thenReturn(mockUser); + + SentMedia sentMedia = new SentMedia(mockTelegramBot); + sentMedia.onUpdateReceived(mockUpdate); + + verify(mockServer, never()).getOnlinePlayers(); + verify(mockMessage, never()).hasPhoto(); + verify(mockDatabase, never()).getLang(any()); + verify(mockPlayer, never()).hasPermission(anyString()); + verify(mockPlayer, never()).sendMessage(anyString()); + verify(mockPlayer, never()).getUniqueId(); + verify(mockPlayerNoPerm, never()).hasPermission(anyString()); + verify(mockPlayerNoPerm, never()).sendMessage(anyString()); + verify(mockPlayerNoPerm, never()).getUniqueId(); + } +} From 333fada2a17bc1f9193e9ad23f49dcfd73f326dc Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:14:03 -0300 Subject: [PATCH 13/56] test: Add user autocomplete feature tests --- .../bot/feature/UserAutocompleteTest.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/bot/feature/UserAutocompleteTest.java diff --git a/src/test/java/org/altart/telegrambridge/bot/feature/UserAutocompleteTest.java b/src/test/java/org/altart/telegrambridge/bot/feature/UserAutocompleteTest.java new file mode 100644 index 0000000..69b4ece --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/bot/feature/UserAutocompleteTest.java @@ -0,0 +1,47 @@ +package org.altart.telegrambridge.bot.feature; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.bot.TelegramBot; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.User; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class UserAutocompleteTest extends StandardMockTest { + @Mock + Update mockUpdate; + @Mock + TelegramBot mockTelegramBot; + @Mock + Message mockMessage; + @Mock + User mockUser; + + @Test + @DisplayName("Get telegram users") + void getTelegramUsers() { + UserAutocomplete userAutocomplete = new UserAutocomplete(mockTelegramBot); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getUserName()).thenReturn("testUser"); + when(mockUpdate.getMessage()).thenReturn(mockMessage); + userAutocomplete.onUpdateReceived(mockUpdate); + assertEquals(1, userAutocomplete.getTelegramUsers().size()); + assertEquals("@testUser", userAutocomplete.getTelegramUsers().get(0)); + } + + @Test + @DisplayName("Get telegram users with null user") + void nullUserName() { + UserAutocomplete userAutocomplete = new UserAutocomplete(mockTelegramBot); + when(mockMessage.getFrom()).thenReturn(mockUser); + when(mockUser.getUserName()).thenReturn(null); + when(mockUpdate.getMessage()).thenReturn(mockMessage); + userAutocomplete.onUpdateReceived(mockUpdate); + assertEquals(0, userAutocomplete.getTelegramUsers().size()); + } +} From 720c19402969f77943ce35e8e65d0a7097dbc74e Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:18:45 -0300 Subject: [PATCH 14/56] chore: Add test dependencies to gradle --- build.gradle | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 9837cdd..167d74e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'com.github.johnrengelman.shadow' version '8.1.1' + id 'idea' } shadowJar { @@ -27,14 +28,16 @@ dependencies { implementation 'org.telegram:telegrambots:6.9.7.1' implementation 'org.xerial:sqlite-jdbc:3.45.3.0' compileOnly 'org.jetbrains:annotations:24.1.0' - compileOnly 'org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT' + implementation 'org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT' + testImplementation platform('org.junit:junit-bom:5.10.2') + testImplementation 'org.junit.jupiter:junit-jupiter' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'org.mockito:mockito-core:5.12.0' } def targetJavaVersion = 8 java { def javaVersion = JavaVersion.toVersion(targetJavaVersion) - sourceCompatibility = javaVersion - targetCompatibility = javaVersion if (JavaVersion.current() < javaVersion) { toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) } @@ -48,6 +51,13 @@ tasks.withType(JavaCompile).configureEach { } } +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } +} + processResources { def props = [version: version] inputs.properties props From a839f0695f43f70572499c3c0f5fca68342624c3 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:21:07 -0300 Subject: [PATCH 15/56] fix: Log message don't need format placeholder --- src/main/java/org/altart/telegrambridge/config/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/config/Config.java b/src/main/java/org/altart/telegrambridge/config/Config.java index 658b631..86eebca 100644 --- a/src/main/java/org/altart/telegrambridge/config/Config.java +++ b/src/main/java/org/altart/telegrambridge/config/Config.java @@ -62,7 +62,7 @@ public void load() { } } } else { - TelegramBridge.log.warning("Config file not found making a new one at %s" + configFile.getAbsolutePath()); + TelegramBridge.log.warning("Config file not found making a new one at " + configFile.getAbsolutePath()); try { FileConfiguration config = new YamlConfiguration(); config.set("botToken", botToken); From 25cfd4c980598b0563ab5c92eb21b8936ebb71f9 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:22:36 -0300 Subject: [PATCH 16/56] fix: Config default atributes do not need to be public --- .../org/altart/telegrambridge/config/Config.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/config/Config.java b/src/main/java/org/altart/telegrambridge/config/Config.java index 86eebca..362dda2 100644 --- a/src/main/java/org/altart/telegrambridge/config/Config.java +++ b/src/main/java/org/altart/telegrambridge/config/Config.java @@ -15,14 +15,14 @@ public class Config { public List chats = Collections.singletonList(new Chat("YOUR_CHAT_ID", null, null)); // default constants - final boolean SEND_TO_CHAT = true; - final boolean SEND_TO_TELEGRAM = true; - final boolean JOIN_AND_LEAVE_EVENT = true; - final boolean DEATH_EVENT = true; - final boolean ADVANCEMENT_EVENT = true; - final boolean SLEEP_EVENT = false; - final String DEFAULT_LANG = "en"; - final String DEFAULT_PINNED = "Hey welcome to the chat!\nThere are %count% players online%players%"; + private final boolean SEND_TO_CHAT = true; + private final boolean SEND_TO_TELEGRAM = true; + private final boolean JOIN_AND_LEAVE_EVENT = true; + private final boolean DEATH_EVENT = true; + private final boolean ADVANCEMENT_EVENT = true; + private final boolean SLEEP_EVENT = false; + private final String DEFAULT_LANG = "en"; + private final String DEFAULT_PINNED = "Hey welcome to the chat!\nThere are %count% players online%players%"; public boolean sendToChat = SEND_TO_CHAT; public boolean sendToTelegram = SEND_TO_TELEGRAM; From 763bf536495052c3375b315b6bf83f263c94cb9b Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:24:23 -0300 Subject: [PATCH 17/56] refactor: Use same variable already declared to get player nick --- src/main/java/org/altart/telegrambridge/events/GameEvent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/events/GameEvent.java b/src/main/java/org/altart/telegrambridge/events/GameEvent.java index eff6947..16b66b8 100644 --- a/src/main/java/org/altart/telegrambridge/events/GameEvent.java +++ b/src/main/java/org/altart/telegrambridge/events/GameEvent.java @@ -21,7 +21,7 @@ public void onPlayerJoin(PlayerJoinEvent event) { String playerNick = event.getPlayer().getDisplayName(); String message = Format.string(TelegramBridge.translations.get().join, "playername", playerNick); TelegramBridge.telegramBot.broadcastMessage(message); - TelegramBridge.telegramBot.pinMessageFeature.addPlayer(event.getPlayer().getDisplayName()); + TelegramBridge.telegramBot.pinMessageFeature.addPlayer(playerNick); } } @@ -31,7 +31,7 @@ public void onPlayerLeave(PlayerQuitEvent event) { String playerNick = event.getPlayer().getDisplayName(); String message = Format.string(TelegramBridge.translations.get().leave, "playername", playerNick); TelegramBridge.telegramBot.broadcastMessage(message); - TelegramBridge.telegramBot.pinMessageFeature.removePlayer(event.getPlayer().getDisplayName()); + TelegramBridge.telegramBot.pinMessageFeature.removePlayer(playerNick); } } From bd93885c39e6533a15381ee531bd9542c1b78eac Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:25:37 -0300 Subject: [PATCH 18/56] refactor: Remove not needed bodyguards on advancement event --- .../org/altart/telegrambridge/events/GameEvent.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/events/GameEvent.java b/src/main/java/org/altart/telegrambridge/events/GameEvent.java index 16b66b8..6bbe4e6 100644 --- a/src/main/java/org/altart/telegrambridge/events/GameEvent.java +++ b/src/main/java/org/altart/telegrambridge/events/GameEvent.java @@ -60,19 +60,17 @@ public void onPlayerAsleep(PlayerBedEnterEvent event) { @EventHandler public void onAdvancement(PlayerAdvancementDoneEvent event) { if (TelegramBridge.config.sendToTelegram && TelegramBridge.config.advancementEvent) { - String playerNick = event.getPlayer().getDisplayName(); String advancementKey = event.getAdvancement().getKey().getKey().replace("/", "."); if (advancementKey.startsWith("recipes.")) { return; } + + String playerNick = event.getPlayer().getDisplayName(); + String advancementText = TranslationRegistry.INSTANCE.translate("advancements." + advancementKey + ".title"); - if (advancementText == null) { - advancementText = advancementKey; - } String advancementDescription = TranslationRegistry.INSTANCE.translate("advancements." + advancementKey + ".description"); - if (advancementDescription != null) { - advancementText += ": " + advancementDescription; - } + advancementText += ": " + advancementDescription; + HashMap values = new HashMap<>(); values.put("playername", playerNick); values.put("advancement", advancementText); From ebfe846137d9f8828cc040271206ad2acd607fcc Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:27:52 -0300 Subject: [PATCH 19/56] fix: Make reply messages use same username getter as the messages --- .../org/altart/telegrambridge/bot/feature/MessageListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java index 7927694..6b4f22e 100644 --- a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java +++ b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java @@ -75,7 +75,7 @@ public void onUpdateReceived(@NotNull Update update) { Message reply = message.getReplyToMessage(); if (reply != null && reply.hasText()) { - String replyUsername = reply.getFrom().getUserName(); + String replyUsername = getUserName(message); String replyMessage = reply.getText(); finalComponent.addExtra(replyComponent(replyUsername, replyMessage, lang)); } From 18f3e1614cad1d6535ca7b9de76f4465c33e75c5 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:29:00 -0300 Subject: [PATCH 20/56] refactor: Remove unneeded condition in username getter --- .../altart/telegrambridge/bot/feature/MessageListener.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java index 6b4f22e..c755498 100644 --- a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java +++ b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java @@ -122,11 +122,6 @@ public void onUpdateReceived(@NotNull Update update) { username += " " + message.getFrom().getLastName(); } } - - if (username.trim().isEmpty()) { - username = "Anonymous"; - } - return username; } From 8c7d1b08f042d776320ce0b545af9a147e14932f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:29:49 -0300 Subject: [PATCH 21/56] refactor: Atributes from `MessageInfo` can be final --- .../telegrambridge/bot/feature/MessageListener.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java index c755498..1373d66 100644 --- a/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java +++ b/src/main/java/org/altart/telegrambridge/bot/feature/MessageListener.java @@ -150,10 +150,10 @@ private static TextComponent replyComponent(String username, String message, @Nu } private static class MessageInfo { - public String chatId; - public Integer messageId; - public String message; - public String username; + public final String chatId; + public final Integer messageId; + public final String message; + public final String username; public MessageInfo(String chatId, Integer messageId, String message, String username) { this.chatId = chatId; From 3187108361db1879cf9bdf58e2938c95d1918312 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:31:25 -0300 Subject: [PATCH 22/56] fix: Update pinned message only when a player enters the game --- .../java/org/altart/telegrambridge/bot/feature/PinMessage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/feature/PinMessage.java b/src/main/java/org/altart/telegrambridge/bot/feature/PinMessage.java index 68912d8..051a91d 100644 --- a/src/main/java/org/altart/telegrambridge/bot/feature/PinMessage.java +++ b/src/main/java/org/altart/telegrambridge/bot/feature/PinMessage.java @@ -13,7 +13,6 @@ public class PinMessage extends TelegramFeature { public PinMessage(TelegramBot telegramBot) { super(telegramBot); - updatePinnedMessage(); } static public String buildPinnedMessage() { From afcd953e3a840233c99d9d12b35db41d5e279c22 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:33:58 -0300 Subject: [PATCH 23/56] refactor: Make HashMap outside the loop keeping less busy --- .../telegrambridge/bot/feature/SentMedia.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/feature/SentMedia.java b/src/main/java/org/altart/telegrambridge/bot/feature/SentMedia.java index 00bb285..9052eec 100644 --- a/src/main/java/org/altart/telegrambridge/bot/feature/SentMedia.java +++ b/src/main/java/org/altart/telegrambridge/bot/feature/SentMedia.java @@ -22,17 +22,17 @@ public SentMedia(TelegramBot telegramBot) { @Override public void onUpdateReceived(@NotNull Update update) { - Message message = update.getMessage(); - if (isMedia(message)) { - String username = message.getFrom().getUserName(); - String caption = message.getCaption(); - caption = caption == null ? "" : "\n" + caption; - if (TelegramBridge.config.sendToChat) { + if (TelegramBridge.config.sendToChat) { + Message message = update.getMessage(); + if (isMedia(message)) { + String username = message.getFrom().getUserName(); + String caption = message.getCaption(); + caption = caption == null ? "" : "\n" + caption; + HashMap values = new HashMap<>(); + values.put("caption", caption); + values.put("user", username); for (Player player : Bukkit.getOnlinePlayers()) { if (player.hasPermission(Permissions.RECEIVE.getString())) { - HashMap values = new HashMap<>(); - values.put("user", username); - values.put("caption", caption); String lang = TelegramBridge.database.getLang(player.getUniqueId()); values.put("type", determineMediaType(message, lang)); String text = Format.string(TelegramBridge.translations.get(lang).telegramMedia, values); From 697da1e06552c85fca16876ebe7cda994a5f2562 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:35:19 -0300 Subject: [PATCH 24/56] fix: Make feature public to easy access on tests --- src/main/java/org/altart/telegrambridge/bot/TelegramBot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index e57f02d..866ace7 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -32,9 +32,9 @@ public class TelegramBot extends TelegramLongPollingBot { private final Plugin plugin; private final Map commands = new HashMap<>(); - private final List features = new ArrayList<>(); + public List features = new ArrayList<>(); - public final PinMessage pinMessageFeature = new PinMessage(this); + public PinMessage pinMessageFeature = new PinMessage(this); public final UserAutocomplete userAutocompleteFeature = new UserAutocomplete(this); public final MessageListener messageListenerFeature = new MessageListener(this); public final SentMedia sentMediaFeature = new SentMedia(this); From 0cd46c084bd6e7c5eee8062a3b84decad98f5e91 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:35:40 -0300 Subject: [PATCH 25/56] fix: Make isNotAdmin public to easy access on tests --- src/main/java/org/altart/telegrambridge/bot/TelegramBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index 866ace7..0f37e88 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -88,7 +88,7 @@ public void onUpdateReceived(@NotNull Update update) { } } - private boolean isNotAdmin(String chatId, Long userId) { + public boolean isNotAdmin(String chatId, Long userId) { GetChatAdministrators getChatAdministrators = new GetChatAdministrators(); getChatAdministrators.setChatId(chatId); try { From de343c0fbf1fdb89ec10764ab9743e1c0cac5561 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:36:25 -0300 Subject: [PATCH 26/56] fix: Mark unpinMessage chatId as not null --- src/main/java/org/altart/telegrambridge/bot/TelegramBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index 0f37e88..28e9d80 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -172,7 +172,7 @@ public void pinMessage(String chatId, Integer messageId) { } } - public void unpinMessage(String chatId, Integer messageId) { + public void unpinMessage(@NotNull String chatId, Integer messageId) { try { execute(new UnpinChatMessage(chatId, messageId)); } catch (TelegramApiException e) { From 39b9407a9e7086552d2750b08598c1d75342ebbd Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:36:57 -0300 Subject: [PATCH 27/56] fix: Mark deleteMessage chatId and messageId as not null --- src/main/java/org/altart/telegrambridge/bot/TelegramBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index 28e9d80..8dbe2af 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -198,7 +198,7 @@ public void editSystemMessage(String message, String chatId, Integer messageId) } } - public void deleteMessage(String chatId, Integer messageId) { + public void deleteMessage(@NotNull String chatId, @NotNull Integer messageId) { try { execute(new DeleteMessage(chatId, messageId)); } catch (TelegramApiException e) { From 03e7193aeaa14dd6e8a9526060cac2fd09e235b6 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:37:36 -0300 Subject: [PATCH 28/56] refactor: `CommandSender` atributes can be final --- .../java/org/altart/telegrambridge/bot/TelegramBot.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index 8dbe2af..8edab17 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -208,9 +208,9 @@ public void deleteMessage(@NotNull String chatId, @NotNull Integer messageId) { } public class CommandSender { - public Plugin plugin; - public Message message; - public TelegramBot bot; + public final Plugin plugin; + public final Message message; + public final TelegramBot bot; private CommandSender(Message message, Plugin plugin, TelegramBot bot) { this.message = message; From 55c2a7ac58622b4a3f967f88aaa233746b7ad021 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:39:16 -0300 Subject: [PATCH 29/56] refactor: Add proper spacing on methods --- .../altart/telegrambridge/bot/TelegramCommandExecutor.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramCommandExecutor.java b/src/main/java/org/altart/telegrambridge/bot/TelegramCommandExecutor.java index fcd371d..77f35e1 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramCommandExecutor.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramCommandExecutor.java @@ -1,9 +1,12 @@ package org.altart.telegrambridge.bot; abstract public class TelegramCommandExecutor { - public boolean requirePermission; + public final boolean requirePermission; + public TelegramCommandExecutor(boolean requirePermission) { this.requirePermission = requirePermission; } - public void onCommand(TelegramBot.CommandSender sender, String[] args) {} + + public void onCommand(TelegramBot.CommandSender sender, String[] args) { + } } From f0358eaffcbcdeb0e8a72acc88dbb7cd8dec77a0 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:39:57 -0300 Subject: [PATCH 30/56] refactor: Make `makeTimeMap` private --- .../org/altart/telegrambridge/bot/commands/TimeCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/commands/TimeCommand.java b/src/main/java/org/altart/telegrambridge/bot/commands/TimeCommand.java index 0a1842a..db1e18b 100644 --- a/src/main/java/org/altart/telegrambridge/bot/commands/TimeCommand.java +++ b/src/main/java/org/altart/telegrambridge/bot/commands/TimeCommand.java @@ -31,7 +31,7 @@ public void onCommand(TelegramBot.CommandSender sender, String[] args) { sender.sendMessage(response); } - public HashMap makeTimeMap(String time, String emoji, int day, int month, int year) { + private HashMap makeTimeMap(String time, String emoji, int day, int month, int year) { HashMap values = new HashMap<>(); values.put("time", time); values.put("emoji", emoji); From 18391a8a57e1cf746e0f0d16b1d67baa55734d0c Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:41:56 -0300 Subject: [PATCH 31/56] fix: Make `Translation` public to easy access on tests --- .../java/org/altart/telegrambridge/config/Translations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/config/Translations.java b/src/main/java/org/altart/telegrambridge/config/Translations.java index 090b1f6..1395c59 100644 --- a/src/main/java/org/altart/telegrambridge/config/Translations.java +++ b/src/main/java/org/altart/telegrambridge/config/Translations.java @@ -81,7 +81,7 @@ public static class Translation { public String replyButton; public String replyHint; - private Translation(@Nullable File translationsFile) { + public Translation(@Nullable File translationsFile) { if (translationsFile != null && translationsFile.exists()) { FileConfiguration translations = YamlConfiguration.loadConfiguration(translationsFile); Field[] fields = this.getClass().getDeclaredFields(); From accabc0352e3bfeb5e625f9c57f856a9cd136772 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:43:32 -0300 Subject: [PATCH 32/56] fix: Check if `pinnedMessageId` is null to remove and unpin message --- .../altart/telegrambridge/bot/commands/UnsetPinCommand.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/commands/UnsetPinCommand.java b/src/main/java/org/altart/telegrambridge/bot/commands/UnsetPinCommand.java index cc7838e..e43b9d6 100644 --- a/src/main/java/org/altart/telegrambridge/bot/commands/UnsetPinCommand.java +++ b/src/main/java/org/altart/telegrambridge/bot/commands/UnsetPinCommand.java @@ -15,9 +15,11 @@ public void onCommand(TelegramBot.CommandSender sender, String[] args) { String chatId = String.valueOf(sender.message.getChatId()); for (Config.Chat chat : TelegramBridge.config.chats) { if (chat.id.equals(chatId)) { + if (chat.pinnedMessageId != null) { + sender.bot.unpinMessage(chatId, chat.pinnedMessageId); + sender.bot.deleteMessage(chatId, chat.pinnedMessageId); + } TelegramBridge.config.setPinnedMessageId(chatId, null); - sender.bot.unpinMessage(chatId, chat.pinnedMessageId); - sender.bot.deleteMessage(chatId, chat.pinnedMessageId); } } } From e971865d0fa44cfebb8bbe060f6e782cf398cd76 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 15:44:19 -0300 Subject: [PATCH 33/56] refactor: `argLength` can be final --- .../org/altart/telegrambridge/commands/UserTabCompletion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/commands/UserTabCompletion.java b/src/main/java/org/altart/telegrambridge/commands/UserTabCompletion.java index 3902f8e..16cf893 100644 --- a/src/main/java/org/altart/telegrambridge/commands/UserTabCompletion.java +++ b/src/main/java/org/altart/telegrambridge/commands/UserTabCompletion.java @@ -11,7 +11,7 @@ import java.util.List; public class UserTabCompletion implements TabCompleter { - int argLength; + final int argLength; public UserTabCompletion(int argLength) { this.argLength = argLength; From e3e7cb496a5e8ea40f6b8e8070a15e34dc5aa05b Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 16:10:18 -0300 Subject: [PATCH 34/56] fix: Remove one language from `TranslationsTest` --- .../java/org/altart/telegrambridge/config/TranslationsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java index 086dbe5..403c3c5 100644 --- a/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java +++ b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java @@ -31,7 +31,7 @@ void getTranslation() { Translations translations = new Translations("en"); List languageCodes = translations.getLoadedLanguages(); - List expectedLanguageCodes = Arrays.asList("en", "es", "jp", "pt", "ru", "uk", "tt"); + List expectedLanguageCodes = Arrays.asList("en", "es", "jp", "pt", "ru", "tt"); assertEquals(expectedLanguageCodes.size(), languageCodes.size()); for (String lang : expectedLanguageCodes) { assertTrue(languageCodes.contains(lang)); From 7c2a8be7981ce5fe2c3346b92a879bfad1aaa8f8 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 16:11:34 -0300 Subject: [PATCH 35/56] feat: Send player leave message when server stops --- .../java/org/altart/telegrambridge/TelegramBridge.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/altart/telegrambridge/TelegramBridge.java b/src/main/java/org/altart/telegrambridge/TelegramBridge.java index 1a1ecfd..c30a54e 100644 --- a/src/main/java/org/altart/telegrambridge/TelegramBridge.java +++ b/src/main/java/org/altart/telegrambridge/TelegramBridge.java @@ -7,8 +7,10 @@ import org.altart.telegrambridge.database.SQLite; import org.altart.telegrambridge.events.ChatEvent; import org.altart.telegrambridge.events.GameEvent; +import org.altart.telegrambridge.utils.Format; import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.telegram.telegrambots.meta.TelegramBotsApi; @@ -73,6 +75,13 @@ public void onEnable() { @Override public void onDisable() { + if (config.sendToTelegram && config.joinAndLeaveEvent) { + StringBuilder message = new StringBuilder(); + for (Player player : Bukkit.getOnlinePlayers()) { + message.append(Format.string(translations.get().leave, "playername", player.getDisplayName())).append("\n"); + } + telegramBot.broadcastMessage(message.toString()); + } database.close(); if (botSession != null) { botSession.stop(); From e14329273ba9a4e3b8d6826b1b73fe008479e0d9 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:19:47 -0300 Subject: [PATCH 36/56] feat: Add server start and stop log config and fix boolean config load --- src/main/java/org/altart/telegrambridge/config/Config.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/altart/telegrambridge/config/Config.java b/src/main/java/org/altart/telegrambridge/config/Config.java index 362dda2..331a557 100644 --- a/src/main/java/org/altart/telegrambridge/config/Config.java +++ b/src/main/java/org/altart/telegrambridge/config/Config.java @@ -21,6 +21,7 @@ public class Config { private final boolean DEATH_EVENT = true; private final boolean ADVANCEMENT_EVENT = true; private final boolean SLEEP_EVENT = false; + private final boolean SERVER_START_STOP = false; private final String DEFAULT_LANG = "en"; private final String DEFAULT_PINNED = "Hey welcome to the chat!\nThere are %count% players online%players%"; @@ -31,6 +32,7 @@ public class Config { public boolean deathEvent = DEATH_EVENT; public boolean advancementEvent = ADVANCEMENT_EVENT; public boolean sleepEvent = SLEEP_EVENT; + public boolean serverStartStop = SERVER_START_STOP; public String lang = DEFAULT_LANG; @@ -50,7 +52,7 @@ public void load() { if (config.contains(field.getName())) { if (field.getType().equals(String.class)) { field.set(this, config.get(field.getName())); - } else if (field.getType().equals(Boolean.class)) { + } else if (field.getType().equals(boolean.class)) { field.set(this, config.getBoolean(field.getName())); } else if (field.getType().equals(List.class)) { field.set(this, Chat.chatsFrom(config.getMapList(field.getName()))); @@ -98,6 +100,9 @@ public void save() { if (sleepEvent != SLEEP_EVENT) { config.set("sleepEvent", sleepEvent); } + if (serverStartStop != SERVER_START_STOP) { + config.set("serverStartStop", serverStartStop); + } if (!lang.equals(DEFAULT_LANG)) { config.set("lang", lang); } From 4dc3e6a843f25aa930bd85cc47304207e4249e7a Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:21:04 -0300 Subject: [PATCH 37/56] docs: Add server start and stop to config documentation --- CONFIG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONFIG.md b/CONFIG.md index 3b165db..faa6a29 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -33,4 +33,6 @@ deathEvent: true advancementEvent: true # Log player sleep in telegram chat sleepEvent: false +# Log when server starts and stops in telegram chat +serverStartStop: false ``` From d64c5ae9c40311e830961d7b949c783346f8c7ce Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:22:09 -0300 Subject: [PATCH 38/56] docs: Add server start and stop to test --- .../telegrambridge/config/ConfigTest.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/altart/telegrambridge/config/ConfigTest.java b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java index 23c82c9..85daf14 100644 --- a/src/test/java/org/altart/telegrambridge/config/ConfigTest.java +++ b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java @@ -4,6 +4,7 @@ import org.altart.telegrambridge.TelegramBridge; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -21,6 +22,12 @@ class ConfigTest extends StandardMockTest { @Mock Plugin mockPlugin; + @SuppressWarnings("ResultOfMethodCallIgnored") + @AfterEach + void afterEach() { + new File("src/test/resources/empty/config.yml").delete(); + } + @Test @DisplayName("Load config") void load() { @@ -52,8 +59,7 @@ void create() { assertEquals("YOUR_CHAT_ID", config.chats.get(0).id); verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); - - assertTrue(new File("src/test/resources/empty/config.yml").delete()); + assertTrue(new File("src/test/resources/empty/config.yml").exists()); } @Test @@ -77,6 +83,7 @@ void save() { config.deathEvent = !config.deathEvent; config.sleepEvent = !config.sleepEvent; config.advancementEvent = !config.advancementEvent; + config.serverStartStop = !config.serverStartStop; config.lang = "LANG"; config.pinned = "PINNED"; config.save(); @@ -103,9 +110,9 @@ void save() { fail(); } } + assertEquals(20, fields.length); verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); - assertTrue(new File("src/test/resources/empty/config.yml").delete()); } @Test @@ -134,7 +141,7 @@ void setPinnedMessageId() { verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); - assertTrue(new File("src/test/resources/empty/config.yml").delete()); + assertTrue(new File("src/test/resources/empty/config.yml").exists()); } @Test @@ -157,7 +164,7 @@ void setLang() { verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); - assertTrue(new File("src/test/resources/empty/config.yml").delete()); + assertTrue(new File("src/test/resources/empty/config.yml").exists()); } @Test @@ -186,6 +193,6 @@ void setThread() { verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); - assertTrue(new File("src/test/resources/empty/config.yml").delete()); + assertTrue(new File("src/test/resources/empty/config.yml").exists()); } } From ff5c187e1f48b024d69eb55d9d2c57f778701d66 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:22:55 -0300 Subject: [PATCH 39/56] feat: Server start and stop events translations --- src/main/resources/lang/en.yml | 4 ++++ src/main/resources/lang/es.yml | 4 ++++ src/main/resources/lang/jp.yml | 4 ++++ src/main/resources/lang/pt.yml | 4 ++++ src/main/resources/lang/ru.yml | 4 ++++ src/test/resources/lang/en.yml | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index dbd69ea..b8d6240 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -15,6 +15,10 @@ death: 'Player %playername% died! %deathmessage%' advancement: 'Player %playername% made an advancement! %advancement%' # When a player sleeps sleep: 'Player %playername% went to bed!' +# When server starts +serverStart: 'Server started!' +# When server stops +serverStop: 'Server stopped!' # When a minecraft player sends a message chatMessage: '[%playername%]: %message%' diff --git a/src/main/resources/lang/es.yml b/src/main/resources/lang/es.yml index 376cd59..a59d72a 100644 --- a/src/main/resources/lang/es.yml +++ b/src/main/resources/lang/es.yml @@ -15,6 +15,10 @@ death: '%playername% murió! %deathmessage%' advancement: '%playername% hizo un logro! %advancement%' # Cuando un jugador duerme sleep: '%playername% se fue a dormir!' +# Cuando el servidor inicia +serverStart: '¡Servidor iniciado!' +# Cuando el servidor se detiene +serverStop: '¡Servidor detenido!' # Cuando un jugador de Minecraft envía un mensaje chatMessage: '[%playername%]: %message%' diff --git a/src/main/resources/lang/jp.yml b/src/main/resources/lang/jp.yml index a77d4d3..7ca096e 100644 --- a/src/main/resources/lang/jp.yml +++ b/src/main/resources/lang/jp.yml @@ -15,6 +15,10 @@ death: '%playername% が死亡しました! %deathmessage%' advancement: '%playername% が実績を達成しました! %advancement%' # プレイヤーが寝たとき sleep: '%playername% が寝ました!' +# サーバーが起動したとき +serverStart: 'サーバーが起動しました!' +# サーバーが停止したとき +serverStop: 'サーバーが停止しました!' # Minecraft プレイヤーがメッセージを送信したとき chatMessage: '[%playername%]: %message%' diff --git a/src/main/resources/lang/pt.yml b/src/main/resources/lang/pt.yml index df09280..339aa58 100644 --- a/src/main/resources/lang/pt.yml +++ b/src/main/resources/lang/pt.yml @@ -15,6 +15,10 @@ death: '%playername% morreu! %deathmessage%' advancement: '%playername% fez uma conquista! %advancement%' # Quando um jogador dorme sleep: '%playername% foi dormir!' +# Quando o servidor inicia +serverStart: 'Servidor foi iniciado!' +# Quando o servidor para +serverStop: 'Servidor foi parado!' # Quando um jogador envia uma mensagem chatMessage: '[%playername%]: %message%' diff --git a/src/main/resources/lang/ru.yml b/src/main/resources/lang/ru.yml index 30e3aec..02fa68b 100644 --- a/src/main/resources/lang/ru.yml +++ b/src/main/resources/lang/ru.yml @@ -15,6 +15,10 @@ death: '%playername% погиб! %deathmessage%' advancement: '%playername% получил достижение «%advancement%»!' # Когда ложится спать sleep: '%playername% лёг спать!' +# Когда сервер запускается +serverStart: 'Сервер запущен!' +# Когда сервер останавливается +serverStop: 'Сервер остановлен!' # Когда в игре кто-то отправляет сообщение chatMessage: '[%playername%]: %message%' diff --git a/src/test/resources/lang/en.yml b/src/test/resources/lang/en.yml index dbd69ea..b8d6240 100644 --- a/src/test/resources/lang/en.yml +++ b/src/test/resources/lang/en.yml @@ -15,6 +15,10 @@ death: 'Player %playername% died! %deathmessage%' advancement: 'Player %playername% made an advancement! %advancement%' # When a player sleeps sleep: 'Player %playername% went to bed!' +# When server starts +serverStart: 'Server started!' +# When server stops +serverStop: 'Server stopped!' # When a minecraft player sends a message chatMessage: '[%playername%]: %message%' From 0535b34ad045c02f4c71ec30ae5359148dae4523 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:23:04 -0300 Subject: [PATCH 40/56] feat: Server start and stop events translations --- .../java/org/altart/telegrambridge/config/Translations.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/altart/telegrambridge/config/Translations.java b/src/main/java/org/altart/telegrambridge/config/Translations.java index 1395c59..facba1a 100644 --- a/src/main/java/org/altart/telegrambridge/config/Translations.java +++ b/src/main/java/org/altart/telegrambridge/config/Translations.java @@ -69,6 +69,8 @@ public static class Translation { public String death; public String advancement; public String sleep; + public String serverStart; + public String serverStop; public String chatMessage; public String telegramMessage; From 8d662d3055ca257de7718f093ad60d926a5287ca Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:24:13 -0300 Subject: [PATCH 41/56] refactor: Small typo in resource folder variable --- .../config/TranslationsTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java index 403c3c5..24b9fa3 100644 --- a/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java +++ b/src/test/java/org/altart/telegrambridge/config/TranslationsTest.java @@ -24,8 +24,8 @@ class TranslationsTest extends StandardMockTest { @Test @DisplayName("Get translation") void getTranslation() { - File resourseFolder = new File("src/test/resources"); - when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + File resourceFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); TelegramBridge.plugin = mockPlugin; @@ -40,7 +40,7 @@ void getTranslation() { assertNotNull(translation); verify(mockPlugin, times(1)).getDataFolder(); Field[] fields = translation.getClass().getDeclaredFields(); - YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourseFolder, "lang/en.yml")); + YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourceFolder, "lang/en.yml")); for (Field field : fields) { field.setAccessible(true); try { @@ -58,8 +58,8 @@ void getTranslation() { @Test @DisplayName("Set default language") void setDefaultLang() { - File resourseFolder = new File("src/test/resources"); - when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + File resourceFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); TelegramBridge.plugin = mockPlugin; @@ -71,7 +71,7 @@ void setDefaultLang() { } Field[] fields = translations.get().getClass().getDeclaredFields(); - YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourseFolder, "lang/pt.yml")); + YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(new File(resourceFolder, "lang/pt.yml")); for (Field field : fields) { field.setAccessible(true); try { @@ -89,8 +89,8 @@ void setDefaultLang() { @Test @DisplayName("Set default language with invalid language and non-existent file") void translationExceptions() { - File resourseFolder = new File("src/test/resources"); - when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + File resourceFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); TelegramBridge.plugin = mockPlugin; @@ -106,8 +106,8 @@ void translationExceptions() { @Test @DisplayName("Empty translations directory") void emptyTranslationsDirectory() { - File resourseFolder = new File("src/test/resources/empty"); - when(mockPlugin.getDataFolder()).thenReturn(resourseFolder); + File resourceFolder = new File("src/test/resources/empty"); + when(mockPlugin.getDataFolder()).thenReturn(resourceFolder); TelegramBridge.plugin = mockPlugin; @@ -119,9 +119,9 @@ void emptyTranslationsDirectory() { verify(mockPlugin, times(1)).saveResource("lang/" + lang + ".yml", false); } - File langDir = new File(resourseFolder, "lang"); + File langDir = new File(resourceFolder, "lang"); assertTrue(langDir.delete()); - assertTrue(resourseFolder.delete()); + assertTrue(resourceFolder.delete()); } @Test From 17f81767c95d0f7ddc328e0edcf0975de8493f9f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:25:18 -0300 Subject: [PATCH 42/56] test: Pseudo lang server start and stop translation --- src/test/resources/lang/tt.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/resources/lang/tt.yml b/src/test/resources/lang/tt.yml index cc5139a..45aca43 100644 --- a/src/test/resources/lang/tt.yml +++ b/src/test/resources/lang/tt.yml @@ -15,6 +15,10 @@ death: 'JM' advancement: 'JC' # Quando um jogador dorme sleep: 'JD' +# Quando o servidor inicia +serverStart: 'JSS' +# Quando o servidor para +serverStop: 'JSP' # Quando um jogador envia uma mensagem chatMessage: 'CM' From 4f7f58968bf68c44831ed10f317917aa509863df Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:25:43 -0300 Subject: [PATCH 43/56] feat: Start and stop event logs --- .../altart/telegrambridge/TelegramBridge.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/TelegramBridge.java b/src/main/java/org/altart/telegrambridge/TelegramBridge.java index c30a54e..0e47286 100644 --- a/src/main/java/org/altart/telegrambridge/TelegramBridge.java +++ b/src/main/java/org/altart/telegrambridge/TelegramBridge.java @@ -49,41 +49,51 @@ public void onEnable() { TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); botSession = telegramBotsApi.registerBot(telegramBot); log.info("Telegram bot registered"); + if (config.sendToTelegram && config.serverStartStop) { + telegramBot.broadcastMessage(translations.get().serverStart); + } + + Bukkit.getPluginManager().registerEvents(new ChatEvent(), plugin); + Bukkit.getPluginManager().registerEvents(new GameEvent(), plugin); + try { + Objects.requireNonNull(getCommand("tbreload")).setExecutor(new ReloadCommand()); + PluginCommand replyCommand = Objects.requireNonNull(getCommand("tbreply")); + replyCommand.setExecutor(new ReplyCommand()); + replyCommand.setTabCompleter(new UserTabCompletion(2)); + PluginCommand mentionCommand = Objects.requireNonNull(getCommand("tbmention")); + mentionCommand.setExecutor(new MentionCommand()); + mentionCommand.setTabCompleter(new UserTabCompletion(1)); + PluginCommand configCommand = Objects.requireNonNull(getCommand("tbconfig")); + configCommand.setExecutor(new ConfigCommand()); + configCommand.setTabCompleter(new ConfigTabCompletion()); + } catch (NullPointerException e) { + log.severe("Error registering command: " + e.getMessage()); + Arrays.stream(e.getStackTrace()).forEach(line -> TelegramBridge.log.severe(line.toString())); + } } catch (Exception e) { log.severe("Error registering bot: " + e.getMessage()); Arrays.stream(e.getStackTrace()).forEach(line -> log.severe(line.toString())); } - - Bukkit.getPluginManager().registerEvents(new ChatEvent(), plugin); - Bukkit.getPluginManager().registerEvents(new GameEvent(), plugin); - try { - Objects.requireNonNull(getCommand("tbreload")).setExecutor(new ReloadCommand()); - PluginCommand replyCommand = Objects.requireNonNull(getCommand("tbreply")); - replyCommand.setExecutor(new ReplyCommand()); - replyCommand.setTabCompleter(new UserTabCompletion(2)); - PluginCommand mentionCommand = Objects.requireNonNull(getCommand("tbmention")); - mentionCommand.setExecutor(new MentionCommand()); - mentionCommand.setTabCompleter(new UserTabCompletion(1)); - PluginCommand configCommand = Objects.requireNonNull(getCommand("tbconfig")); - configCommand.setExecutor(new ConfigCommand()); - configCommand.setTabCompleter(new ConfigTabCompletion()); - } catch (NullPointerException e) { - log.severe("Error registering command: " + e.getMessage()); - Arrays.stream(e.getStackTrace()).forEach(line -> TelegramBridge.log.severe(line.toString())); - } } @Override public void onDisable() { - if (config.sendToTelegram && config.joinAndLeaveEvent) { - StringBuilder message = new StringBuilder(); - for (Player player : Bukkit.getOnlinePlayers()) { - message.append(Format.string(translations.get().leave, "playername", player.getDisplayName())).append("\n"); - } - telegramBot.broadcastMessage(message.toString()); - } database.close(); if (botSession != null) { + if (config.sendToTelegram) { + if (config.joinAndLeaveEvent) { + StringBuilder message = new StringBuilder(); + for (Player player : Bukkit.getOnlinePlayers()) { + message.append(Format.string(translations.get().leave, "playername", player.getDisplayName())).append("\n"); + } + if (message.length() > 0) { + telegramBot.broadcastMessage(message.toString()); + } + } + if (config.serverStartStop) { + telegramBot.broadcastMessage(translations.get().serverStop); + } + } botSession.stop(); } } From 0f3dee245d07060691d74db968e620b4d60cb739 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:40:45 -0300 Subject: [PATCH 44/56] chore: Add actions test --- .github/workflows/tests.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..fc840ba --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,26 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up JDK 8 + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'corretto' + - name: Run tests + run: ./gradlew test + - name: Report test results + uses: mikepenz/action-junit-report@v4 + if: success() || failure() From 19d9e5693dd75d9b95b2c42ee4f9fe4f22eff326 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:43:41 -0300 Subject: [PATCH 45/56] fix: Change java version to see if actions works --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 223f0bc..a656e53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 8 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '8' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fc840ba..00d6520 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,15 +9,15 @@ on: - main jobs: - build: + test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 8 + - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '8' + java-version: '17' distribution: 'corretto' - name: Run tests run: ./gradlew test From c70d1b1aa6954629f4562f57f902302436e473e8 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:49:30 -0300 Subject: [PATCH 46/56] fix: Change gradlew command to see if actions works --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 00d6520..6651335 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: java-version: '17' distribution: 'corretto' - name: Run tests - run: ./gradlew test + run: ./gradlew - name: Report test results uses: mikepenz/action-junit-report@v4 if: success() || failure() From 3a4675358726a5574950b8a51917bea19df862eb Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 18:53:38 -0300 Subject: [PATCH 47/56] fix: Specify the test report path to see if actions works --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6651335..b0bcd98 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,3 +24,5 @@ jobs: - name: Report test results uses: mikepenz/action-junit-report@v4 if: success() || failure() + with: + report_paths: '**/build/test-results/test/TEST-*.xml' From c3636a9bad447d30ac6fd399e6ca4d61e707fcff Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 19:59:07 -0300 Subject: [PATCH 48/56] fix: Return false when the command don't succeed --- .../org/altart/telegrambridge/commands/ConfigCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/commands/ConfigCommand.java b/src/main/java/org/altart/telegrambridge/commands/ConfigCommand.java index 8a7ba8f..5a3330a 100644 --- a/src/main/java/org/altart/telegrambridge/commands/ConfigCommand.java +++ b/src/main/java/org/altart/telegrambridge/commands/ConfigCommand.java @@ -17,7 +17,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command _comman if (args[0].equals("default-lang")) { if (!sender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())) { sender.sendMessage("You do not have permission to use this command."); - return true; + return false; } try { TelegramBridge.translations.setDefaultLang(args[1]); @@ -31,14 +31,14 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command _comman if (args[0].equals("lang")) { if (!sender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())) { sender.sendMessage("You do not have permission to use this command."); - return true; + return false; } try { if (sender instanceof Player) { TelegramBridge.database.setLang(((Player) sender).getUniqueId(), args[1]); } else { sender.sendMessage("This command can only be used by players."); - return true; + return false; } } catch (Exception e) { sender.sendMessage(e.getMessage()); From 95677cfdb90cc0b4e0943bb460bfcbecfae3ce49 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 19:59:40 -0300 Subject: [PATCH 49/56] test: Add `ConfigCommand` tests --- .../commands/ConfigCommandTest.java | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/ConfigCommandTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/ConfigCommandTest.java b/src/test/java/org/altart/telegrambridge/commands/ConfigCommandTest.java new file mode 100644 index 0000000..8b56981 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/ConfigCommandTest.java @@ -0,0 +1,155 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.Permissions; +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.altart.telegrambridge.database.SQLite; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ConfigCommandTest extends StandardMockTest { + @Mock + Command _command; + + @Mock + Translations mockTranslations; + @Mock + Config mockConfig; + @Mock + SQLite mockDatabase; + + @Test + @DisplayName("Test set default translations command") + void onDefaultTranslationsCommand() throws Exception { + CommandSender mockSender = mock(CommandSender.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.translations = mockTranslations; + TelegramBridge.config = mockConfig; + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"default-lang", "en"}); + + verify(mockTranslations, times(1)).setDefaultLang("en"); + verify(mockConfig, times(1)).setLang("en"); + verify(mockSender, never()).sendMessage(anyString()); + verify(mockSender, times(1)).hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString()); + assertTrue(result); + } + + @Test + @DisplayName("Test set default translations command without permission") + void onDefaultTranslationsCommandWithoutPermission() throws Exception { + CommandSender mockSender = mock(CommandSender.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.translations = mockTranslations; + TelegramBridge.config = mockConfig; + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(false); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"default-lang", "en"}); + + verify(mockTranslations, never()).setDefaultLang("en"); + verify(mockConfig, never()).setLang("en"); + verify(mockSender, times(1)).sendMessage("You do not have permission to use this command."); + verify(mockSender, times(1)).hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString()); + assertFalse(result); + } + + @Test + @DisplayName("Test set default translations command with exception") + void onDefaultTranslationsCommandWithException() throws Exception { + CommandSender mockSender = mock(CommandSender.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.translations = mockTranslations; + TelegramBridge.config = mockConfig; + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + doThrow(new Exception("Test exception")).when(mockTranslations).setDefaultLang("en"); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"default-lang", "en"}); + + verify(mockTranslations, times(1)).setDefaultLang("en"); + verify(mockConfig, never()).setLang("en"); + verify(mockSender, times(1)).sendMessage("Test exception"); + verify(mockSender, times(1)).hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString()); + assertFalse(result); + } + + @Test + @DisplayName("Test set translations command") + void onTranslationsCommand() { + Player mockSender = mock(Player.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.database = mockDatabase; + + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + UUID uuid = UUID.randomUUID(); + + when(mockSender.getUniqueId()).thenReturn(uuid); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"lang", "en"}); + + verify(mockDatabase, times(1)).setLang(uuid, "en"); + verify(mockSender, never()).sendMessage(anyString()); + verify(mockSender, times(1)).hasPermission(Permissions.TRANSLATION_CONFIG.getString()); + assertTrue(result); + } + + @Test + @DisplayName("Test set translations command without permission") + void onTranslationsCommandWithoutPermission() { + Player mockSender = mock(Player.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.database = mockDatabase; + + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(false); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"lang", "en"}); + + verify(mockDatabase, never()).setLang(any(UUID.class), anyString()); + verify(mockSender, times(1)).sendMessage("You do not have permission to use this command."); + verify(mockSender, times(1)).hasPermission(Permissions.TRANSLATION_CONFIG.getString()); + assertFalse(result); + } + + @Test + @DisplayName("Test set translations command without player") + void onTranslationsCommandWithoutPlayer() { + CommandSender mockSender = mock(CommandSender.class); + + ConfigCommand configCommand = new ConfigCommand(); + + TelegramBridge.database = mockDatabase; + + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + + boolean result = configCommand.onCommand(mockSender, _command, "config", new String[]{"lang", "en"}); + + verify(mockDatabase, never()).setLang(any(UUID.class), anyString()); + verify(mockSender, times(1)).sendMessage("This command can only be used by players."); + verify(mockSender, times(1)).hasPermission(Permissions.TRANSLATION_CONFIG.getString()); + assertFalse(result); + } +} From 5c4db944c3247e5fd5d3bd7550e728f31bbbaf42 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 13 Jul 2024 19:59:56 -0300 Subject: [PATCH 50/56] test: Add `ConfigTabCompletion` tests --- .../commands/ConfigTabCompletionTest.java | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/ConfigTabCompletionTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/ConfigTabCompletionTest.java b/src/test/java/org/altart/telegrambridge/commands/ConfigTabCompletionTest.java new file mode 100644 index 0000000..7fd1c6e --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/ConfigTabCompletionTest.java @@ -0,0 +1,150 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.Permissions; +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.config.Translations; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ConfigTabCompletionTest extends StandardMockTest { + @Mock + Command _command; + @Mock + CommandSender mockSender; + @Mock + Translations mockTranslations; + + @Test + @DisplayName("Test tab completion first argument") + void onTabComplete() { + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + + String[] args = new String[1]; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assertNotNull(result); + assertEquals(2, result.size()); + assertTrue(result.contains("default-lang")); + assertTrue(result.contains("lang")); + } + + @Test + @DisplayName("Test tab completion second argument default-lang") + void onTabCompleteDefaultLang() { + List languages = new ArrayList<>(); + languages.add("en"); + languages.add("de"); + languages.add("fr"); + + when(mockTranslations.getLoadedLanguages()).thenReturn(languages); + + TelegramBridge.translations = mockTranslations; + + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + + String[] args = new String[2]; + args[0] = "default-lang"; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assertNotNull(result); + assertEquals(3, result.size()); + assertTrue(result.contains("en")); + assertTrue(result.contains("de")); + assertTrue(result.contains("fr")); + } + + @Test + @DisplayName("Test tab completion second argument lang") + void onTabCompleteLang() { + List languages = new ArrayList<>(); + languages.add("en"); + languages.add("de"); + languages.add("fr"); + + when(mockTranslations.getLoadedLanguages()).thenReturn(languages); + + TelegramBridge.translations = mockTranslations; + + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + + String[] args = new String[2]; + args[0] = "lang"; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assertNotNull(result); + assertEquals(3, result.size()); + assertTrue(result.contains("en")); + assertTrue(result.contains("de")); + assertTrue(result.contains("fr")); + } + + @Test + @DisplayName("Test tab completion second argument lang without permission") + void onTabCompleteLangWithoutPermission() { + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(true); + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(false); + + String[] args = new String[2]; + args[0] = "lang"; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assertNull(result); + } + + @Test + @DisplayName("Test tab completion second argument default-lang without permission") + void onTabCompleteDefaultLangWithoutPermission() { + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(false); + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(true); + + String[] args = new String[2]; + args[0] = "default-lang"; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assertNull(result); + } + + @Test + @DisplayName("Test tab completion first argument without permission") + void onTabCompleteWithoutPermission() { + ConfigTabCompletion configTabCompletion = new ConfigTabCompletion(); + + when(mockSender.hasPermission(Permissions.DEFAULT_TRANSLATION_CONFIG.getString())).thenReturn(false); + when(mockSender.hasPermission(Permissions.TRANSLATION_CONFIG.getString())).thenReturn(false); + + String[] args = new String[1]; + + List result = configTabCompletion.onTabComplete(mockSender, _command, "config", args); + + assert result != null; + assertEquals(0, result.size()); + } +} From 00f6b69c5fc635cb639d81b810bad182cefa8e50 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 13:55:12 -0300 Subject: [PATCH 51/56] test: Add `MentionCommand` tests --- .../commands/MentionCommandTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/MentionCommandTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/MentionCommandTest.java b/src/test/java/org/altart/telegrambridge/commands/MentionCommandTest.java new file mode 100644 index 0000000..570106e --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/MentionCommandTest.java @@ -0,0 +1,36 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.StandardMockTest; +import org.bukkit.entity.Player; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class MentionCommandTest extends StandardMockTest { + @Mock + Player player; + + @Test + void onCommand() { + MentionCommand mentionCommand = new MentionCommand(); + String[] args = {"Hello", "World"}; + assertTrue(mentionCommand.onCommand(player, null, null, args)); + verify(player).chat("Hello World"); + } + + @Test + void onCommandNoArgs() { + MentionCommand mentionCommand = new MentionCommand(); + String[] args = {}; + assertFalse(mentionCommand.onCommand(player, null, null, args)); + } + + @Test + void onCommandNotPlayer() { + MentionCommand mentionCommand = new MentionCommand(); + String[] args = {"Hello", "World"}; + assertFalse(mentionCommand.onCommand(null, null, null, args)); + } +} From 6ba3d2096f43e6f2cdc2b46a7ff41379f3e8bc59 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 13:55:45 -0300 Subject: [PATCH 52/56] test: Add `ReloadCommand` tests --- .../commands/ReloadCommandTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/ReloadCommandTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/ReloadCommandTest.java b/src/test/java/org/altart/telegrambridge/commands/ReloadCommandTest.java new file mode 100644 index 0000000..dedc60c --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/ReloadCommandTest.java @@ -0,0 +1,29 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.config.Config; +import org.bukkit.command.CommandSender; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ReloadCommandTest extends StandardMockTest { + @Mock + CommandSender sender; + + @Mock + Config config; + + @Test + void onCommand() { + TelegramBridge.config = config; + + ReloadCommand reloadCommand = new ReloadCommand(); + assertTrue(reloadCommand.onCommand(sender, null, null, null)); + verify(TelegramBridge.config).load(); + verify(sender).sendMessage("Config reloaded!"); + } +} From b9c1a241ee5fddce3d47b836bd6e1d88243318cb Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 13:56:09 -0300 Subject: [PATCH 53/56] test: Add `ReplyCommand` tests --- .../commands/ReplyCommandTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/ReplyCommandTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/ReplyCommandTest.java b/src/test/java/org/altart/telegrambridge/commands/ReplyCommandTest.java new file mode 100644 index 0000000..4128cd0 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/ReplyCommandTest.java @@ -0,0 +1,51 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.bot.feature.MessageListener; +import org.altart.telegrambridge.config.Config; +import org.altart.telegrambridge.config.Translations; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ReplyCommandTest extends StandardMockTest { + @Mock + CommandSender sender; + @Mock + Plugin mockPlugin; + @Mock + MessageListener mockMessageListener; + + @Test + void onCommand() { + File translationsFolder = new File("src/test/resources"); + when(mockPlugin.getDataFolder()).thenReturn(translationsFolder); + + TelegramBridge.plugin = mockPlugin; + TelegramBridge.config = new Config(); + TelegramBridge.telegramBot = new TelegramBot(mockPlugin); + TelegramBridge.telegramBot.messageListenerFeature = mockMessageListener; + TelegramBridge.translations = new Translations("en"); + + when(sender.getName()).thenReturn("playerName"); + + ReplyCommand replyCommand = new ReplyCommand(); + replyCommand.onCommand(sender, null, null, new String[]{"uuid", "message", "message"}); + verify(sender, times(1)).getName(); + verify(mockMessageListener, times(1)).reply("uuid", "[playerName]: message message"); + } + + @Test + void onCommandWithEmptyArgs() { + ReplyCommand replyCommand = new ReplyCommand(); + assertFalse(replyCommand.onCommand(sender, null, null, new String[]{})); + } +} From 7c409f7774b952d125da9314a16de7c70f0f3713 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 13:57:28 -0300 Subject: [PATCH 54/56] test: Add `UserTabCompletion` tests --- .../commands/UserTabCompletionTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/java/org/altart/telegrambridge/commands/UserTabCompletionTest.java diff --git a/src/test/java/org/altart/telegrambridge/commands/UserTabCompletionTest.java b/src/test/java/org/altart/telegrambridge/commands/UserTabCompletionTest.java new file mode 100644 index 0000000..a001904 --- /dev/null +++ b/src/test/java/org/altart/telegrambridge/commands/UserTabCompletionTest.java @@ -0,0 +1,63 @@ +package org.altart.telegrambridge.commands; + +import org.altart.telegrambridge.StandardMockTest; +import org.altart.telegrambridge.TelegramBridge; +import org.altart.telegrambridge.bot.TelegramBot; +import org.altart.telegrambridge.bot.feature.UserAutocomplete; +import org.bukkit.command.CommandSender; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class UserTabCompletionTest extends StandardMockTest { + @Mock + CommandSender mockCommandSender; + @Mock + TelegramBot mockTelegramBot; + @Mock + UserAutocomplete mockUserAutocomplete; + + @Test + void onTabComplete() { + TelegramBridge.telegramBot = mockTelegramBot; + TelegramBridge.telegramBot.userAutocompleteFeature = mockUserAutocomplete; + + UserTabCompletion userTabCompletion = new UserTabCompletion(1); + String[] args = new String[]{"test"}; + + List users = new ArrayList<>(); + users.add("test1"); + users.add("test2"); + users.add("test3"); + when(mockUserAutocomplete.getTelegramUsers()).thenReturn(users); + + List result = userTabCompletion.onTabComplete(mockCommandSender, null, null, args); + assertEquals(3, result.size()); + assertEquals("test1", result.get(0)); + assertEquals("test2", result.get(1)); + assertEquals("test3", result.get(2)); + } + + @Test + void onTabCompleteNoArgs() { + TelegramBridge.telegramBot = mockTelegramBot; + TelegramBridge.telegramBot.userAutocompleteFeature = mockUserAutocomplete; + + UserTabCompletion userTabCompletion = new UserTabCompletion(1); + String[] args = {"test", "test2"}; + + List users = new ArrayList<>(); + users.add("test1"); + users.add("test2"); + users.add("test3"); + when(mockUserAutocomplete.getTelegramUsers()).thenReturn(users); + + List result = userTabCompletion.onTabComplete(mockCommandSender, null, null, args); + assertEquals(0, result.size()); + } +} From 64e8bc68fc629656b9566805cafcfdb875ca7227 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 13:59:04 -0300 Subject: [PATCH 55/56] fix: Make feature fields final to do tests --- src/main/java/org/altart/telegrambridge/bot/TelegramBot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java index 8edab17..0afea2d 100644 --- a/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java +++ b/src/main/java/org/altart/telegrambridge/bot/TelegramBot.java @@ -35,8 +35,8 @@ public class TelegramBot extends TelegramLongPollingBot { public List features = new ArrayList<>(); public PinMessage pinMessageFeature = new PinMessage(this); - public final UserAutocomplete userAutocompleteFeature = new UserAutocomplete(this); - public final MessageListener messageListenerFeature = new MessageListener(this); + public UserAutocomplete userAutocompleteFeature = new UserAutocomplete(this); + public MessageListener messageListenerFeature = new MessageListener(this); public final SentMedia sentMediaFeature = new SentMedia(this); public TelegramBot(Plugin plugin) { From 574db3086d040a57b7e4defa79e6164b5b32e586 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Fri, 19 Jul 2024 14:15:18 -0300 Subject: [PATCH 56/56] test: Fix `ConfigTest` amount of fields --- src/test/java/org/altart/telegrambridge/config/ConfigTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/altart/telegrambridge/config/ConfigTest.java b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java index 85daf14..3d81531 100644 --- a/src/test/java/org/altart/telegrambridge/config/ConfigTest.java +++ b/src/test/java/org/altart/telegrambridge/config/ConfigTest.java @@ -110,7 +110,6 @@ void save() { fail(); } } - assertEquals(20, fields.length); verify(log, times(1)).warning(anyString()); verify(log, times(1)).info(anyString()); }