Skip to content

Commit 4b19715

Browse files
🐛 fix: PaidCommandInterceptor | handle withdraw resources from non-existing resource pool (#23)
1 parent 204da71 commit 4b19715

5 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/main/java/com/dddheroes/heroesofddd/resourcespool/write/ResourcesPool.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ void evolve(ResourcesWithdrawn event) {
5252
ResourcesPool() {
5353
// required by Axon
5454
}
55+
56+
public ResourcesPool(ResourcesPoolId resourcesPoolId) {
57+
this.resourcesPoolId = resourcesPoolId;
58+
}
5559
}

src/main/java/com/dddheroes/heroesofddd/resourcespool/write/withdraw/PaidCommandInterceptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public Object handle(
5353
return interceptorChain.proceed();
5454
}
5555

56-
private void withdrawResourcesToSpend(ResourcesPoolId resourcesPoolId, Resources cost) {
56+
private void withdrawResourcesToSpend(ResourcesPoolId resourcesPoolId, Resources cost) throws Exception {
5757
var rawResourcesPoolId = resourcesPoolId.raw();
5858
var withdrawResources = WithdrawResources.command(rawResourcesPoolId, cost.raw());
59-
resourcesPoolRepository.load(rawResourcesPoolId)
59+
resourcesPoolRepository.loadOrCreate(rawResourcesPoolId, () -> new ResourcesPool(resourcesPoolId))
6060
.execute(resourcesPool -> resourcesPool.decide(withdrawResources));
6161
}
6262
}

src/test/java/com/dddheroes/heroesofddd/creaturerecruitment/write/recruitcreature/RecruitCreatureRequiresResourcesTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
import static org.junit.jupiter.api.Assertions.*;
2929

3030
@Import(TestcontainersConfiguration.class)
31-
@SpringBootTest
31+
@SpringBootTest(properties = {
32+
"application.interceptors.paid-commands.enabled=true"
33+
})
3234
class RecruitCreatureRequiresResourcesTest {
3335

3436
private static final String GAME_ID = GameId.random().raw();

src/test/java/com/dddheroes/heroesofddd/resourcespool/write/withdraw/PaidCommandInterceptorTest.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3333

3434
@Import(TestcontainersConfiguration.class)
35-
@SpringBootTest
35+
@SpringBootTest(properties = {
36+
"application.interceptors.paid-commands.enabled=true"
37+
})
3638
class PaidCommandInterceptorTest {
3739

3840
private static final String GAME_ID = GameId.random().raw();
@@ -93,7 +95,8 @@ void givenSufficientResources_whenPaidCommandFailed_thenResourcesNotWithdrawn()
9395
var paidCommand = TestPaidCommand.failing(COMMAND_COST);
9496
assertThatThrownBy(() -> executePlayerCommand(paidCommand))
9597
.cause()
96-
.satisfies(e -> assertThat(e).hasMessageContaining("TestPaidCommand failed! Resources withdrawal should be rolled back"));
98+
.satisfies(e -> assertThat(e).hasMessageContaining(
99+
"TestPaidCommand failed! Resources withdrawal should be rolled back"));
97100

98101
// then
99102
eventStoreAssertions.assertEventNotStored(resourcesPoolId, ResourcesWithdrawn.class);
@@ -152,6 +155,19 @@ void givenResources_whenExecutingNonPaidCommand_thenNoResourcesWithdrawn() {
152155
eventStoreAssertions.assertEventsStoredCount(nonPaidCommand.identifier, 1);
153156
}
154157

158+
@Test
159+
void givenNoResources_whenExecutingPaidCommand_thenResourcesNotWithdrewAndCommandNotExecuted() {
160+
// when
161+
var paidCommand = new TestPaidCommand(COMMAND_COST);
162+
163+
// then
164+
assertThatThrownBy(() -> executePlayerCommand(paidCommand))
165+
.cause()
166+
.satisfies(e -> assertThat(e).hasMessageContaining("Cannot withdraw more than deposited resources"));
167+
eventStoreAssertions.assertEventNotStored(resourcesPoolId, ResourcesWithdrawn.class);
168+
eventStoreAssertions.assertNoEventsStored(paidCommand.identifier);
169+
}
170+
155171
private void executePlayerCommand(Command command) {
156172
commandGateway.sendAndWait(command, gameMetaData());
157173
}

src/test/resources/application-test.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)