diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ArchUnitIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ArchUnitIT.java index 68077e7d..9e477cd0 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ArchUnitIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/ArchUnitIT.java @@ -11,6 +11,9 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.web.bind.annotation.RequestMapping; +import java.util.Collection; +import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import static org.assertj.core.api.Assertions.assertThat; @@ -38,6 +41,22 @@ class ArchUnitIT { rule.check(importedClasses); } + @Test + void public_controller_methods_do_not_return_collection_type() { + ArchRule rule = ArchRuleDefinition.methods().that() + .areDeclaredInClassesThat().areAnnotatedWith(RequestMapping.class) + .and() + .arePublic() + .should() + .notHaveRawReturnType(Collection.class) + .andShould() + .notHaveRawReturnType(List.class) + .andShould() + .notHaveRawReturnType(Set.class); + assertThat(importedClasses).isNotEmpty(); + rule.check(importedClasses); + } + private static class DoNotIncludeTests implements ImportOption { private static final Pattern GRADLE_PATTERN = Pattern.compile(".*/build/classes/([^/]+/)?[a-zA-Z-]*[tT]est/.*"); diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerIT.java index d4cc2d5a..d4ef1181 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerIT.java @@ -1,6 +1,7 @@ package de.cotto.lndmanagej.controller; import de.cotto.lndmanagej.model.ChannelIdResolver; +import de.cotto.lndmanagej.model.Coins; import de.cotto.lndmanagej.service.SelfPaymentsService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -44,8 +45,8 @@ class SelfPaymentsControllerIT { when(selfPaymentsService.getSelfPaymentsFromChannel(CHANNEL_ID)) .thenReturn(List.of(SELF_PAYMENT_2, SELF_PAYMENT)); mockMvc.perform(get(CHANNEL_PREFIX + "/self-payments-from-channel/")) - .andExpect(jsonPath("$[0].memo", is(SELF_PAYMENT_2.memo()))) - .andExpect(jsonPath("$[1].memo", is(SELF_PAYMENT.memo()))); + .andExpect(jsonPath("$.selfPayments[0].memo", is(SELF_PAYMENT_2.memo()))) + .andExpect(jsonPath("$.selfPayments[1].memo", is(SELF_PAYMENT.memo()))); } @Test @@ -53,8 +54,8 @@ class SelfPaymentsControllerIT { when(selfPaymentsService.getSelfPaymentsFromPeer(PUBKEY)) .thenReturn(List.of(SELF_PAYMENT_2, SELF_PAYMENT)); mockMvc.perform(get(NODE_PREFIX + "/self-payments-from-peer/")) - .andExpect(jsonPath("$[0].memo", is(SELF_PAYMENT_2.memo()))) - .andExpect(jsonPath("$[1].memo", is(SELF_PAYMENT.memo()))); + .andExpect(jsonPath("$.selfPayments[0].memo", is(SELF_PAYMENT_2.memo()))) + .andExpect(jsonPath("$.selfPayments[1].memo", is(SELF_PAYMENT.memo()))); } @Test @@ -62,18 +63,18 @@ class SelfPaymentsControllerIT { when(selfPaymentsService.getSelfPaymentsToChannel(CHANNEL_ID)) .thenReturn(List.of(SELF_PAYMENT, SELF_PAYMENT_2)); mockMvc.perform(get(CHANNEL_PREFIX + "/self-payments-to-channel/")) - .andExpect(jsonPath("$[0].memo", is(SELF_PAYMENT.memo()))) - .andExpect(jsonPath("$[0].settleDate", is(SELF_PAYMENT.settleDate().toString()))) - .andExpect(jsonPath("$[0].value", is(String.valueOf(SELF_PAYMENT.value().milliSatoshis())))) - .andExpect(jsonPath("$[0].fees", is(String.valueOf(SELF_PAYMENT.fees().milliSatoshis())))) - .andExpect(jsonPath("$[0].firstChannel", is(CHANNEL_ID_4.toString()))) - .andExpect(jsonPath("$[0].lastChannel", is(CHANNEL_ID_2.toString()))) - .andExpect(jsonPath("$[1].memo", is(SELF_PAYMENT_2.memo()))) - .andExpect(jsonPath("$[1].settleDate", is(SELF_PAYMENT_2.settleDate().toString()))) - .andExpect(jsonPath("$[1].value", is(String.valueOf(SELF_PAYMENT_2.value().milliSatoshis())))) - .andExpect(jsonPath("$[1].fees", is(String.valueOf(SELF_PAYMENT_2.fees().milliSatoshis())))) - .andExpect(jsonPath("$[1].firstChannel", is(not(empty())))) - .andExpect(jsonPath("$[1].lastChannel", is(CHANNEL_ID.toString()))); + .andExpect(jsonPath("$.selfPayments[0].memo", is(SELF_PAYMENT.memo()))) + .andExpect(jsonPath("$.selfPayments[0].settleDate", is(SELF_PAYMENT.settleDate().toString()))) + .andExpect(jsonPath("$.selfPayments[0].value", is(msat(SELF_PAYMENT.value())))) + .andExpect(jsonPath("$.selfPayments[0].fees", is(msat(SELF_PAYMENT.fees())))) + .andExpect(jsonPath("$.selfPayments[0].firstChannel", is(CHANNEL_ID_4.toString()))) + .andExpect(jsonPath("$.selfPayments[0].lastChannel", is(CHANNEL_ID_2.toString()))) + .andExpect(jsonPath("$.selfPayments[1].memo", is(SELF_PAYMENT_2.memo()))) + .andExpect(jsonPath("$.selfPayments[1].settleDate", is(SELF_PAYMENT_2.settleDate().toString()))) + .andExpect(jsonPath("$.selfPayments[1].value", is(msat(SELF_PAYMENT_2.value())))) + .andExpect(jsonPath("$.selfPayments[1].fees", is(msat(SELF_PAYMENT_2.fees())))) + .andExpect(jsonPath("$.selfPayments[1].firstChannel", is(not(empty())))) + .andExpect(jsonPath("$.selfPayments[1].lastChannel", is(CHANNEL_ID.toString()))); } @Test @@ -81,7 +82,11 @@ class SelfPaymentsControllerIT { when(selfPaymentsService.getSelfPaymentsToPeer(PUBKEY)) .thenReturn(List.of(SELF_PAYMENT_2, SELF_PAYMENT)); mockMvc.perform(get(NODE_PREFIX + "/self-payments-to-peer/")) - .andExpect(jsonPath("$[0].memo", is(SELF_PAYMENT_2.memo()))) - .andExpect(jsonPath("$[1].memo", is(SELF_PAYMENT.memo()))); + .andExpect(jsonPath("$.selfPayments[0].memo", is(SELF_PAYMENT_2.memo()))) + .andExpect(jsonPath("$.selfPayments[1].memo", is(SELF_PAYMENT.memo()))); + } + + private String msat(Coins value) { + return String.valueOf(value.milliSatoshis()); } } \ No newline at end of file diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/SelfPaymentsController.java b/web/src/main/java/de/cotto/lndmanagej/controller/SelfPaymentsController.java index 029f8b5c..b6a1ca34 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/SelfPaymentsController.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/SelfPaymentsController.java @@ -3,6 +3,7 @@ package de.cotto.lndmanagej.controller; import com.codahale.metrics.annotation.Timed; import de.cotto.lndmanagej.controller.dto.ObjectMapperConfiguration; import de.cotto.lndmanagej.controller.dto.SelfPaymentDto; +import de.cotto.lndmanagej.dto.SelfPaymentsDto; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.Pubkey; import de.cotto.lndmanagej.service.SelfPaymentsService; @@ -12,8 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/api/") @Import(ObjectMapperConfiguration.class) @@ -26,33 +25,33 @@ public class SelfPaymentsController { @Timed @GetMapping("/channel/{channelId}/self-payments-from-channel") - public List getSelfPaymentsFromChannel(@PathVariable ChannelId channelId) { - return selfPaymentsService.getSelfPaymentsFromChannel(channelId).stream() + public SelfPaymentsDto getSelfPaymentsFromChannel(@PathVariable ChannelId channelId) { + return new SelfPaymentsDto(selfPaymentsService.getSelfPaymentsFromChannel(channelId).stream() .map(SelfPaymentDto::createFromModel) - .toList(); + .toList()); } @Timed @GetMapping("/node/{pubkey}/self-payments-from-peer") - public List getSelfPaymentsFromPeer(@PathVariable Pubkey pubkey) { - return selfPaymentsService.getSelfPaymentsFromPeer(pubkey).stream() + public SelfPaymentsDto getSelfPaymentsFromPeer(@PathVariable Pubkey pubkey) { + return new SelfPaymentsDto(selfPaymentsService.getSelfPaymentsFromPeer(pubkey).stream() .map(SelfPaymentDto::createFromModel) - .toList(); + .toList()); } @Timed @GetMapping("/channel/{channelId}/self-payments-to-channel") - public List getSelfPaymentsToChannel(@PathVariable ChannelId channelId) { - return selfPaymentsService.getSelfPaymentsToChannel(channelId).stream() + public SelfPaymentsDto getSelfPaymentsToChannel(@PathVariable ChannelId channelId) { + return new SelfPaymentsDto(selfPaymentsService.getSelfPaymentsToChannel(channelId).stream() .map(SelfPaymentDto::createFromModel) - .toList(); + .toList()); } @Timed @GetMapping("/node/{pubkey}/self-payments-to-peer") - public List getSelfPaymentsToPeer(@PathVariable Pubkey pubkey) { - return selfPaymentsService.getSelfPaymentsToPeer(pubkey).stream() + public SelfPaymentsDto getSelfPaymentsToPeer(@PathVariable Pubkey pubkey) { + return new SelfPaymentsDto(selfPaymentsService.getSelfPaymentsToPeer(pubkey).stream() .map(SelfPaymentDto::createFromModel) - .toList(); + .toList()); } } diff --git a/web/src/main/java/de/cotto/lndmanagej/dto/SelfPaymentsDto.java b/web/src/main/java/de/cotto/lndmanagej/dto/SelfPaymentsDto.java new file mode 100644 index 00000000..cf6b1a27 --- /dev/null +++ b/web/src/main/java/de/cotto/lndmanagej/dto/SelfPaymentsDto.java @@ -0,0 +1,8 @@ +package de.cotto.lndmanagej.dto; + +import de.cotto.lndmanagej.controller.dto.SelfPaymentDto; + +import java.util.List; + +public record SelfPaymentsDto(List selfPayments) { +} diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerTest.java index 2fea815c..9839ae44 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/SelfPaymentsControllerTest.java @@ -28,7 +28,7 @@ class SelfPaymentsControllerTest { @Test void getSelfPaymentsFromChannel() { when(service.getSelfPaymentsFromChannel(CHANNEL_ID)).thenReturn(List.of(SELF_PAYMENT, SELF_PAYMENT_2)); - assertThat(selfPaymentsController.getSelfPaymentsFromChannel(CHANNEL_ID)).containsExactly( + assertThat(selfPaymentsController.getSelfPaymentsFromChannel(CHANNEL_ID).selfPayments()).containsExactly( SelfPaymentDto.createFromModel(SELF_PAYMENT), SelfPaymentDto.createFromModel(SELF_PAYMENT_2) ); @@ -37,7 +37,7 @@ class SelfPaymentsControllerTest { @Test void getSelfPaymentsFromPeer() { when(service.getSelfPaymentsFromPeer(PUBKEY)).thenReturn(List.of(SELF_PAYMENT, SELF_PAYMENT_2)); - assertThat(selfPaymentsController.getSelfPaymentsFromPeer(PUBKEY)).containsExactly( + assertThat(selfPaymentsController.getSelfPaymentsFromPeer(PUBKEY).selfPayments()).containsExactly( SelfPaymentDto.createFromModel(SELF_PAYMENT), SelfPaymentDto.createFromModel(SELF_PAYMENT_2) ); @@ -46,7 +46,7 @@ class SelfPaymentsControllerTest { @Test void getSelfPaymentsToChannel() { when(service.getSelfPaymentsToChannel(CHANNEL_ID)).thenReturn(List.of(SELF_PAYMENT, SELF_PAYMENT_2)); - assertThat(selfPaymentsController.getSelfPaymentsToChannel(CHANNEL_ID)).containsExactly( + assertThat(selfPaymentsController.getSelfPaymentsToChannel(CHANNEL_ID).selfPayments()).containsExactly( SelfPaymentDto.createFromModel(SELF_PAYMENT), SelfPaymentDto.createFromModel(SELF_PAYMENT_2) ); @@ -55,7 +55,7 @@ class SelfPaymentsControllerTest { @Test void getSelfPaymentsToPeer() { when(service.getSelfPaymentsToPeer(PUBKEY)).thenReturn(List.of(SELF_PAYMENT, SELF_PAYMENT_2)); - assertThat(selfPaymentsController.getSelfPaymentsToPeer(PUBKEY)).containsExactly( + assertThat(selfPaymentsController.getSelfPaymentsToPeer(PUBKEY).selfPayments()).containsExactly( SelfPaymentDto.createFromModel(SELF_PAYMENT), SelfPaymentDto.createFromModel(SELF_PAYMENT_2) );