diff --git a/src/test/java/com/diamonddagger590/mccore/bootstrap/registrar/CommandRegistrarTest.java b/src/test/java/com/diamonddagger590/mccore/bootstrap/registrar/CommandRegistrarTest.java new file mode 100644 index 0000000..b42bb1e --- /dev/null +++ b/src/test/java/com/diamonddagger590/mccore/bootstrap/registrar/CommandRegistrarTest.java @@ -0,0 +1,93 @@ +package com.diamonddagger590.mccore.bootstrap.registrar; + +import com.diamonddagger590.mccore.CorePlugin; +import com.diamonddagger590.mccore.bootstrap.BootstrapContext; +import com.diamonddagger590.mccore.bootstrap.StartupProfile; +import com.diamonddagger590.mccore.command.CoreCommandManager; +import com.diamonddagger590.mccore.registry.RegistryAccess; +import com.diamonddagger590.mccore.registry.RegistryKey; +import com.diamonddagger590.mccore.registry.manager.ManagerRegistry; +import com.diamonddagger590.mccore.testing.RegistryResetExtension; +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.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.junit.jupiter.MockitoExtension; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CommandRegistrarTest { + + @Mock + private CorePlugin mockPlugin; + + private ManagerRegistry managerRegistry; + + @BeforeEach + void setUp() { + RegistryResetExtension.setupRegistry(); + managerRegistry = RegistryAccess.registryAccess().registry(RegistryKey.MANAGER); + when(mockPlugin.registryAccess()).thenReturn(RegistryAccess.registryAccess()); + } + + @AfterEach + void tearDown() { + RegistryResetExtension.resetRegistry(); + } + + @NotNull + private BootstrapContext context() { + return new BootstrapContext<>(mockPlugin, StartupProfile.PROD); + } + + @Test + @DisplayName("Given a valid context, when register is called, then CoreCommandManager is registered in ManagerRegistry") + void register_registersCoreCommandManager_whenContextIsValid() { + try (MockedConstruction mocked = mockConstruction(CoreCommandManager.class)) { + new CommandRegistrar().register(context()); + + assertEquals(1, mocked.constructed().size()); + CoreCommandManager constructed = mocked.constructed().get(0); + assertTrue(managerRegistry.registered(constructed)); + } + } + + @Test + @DisplayName("Given a valid context, when register is called, then CoreCommandManager receives the plugin from context") + void register_passesPluginToManager_whenContextIsValid() { + AtomicReference capturedContext = new AtomicReference<>(); + try (MockedConstruction mocked = mockConstruction(CoreCommandManager.class, + (mock, ctx) -> capturedContext.set(ctx))) { + new CommandRegistrar().register(context()); + + assertEquals(1, mocked.constructed().size()); + assertNotNull(capturedContext.get()); + assertEquals(1, capturedContext.get().arguments().size()); + assertSame(mockPlugin, capturedContext.get().arguments().get(0)); + } + } + + @Test + @DisplayName("Given register was already called, when register is called again, then it throws IllegalArgumentException") + void register_throwsIllegalArgumentException_whenCalledTwice() { + try (MockedConstruction mocked = mockConstruction(CoreCommandManager.class)) { + CommandRegistrar registrar = new CommandRegistrar<>(); + registrar.register(context()); + + assertThrows(IllegalArgumentException.class, () -> registrar.register(context())); + } + } +} diff --git a/src/test/java/com/diamonddagger590/mccore/command/CoreCommandManagerTest.java b/src/test/java/com/diamonddagger590/mccore/command/CoreCommandManagerTest.java new file mode 100644 index 0000000..b8ecc4d --- /dev/null +++ b/src/test/java/com/diamonddagger590/mccore/command/CoreCommandManagerTest.java @@ -0,0 +1,136 @@ +package com.diamonddagger590.mccore.command; + +import com.diamonddagger590.mccore.CorePlugin; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.incendo.cloud.annotations.AnnotationParser; +import org.incendo.cloud.paper.PaperCommandManager; +import org.incendo.cloud.processors.confirmation.ConfirmationManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CoreCommandManagerTest { + + @Mock + private CorePlugin mockPlugin; + + private CoreCommandManager manager; + + @BeforeEach + @SuppressWarnings("unchecked") + void setUp() { + try (MockedStatic paperStatic = mockStatic(PaperCommandManager.class); + MockedConstruction parserConstruction = mockConstruction(AnnotationParser.class)) { + + PaperCommandManager.Builder mockBuilder = mock(PaperCommandManager.Builder.class); + PaperCommandManager.CoordinatedBuilder mockCoordinatedBuilder = mock(PaperCommandManager.CoordinatedBuilder.class); + PaperCommandManager mockPaperManager = mock(PaperCommandManager.class); + + paperStatic.when(PaperCommandManager::builder).thenReturn(mockBuilder); + when(mockBuilder.executionCoordinator(any())).thenReturn(mockCoordinatedBuilder); + when(mockCoordinatedBuilder.buildOnEnable(any())).thenReturn(mockPaperManager); + + manager = new CoreCommandManager(mockPlugin); + } + } + + @Nested + @DisplayName("getCommandManager") + class GetCommandManager { + + @Test + @DisplayName("Given a constructed manager, when getCommandManager is called, then it returns a non-null PaperCommandManager") + void getCommandManager_returnsNonNull_whenConstructed() { + assertNotNull(manager.getCommandManager()); + } + } + + @Nested + @DisplayName("getAnnotationParser") + class GetAnnotationParser { + + @Test + @DisplayName("Given a constructed manager, when getAnnotationParser is called, then it returns a non-null AnnotationParser") + void getAnnotationParser_returnsNonNull_whenConstructed() { + assertNotNull(manager.getAnnotationParser()); + } + } + + @Nested + @DisplayName("plugin") + class Plugin { + + @Test + @DisplayName("Given a constructed manager, when plugin is called, then it returns the plugin passed to constructor") + void plugin_returnsPluginFromConstructor_whenCalled() { + assertSame(mockPlugin, manager.plugin()); + } + } + + @Nested + @DisplayName("registerConfirmationCommand") + class RegisterConfirmationCommand { + + @Test + @DisplayName("Given no confirmation manager registered, when registerConfirmationCommand is called, then it succeeds") + @SuppressWarnings("unchecked") + void registerConfirmationCommand_succeeds_whenNotYetRegistered() { + ConfirmationManager confirmationManager = mock(ConfirmationManager.class); + + manager.registerConfirmationCommand(confirmationManager); + + assertSame(confirmationManager, manager.getConfirmationManager()); + } + + @Test + @DisplayName("Given a confirmation manager already registered, when registerConfirmationCommand is called again, then it throws IllegalStateException") + @SuppressWarnings("unchecked") + void registerConfirmationCommand_throwsIllegalStateException_whenAlreadyRegistered() { + ConfirmationManager first = mock(ConfirmationManager.class); + ConfirmationManager second = mock(ConfirmationManager.class); + + manager.registerConfirmationCommand(first); + + assertThrows(IllegalStateException.class, () -> manager.registerConfirmationCommand(second)); + } + } + + @Nested + @DisplayName("getConfirmationManager") + class GetConfirmationManager { + + @Test + @DisplayName("Given no confirmation manager registered, when getConfirmationManager is called, then it throws IllegalStateException") + void getConfirmationManager_throwsIllegalStateException_whenNotRegistered() { + assertThrows(IllegalStateException.class, () -> manager.getConfirmationManager()); + } + + @Test + @DisplayName("Given a confirmation manager registered, when getConfirmationManager is called, then it returns the registered manager") + @SuppressWarnings("unchecked") + void getConfirmationManager_returnsRegisteredManager_whenRegistered() { + ConfirmationManager confirmationManager = mock(ConfirmationManager.class); + manager.registerConfirmationCommand(confirmationManager); + + ConfirmationManager result = manager.getConfirmationManager(); + + assertSame(confirmationManager, result); + } + } +} diff --git a/src/test/java/com/diamonddagger590/mccore/database/table/impl/MutexDAOTest.java b/src/test/java/com/diamonddagger590/mccore/database/table/impl/MutexDAOTest.java index 0cf6e2f..02c4d8b 100644 --- a/src/test/java/com/diamonddagger590/mccore/database/table/impl/MutexDAOTest.java +++ b/src/test/java/com/diamonddagger590/mccore/database/table/impl/MutexDAOTest.java @@ -99,6 +99,20 @@ void updateTable_performsNoUpdate_whenVersionIsCurrent() throws SQLException { verify(mockStatement, never()).executeUpdate(); } + @Test + @DisplayName("Given the table is above current version, when updateTable is called, then no updates are performed") + void updateTable_performsNoUpdate_whenVersionIsAboveCurrent() throws SQLException { + when(mockConnection.prepareStatement(anyString())).thenReturn(mockStatement); + when(mockStatement.executeQuery()).thenReturn(mockResultSet); + when(mockResultSet.next()).thenReturn(true, false); + when(mockResultSet.getInt("table_version")).thenReturn(5); + + MutexDAO.updateTable(mockConnection); + + verify(mockStatement).setString(1, "player_mutex"); + verify(mockStatement, never()).executeUpdate(); + } + @Test @DisplayName("Given the table is at version 0, when updateTable is called, then it updates to version 1") void updateTable_updatesToVersion1_whenVersionIsZero() throws SQLException { diff --git a/src/test/java/com/diamonddagger590/mccore/database/table/impl/PlayerSettingDAOTest.java b/src/test/java/com/diamonddagger590/mccore/database/table/impl/PlayerSettingDAOTest.java index 05ca199..360ae21 100644 --- a/src/test/java/com/diamonddagger590/mccore/database/table/impl/PlayerSettingDAOTest.java +++ b/src/test/java/com/diamonddagger590/mccore/database/table/impl/PlayerSettingDAOTest.java @@ -43,6 +43,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -169,6 +170,20 @@ void updateTable_performsNoUpdate_whenVersionIsCurrent() throws SQLException { PlayerSettingDAO.updateTable(mockConnection); } + @Test + @DisplayName("Given the table is above current version, when updateTable is called, then no updates are performed") + void updateTable_performsNoUpdate_whenVersionIsAboveCurrent() throws SQLException { + when(mockConnection.prepareStatement(anyString())).thenReturn(mockStatement); + when(mockStatement.executeQuery()).thenReturn(mockResultSet); + when(mockResultSet.next()).thenReturn(true, false); + when(mockResultSet.getInt("table_version")).thenReturn(5); + + PlayerSettingDAO.updateTable(mockConnection); + + verify(mockStatement).setString(1, "player_settings"); + verify(mockStatement, never()).executeUpdate(); + } + @Test @DisplayName("Given the table is at version 0, when updateTable is called, then it updates to version 1") void updateTable_updatesToVersion1_whenVersionIsZero() throws SQLException {