diff --git a/web/src/main/java/de/cotto/lndmanagej/UiDataServiceImpl.java b/web/src/main/java/de/cotto/lndmanagej/UiDataServiceImpl.java index 61af5e56..7f006a92 100644 --- a/web/src/main/java/de/cotto/lndmanagej/UiDataServiceImpl.java +++ b/web/src/main/java/de/cotto/lndmanagej/UiDataServiceImpl.java @@ -42,6 +42,7 @@ public class UiDataServiceImpl extends UiDataService { NodeService nodeService, ChannelService channelService ) { + super(); this.channelController = channelController; this.statusController = statusController; this.warningsController = warningsController; diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/UiDataService.java b/web/src/main/java/de/cotto/lndmanagej/ui/UiDataService.java index 65e94787..24ddb751 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/UiDataService.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/UiDataService.java @@ -16,6 +16,10 @@ import java.util.stream.Collectors; public abstract class UiDataService { + public UiDataService() { + // default constructor + } + public abstract StatusModel getStatus(); public abstract List getOpenChannels(); diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/controller/ChanDetailsController.java b/web/src/main/java/de/cotto/lndmanagej/ui/controller/ChanDetailsController.java index bb97dfa3..dcad8f7b 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/controller/ChanDetailsController.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/controller/ChanDetailsController.java @@ -18,10 +18,9 @@ public class ChanDetailsController { } @GetMapping("/channel/{id}") - public String channelDetails(@PathVariable(name = "id") long id, Model model) { + public String channelDetails(@PathVariable(name = "id") long channelId, Model model) { try { - ChannelId channelId = ChannelId.fromShortChannelId(id); - return page.channelDetails(channelId).create(model); + return page.channelDetails(ChannelId.fromShortChannelId(channelId)).create(model); } catch (NotFoundException e) { return page.error("Channel not found.").create(model); } diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/controller/SearchController.java b/web/src/main/java/de/cotto/lndmanagej/ui/controller/SearchController.java index 0bfc2ccb..f379f6a6 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/controller/SearchController.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/controller/SearchController.java @@ -19,6 +19,8 @@ import java.util.stream.Collectors; @Controller public class SearchController { + private static final int SINGLE_NODE = 1; + private final UiDataService dataService; private final PageService page; @@ -49,20 +51,21 @@ public class SearchController { return page.nodeDetails(Pubkey.create(query)).create(model); } - List matchingChannel = openChannels.stream() + List matchingChannels = openChannels.stream() .filter(chan -> chan.remoteAlias().toLowerCase(Locale.ROOT) .contains(query.toLowerCase(Locale.ROOT))) .collect(Collectors.toList()); - if (matchingChannel.size() > 1) { - return page.nodes(matchingChannel).create(model); + if (matchingChannels.isEmpty()) { + return page.error("No search result.").create(model); + } - if (matchingChannel.size() == 1) { - return page.nodeDetails(matchingChannel.get(0).remotePubkey()).create(model); + if (matchingChannels.size() == SINGLE_NODE) { + return page.nodeDetails(matchingChannels.get(0).remotePubkey()).create(model); } - return page.error("No search result.").create(model); + return page.nodes(matchingChannels).create(model); } private String detailsPage(ChannelId channelId, Model model) { diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/PageService.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/PageService.java index ee0c1ca2..efee3f9c 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/PageService.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/PageService.java @@ -32,8 +32,8 @@ public class PageService { return new ChannelsPage(dataService.getOpenChannels()); } - public ChannelDetailsPage channelDetails(ChannelId id) throws NotFoundException { - return new ChannelDetailsPage(dataService.getChannelDetails(id)); + public ChannelDetailsPage channelDetails(ChannelId channelId) throws NotFoundException { + return new ChannelDetailsPage(dataService.getChannelDetails(channelId)); } public NodesPage nodes() { diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelDetailsPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelDetailsPage.java index 5e214b9a..6cfc800d 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelDetailsPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelDetailsPage.java @@ -6,6 +6,7 @@ import de.cotto.lndmanagej.ui.page.general.ThymeleafPage; public class ChannelDetailsPage extends ThymeleafPage { public ChannelDetailsPage(ChanDetailsDto channel) { + super(); add("id", channel.channelId()); add("channel", channel); } diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelsPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelsPage.java index 209514c2..bdf8cc94 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelsPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/channel/ChannelsPage.java @@ -9,6 +9,7 @@ import java.util.List; public class ChannelsPage extends ThymeleafPage { public ChannelsPage(List channels) { + super(); List sortedChannels = channels.stream() .sorted(Comparator.comparing(OpenChannelDto::getOutboundPercentage)) .toList(); diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/DashboardPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/DashboardPage.java index 2460d2c2..50f292ea 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/DashboardPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/DashboardPage.java @@ -10,6 +10,7 @@ import java.util.List; public class DashboardPage extends ThymeleafPage { public DashboardPage(List channels, List nodes, StatusModel statusModel) { + super(); List sortedChannels = channels.stream() .sorted(Comparator.comparing(OpenChannelDto::getOutboundPercentage)) .toList(); diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ErrorPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ErrorPage.java index ad8b931e..319049b5 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ErrorPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ErrorPage.java @@ -3,6 +3,7 @@ package de.cotto.lndmanagej.ui.page.general; public class ErrorPage extends ThymeleafPage { public ErrorPage(String message) { + super(); add("error", message); } diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ThymeleafPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ThymeleafPage.java index d2c5a0fa..5fa7422d 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ThymeleafPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/general/ThymeleafPage.java @@ -7,7 +7,11 @@ import java.util.Map; public abstract class ThymeleafPage { - Map modelAttributes = new HashMap<>(); + private final Map modelAttributes = new HashMap<>(); + + public ThymeleafPage() { + // default constructor + } public abstract String getView(); diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodeDetailsPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodeDetailsPage.java index f1fd2e9b..c9ba4e3d 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodeDetailsPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodeDetailsPage.java @@ -5,6 +5,7 @@ import de.cotto.lndmanagej.ui.page.general.ThymeleafPage; public class NodeDetailsPage extends ThymeleafPage { public NodeDetailsPage(NodeDetailsDto nodeDetails) { + super(); add("pubkey", nodeDetails.node()); add("node", nodeDetails); } diff --git a/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodesPage.java b/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodesPage.java index f0204bb7..8dcd608f 100644 --- a/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodesPage.java +++ b/web/src/main/java/de/cotto/lndmanagej/ui/page/node/NodesPage.java @@ -8,6 +8,7 @@ import java.util.List; public class NodesPage extends ThymeleafPage { public NodesPage(List nodes) { + super(); add("nodes", nodes); } diff --git a/web/src/test/java/de/cotto/lndmanagej/DemoApplication.java b/web/src/test/java/de/cotto/lndmanagej/DemoApplication.java index f2c59c0f..c24356b9 100644 --- a/web/src/test/java/de/cotto/lndmanagej/DemoApplication.java +++ b/web/src/test/java/de/cotto/lndmanagej/DemoApplication.java @@ -1,70 +1,41 @@ package de.cotto.lndmanagej; -import de.cotto.lndmanagej.controller.dto.BalanceInformationDto; -import de.cotto.lndmanagej.controller.dto.ChannelWithWarningsDto; -import de.cotto.lndmanagej.controller.dto.FeeReportDto; -import de.cotto.lndmanagej.controller.dto.FlowReportDto; import de.cotto.lndmanagej.controller.dto.NodeDetailsDto; -import de.cotto.lndmanagej.controller.dto.NodeWithWarningsDto; -import de.cotto.lndmanagej.controller.dto.NodesAndChannelsWithWarningsDto; -import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; -import de.cotto.lndmanagej.controller.dto.OnlineReportDto; -import de.cotto.lndmanagej.controller.dto.RebalanceReportDto; import de.cotto.lndmanagej.model.ChannelId; -import de.cotto.lndmanagej.model.ChannelIdFixtures; -import de.cotto.lndmanagej.model.FeeReportFixtures; -import de.cotto.lndmanagej.model.FlowReportFixtures; -import de.cotto.lndmanagej.model.OnlineReport; -import de.cotto.lndmanagej.model.OnlineReportFixtures; -import de.cotto.lndmanagej.model.OpenInitiator; import de.cotto.lndmanagej.model.Pubkey; -import de.cotto.lndmanagej.model.RebalanceReportFixtures; -import de.cotto.lndmanagej.model.warnings.ChannelWarningsFixtures; -import de.cotto.lndmanagej.model.warnings.NodeWarningsFixtures; -import de.cotto.lndmanagej.model.warnings.Warning; import de.cotto.lndmanagej.ui.UiDataService; import de.cotto.lndmanagej.ui.dto.ChanDetailsDto; import de.cotto.lndmanagej.ui.dto.NodeDto; import de.cotto.lndmanagej.ui.dto.OpenChannelDto; import de.cotto.lndmanagej.ui.dto.StatusModel; -import org.slf4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.logging.LoggingSystem; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.util.List; -import java.util.stream.Collectors; - -import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION; -import static de.cotto.lndmanagej.model.OnChainCostsFixtures.ON_CHAIN_COSTS; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.ACINQ; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.ACINQ2; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.BCASH; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.COTTO; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.OPEN_CHANNEL_DTO; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.WOS; -import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.WOS2; +import static de.cotto.lndmanagej.MockUtil.createChannelDetails; +import static de.cotto.lndmanagej.MockUtil.createNodeDetails; +import static de.cotto.lndmanagej.MockUtil.createOpenChannels; +import static de.cotto.lndmanagej.MockUtil.getStatusModel; +@SuppressWarnings("CPD-START") @Configuration @EnableAutoConfiguration( exclude = { - DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class, - HibernateJpaAutoConfiguration.class + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class } ) @ComponentScan("de.cotto.lndmanagej.ui") public class DemoApplication { public static void main(String[] arguments) { - LoggingSystem.get(ClassLoader.getSystemClassLoader()).setLogLevel(Logger.ROOT_LOGGER_NAME, LogLevel.ERROR); SpringApplication.run(DemoApplication.class, arguments); } @@ -73,28 +44,12 @@ public class DemoApplication { @Override public StatusModel getStatus() { - return new StatusModel(true, 735642, createNodeWarnings()); - } - - private NodesAndChannelsWithWarningsDto createNodeWarnings() { - return new NodesAndChannelsWithWarningsDto( - List.of(new NodeWithWarningsDto(NodeWarningsFixtures.NODE_WARNINGS.warnings().stream() - .map(Warning::description) - .collect(Collectors.toSet()), WOS.remoteAlias(), WOS.remotePubkey()), - new NodeWithWarningsDto(NodeWarningsFixtures.NODE_WARNINGS.warnings().stream() - .map(Warning::description) - .collect(Collectors.toSet()), ACINQ.remoteAlias(), ACINQ.remotePubkey()) - ), - List.of(new ChannelWithWarningsDto(ChannelWarningsFixtures.CHANNEL_WARNINGS.warnings().stream() - .map(Warning::description) - .collect(Collectors.toSet()), WOS.channelId()) - ) - ); + return getStatusModel(); } @Override public List getOpenChannels() { - return List.of(OPEN_CHANNEL_DTO, ACINQ, ACINQ2, WOS, WOS2, BCASH, COTTO); + return createOpenChannels(); } @Override @@ -106,21 +61,6 @@ public class DemoApplication { return createChannelDetails(localOpenChannel); } - private ChanDetailsDto createChannelDetails(OpenChannelDto channel) { - return new ChanDetailsDto( - channel.channelId(), - channel.remotePubkey(), - channel.remoteAlias(), - OpenInitiator.REMOTE, - channel.balanceInformation(), - OnChainCostsDto.createFromModel(ON_CHAIN_COSTS), - channel.policies(), - FeeReportDto.createFromModel(FeeReportFixtures.FEE_REPORT), - FlowReportDto.createFromModel(FlowReportFixtures.FLOW_REPORT), - RebalanceReportDto.createFromModel(RebalanceReportFixtures.REBALANCE_REPORT), - ChannelWarningsFixtures.CHANNEL_WARNINGS.descriptions()); - } - @Override public NodeDto getNode(Pubkey pubkey) { return getOpenChannels().stream() @@ -134,28 +74,9 @@ public class DemoApplication { return createNodeDetails(getNode(pubkey)); } - private static NodeDetailsDto createNodeDetails(NodeDto node) { - OnlineReport onlineReport = node.online() - ? OnlineReportFixtures.ONLINE_REPORT : OnlineReportFixtures.ONLINE_REPORT_OFFLINE; - return new NodeDetailsDto( - Pubkey.create(node.pubkey()), - node.alias(), - List.of(ChannelIdFixtures.CHANNEL_ID), - List.of(ChannelIdFixtures.CHANNEL_ID_2), - List.of(), - List.of(), - OnChainCostsDto.createFromModel(ON_CHAIN_COSTS), - BalanceInformationDto.createFromModel(BALANCE_INFORMATION), - OnlineReportDto.createFromModel(onlineReport), - FeeReportDto.createFromModel(FeeReportFixtures.FEE_REPORT), - FlowReportDto.createFromModel(FlowReportFixtures.FLOW_REPORT), - RebalanceReportDto.createFromModel(RebalanceReportFixtures.REBALANCE_REPORT), - ChannelWarningsFixtures.CHANNEL_WARNINGS.descriptions()); - } - } - private static boolean isOnline(OpenChannelDto c) { - return c.channelId().getShortChannelId() % 2 != 0; + private static boolean isOnline(OpenChannelDto channel) { + return channel.channelId().getShortChannelId() % 2 != 0; } } \ No newline at end of file diff --git a/web/src/test/java/de/cotto/lndmanagej/MockUtil.java b/web/src/test/java/de/cotto/lndmanagej/MockUtil.java new file mode 100644 index 00000000..38c69908 --- /dev/null +++ b/web/src/test/java/de/cotto/lndmanagej/MockUtil.java @@ -0,0 +1,106 @@ +package de.cotto.lndmanagej; + +import de.cotto.lndmanagej.controller.dto.BalanceInformationDto; +import de.cotto.lndmanagej.controller.dto.ChannelWithWarningsDto; +import de.cotto.lndmanagej.controller.dto.FeeReportDto; +import de.cotto.lndmanagej.controller.dto.FlowReportDto; +import de.cotto.lndmanagej.controller.dto.NodeDetailsDto; +import de.cotto.lndmanagej.controller.dto.NodeWithWarningsDto; +import de.cotto.lndmanagej.controller.dto.NodesAndChannelsWithWarningsDto; +import de.cotto.lndmanagej.controller.dto.OnChainCostsDto; +import de.cotto.lndmanagej.controller.dto.OnlineReportDto; +import de.cotto.lndmanagej.controller.dto.RebalanceReportDto; +import de.cotto.lndmanagej.model.ChannelIdFixtures; +import de.cotto.lndmanagej.model.FeeReportFixtures; +import de.cotto.lndmanagej.model.FlowReportFixtures; +import de.cotto.lndmanagej.model.OnlineReport; +import de.cotto.lndmanagej.model.OnlineReportFixtures; +import de.cotto.lndmanagej.model.OpenInitiator; +import de.cotto.lndmanagej.model.Pubkey; +import de.cotto.lndmanagej.model.RebalanceReportFixtures; +import de.cotto.lndmanagej.model.warnings.ChannelWarningsFixtures; +import de.cotto.lndmanagej.model.warnings.NodeWarningsFixtures; +import de.cotto.lndmanagej.model.warnings.Warning; +import de.cotto.lndmanagej.ui.dto.ChanDetailsDto; +import de.cotto.lndmanagej.ui.dto.NodeDto; +import de.cotto.lndmanagej.ui.dto.OpenChannelDto; +import de.cotto.lndmanagej.ui.dto.StatusModel; + +import java.util.List; +import java.util.stream.Collectors; + +import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION; +import static de.cotto.lndmanagej.model.OnChainCostsFixtures.ON_CHAIN_COSTS; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.ACINQ; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.ACINQ2; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.BCASH; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.COTTO; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.OPEN_CHANNEL_DTO; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.WOS; +import static de.cotto.lndmanagej.ui.model.OpenChannelDtoFixture.WOS2; + +public final class MockUtil { + + private MockUtil() { + // util class + } + + public static StatusModel getStatusModel() { + return new StatusModel(true, 735_642, createNodeWarnings()); + } + + + public static List createOpenChannels() { + return List.of(OPEN_CHANNEL_DTO, ACINQ, ACINQ2, WOS, WOS2, BCASH, COTTO); + } + + public static NodesAndChannelsWithWarningsDto createNodeWarnings() { + return new NodesAndChannelsWithWarningsDto( + List.of(new NodeWithWarningsDto(NodeWarningsFixtures.NODE_WARNINGS.warnings().stream() + .map(Warning::description) + .collect(Collectors.toSet()), WOS.remoteAlias(), WOS.remotePubkey()), + new NodeWithWarningsDto(NodeWarningsFixtures.NODE_WARNINGS.warnings().stream() + .map(Warning::description) + .collect(Collectors.toSet()), ACINQ.remoteAlias(), ACINQ.remotePubkey()) + ), + List.of(new ChannelWithWarningsDto(ChannelWarningsFixtures.CHANNEL_WARNINGS.warnings().stream() + .map(Warning::description) + .collect(Collectors.toSet()), WOS.channelId()) + ) + ); + } + + public static ChanDetailsDto createChannelDetails(OpenChannelDto channel) { + return new ChanDetailsDto( + channel.channelId(), + channel.remotePubkey(), + channel.remoteAlias(), + OpenInitiator.REMOTE, + channel.balanceInformation(), + OnChainCostsDto.createFromModel(ON_CHAIN_COSTS), + channel.policies(), + FeeReportDto.createFromModel(FeeReportFixtures.FEE_REPORT), + FlowReportDto.createFromModel(FlowReportFixtures.FLOW_REPORT), + RebalanceReportDto.createFromModel(RebalanceReportFixtures.REBALANCE_REPORT), + ChannelWarningsFixtures.CHANNEL_WARNINGS.descriptions()); + } + + public static NodeDetailsDto createNodeDetails(NodeDto node) { + OnlineReport onlineReport = node.online() + ? OnlineReportFixtures.ONLINE_REPORT : OnlineReportFixtures.ONLINE_REPORT_OFFLINE; + return new NodeDetailsDto( + Pubkey.create(node.pubkey()), + node.alias(), + List.of(ChannelIdFixtures.CHANNEL_ID), + List.of(ChannelIdFixtures.CHANNEL_ID_2), + List.of(), + List.of(), + OnChainCostsDto.createFromModel(ON_CHAIN_COSTS), + BalanceInformationDto.createFromModel(BALANCE_INFORMATION), + OnlineReportDto.createFromModel(onlineReport), + FeeReportDto.createFromModel(FeeReportFixtures.FEE_REPORT), + FlowReportDto.createFromModel(FlowReportFixtures.FLOW_REPORT), + RebalanceReportDto.createFromModel(RebalanceReportFixtures.REBALANCE_REPORT), + ChannelWarningsFixtures.CHANNEL_WARNINGS.descriptions()); + } +}