Skip to content
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

Merged
merged 14 commits into from
Feb 11, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .aws/deploy
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ AWS_EB_ENV=$1
eb setenv -e ${AWS_EB_ENV} \
MIGRATE_DATABASE_AT_STARTUP=true \
USE_IN_MEMORY_DATABASE=false \
SCHEME_OVERRIDE_HEADER=X-Forwarded-Proto \
SENTRY_RELEASE=${CI_BUILD_REF}

~/.local/bin/eb deploy ${AWS_EB_ENV} --staged --verbose
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Available configuration values:
|USE_IN_MEMORY_DATABASE|bool|Subtitutes the actual datastore with a non-persistent hashtable.|false|
|MIGRATE_DATABASE_AT_STARTUP|bool|Migrates the defined database to the latest version. Incompatible with `USE_IN_MEMORY_DATABASE`.|false|
|DATABASE_CONNECTION_STRING|string|The connection string the application should use to connect to a database.|-|
|SCHEME_OVERRIDE_HEADER|string|The HTTP-Header that the API uses to override the scheme of generated links, if present.|-|

## Documentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface AcceptOverrides extends AcceptEnvironment, BuildConfig {

AcceptOverrides overrideDatabase(DatabaseConfig databaseConfig);

AcceptOverrides overrideSchemeOverrideHeader(String schemeOverrideHeader);

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@

public final class Config {

public enum Keys {
PORT,
DATABASE_CONNECTION_STRING,
USE_IN_MEMORY_DATABASE,
MIGRATE_DATABASE_AT_STARTUP
}

public Config(Integer port, Boolean useInMemoryDatabase, Boolean migrateDatabaseAtStartUp, DatabaseConfig databaseConfig) {
private final Integer port;
private final Boolean useInMemoryDatabase;
private final Boolean migrateDatabaseAtStartUp;
private final DatabaseConfig databaseConfig;
private final String schemeOverrideHeader;
public Config(Integer port, Boolean useInMemoryDatabase, Boolean migrateDatabaseAtStartUp, DatabaseConfig databaseConfig, String schemeOverrideHeader) {
this.port = port;
this.useInMemoryDatabase = useInMemoryDatabase;
this.migrateDatabaseAtStartUp = migrateDatabaseAtStartUp;
this.databaseConfig = databaseConfig;
this.schemeOverrideHeader = schemeOverrideHeader;
}

private Integer port;
private Boolean useInMemoryDatabase;
private Boolean migrateDatabaseAtStartUp;
private DatabaseConfig databaseConfig;
public String schemeOverrideHeader() {
return schemeOverrideHeader;
}

public Integer port() {
return port;
Expand All @@ -49,11 +47,20 @@ public boolean equals(Object o) {
return Objects.equals(port, config.port) &&
Objects.equals(useInMemoryDatabase, config.useInMemoryDatabase) &&
Objects.equals(migrateDatabaseAtStartUp, config.migrateDatabaseAtStartUp) &&
Objects.equals(databaseConfig, config.databaseConfig);
Objects.equals(databaseConfig, config.databaseConfig) &&
Objects.equals(schemeOverrideHeader, config.schemeOverrideHeader);
}

@Override
public int hashCode() {
return Objects.hash(port, useInMemoryDatabase, migrateDatabaseAtStartUp, databaseConfig);
return Objects.hash(port, useInMemoryDatabase, migrateDatabaseAtStartUp, databaseConfig, schemeOverrideHeader);
}

public enum Keys {
PORT,
DATABASE_CONNECTION_STRING,
USE_IN_MEMORY_DATABASE,
MIGRATE_DATABASE_AT_STARTUP,
SCHEME_OVERRIDE_HEADER
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class ConfigBuilder implements AcceptEnvironment, AcceptOverrides {
private Integer port;
private Boolean useInMemoryDatabase;
private Boolean migrateDatabaseAtStartup;
private String schemeOverrideHeader;

public static AcceptEnvironment newInstance() {
return new ConfigBuilder();
Expand Down Expand Up @@ -54,6 +55,12 @@ public AcceptOverrides overrideDatabase(DatabaseConfig databaseConfig) {
return this;
}

@Override
public AcceptOverrides overrideSchemeOverrideHeader(String schemeOverrideHeader) {
this.schemeOverrideHeader = schemeOverrideHeader;
return this;
}

@Override
public Config build() {

Expand Down Expand Up @@ -85,7 +92,7 @@ public Config build() {
));
}

return new Config(port(), useInMemoryDatabase(), migrateDatabaseAtStartup(), databaseConfig());
return new Config(port(), useInMemoryDatabase(), migrateDatabaseAtStartup(), databaseConfig(), schemeOverrideHeader());
}

private DatabaseConfig databaseConfig() {
Expand Down Expand Up @@ -124,6 +131,15 @@ private Integer port() {
return getEnvVariableValue(environment, PORT, Integer::parseInt).orElse(null);
}

private String schemeOverrideHeader() {

if (schemeOverrideHeader != null) {
return schemeOverrideHeader;
}

return getEnvVariableValue(environment, SCHEME_OVERRIDE_HEADER, Function.identity()).orElse(null);
}

private static <T> Optional<T> getEnvVariableValue(Environment environment, Config.Keys key, Function<String, T> mapper) {

final String envVariableValue = environment.getValue(key.name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ public void shouldParseValuesFromEnvironment(Environment environment, Config exp
private static Object[] parseExamples() {
return $(
$(
staticEnvironment("8080", "false", "true", VALID_CONNECTION_STRING),
new Config(8080, false, true, ConnectionStringAdapter.parse(VALID_CONNECTION_STRING))
staticEnvironment("8080", "false", "true", VALID_CONNECTION_STRING, "X-Custom-Header"),
new Config(8080, false, true, ConnectionStringAdapter.parse(VALID_CONNECTION_STRING), "X-Custom-Header")
),
$(
staticEnvironment("8080", "true", "false", unset()),
new Config(8080, true, false, null)
staticEnvironment("8080", "true", "false", unset(), unset()),
new Config(8080, true, false, null, null)
)
);
}
Expand All @@ -62,16 +62,16 @@ public void testInvalidConfigurations(Environment environment) throws Exception

private static Object[] invalidEnvironments() {
return $(
staticEnvironment(aPort(), unset(), unset(), unset()),
staticEnvironment(aPort(), unset(), unset(), unset(), "X-Custom-Header"),

staticEnvironment(aPort(), "false", "true", unset()),
staticEnvironment(aPort(), unset(), "true", unset()),
staticEnvironment(aPort(), "false", unset(), unset()),
staticEnvironment(aPort(), "false", "true", unset(), "X-Custom-Header"),
staticEnvironment(aPort(), unset(), "true", unset(), "X-Custom-Header"),
staticEnvironment(aPort(), "false", unset(), unset(), "X-Custom-Header"),

staticEnvironment(aPort(), "true", "true", unset()),
staticEnvironment(aPort(), "true", unset(), unset()),
staticEnvironment(aPort(), "true", "true", unset(), "X-Custom-Header"),
staticEnvironment(aPort(), "true", unset(), unset(), "X-Custom-Header"),

staticEnvironment(aPort(), "false", "false", unset())
staticEnvironment(aPort(), "false", "false", unset(), "X-Custom-Header")
);
}

Expand All @@ -83,10 +83,10 @@ public void testValidConfigurations(Environment environment) throws Exception {

private static Object[] validEnvironments() {
return $(
staticEnvironment(aPort(), "true", "false", unset()),
staticEnvironment(aPort(), "false", unset(), VALID_CONNECTION_STRING),
staticEnvironment(aPort(), unset(), "true", VALID_CONNECTION_STRING),
staticEnvironment(aPort(), unset(), unset(), VALID_CONNECTION_STRING)
staticEnvironment(aPort(), "true", "false", unset(), "X-Custom-Header"),
staticEnvironment(aPort(), "false", unset(), VALID_CONNECTION_STRING, "X-Custom-Header"),
staticEnvironment(aPort(), unset(), "true", VALID_CONNECTION_STRING, "X-Custom-Header"),
staticEnvironment(aPort(), unset(), unset(), VALID_CONNECTION_STRING, "X-Custom-Header")
);
}

Expand All @@ -98,12 +98,13 @@ private static String aPort() {
return "8080";
}

private static StaticEnvironment staticEnvironment(final String port, final String inMemory, final String migrate, final String dbConnection) {
private static StaticEnvironment staticEnvironment(final String port, final String inMemory, final String migrate, final String dbConnection, String schemeOverrideHeader) {
return new StaticEnvironment(new HashMap<String, String>() {{
put(PORT.name(), port);
put(MIGRATE_DATABASE_AT_STARTUP.name(), migrate);
put(USE_IN_MEMORY_DATABASE.name(), inMemory);
put(DATABASE_CONNECTION_STRING.name(), dbConnection);
put(SCHEME_OVERRIDE_HEADER.name(), schemeOverrideHeader);
}});
}
}
5 changes: 5 additions & 0 deletions core/src/main/java/io/nobt/core/UnknownExpenseException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.nobt.core;

public class UnknownExpenseException extends RuntimeException {

}
19 changes: 17 additions & 2 deletions core/src/main/java/io/nobt/core/domain/Nobt.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.nobt.core.domain;

import io.nobt.core.UnknownExpenseException;
import io.nobt.core.domain.debt.Debt;
import io.nobt.core.optimizer.Optimizer;

Expand All @@ -18,16 +19,18 @@ public class Nobt {
private final String name;
private final Set<Person> explicitParticipants;
private final Set<Expense> expenses;
private final Set<Expense> deletedExpenses;
private final Set<Payment> payments;
private final ZonedDateTime createdOn;
private final Optimizer optimizer;

public Nobt(NobtId id, CurrencyKey currencyKey, String name, Set<Person> explicitParticipants, Set<Expense> expenses, Set<Payment> payments, ZonedDateTime createdOn, Optimizer optimizer) {
public Nobt(NobtId id, CurrencyKey currencyKey, String name, Set<Person> explicitParticipants, Set<Expense> expenses, Set<Expense> deletedExpenses, Set<Payment> payments, ZonedDateTime createdOn, Optimizer optimizer) {
this.id = id;
this.currencyKey = currencyKey;
this.name = name;
this.explicitParticipants = new HashSet<>(explicitParticipants);
this.expenses = new HashSet<>(expenses);
this.deletedExpenses = new HashSet<>(deletedExpenses);
this.payments = new HashSet<>(payments);
this.createdOn = createdOn;
this.optimizer = optimizer;
Expand Down Expand Up @@ -57,6 +60,10 @@ public Set<Expense> getExpenses() {
return Collections.unmodifiableSet(expenses);
}

public Set<Expense> getDeletedExpenses() {
return Collections.unmodifiableSet(deletedExpenses);
}

public Set<Payment> getPayments() {
return payments;
}
Expand Down Expand Up @@ -118,6 +125,14 @@ private long getNextIdentifier() {
}

public void removeExpense(long expenseId) {
this.expenses.removeIf(e -> e.getId() == expenseId);

Expense expenseToDelete = expenses.stream()
.filter(e -> e.getId() == expenseId)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funktioniert der Referenzvergleich hier?

Copy link
Contributor Author

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

.findFirst()
.orElseThrow(UnknownExpenseException::new);

expenses.remove(expenseToDelete);
deletedExpenses.add(expenseToDelete);
}

}
2 changes: 1 addition & 1 deletion core/src/main/java/io/nobt/core/domain/NobtFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public NobtFactory(Supplier<Optimizer> optimizerFactory, Clock clock) {
}

public Nobt create(String name, Set<Person> explicitParticipants, CurrencyKey currencyKey) {
return new Nobt(NobtId.newInstance(), currencyKey, name, explicitParticipants, emptySet(), emptySet(), ZonedDateTime.now(clock), optimizerFactory.get());
return new Nobt(NobtId.newInstance(), currencyKey, name, explicitParticipants, emptySet(), emptySet(), emptySet(), ZonedDateTime.now(clock), optimizerFactory.get());
}
}
4 changes: 2 additions & 2 deletions core/src/test/java/io/nobt/core/domain/NobtTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
import static io.nobt.test.domain.factories.StaticPersonFactory.david;
import static io.nobt.test.domain.factories.StaticPersonFactory.thomas;
import static io.nobt.test.domain.matchers.ExpenseMatchers.hasId;
import static io.nobt.test.domain.matchers.NobtMatchers.hasExpenses;
import static io.nobt.test.domain.matchers.NobtMatchers.hasPayments;
import static io.nobt.test.domain.matchers.NobtMatchers.*;
import static io.nobt.test.domain.matchers.PaymentMatchers.*;
import static io.nobt.test.domain.provider.ExpenseBuilderProvider.anExpense;
import static io.nobt.test.domain.provider.ExpenseDraftBuilderProvider.anExpenseDraft;
Expand Down Expand Up @@ -163,6 +162,7 @@ public void shouldRemoveExpenseById() throws Exception {


assertThat(nobt, hasExpenses(iterableWithSize(0)));
assertThat(nobt, hasDeletedExpenses(iterableWithSize(1)));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public class NobtBuilder {

private Set<Expense> expenses;
private Set<Expense> deletedExpenses;
private Set<Person> participants;
private Set<Payment> payments;
private ZonedDateTime dateTime;
Expand All @@ -33,6 +34,19 @@ public NobtBuilder withExpenses(ExpenseBuilder... expenseBuilders) {
return withExpenses(Arrays.stream(expenseBuilders).map(ExpenseBuilder::build).collect(toSet()));
}

public NobtBuilder withDeletedExpenses(Set<Expense> expenses) {
this.deletedExpenses = expenses;
return this;
}

public NobtBuilder withDeletedExpenses(Expense... expenses) {
return withDeletedExpenses(Arrays.stream(expenses).collect(toSet()));
}

public NobtBuilder withDeletedExpenses(ExpenseBuilder... expenseBuilders) {
return withDeletedExpenses(Arrays.stream(expenseBuilders).map(ExpenseBuilder::build).collect(toSet()));
}

public NobtBuilder withPayments(PaymentBuilder... payments) {
return withPayments(Arrays.stream(payments).map(PaymentBuilder::build).collect(toSet()));
}
Expand Down Expand Up @@ -87,6 +101,7 @@ public Nobt build() {
name,
participants,
expenses,
deletedExpenses,
payments,
dateTime,
optimizer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ protected Set<Expense> featureValueOf(Nobt actual) {
};
}

public static Matcher<Nobt> hasDeletedExpenses(final Matcher<? super Iterable<Expense>> subMatcher) {
return new FeatureMatcher<Nobt, Set<Expense>>(subMatcher, "deletedExpenses", "deletedExpenses") {
@Override
protected Set<Expense> featureValueOf(Nobt actual) {
return actual.getDeletedExpenses();
}
};
}

public static Matcher<Nobt> hasPayments(final Matcher<? super Iterable<Payment>> subMatcher) {
return new FeatureMatcher<Nobt, Set<Payment>>(subMatcher, "payments", "payments") {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static NobtBuilder aNobt() {
return new NobtBuilder()
.withId(NobtId.newInstance())
.withExpenses(emptySet())
.withDeletedExpenses(emptySet())
.withParticipants(emptySet())
.withPayments(emptySet())
.withCurrency(new CurrencyKey("EUR"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE expenses
ADD deleted BOOLEAN;
Copy link
Member

Choose a reason for hiding this comment

The 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
Expand Up @@ -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);
Expand All @@ -156,12 +159,14 @@ public void shouldRemoveOrphanExpense() throws Exception {

save(retrievedNobt);


final Nobt nobtWithoutExpense = fetch(id);

assertThat(nobtWithoutExpense, hasExpenses(
iterableWithSize(0)
));
assertThat(nobtWithoutExpense, hasDeletedExpenses(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die beiden Assertions kannst du zusammenfassen auf ein: allOf(hasExpenses(...), hasDeletedExpenses(...))

iterableWithSize(1)
));
}

@Test
Expand Down Expand Up @@ -211,4 +216,5 @@ private NobtId save(Nobt nobtToSave) {
private Nobt fetch(NobtId id) {
return invoker.invoke(new RetrieveNobtCommand(id));
}

}
Loading