diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java index 804a51b6..5f92dbcd 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java @@ -18,9 +18,11 @@ import java.util.Optional; import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION_2; import static de.cotto.lndmanagej.model.ChannelFixtures.CAPACITY; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; +import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_2; import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT; import static de.cotto.lndmanagej.model.FeeConfigurationFixtures.FEE_CONFIGURATION; import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL; +import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_2; import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_PRIVATE; import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS_2; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; @@ -57,7 +59,30 @@ class ChannelControllerIT { private FeeService feeService; @Test - void not_found() throws Exception { + void getBasicInformation_not_found() throws Exception { + mockMvc.perform(get(CHANNEL_PREFIX + "/")) + .andExpect(status().isNotFound()); + } + + @Test + void getBasicInformation() throws Exception { + when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_2)); + mockMvc.perform(get(CHANNEL_PREFIX + "/")) + .andExpect(jsonPath("$.channelIdShort", is(String.valueOf(CHANNEL_ID_2.getShortChannelId())))) + .andExpect(jsonPath("$.channelIdCompact", is(CHANNEL_ID_2.getCompactForm()))) + .andExpect(jsonPath("$.channelIdCompactLnd", is(CHANNEL_ID_2.getCompactFormLnd()))) + .andExpect(jsonPath("$.channelPoint", is(CHANNEL_POINT.toString()))) + .andExpect(jsonPath("$.remotePubkey", is(PUBKEY_2.toString()))) + .andExpect(jsonPath("$.capacity", is(String.valueOf(CAPACITY.satoshis())))) + .andExpect(jsonPath("$.openHeight", is(CHANNEL_ID_2.getBlockHeight()))) + .andExpect(jsonPath("$.status.private", is(false))) + .andExpect(jsonPath("$.status.active", is(false))) + .andExpect(jsonPath("$.status.closed", is(false))) + .andExpect(jsonPath("$.status.openClosed", is("OPEN"))); + } + + @Test + void getChannelDetails_not_found() throws Exception { mockMvc.perform(get(CHANNEL_PREFIX + "/details")) .andExpect(status().isNotFound()); } diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java b/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java index 800549d8..7a41ff99 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java @@ -3,6 +3,7 @@ package de.cotto.lndmanagej.controller; import com.codahale.metrics.MetricRegistry; import de.cotto.lndmanagej.controller.dto.BalanceInformationDto; import de.cotto.lndmanagej.controller.dto.ChannelDetailsDto; +import de.cotto.lndmanagej.controller.dto.ChannelDto; import de.cotto.lndmanagej.controller.dto.FeeConfigurationDto; import de.cotto.lndmanagej.controller.dto.ObjectMapperConfiguration; import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; @@ -54,6 +55,16 @@ public class ChannelController { this.feeService = feeService; } + @GetMapping("/") + public ChannelDto getBasicInformation(@PathVariable ChannelId channelId) throws NotFoundException { + metrics.mark(MetricRegistry.name(getClass(), "getBasicInformation")); + LocalChannel localChannel = channelService.getLocalChannel(channelId).orElse(null); + if (localChannel == null) { + throw new NotFoundException(); + } + return new ChannelDto(localChannel); + } + @GetMapping("/details") public ChannelDetailsDto getDetails(@PathVariable ChannelId channelId) throws NotFoundException { metrics.mark(MetricRegistry.name(getClass(), "getDetails")); diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java index 8456244d..e3267b90 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDto.java @@ -19,6 +19,29 @@ public record ChannelDetailsDto( OnChainCostsDto onChainCosts, FeeConfigurationDto feeConfiguration ) { + public ChannelDetailsDto( + ChannelDto channelDto, + String remoteAlias, + BalanceInformation balanceInformation, + OnChainCostsDto onChainCosts, + FeeConfigurationDto feeConfiguration + ) { + this( + channelDto.channelIdShort(), + channelDto.channelIdCompact(), + channelDto.channelIdCompactLnd(), + channelDto.channelPoint(), + channelDto.openHeight(), + channelDto.remotePubkey(), + remoteAlias, + channelDto.capacity(), + channelDto.status(), + BalanceInformationDto.createFrom(balanceInformation), + onChainCosts, + feeConfiguration + ); + } + public ChannelDetailsDto( LocalChannel localChannel, String remoteAlias, @@ -27,16 +50,9 @@ public record ChannelDetailsDto( FeeConfigurationDto feeConfiguration ) { this( - String.valueOf(localChannel.getId().getShortChannelId()), - localChannel.getId().getCompactForm(), - localChannel.getId().getCompactFormLnd(), - localChannel.getChannelPoint(), - localChannel.getId().getBlockHeight(), - localChannel.getRemotePubkey(), + new ChannelDto(localChannel), remoteAlias, - String.valueOf(localChannel.getCapacity().satoshis()), - ChannelStatusDto.createFrom(localChannel.getStatus()), - BalanceInformationDto.createFrom(balanceInformation), + balanceInformation, onChainCosts, feeConfiguration ); diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDto.java new file mode 100644 index 00000000..021820ac --- /dev/null +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDto.java @@ -0,0 +1,29 @@ +package de.cotto.lndmanagej.controller.dto; + +import de.cotto.lndmanagej.model.ChannelPoint; +import de.cotto.lndmanagej.model.LocalChannel; +import de.cotto.lndmanagej.model.Pubkey; + +public record ChannelDto( + String channelIdShort, + String channelIdCompact, + String channelIdCompactLnd, + ChannelPoint channelPoint, + int openHeight, + Pubkey remotePubkey, + String capacity, + ChannelStatusDto status +) { + public ChannelDto(LocalChannel localChannel) { + this( + String.valueOf(localChannel.getId().getShortChannelId()), + localChannel.getId().getCompactForm(), + localChannel.getId().getCompactFormLnd(), + localChannel.getChannelPoint(), + localChannel.getId().getBlockHeight(), + localChannel.getRemotePubkey(), + String.valueOf(localChannel.getCapacity().satoshis()), + ChannelStatusDto.createFrom(localChannel.getStatus()) + ); + } +} diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java index 5921f6f8..1f357eea 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java @@ -2,6 +2,7 @@ package de.cotto.lndmanagej.controller; import de.cotto.lndmanagej.controller.dto.BalanceInformationDto; import de.cotto.lndmanagej.controller.dto.ChannelDetailsDto; +import de.cotto.lndmanagej.controller.dto.ChannelDto; import de.cotto.lndmanagej.controller.dto.FeeConfigurationDto; import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; import de.cotto.lndmanagej.metrics.Metrics; @@ -73,6 +74,20 @@ class ChannelControllerTest { lenient().when(feeService.getFeeConfiguration(CHANNEL_ID)).thenReturn(FEE_CONFIGURATION); } + @Test + void getBasicInformation_channel_not_found() { + assertThatExceptionOfType(NotFoundException.class) + .isThrownBy(() -> channelController.getBasicInformation(CHANNEL_ID)); + } + + @Test + void getBasicInformation() throws NotFoundException { + ChannelDto basicInformation = new ChannelDto(LOCAL_OPEN_CHANNEL); + when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL)); + assertThat(channelController.getBasicInformation(CHANNEL_ID)).isEqualTo(basicInformation); + verify(metrics).mark(argThat(name -> name.endsWith(".getBasicInformation"))); + } + @Test void getDetails_channel_not_found() { assertThatExceptionOfType(NotFoundException.class) diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDtoTest.java new file mode 100644 index 00000000..6e2a4dbc --- /dev/null +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDtoTest.java @@ -0,0 +1,60 @@ +package de.cotto.lndmanagej.controller.dto; + +import de.cotto.lndmanagej.model.ChannelStatus; +import org.junit.jupiter.api.Test; + +import static de.cotto.lndmanagej.model.ChannelFixtures.CAPACITY; +import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID; +import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT; +import static de.cotto.lndmanagej.model.CoopClosedChannelFixtures.CLOSED_CHANNEL; +import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL; +import static de.cotto.lndmanagej.model.OpenCloseStatus.OPEN; +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2; +import static org.assertj.core.api.Assertions.assertThat; + +class ChannelDtoTest { + private static final ChannelDto CHANNEL_DTO = new ChannelDto(CLOSED_CHANNEL); + + @Test + void channelIdShort() { + assertThat(CHANNEL_DTO.channelIdShort()).isEqualTo(String.valueOf(CHANNEL_ID.getShortChannelId())); + } + + @Test + void channelIdCompact() { + assertThat(CHANNEL_DTO.channelIdCompact()).isEqualTo(CHANNEL_ID.getCompactForm()); + } + + @Test + void channelIdCompactLnd() { + assertThat(CHANNEL_DTO.channelIdCompactLnd()).isEqualTo(CHANNEL_ID.getCompactFormLnd()); + } + + @Test + void channelPoint() { + assertThat(CHANNEL_DTO.channelPoint()).isEqualTo(CHANNEL_POINT); + } + + @Test + void openHeight() { + assertThat(CHANNEL_DTO.openHeight()).isEqualTo(CHANNEL_ID.getBlockHeight()); + } + + @Test + void remotePubkey() { + assertThat(CHANNEL_DTO.remotePubkey()).isEqualTo(PUBKEY_2); + } + + @Test + void capacity() { + assertThat(CHANNEL_DTO.capacity()).isEqualTo(String.valueOf(CAPACITY.satoshis())); + } + + @Test + void status() { + ChannelDto dto = new ChannelDto(LOCAL_OPEN_CHANNEL); + ChannelStatusDto channelStatusDto = + ChannelStatusDto.createFrom(new ChannelStatus(false, true, false, OPEN)); + assertThat(dto.status()).isEqualTo(channelStatusDto); + } +} \ No newline at end of file