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 5e267d96..a4da9382 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ChannelControllerIT.java @@ -37,6 +37,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +@SuppressWarnings("PMD.AvoidDuplicateLiterals") @WebMvcTest(controllers = ChannelController.class) class ChannelControllerIT { private static final String CHANNEL_PREFIX = "/api/channel/" + CHANNEL_ID.getShortChannelId(); @@ -90,6 +91,19 @@ class ChannelControllerIT { .andExpect(jsonPath("$.status.openClosed", is("OPEN"))); } + @Test + void getBasicInformation_closed_channel() throws Exception { + when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); + mockMvc.perform(get(CHANNEL_PREFIX + "/")) + .andExpect(jsonPath("$.totalSent", is("0"))) + .andExpect(jsonPath("$.totalReceived", is("0"))) + .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) + .andExpect(jsonPath("$.closeDetails.height", is(987_654))) + .andExpect(jsonPath("$.status.active", is(false))) + .andExpect(jsonPath("$.status.closed", is(true))) + .andExpect(jsonPath("$.status.openClosed", is("CLOSED"))); + } + @Test void getChannelDetails_not_found() throws Exception { mockMvc.perform(get(DETAILS_PREFIX)).andExpect(status().isNotFound()); @@ -139,11 +153,13 @@ class ChannelControllerIT { void getChannelDetails_closed_channel() throws Exception { when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_CHANNEL)); mockMvc.perform(get(DETAILS_PREFIX)) + .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) + .andExpect(jsonPath("$.closeDetails.height", is(987_654))) + .andExpect(jsonPath("$.status.openClosed", is("CLOSED"))) .andExpect(jsonPath("$.totalSent", is("0"))) .andExpect(jsonPath("$.totalReceived", is("0"))) .andExpect(jsonPath("$.status.active", is(false))) .andExpect(jsonPath("$.status.closed", is(true))) - .andExpect(jsonPath("$.status.openClosed", is("CLOSED"))) .andExpect(jsonPath("$.balance.localBalance", is("0"))) .andExpect(jsonPath("$.balance.localReserve", is("0"))) .andExpect(jsonPath("$.balance.localAvailable", is("0"))) @@ -151,9 +167,7 @@ class ChannelControllerIT { .andExpect(jsonPath("$.balance.remoteReserve", is("0"))) .andExpect(jsonPath("$.balance.remoteAvailable", is("0"))) .andExpect(jsonPath("$.policies.local.enabled", is(false))) - .andExpect(jsonPath("$.policies.remote.enabled", is(false))) - .andExpect(jsonPath("$.closeDetails.initiator", is("REMOTE"))) - .andExpect(jsonPath("$.closeDetails.height", is(987_654))); + .andExpect(jsonPath("$.policies.remote.enabled", is(false))); } @Test 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 a37a9737..0581674a 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/ChannelController.java @@ -64,7 +64,8 @@ public class ChannelController { if (localChannel == null) { throw new NotFoundException(); } - return new ChannelDto(localChannel); + ClosedChannelDetailsDto closeDetailsForChannel = getCloseDetailsForChannel(localChannel); + return new ChannelDto(localChannel, closeDetailsForChannel); } @GetMapping("/details") @@ -135,7 +136,7 @@ public class ChannelController { ClosedChannel closedChannel = localChannel.getAsClosedChannel(); return new ClosedChannelDetailsDto(closedChannel.getCloseInitiator(), closedChannel.getCloseHeight()); } else { - return new ClosedChannelDetailsDto("", 0); + return ClosedChannelDetailsDto.UNKNOWN; } } 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 f42dd6a7..b2dabeff 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 @@ -29,8 +29,7 @@ public record ChannelDetailsDto( String remoteAlias, BalanceInformation balanceInformation, OnChainCostsDto onChainCosts, - PoliciesDto policies, - ClosedChannelDetailsDto closeDetails + PoliciesDto policies ) { this( channelDto.channelIdShort(), @@ -48,7 +47,7 @@ public record ChannelDetailsDto( BalanceInformationDto.createFrom(balanceInformation), onChainCosts, policies, - closeDetails + channelDto.closeDetails() ); } @@ -61,12 +60,11 @@ public record ChannelDetailsDto( ClosedChannelDetailsDto closeDetails ) { this( - new ChannelDto(localChannel), + new ChannelDto(localChannel, closeDetails), remoteAlias, balanceInformation, onChainCosts, - policies, - closeDetails + policies ); } } 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 index 5e249dd2..8512c4a5 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDto.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ChannelDto.java @@ -16,9 +16,10 @@ public record ChannelDto( String totalSent, String totalReceived, ChannelStatusDto status, - OpenInitiator openInitiator + OpenInitiator openInitiator, + ClosedChannelDetailsDto closeDetails ) { - public ChannelDto(LocalChannel localChannel) { + public ChannelDto(LocalChannel localChannel, ClosedChannelDetailsDto closeDetails) { this( String.valueOf(localChannel.getId().getShortChannelId()), localChannel.getId().getCompactForm(), @@ -30,7 +31,8 @@ public record ChannelDto( String.valueOf(localChannel.getTotalSent().satoshis()), String.valueOf(localChannel.getTotalReceived().satoshis()), ChannelStatusDto.createFrom(localChannel.getStatus()), - localChannel.getOpenInitiator() + localChannel.getOpenInitiator(), + closeDetails ); } } diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ClosedChannelDetailsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ClosedChannelDetailsDto.java index dc7883b9..f0f444c2 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/dto/ClosedChannelDetailsDto.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/ClosedChannelDetailsDto.java @@ -3,6 +3,8 @@ package de.cotto.lndmanagej.controller.dto; import de.cotto.lndmanagej.model.CloseInitiator; public record ClosedChannelDetailsDto(String initiator, int height) { + public static final ClosedChannelDetailsDto UNKNOWN = new ClosedChannelDetailsDto("", 0); + public ClosedChannelDetailsDto(CloseInitiator initiator, int height) { this(initiator.toString(), height); } 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 8aaef876..a8e88800 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/ChannelControllerTest.java @@ -86,12 +86,20 @@ class ChannelControllerTest { @Test void getBasicInformation() throws NotFoundException { - ChannelDto basicInformation = new ChannelDto(LOCAL_OPEN_CHANNEL); + ChannelDto basicInformation = new ChannelDto(LOCAL_OPEN_CHANNEL, ClosedChannelDetailsDto.UNKNOWN); 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 getBasicInformation_closed_channel() throws NotFoundException { + ChannelDto basicInformation = new ChannelDto(CLOSED_CHANNEL, CLOSED_CHANNEL_DETAILS_DTO); + when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(CLOSED_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) @@ -106,7 +114,7 @@ class ChannelControllerTest { LOCAL_OPEN_CHANNEL.getBalanceInformation(), ON_CHAIN_COSTS, FEE_CONFIGURATION_DTO, - new ClosedChannelDetailsDto("", 0) + ClosedChannelDetailsDto.UNKNOWN ); when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2); when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL)); @@ -125,7 +133,7 @@ class ChannelControllerTest { LOCAL_OPEN_CHANNEL_PRIVATE.getBalanceInformation(), ON_CHAIN_COSTS, FEE_CONFIGURATION_DTO, - new ClosedChannelDetailsDto("", 0) + ClosedChannelDetailsDto.UNKNOWN ); when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2); when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE)); diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java index 89ffba30..dbd2f75a 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDetailsDtoTest.java @@ -19,13 +19,14 @@ import static org.assertj.core.api.Assertions.assertThat; class ChannelDetailsDtoTest { private static final OnChainCostsDto ON_CHAIN_COSTS = new OnChainCostsDto(Coins.ofSatoshis(1), Coins.ofSatoshis(2)); + private static final ClosedChannelDetailsDto CLOSE_DETAILS = new ClosedChannelDetailsDto("abc", 123); private static final ChannelDetailsDto CHANNEL_DETAILS_DTO = new ChannelDetailsDto( CLOSED_CHANNEL, ALIAS, BALANCE_INFORMATION, ON_CHAIN_COSTS, PoliciesDto.EMPTY, - new ClosedChannelDetailsDto("", 0) + CLOSE_DETAILS ); @Test @@ -81,13 +82,18 @@ class ChannelDetailsDtoTest { BALANCE_INFORMATION, ON_CHAIN_COSTS, PoliciesDto.EMPTY, - new ClosedChannelDetailsDto("", 0) + CLOSE_DETAILS ); ChannelStatusDto channelStatusDto = ChannelStatusDto.createFrom(new ChannelStatus(false, true, false, OPEN)); assertThat(dto.status()).isEqualTo(channelStatusDto); } + @Test + void closeDetails() { + assertThat(CHANNEL_DETAILS_DTO.closeDetails()).isEqualTo(CLOSE_DETAILS); + } + @Test void balance() { assertThat(CHANNEL_DETAILS_DTO.balance()).isEqualTo(BalanceInformationDto.createFrom(BALANCE_INFORMATION)); 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 index 55126bea..dc73bfa9 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDtoTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/ChannelDtoTest.java @@ -16,7 +16,8 @@ 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); + private static final ClosedChannelDetailsDto CLOSE_DETAILS = new ClosedChannelDetailsDto("abc", 123); + private static final ChannelDto CHANNEL_DTO = new ChannelDto(CLOSED_CHANNEL, CLOSE_DETAILS); @Test void channelIdShort() { @@ -55,13 +56,13 @@ class ChannelDtoTest { @Test void totalSent() { - assertThat(new ChannelDto(LOCAL_OPEN_CHANNEL).totalSent()) + assertThat(new ChannelDto(LOCAL_OPEN_CHANNEL, CLOSE_DETAILS).totalSent()) .isEqualTo(String.valueOf(TOTAL_SENT.satoshis())); } @Test void totalReceived() { - assertThat(new ChannelDto(LOCAL_OPEN_CHANNEL).totalReceived()) + assertThat(new ChannelDto(LOCAL_OPEN_CHANNEL, CLOSE_DETAILS).totalReceived()) .isEqualTo(String.valueOf(TOTAL_RECEIVED.satoshis())); } @@ -70,9 +71,14 @@ class ChannelDtoTest { assertThat(CHANNEL_DTO.openInitiator()).isEqualTo(OpenInitiator.LOCAL); } + @Test + void closeDetails() { + assertThat(CHANNEL_DTO.closeDetails()).isEqualTo(CLOSE_DETAILS); + } + @Test void status() { - ChannelDto dto = new ChannelDto(LOCAL_OPEN_CHANNEL); + ChannelDto dto = new ChannelDto(LOCAL_OPEN_CHANNEL, CLOSE_DETAILS); ChannelStatusDto channelStatusDto = ChannelStatusDto.createFrom(new ChannelStatus(false, true, false, OPEN)); assertThat(dto.status()).isEqualTo(channelStatusDto);