Skip to content
This repository has been archived by the owner on Sep 3, 2018. It is now read-only.

Commit

Permalink
Added recurring expense with system test
Browse files Browse the repository at this point in the history
  • Loading branch information
roamingthings committed Apr 10, 2017
1 parent 53ae760 commit 1852d34
Show file tree
Hide file tree
Showing 14 changed files with 458 additions and 18 deletions.
16 changes: 15 additions & 1 deletion expenses-service-st/build.gradle
@@ -1,3 +1,17 @@
plugins {
id 'io.franzbecker.gradle-lombok' version '1.8'
id 'java'
}

repositories {
jcenter() // or Maven central, required for Lombok dependency
}

lombok { // optional: values below are the defaults
version = "1.16.4"
sha256 = "3ca225ce3917eac8bf4b7d2186845df4e70dcdede356dca8537b6d78a535c91e"
}

apply plugin: 'java'
apply plugin: 'groovy'

Expand All @@ -18,8 +32,8 @@ dependencies {
compile('org.glassfish.jersey.media:jersey-media-json-processing:2.25')
compile('org.glassfish:javax.json:1.0.4')
compile('org.codehaus.groovy:groovy-all:2.4.9')
testCompile "org.spockframework:spock-core:1.1-groovy-2.4-rc-3"

testCompile "org.spockframework:spock-core:1.1-groovy-2.4-rc-3"
testCompile('junit:junit:4.12')
testCompile('org.hamcrest:hamcrest-core:1.3')
testCompile "org.spockframework:spock-core:1.1-groovy-2.4-rc-3"
Expand Down
@@ -0,0 +1,114 @@
package de.roamingthings.expenses.expense;

import org.junit.Rule;
import org.junit.Test;

import java.math.BigDecimal;
import java.net.URI;
import java.util.List;

import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

/**
* @author Alexander Sparkowsky [info@roamingthings.de]
* @version 2017/04/10
*/
public class ExpenseServiceST {
@Rule
public RecurringExpenseClient client = new RecurringExpenseClient("http://localhost:8080/recurring_expenses");

@Test
public void shouldCreateRecurringExpense() {
final URI createdAccountUri1 = createAndAssertRecurringExpense(
"Recurring Payment 1",
"testpayment",
"MEMBERSHIP",
"YEARLY",
BigDecimal.valueOf(1.23),
"EUR",
"Creditor 1",
"Note 1"
);
final URI createdAccountUri2 = createAndAssertRecurringExpense(
"Recurring Payment 2",
"testpayment",
"MEMBERSHIP",
"MONTHLY",
BigDecimal.valueOf(2.34),
"USD",
"Creditor 2",
"Note 2"
);
final URI createdAccountUri3 = createAndAssertRecurringExpense(
"Recurring Payment 3",
"testpayment",
"MEMBERSHIP",
"WEEKLY",
BigDecimal.valueOf(5.67),
"GBP",
"Creditor 3",
"Note 3"
);

assertRecurringPaymentExist(createdAccountUri1, createdAccountUri2, createdAccountUri3);

deletePaymentAccount(createdAccountUri1);
deletePaymentAccount(createdAccountUri2);

assertNotFound(createdAccountUri1);
assertNotFound(createdAccountUri2);
assertFound(createdAccountUri3);
}

private URI createAndAssertRecurringExpense(
final String description,
final String label,
final String expenseType,
final String recurringPeriod,
final BigDecimal amount,
final String currency,
final String creditorName,
final String note
) {
final URI uri = client.create(description,
label,
recurringPeriod,
expenseType,
amount,
currency,
creditorName,
note);
final RecurringExpense recurringExpense = client.retrieve(uri);

assertThat(recurringExpense.getLabel(), is(label));
assertThat(recurringExpense.getExpenseType(), is(expenseType));
assertThat(recurringExpense.getRecurrencePeriod(), is(recurringPeriod));
assertThat(recurringExpense.getAmount(), is(amount));
assertThat(recurringExpense.getCurrency(), is(currency));
assertThat(recurringExpense.getCreditorName(), is(creditorName));
assertThat(recurringExpense.getNote(), is(note));

return uri;
}

private void assertRecurringPaymentExist(final URI... uris) {
final List<URI> paymentAccounts = client.retrieve();
assertThat(paymentAccounts, hasItems(uris));
}

private void deletePaymentAccount(URI uri) {
client.delete(uri);
}

private void assertNotFound(URI uri) {
assertNull(client.retrieve(uri));
}

private void assertFound(URI uri) {
assertNotNull(client.retrieve(uri));
}
}
@@ -0,0 +1,68 @@
package de.roamingthings.expenses.expense;

import java.math.BigDecimal;

/**
* @author Alexander Sparkowsky [info@roamingthings.de]
* @version 2017/04/10
*/
public class RecurringExpense {
private final String description;

private final String label;

private final String recurrencePeriod;

private final String expenseType;

private final BigDecimal amount;

private final String currency;

private final String creditorName;

private final String note;

public RecurringExpense(String description, String label, String recurrencePeriod, String expenseType, BigDecimal amount, String currency, String creditorName, String note) {
this.description = description;
this.label = label;
this.recurrencePeriod = recurrencePeriod;
this.expenseType = expenseType;
this.amount = amount;
this.currency = currency;
this.creditorName = creditorName;
this.note = note;
}

public String getDescription() {
return description;
}

public String getLabel() {
return label;
}

public String getRecurrencePeriod() {
return recurrencePeriod;
}

public String getExpenseType() {
return expenseType;
}

public BigDecimal getAmount() {
return amount;
}

public String getCurrency() {
return currency;
}

public String getCreditorName() {
return creditorName;
}

public String getNote() {
return note;
}
}
@@ -0,0 +1,120 @@
package de.roamingthings.expenses.expense;

import org.junit.rules.ExternalResource;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.math.BigDecimal;
import java.net.URI;
import java.util.List;

import static java.util.stream.Collectors.toList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

/**
* @author Alexander Sparkowsky [info@roamingthings.de]
* @version 2017/04/10
*/
public class RecurringExpenseClient extends ExternalResource {

private final String baseURI;
private Client client;
private WebTarget baseTarget;

public RecurringExpenseClient(String baseURI) {
this.baseURI = baseURI;
}


@Override
protected void before() throws Throwable {
client = ClientBuilder.newClient();

baseTarget = client.target(baseURI);
}

public URI create(
final String description,
final String label,
final String recurrencePeriod,
final String expenseType,
final BigDecimal amount,
final String currency,
final String creditorName,
final String note
) {
final JsonObject expenseObject = Json.createObjectBuilder()
.add("description", description)
.add("label", label)
.add("recurrencePeriod", recurrencePeriod)
.add("expenseType", expenseType)
.add("amount", amount)
.add("currency", currency)
.add("creditorName", creditorName)
.add("note", note)
.build();

final Response response = baseTarget
.request()
.post(Entity.json(expenseObject));

assertStatus(Response.Status.CREATED, response);

final URI uri = response.getLocation();
assertNotNull(uri);

return uri;
}

public List<URI> retrieve() {
final Response response = baseTarget.request(MediaType.APPLICATION_JSON_TYPE).get();
assertStatus(Response.Status.OK, response);

final JsonArray jsonArray = response.readEntity(JsonObject.class).getJsonObject("_embedded").getJsonArray("recurring_expenses");
assertThat(jsonArray, notNullValue());
return jsonArray.getValuesAs(JsonObject.class).stream()
.map(o -> o.getJsonObject("_links").getJsonObject("self").getString("href"))
.map(URI::create)
.collect(toList());
}

public RecurringExpense retrieve(URI uri) {
final Response response = client.target(uri).request(MediaType.APPLICATION_JSON_TYPE).get();
if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
return null;
}
assertStatus(Response.Status.OK, response);

final JsonObject object = response.readEntity(JsonObject.class);

return new RecurringExpense(
object.getString("description"),
object.getString("label"),
object.getString("recurrencePeriod"),
object.getString("expenseType"),
object.getJsonNumber("amount").bigDecimalValue(),
object.getString("currency"),
object.getString("creditorName"),
object.getString("note"));
}


public void delete(URI uri) {
final Response response = client.target(uri).request().delete();
assertStatus(Response.Status.NO_CONTENT, response);
}

private void assertStatus(Response.Status expectedStatus, Response response) {
assertThat(response.getStatus(), is(expectedStatus.getStatusCode()));
}
}
Expand Up @@ -16,12 +16,12 @@
* @version 2017/04/09
*/
public class SmokeST {

public static final String URI_SERVICE = "http://localhost:8080/health";
private WebTarget baseTarget;

@Before
public void setUp() {
baseTarget = ClientBuilder.newClient().target("http://localhost:9191/health");
baseTarget = ClientBuilder.newClient().target(URI_SERVICE);
}

@Test
Expand Down
11 changes: 6 additions & 5 deletions expenses-service/build.gradle
Expand Up @@ -24,11 +24,13 @@ repositories {


dependencies {
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-jersey')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('org.springframework.boot:spring-boot-starter-jersey')

compile('org.springframework.boot:spring-boot-starter-validation')

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-jdbc')
runtime('com.h2database:h2')
runtime('org.postgresql:postgresql')

Expand All @@ -37,5 +39,4 @@ dependencies {
runtime('org.springframework.boot:spring-boot-devtools')

testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
}
Expand Up @@ -3,6 +3,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author Alexander Sparkowsky [info@roamingthings.de]
* @version 2017/04/10
*/
@SpringBootApplication
public class ExpensesServiceApplication {

Expand Down
@@ -0,0 +1,9 @@
package de.roamingthings.expenses.business.expense.domain;

/**
* @author Alexander Sparkowsky [info@roamingthings.de]
* @version 2017/04/10
*/
public enum ExpenseType {
MEMBERSHIP, SUBSCRIPTION, INSURANCE, FEE, TAX,
}

0 comments on commit 1852d34

Please sign in to comment.