more code coverage

This commit is contained in:
nossr50
2025-11-27 11:45:05 -08:00
parent 02ef9fad1d
commit ac9f060e79
2 changed files with 111 additions and 35 deletions

View File

@@ -6,6 +6,7 @@ import com.gmail.nossr50.config.GeneralConfig;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
@@ -23,6 +24,7 @@ import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.testcontainers.containers.JdbcDatabaseContainer;
@@ -47,7 +49,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@TestInstance(Lifecycle.PER_CLASS)
@@ -382,7 +388,7 @@ class SQLDatabaseManagerTest {
}
// ------------------------------------------------------------------------
// Schema upgrades (legacy spears)
// Schema upgrades
// ------------------------------------------------------------------------
@ParameterizedTest(name = "{0} - upgrades legacy schema to add spears columns")
@@ -421,6 +427,55 @@ class SQLDatabaseManagerTest {
}
}
@ParameterizedTest(name = "{0} - SQL_CHARSET_UTF8MB4 upgrade runs without error")
@MethodSource("dbFlavors")
void whenCharsetUpgradeIsRequiredShouldUpdateCharacterSet(DbFlavor flavor) {
// GIVEN
truncateAllCoreTables(flavor);
// First reset and restub the upgrade manager so only the charset upgrade runs
reset(upgradeManager);
when(mcMMO.getUpgradeManager()).thenReturn(upgradeManager);
when(upgradeManager.shouldUpgrade(any(UpgradeType.class))).thenReturn(false);
when(upgradeManager.shouldUpgrade(UpgradeType.SQL_CHARSET_UTF8MB4)).thenReturn(true);
// WHEN constructor will call checkStructure(), which will in turn call updateCharacterSet(...)
SQLDatabaseManager manager = createManagerFor(flavor);
// THEN we at least expect the upgrade to be marked completed
verify(upgradeManager, atLeastOnce()).setUpgradeCompleted(UpgradeType.SQL_CHARSET_UTF8MB4);
manager.onDisable();
// Restore default behavior for other tests: no upgrades
when(upgradeManager.shouldUpgrade(any(UpgradeType.class))).thenReturn(false);
}
@ParameterizedTest(name = "{0} - when all upgrades are required, all upgrade helpers execute")
@MethodSource("dbFlavors")
void whenAllUpgradesRequiredShouldExecuteAllUpgradeHelpers(DbFlavor flavor) {
// GIVEN clean schema
truncateAllCoreTables(flavor);
// GIVEN every UpgradeType should be considered "needed"
reset(upgradeManager);
when(mcMMO.getUpgradeManager()).thenReturn(upgradeManager);
when(upgradeManager.shouldUpgrade(any(UpgradeType.class))).thenReturn(true);
// WHEN constructor will call checkStructure() which loops all UpgradeType values
SQLDatabaseManager databaseManager = createManagerFor(flavor);
// THEN at least one call to mark some upgrades complete (and in practice, many)
verify(upgradeManager, atLeastOnce()).setUpgradeCompleted(any(UpgradeType.class));
databaseManager.onDisable();
// Restore default for other tests
when(upgradeManager.shouldUpgrade(any(UpgradeType.class))).thenReturn(false);
}
// ------------------------------------------------------------------------
// New user -> rows in all core tables
// ------------------------------------------------------------------------
@@ -1153,6 +1208,59 @@ class SQLDatabaseManagerTest {
}
}
// --------------------------------------------------------------------------
// Convert Users Tests
// --------------------------------------------------------------------------
@ParameterizedTest(name = "{0} - convertUsers migrates all stored users")
@MethodSource("dbFlavors")
void whenConvertingUsersShouldSaveEachStoredUserToDestination(DbFlavor flavor) {
// GIVEN
truncateAllCoreTables(flavor);
SQLDatabaseManager sourceManager = createManagerFor(flavor);
String userA = "convert_user_a_" + flavor.name().toLowerCase();
String userB = "convert_user_b_" + flavor.name().toLowerCase();
sourceManager.newUser(userA, new UUID(1L, 2L));
sourceManager.newUser(userB, new UUID(3L, 4L));
DatabaseManager destination = mock(DatabaseManager.class);
when(destination.saveUser(any(PlayerProfile.class))).thenReturn(true);
// WHEN
sourceManager.convertUsers(destination);
// THEN destination.saveUser(...) called once per stored user
ArgumentCaptor<PlayerProfile> profileCaptor = ArgumentCaptor.forClass(PlayerProfile.class);
verify(destination, times(2)).saveUser(profileCaptor.capture());
assertThat(profileCaptor.getAllValues())
.extracting(PlayerProfile::getPlayerName)
.containsExactlyInAnyOrder(userA, userB);
sourceManager.onDisable();
}
@ParameterizedTest(name = "{0} - convertUsers on empty database does nothing")
@MethodSource("dbFlavors")
void whenConvertingUsersWithNoStoredUsersShouldNotCallDestination(DbFlavor flavor) {
// GIVEN
truncateAllCoreTables(flavor);
SQLDatabaseManager sourceManager = createManagerFor(flavor);
DatabaseManager destination = mock(DatabaseManager.class);
when(destination.saveUser(any(PlayerProfile.class))).thenReturn(true);
// WHEN
sourceManager.convertUsers(destination);
// THEN
verify(destination, times(0)).saveUser(any(PlayerProfile.class));
sourceManager.onDisable();
}
// ------------------------------------------------------------------------
// Helpers for legacy schema tests
// ------------------------------------------------------------------------