-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delete bills #8
Delete bills #8
Changes from 2 commits
66040bb
f1e4ea1
c4c5627
68a0a18
cc5860b
1189594
ee2f22b
5381c7f
ad90115
ba9bea4
4758bb1
c7db496
fb56bb7
3be7fff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package io.nobt.core; | ||
|
||
public class UnknownExpenseException extends RuntimeException { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
ALTER TABLE expenses | ||
ADD deleted BOOLEAN; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sollten wir das vielleicht NOT NULL machen und alle anderen explizit auf false setzen? |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,14 +136,17 @@ public void savingAndFetchingResultsInDifferentInstance() throws Exception { | |
} | ||
|
||
@Test | ||
public void shouldRemoveOrphanExpense() throws Exception { | ||
public void shouldDeleteExpense() throws Exception { | ||
|
||
final Share thomasShare = ShareFactory.randomShare(thomas); | ||
final Share matthiasShare = ShareFactory.randomShare(matthias); | ||
final LocalDate expenseDate = LocalDate.now(); | ||
|
||
final Nobt nobtToSave = aNobt() | ||
.withExpenses(anExpense().withDebtee(thomas).withShares(thomasShare, matthiasShare).happendOn(expenseDate)) | ||
.withExpenses(anExpense() | ||
.withDebtee(thomas) | ||
.withShares(thomasShare, matthiasShare) | ||
.happendOn(expenseDate)) | ||
.build(); | ||
|
||
final NobtId id = save(nobtToSave); | ||
|
@@ -156,12 +159,14 @@ public void shouldRemoveOrphanExpense() throws Exception { | |
|
||
save(retrievedNobt); | ||
|
||
|
||
final Nobt nobtWithoutExpense = fetch(id); | ||
|
||
assertThat(nobtWithoutExpense, hasExpenses( | ||
iterableWithSize(0) | ||
)); | ||
assertThat(nobtWithoutExpense, hasDeletedExpenses( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Die beiden Assertions kannst du zusammenfassen auf ein: |
||
iterableWithSize(1) | ||
)); | ||
} | ||
|
||
@Test | ||
|
@@ -211,4 +216,5 @@ private NobtId save(Nobt nobtToSave) { | |
private Nobt fetch(NobtId id) { | ||
return invoker.invoke(new RetrieveNobtCommand(id)); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,9 @@ public class ExpenseEntity extends CashFlowEntity { | |
@Column(name = "date", nullable = false) | ||
private LocalDate date; | ||
|
||
@Column(name = "deleted", nullable = false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wenns hier nullable=false ist, sollte das auch im Migrationskript so in die DB geschrieben werden. Ich würde vielleicht auch |
||
private boolean deleted; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
@@ -93,4 +96,15 @@ public void setDate(LocalDate date) { | |
this.date = date; | ||
} | ||
|
||
public boolean isDeleted() { | ||
return deleted; | ||
} | ||
|
||
public void setDeleted(boolean deleted) { | ||
this.deleted = deleted; | ||
} | ||
|
||
public boolean isNotDeleted() { | ||
return !isDeleted(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,4 +52,5 @@ public ExpenseEntity mapToDatabaseModel(Expense domainModel) { | |
|
||
return expense; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,9 @@ public class NobtMapper implements DomainModelMapper<NobtEntity, Nobt> { | |
private final DomainModelMapper<ExpenseEntity, Expense> expenseMapper; | ||
private final DomainModelMapper<PaymentEntity, Payment> paymentMapper; | ||
|
||
public NobtMapper(NobtDatabaseIdResolver nobtDatabaseIdResolver, DomainModelMapper<ExpenseEntity, Expense> expenseMapper, DomainModelMapper<PaymentEntity, Payment> paymentMapper) { | ||
public NobtMapper(NobtDatabaseIdResolver nobtDatabaseIdResolver, | ||
DomainModelMapper<ExpenseEntity, Expense> expenseMapper, | ||
DomainModelMapper<PaymentEntity, Payment> paymentMapper) { | ||
this.nobtDatabaseIdResolver = nobtDatabaseIdResolver; | ||
this.expenseMapper = expenseMapper; | ||
this.paymentMapper = paymentMapper; | ||
|
@@ -26,15 +28,25 @@ public NobtMapper(NobtDatabaseIdResolver nobtDatabaseIdResolver, DomainModelMapp | |
public Nobt mapToDomainModel(NobtEntity databaseModel) { | ||
|
||
final Set<Person> explicitParticipants = databaseModel.getExplicitParticipants(); | ||
final Set<Expense> expenses = databaseModel.getExpenses().stream().map(expenseMapper::mapToDomainModel).collect(toSet()); | ||
final Set<Payment> payments = databaseModel.getPayments().stream().map(paymentMapper::mapToDomainModel).collect(toSet()); | ||
final Set<Expense> expenses = databaseModel.getExpenses().stream() | ||
.filter(ExpenseEntity::isNotDeleted) | ||
.map(expenseMapper::mapToDomainModel) | ||
.collect(toSet()); | ||
final Set<Expense> deletedExpenses = databaseModel.getExpenses().stream() | ||
.filter(ExpenseEntity::isDeleted) | ||
.map(expenseMapper::mapToDomainModel) | ||
.collect(toSet()); | ||
final Set<Payment> payments = databaseModel.getPayments().stream() | ||
.map(paymentMapper::mapToDomainModel) | ||
.collect(toSet()); | ||
|
||
return new Nobt( | ||
new NobtId(databaseModel.getExternalId()), | ||
new CurrencyKey(databaseModel.getCurrency()), | ||
databaseModel.getName(), | ||
explicitParticipants, | ||
expenses, | ||
deletedExpenses, | ||
payments, | ||
databaseModel.getCreatedOn(), | ||
databaseModel.getOptimizer() | ||
|
@@ -60,6 +72,10 @@ public NobtEntity mapToDatabaseModel(Nobt domainModel) { | |
nobtEntity.setExplicitParticipant(domainModel.getParticipatingPersons()); | ||
|
||
domainModel.getExpenses().stream().map(expenseMapper::mapToDatabaseModel).forEach(nobtEntity::addExpense); | ||
domainModel.getDeletedExpenses().stream() | ||
.map(expenseMapper::mapToDatabaseModel) | ||
.peek(e -> e.setDeleted(true)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Da wir eine Expense eigentlich nie mehr auf "nicht deleted" setzen wollen, könnte man in der Expense-Entity eine Methode anbieten die heißt |
||
.forEach(nobtEntity::addExpense); | ||
domainModel.getPayments().stream().map(paymentMapper::mapToDatabaseModel).forEach(nobtEntity::addPayment); | ||
|
||
return nobtEntity; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,6 +176,61 @@ public void shouldAddNewExpense() throws Exception { | |
.statusCode(201); | ||
} | ||
|
||
@Test | ||
public void shouldDeleteExpense() throws Exception { | ||
|
||
final String nobtId = client.createGrillfeierNobt(); | ||
client.addFleischExpense(nobtId); | ||
|
||
final Long idOfFirstExpense = client.getNobt(nobtId).jsonPath().getLong("expenses[0].id"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Das hier sollte dann den Link aus der Response holen und nicht die ID, sobald der Link mal zurückgeliefert wird. |
||
|
||
|
||
given(this.documentationSpec) | ||
.port(config.port()) | ||
.filter( | ||
document("delete-expense", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Für dieses Snippet müsstest du im |
||
preprocessRequest( | ||
configureHost(), | ||
replaceLocalhost() | ||
), | ||
preprocessResponse( | ||
replaceLocalhost() | ||
) | ||
) | ||
) | ||
|
||
.when() | ||
|
||
.delete("/nobts/{nobtId}/expenses/{expenseId}", nobtId, idOfFirstExpense) | ||
|
||
.then() | ||
|
||
.statusCode(204); | ||
|
||
|
||
client.getNobt(nobtId) | ||
.then() | ||
.body("expenses", response -> hasSize(0)); | ||
} | ||
|
||
@Test | ||
public void deletingExpenseThatDoesNotExistRespondsWith404() throws Exception { | ||
|
||
final String nobtId = client.createGrillfeierNobt(); | ||
client.addFleischExpense(nobtId); | ||
|
||
given(this.documentationSpec) | ||
.port(config.port()) | ||
|
||
.when() | ||
|
||
.delete("/nobts/{nobtId}/expenses/{expenseId}", nobtId, 104) | ||
|
||
.then() | ||
|
||
.statusCode(404); | ||
} | ||
|
||
@Test | ||
public void shouldAddNewPayment() throws Exception { | ||
|
||
|
@@ -245,6 +300,7 @@ public void shouldGetCompleteNobt() throws Exception { | |
fieldWithPath("createdOn").type(JsonFieldType.STRING).description("An ISO6801-compliant timestamp when the nobt was created."), | ||
|
||
fieldWithPath("expenses").type(JsonFieldType.ARRAY).description("All expenses associated with this nobt."), | ||
fieldWithPath("deletedExpenses").type(JsonFieldType.ARRAY).description("All deleted expenses associated with this nobt."), | ||
fieldWithPath("expenses[].id").type(JsonFieldType.NUMBER).description("The id of the expense."), | ||
fieldWithPath("expenses[].createdOn").type(JsonFieldType.STRING).description("An ISO6801-compliant timestamp when the expense was created."), | ||
fieldWithPath("expenses[].date").type(JsonFieldType.STRING).description("The given date of the expense."), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Funktioniert der Referenzvergleich hier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ja, ist ein primitive type