Skip to content

Commit

Permalink
feat: add teleport to station position command
Browse files Browse the repository at this point in the history
  • Loading branch information
sotterbeck committed Aug 15, 2024
1 parent 7406a65 commit 5768608
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import de.sotterbeck.iumetro.usecase.station.MetroStationManagingInteractor;
import de.sotterbeck.iumetro.usecase.station.MetroStationModifyInteractor;
import de.sotterbeck.iumetro.usecase.station.MetroStationRepository;
import de.sotterbeck.iumetro.usecase.station.MetroStationTeleportInteractor;
import jakarta.inject.Singleton;
import org.bukkit.plugin.java.JavaPlugin;

import javax.sql.DataSource;

Expand All @@ -32,6 +34,12 @@ static MetroStationModifyInteractor provideMetroStationModifyInteractor(MetroSta
return new MetroStationModifyInteractor(metroStationRepository);
}

@Provides
@Singleton
static MetroStationTeleportInteractor provideMetroStationTeleportInteractor(MetroStationRepository metroStationRepository) {
return new MetroStationTeleportInteractor(metroStationRepository);
}

@ProvidesIntoSet
static CloudAnnotated provideMetroStationListCommand(MetroStationManagingInteractor metroStationManagingInteractor) {
return new MetroStationListCommand(metroStationManagingInteractor);
Expand All @@ -47,4 +55,9 @@ static CloudAnnotated provideMetroStationModifyCommand(MetroStationManagingInter
return new MetroStationModifyCommand(metroStationManagingInteractor, metroStationModifyInteractor);
}

@ProvidesIntoSet
static CloudAnnotated provideMetroStationTpCommand(MetroStationTeleportInteractor metroStationTeleportInteractor, JavaPlugin plugin) {
return new MetroStationTpCommand(metroStationTeleportInteractor, plugin);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package de.sotterbeck.iumetro.entrypoint.papermc.station;

import de.sotterbeck.iumetro.entrypoint.papermc.common.CloudAnnotated;
import de.sotterbeck.iumetro.usecase.faregate.PositionDto;
import de.sotterbeck.iumetro.usecase.station.MetroStationTeleportInteractor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.incendo.cloud.annotation.specifier.Greedy;
import org.incendo.cloud.annotations.Argument;
import org.incendo.cloud.annotations.Command;
import org.incendo.cloud.annotations.Permission;
import org.incendo.cloud.annotations.suggestion.Suggestions;

import java.util.List;

public class MetroStationTpCommand implements CloudAnnotated {

private final MetroStationTeleportInteractor metroStationTeleportInteractor;
private final World world;
private final Plugin plugin;

public MetroStationTpCommand(MetroStationTeleportInteractor metroStationTeleportInteractor, Plugin plugin) {
this.metroStationTeleportInteractor = metroStationTeleportInteractor;
this.world = plugin.getServer().getWorlds().getFirst();
this.plugin = plugin;
}

@Command("metrostation tp <station>")
@Permission("iumetro.metrostation.tp")
public void metroStationTp(
CommandSender sender,
@Argument(value = "station", suggestions = "teleportableStationNames") @Greedy String station
) {
if (!(sender instanceof Player player)) {
sender.sendRichMessage("<red>Only players can use this command!");
return;
}
boolean teleportable = metroStationTeleportInteractor.isTeleportable(station);
if (!teleportable) {
player.sendRichMessage("<red>You can't teleport to this station!");
return;
}

PositionDto position = metroStationTeleportInteractor.getPosition(station).orElseThrow();

Location location = new Location(world, position.x(), position.y(), position.z());
plugin.getServer().getScheduler().runTask(plugin, () -> player.teleport(location));
player.sendRichMessage("<green>You have been teleported to station " + station + ".");
}

@Suggestions("teleportableStationNames")
public List<String> suggestions() {
return metroStationTeleportInteractor.getAllTeleportableStationNames();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.sotterbeck.iumetro.usecase.station;

import de.sotterbeck.iumetro.usecase.faregate.PositionDto;

import java.util.List;
import java.util.Optional;

public class MetroStationTeleportInteractor {

private final MetroStationRepository metroStationRepository;

public MetroStationTeleportInteractor(MetroStationRepository metroStationRepository) {
this.metroStationRepository = metroStationRepository;
}

public List<String> getAllTeleportableStationNames() {
return metroStationRepository.getAll().stream()
.filter(metroStationDto -> metroStationDto.position().isPresent())
.map(MetroStationDto::name)
.toList();
}

public boolean isTeleportable(String stationName) {
Optional<MetroStationDto> station = metroStationRepository.getByName(stationName);
if (station.isEmpty()) {
return false;
}

Optional<PositionDto> position = station.orElseThrow().position();

return position.isPresent();
}

public Optional<PositionDto> getPosition(String stationName) {
if (!isTeleportable(stationName)) {
return Optional.empty();
}

return metroStationRepository.getByName(stationName).flatMap(MetroStationDto::position);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package de.sotterbeck.iumetro.usecase.station;

import de.sotterbeck.iumetro.usecase.faregate.PositionDto;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class MetroStationTeleportInteractorTest {

@Mock
private MetroStationRepository metroStationRepository;

private MetroStationTeleportInteractor metroStationTeleportInteractor;

@BeforeEach
void setUp() {
metroStationTeleportInteractor = new MetroStationTeleportInteractor(metroStationRepository);
}

@Test
void getAllTeleportableStationNames_ShouldOnlyReturnStationNamesWithPositions() {
MetroStationDto stationWithPosition = new MetroStationDto(UUID.fromString("2acd6e2a-b4da-4aa4-b19f-92805c14a1a3"),
"Station 1",
"ST",
new PositionDto(0, 0, 0));
MetroStationDto stationWithoutPosition = new MetroStationDto(UUID.fromString("bcc38a6a-0816-473a-85be-3186560c7e5d"),
"Station 2",
"ST2");
when(metroStationRepository.getAll()).thenReturn(List.of(
stationWithPosition,
stationWithoutPosition));

List<String> response = metroStationTeleportInteractor.getAllTeleportableStationNames();

assertThat(response).containsOnly(stationWithPosition.name());
}

@Test
void isTeleportable_ShouldReturnFalse_WhenStationDoesNotExist() {
String stationName = "Station 1";
when(metroStationRepository.getByName(stationName)).thenReturn(Optional.empty());

boolean teleportable = metroStationTeleportInteractor.isTeleportable(stationName);

assertThat(teleportable).isFalse();
}

@Test
void isTeleportable_ShouldReturnFalse_WhenStationExitsButHasNoPosition() {
String stationName = "Station 2";
MetroStationDto stationWithoutPosition = new MetroStationDto(UUID.fromString("bcc38a6a-0816-473a-85be-3186560c7e5d"),
stationName,
"ST2");
when(metroStationRepository.getByName(stationName)).thenReturn(Optional.of(stationWithoutPosition));

boolean teleportable = metroStationTeleportInteractor.isTeleportable(stationName);

assertThat(teleportable).isFalse();
}

@Test
void isTeleportable_ShouldReturnTrue_WhenStationExitsAndHasPosition() {
String stationName = "Station 1";
MetroStationDto stationWithPosition = new MetroStationDto(UUID.fromString("2acd6e2a-b4da-4aa4-b19f-92805c14a1a3"),
stationName,
"ST",
new PositionDto(0, 0, 0));
when(metroStationRepository.getByName(stationName)).thenReturn(Optional.of(stationWithPosition));

boolean teleportable = metroStationTeleportInteractor.isTeleportable(stationName);

assertThat(teleportable).isTrue();
}

@Test
void getPosition_ShouldReturnOptionalEmpty_WhenStationIsNotTeleportable() {
String stationName = "Station 2";
MetroStationDto stationWithoutPosition = new MetroStationDto(UUID.fromString("bcc38a6a-0816-473a-85be-3186560c7e5d"),
stationName,
"ST2");
when(metroStationRepository.getByName(stationName)).thenReturn(Optional.of(stationWithoutPosition));

Optional<PositionDto> position = metroStationTeleportInteractor.getPosition(stationName);

assertThat(position).isEmpty();
}

@Test
void getPosition_ShouldReturnPosition_WhenStationIsTeleportable() {
String stationName = "Station 1";
PositionDto stationPosition = new PositionDto(0, 0, 0);
MetroStationDto stationWithPosition = new MetroStationDto(UUID.fromString("2acd6e2a-b4da-4aa4-b19f-92805c14a1a3"),
stationName,
"ST",
stationPosition);
when(metroStationRepository.getByName(stationName)).thenReturn(Optional.of(stationWithPosition));

Optional<PositionDto> position = metroStationTeleportInteractor.getPosition(stationName);

assertThat(position).hasValue(stationPosition);
}

}

0 comments on commit 5768608

Please sign in to comment.