130 lines
5.2 KiB
Java
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()
|
|
);
|
|
}
|
|
}
|