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 all 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 {

}
66 changes: 66 additions & 0 deletions core/src/main/java/io/nobt/core/domain/DeletedExpense.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.nobt.core.domain;

import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.Set;

public class DeletedExpense {

private final Expense originalExpense;
private final Instant deletedOn;

public DeletedExpense(Expense originalExpense) {
this(originalExpense, Clock.systemUTC().instant());
}

public DeletedExpense(Expense originalExpense, Instant deletedOn) {
this.originalExpense = originalExpense;
this.deletedOn = deletedOn;
}

public long getId() {
return originalExpense.getId();
}

public String getName() {
return originalExpense.getName();
}

public String getSplitStrategy() {
return originalExpense.getSplitStrategy();
}

public Person getDebtee() {
return originalExpense.getDebtee();
}

public Set<Share> getShares() {
return originalExpense.getShares();
}

public LocalDate getDate() {
return originalExpense.getDate();
}

public ZonedDateTime getCreatedOn() {
return originalExpense.getCreatedOn();
}

public ConversionInformation getConversionInformation() {
return originalExpense.getConversionInformation();
}

public Set<Person> getParticipants() {
return originalExpense.getParticipants();
}

public Expense getOriginalExpense() {
return originalExpense;
}

public Instant getDeletedOn() {
return deletedOn;
}
}
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<DeletedExpense> 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<DeletedExpense> 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<DeletedExpense> 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(new DeletedExpense(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());
}
}
8 changes: 5 additions & 3 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 @@ -162,7 +161,10 @@ public void shouldRemoveExpenseById() throws Exception {
nobt.removeExpense(1L);


assertThat(nobt, hasExpenses(iterableWithSize(0)));
assertThat(nobt, allOf(
hasExpenses(iterableWithSize(0)),
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<DeletedExpense> 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.stream().map(DeletedExpense::new).collect(toSet());
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
Loading