Files
spigot-tyrant/src/test/java/games/dmg/spigottyrant/ClassAssignmentServiceTest.java
T
dmg 1642d46f1b
Release / release (push) Successful in 2m17s
CI / build (push) Successful in 1m1s
feat(assassin): add stealth and double jump
2026-08-14 23:08:18 -04:00

130 lines
5.2 KiB
Java

package games.dmg.spigottyrant;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.Test;
final class ClassAssignmentServiceTest {
private static final UUID TYRANT = UUID.fromString("11111111-1111-1111-1111-111111111111");
private static final UUID VIGILANTE = UUID.fromString("22222222-2222-2222-2222-222222222222");
private static final UUID FOLLOWER = UUID.fromString("33333333-3333-3333-3333-333333333333");
private static final Instant NOW = Instant.parse("2026-08-14T12:00:00Z");
private final ClassAssignmentService service = new ClassAssignmentService();
@Test
void purchasedClassCanBeAssignedToVigilanteOrFollower() {
GameState game = gameWith(TyrantUnlock.ASSASSIN);
PlayerState vigilante = PlayerState.newPlayer(VIGILANTE, "Vigilante");
PlayerState follower = withFollower(
PlayerState.newPlayer(FOLLOWER, "Follower"),
VIGILANTE
);
ClassAssignmentResult vigilanteResult = service.assign(
game,
Map.of(VIGILANTE, vigilante, FOLLOWER, follower),
TYRANT,
VIGILANTE,
TyrantClass.ASSASSIN,
NOW
);
ClassAssignmentResult followerResult = service.assign(
game,
vigilanteResult.players(),
TYRANT,
FOLLOWER,
TyrantClass.ASSASSIN,
NOW
);
assertEquals(ClassAssignmentStatus.ASSIGNED, vigilanteResult.status());
assertEquals(TyrantClass.ASSASSIN,
vigilanteResult.players().get(VIGILANTE).tyrantClass());
assertEquals(Set.of(Ability.ASSASSIN_INVISIBILITY),
vigilanteResult.players().get(VIGILANTE).readyAbilityItems());
assertEquals(ClassAssignmentStatus.ASSIGNED, followerResult.status());
assertEquals(TyrantClass.NONE,
followerResult.players().get(VIGILANTE).tyrantClass());
assertEquals(TyrantClass.ASSASSIN,
followerResult.players().get(FOLLOWER).tyrantClass());
assertEquals(Optional.of(VIGILANTE), followerResult.previousHolderId());
}
@Test
void rejectsLockedSelfAndOptedOutAssignments() {
PlayerState target = PlayerState.newPlayer(FOLLOWER, "Target");
PlayerState optedOut = new PlayerState(
target.playerId(), target.latestName(), target.lastLogin(),
Optional.of(NOW.plusSeconds(60)), target.tyrantClass(), target.followerOf(),
target.cooldownEnds(), target.readyAbilityItems(), target.capturedMobs()
);
assertEquals(ClassAssignmentStatus.CLASS_NOT_UNLOCKED, service.assign(
gameWith(TyrantUnlock.FIXER), Map.of(FOLLOWER, target), TYRANT, FOLLOWER,
TyrantClass.ASSASSIN, NOW
).status());
assertEquals(ClassAssignmentStatus.TARGET_IS_TYRANT, service.assign(
gameWith(TyrantUnlock.ASSASSIN), Map.of(TYRANT,
PlayerState.newPlayer(TYRANT, "Tyrant")), TYRANT, TYRANT,
TyrantClass.ASSASSIN, NOW
).status());
assertEquals(ClassAssignmentStatus.TARGET_OPTED_OUT, service.assign(
gameWith(TyrantUnlock.ASSASSIN), Map.of(FOLLOWER, optedOut), TYRANT,
FOLLOWER, TyrantClass.ASSASSIN, NOW
).status());
}
@Test
void reassignmentAndReignEndClearClassAbilityState() {
Instant cooldown = NOW.plusSeconds(3600);
PlayerState holder = new PlayerState(
VIGILANTE, "Holder", Optional.empty(), Optional.empty(),
TyrantClass.ASSASSIN, Optional.empty(),
Map.of(Ability.ASSASSIN_INVISIBILITY, cooldown),
Set.of(Ability.ASSASSIN_INVISIBILITY), java.util.List.of()
);
PlayerState replacement = PlayerState.newPlayer(FOLLOWER, "Replacement");
ClassAssignmentResult reassigned = service.assign(
gameWith(TyrantUnlock.ASSASSIN),
Map.of(VIGILANTE, holder, FOLLOWER, replacement),
TYRANT, FOLLOWER, TyrantClass.ASSASSIN, NOW
);
PlayerState former = reassigned.players().get(VIGILANTE);
Map<UUID, PlayerState> cleared = service.clearAll(reassigned.players());
assertEquals(Map.of(), former.cooldownEnds());
assertEquals(Set.of(), former.readyAbilityItems());
assertEquals(TyrantClass.NONE, cleared.get(FOLLOWER).tyrantClass());
}
private static GameState gameWith(TyrantUnlock unlock) {
return new GameState(
GameLifecycle.RUNNING,
Optional.of(TYRANT),
Optional.of(VIGILANTE),
Optional.empty(),
Optional.empty(),
Optional.empty(),
Duration.ZERO,
1,
0,
Set.of(unlock)
);
}
private static PlayerState withFollower(PlayerState player, UUID vigilanteId) {
return new PlayerState(
player.playerId(), player.latestName(), player.lastLogin(), player.optedOutUntil(),
player.tyrantClass(), Optional.of(vigilanteId), player.cooldownEnds(),
player.readyAbilityItems(), player.capturedMobs()
);
}
}