Merge pull request 'Modultests' (#132) from feature/module_tests into master

Reviewed-on: #132
Reviewed-by: CodeSteak <codesteak@shellf.art>
This commit is contained in:
CodeSteak 2020-06-29 10:44:48 +02:00
commit d03d94049d
8 changed files with 513 additions and 1 deletions

View File

@ -1,6 +1,7 @@
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.7.RELEASE")
@ -29,7 +30,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'org.xerial:sqlite-jdbc:3.31.1'
implementation 'org.yaml:snakeyaml:1.26'
testCompile("org.springframework.boot:spring-boot-starter-test")
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}
group 'org.hso'
@ -38,3 +39,11 @@ version '0.1.0'
bootRun {
args = ["--spring.profiles.active=dev --spring.config.location=classpath:/application.properties"]
}
test {
useJUnitPlatform()
testLogging {
events 'PASSED', 'FAILED', 'SKIPPED'
}
}

View File

@ -0,0 +1,37 @@
package org.hso.ecommerce.action.booking;
import static org.junit.jupiter.api.Assertions.*;
import org.hso.ecommerce.entities.booking.Booking;
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
import org.hso.ecommerce.entities.booking.BookingReason;
import org.junit.jupiter.api.Test;
class CreateBookingTest {
@Test
void test() {
BookingAccountEntry sourceAccount = new BookingAccountEntry();
sourceAccount.isMainAccount = true;
sourceAccount.newSumCent = 600_00;
BookingAccountEntry destinationAccount = new BookingAccountEntry();
destinationAccount.isVATAccount = true;
destinationAccount.newSumCent = 100_00;
BookingReason reason = new BookingReason();
reason.comment = "some test";
Booking result = new CreateBookingAction(sourceAccount, destinationAccount, reason, 42_00).finish();
assertTrue(result.source.isMainAccount);
assertFalse(result.source.isVATAccount);
assertEquals(558_00, result.source.newSumCent);
assertFalse(result.destination.isMainAccount);
assertTrue(result.destination.isVATAccount);
assertEquals(142_00, result.destination.newSumCent);
assertEquals("some test", result.reason.comment);
assertEquals(42_00, result.amountCent);
}
}

View File

@ -0,0 +1,115 @@
package org.hso.ecommerce.action.cronjob;
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.hso.ecommerce.action.cronjob.ReadSupplierDataAction.ArticleIdentifier;
import org.hso.ecommerce.action.cronjob.ReadSupplierDataAction.Offer;
import org.hso.ecommerce.entities.supplier.ArticleOffer;
import org.hso.ecommerce.entities.supplier.Supplier;
import org.junit.jupiter.api.Test;
class UpdateOffersTest {
@Test
void test() {
// suppliers
Supplier mcDonalds = new Supplier();
Supplier burgerKing = new Supplier();
org.hso.ecommerce.api.data.Supplier apiMcDonalds = new org.hso.ecommerce.api.data.Supplier();
apiMcDonalds.articles = new ArrayList<>();
org.hso.ecommerce.api.data.Supplier apiBurgerKing = new org.hso.ecommerce.api.data.Supplier();
apiBurgerKing.articles = new ArrayList<>();
// previously stored offers
List<ArticleOffer> offers = new ArrayList<>();
ArticleOffer fries = new ArticleOffer();
fries.manufacturer = "potatoe Inc.";
fries.articleNumber = "FR-13S";
fries.cheapestSupplier = mcDonalds;
offers.add(fries);
ArticleOffer burger = new ArticleOffer();
burger.manufacturer = "Hamburger GmbH";
burger.articleNumber = "BU-4934";
burger.cheapestSupplier = mcDonalds;
offers.add(burger);
ArticleOffer pizza = new ArticleOffer();
pizza.manufacturer = "Teig Verarbeitung AG";
pizza.articleNumber = "3.14-ZZA";
offers.add(pizza);
ArticleOffer donut = new ArticleOffer();
donut.manufacturer = "Hevert Süßwarengroßhändler";
donut.articleNumber = "D-HITM";
donut.shouldBeAdvertised = true;
offers.add(donut);
// new offers
org.hso.ecommerce.api.data.Article apiPizza = new org.hso.ecommerce.api.data.Article();
apiPizza.title = "Pizza";
apiPizza.manufacturer = "Teig Verarbeitung AG";
apiPizza.articleNumber = "3.14-ZZA";
apiPizza.shouldBeAdvertised = true;
apiMcDonalds.articles.add(apiPizza);
org.hso.ecommerce.api.data.Article apiSausage = new org.hso.ecommerce.api.data.Article();
apiSausage.title = "Wurst";
apiSausage.manufacturer = "Schlachterei Müller";
apiSausage.articleNumber = "SGE-24";
apiBurgerKing.articles.add(apiSausage);
org.hso.ecommerce.api.data.Article apiBurger = new org.hso.ecommerce.api.data.Article();
apiBurger.title = "Burger";
apiBurger.manufacturer = "Hamburger GmbH";
apiBurger.articleNumber = "BU-4934";
apiBurgerKing.articles.add(apiBurger);
org.hso.ecommerce.api.data.Article apiDonut = new org.hso.ecommerce.api.data.Article();
apiDonut.title = "Donut";
apiDonut.manufacturer = "Hevert Süßwarengroßhändler";
apiDonut.articleNumber = "D-HITM";
apiBurgerKing.articles.add(apiDonut);
// The currently cheapest suppliers
HashMap<ArticleIdentifier, Offer> cheapestOffers = new HashMap<>();
cheapestOffers.put(new ArticleIdentifier("Schlachterei Müller", "SGE-24"),
new Offer(burgerKing, apiBurgerKing));
cheapestOffers.put(new ArticleIdentifier("Hamburger GmbH", "BU-4934"), new Offer(burgerKing, apiBurgerKing));
cheapestOffers.put(new ArticleIdentifier("Teig Verarbeitung AG", "3.14-ZZA"),
new Offer(mcDonalds, apiMcDonalds));
cheapestOffers.put(new ArticleIdentifier("Hevert Süßwarengroßhändler", "D-HITM"),
new Offer(burgerKing, apiBurgerKing));
List<ArticleOffer> result = new UpdateOffersAction(offers, cheapestOffers).finish();
// fries are no longer available
assertEquals(null, find(result, "potatoe Inc.", "FR-13S").cheapestSupplier);
// the sausage was not available before, but is now
assertEquals("Wurst", find(result, "Schlachterei Müller", "SGE-24").title);
// BurgerKing offers burgers cheaper than McDonalds
assertEquals(burgerKing, find(result, "Hamburger GmbH", "BU-4934").cheapestSupplier);
// pizza should now be advertised
assertTrue(find(result, "Teig Verarbeitung AG", "3.14-ZZA").shouldBeAdvertised);
// donuts should no longer be advertised
assertFalse(find(result, "Hevert Süßwarengroßhändler", "D-HITM").shouldBeAdvertised);
}
private ArticleOffer find(List<ArticleOffer> list, String manufacturer, String articleNumber) {
for (ArticleOffer offer : list) {
if (offer.manufacturer.equals(manufacturer) && offer.articleNumber.equals(articleNumber)) {
return offer;
}
}
return null;
}
}

View File

@ -0,0 +1,108 @@
package org.hso.ecommerce.action.shop;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.hso.ecommerce.action.shop.CreateOrderAction.ArticleNotInStockException;
import org.hso.ecommerce.action.shop.CreateOrderAction.Result;
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
import org.hso.ecommerce.entities.booking.PaymentMethod;
import org.hso.ecommerce.entities.shop.Address;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.supplier.ArticleOffer;
import org.hso.ecommerce.entities.user.User;
import org.hso.ecommerce.entities.warehouse.Slot;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.junit.jupiter.api.Test;
class CreateOrderTest {
@Test
void test() throws ArticleNotInStockException {
User user = new User();
int expectedTotalGrossCent = 28_83;
Address destination = new Address();
PaymentMethod method = new PaymentMethod();
BookingAccountEntry latestUserBooking = new BookingAccountEntry();
latestUserBooking.newSumCent = 0;
latestUserBooking.userAccount = user;
BookingAccountEntry latestVatBooking = new BookingAccountEntry();
latestVatBooking.isVATAccount = true;
latestVatBooking.newSumCent = 100_00;
BookingAccountEntry latestMainBooking = new BookingAccountEntry();
latestMainBooking.isMainAccount = true;
latestMainBooking.newSumCent = 500_00;
CreateOrderAction action = new CreateOrderAction(user, expectedTotalGrossCent, destination, method,
latestUserBooking, latestVatBooking, latestMainBooking);
// orders
ArticleOffer fantaOffer = new ArticleOffer();
fantaOffer.vatPercent = 7;
Article fanta = new Article();
fanta.shopPricePerUnitNetCent = 1_40;
fanta.related = fantaOffer;
fanta.warehouseUnitsPerSlot = 20;
action.addArticle(fanta, 10, slots(fanta, 1, new int[] { 20, 3 }));
ArticleOffer colaOffer = new ArticleOffer();
colaOffer.vatPercent = 7;
Article cola = new Article();
cola.shopPricePerUnitNetCent = 1_86;
cola.related = colaOffer;
cola.warehouseUnitsPerSlot = 20;
action.addArticle(cola, 7, slots(cola, 4, new int[] { 2, 20, 18, 3 }));
Result result = action.finish();
assertEquals(28_83, result.bookings.get(0).amountCent); // purchase
assertTrue(result.bookings.get(0).destination.isMainAccount);
assertEquals(28_83, result.bookings.get(1).amountCent); // payment
assertEquals(user, result.bookings.get(1).destination.userAccount);
assertEquals(1_81, result.bookings.get(2).amountCent); // vat
assertTrue(result.bookings.get(2).destination.isVATAccount);
assertEquals(2, result.customerOrder.positions.size());
assertEquals(28_83, result.customerOrder.totalGrossCent);
assertEquals(27_02, result.customerOrder.totalNetCent);
List<WarehouseBookingPosition> warehousePositions = result.warehouseBooking.positions;
assertEquals(-7, find(warehousePositions, 1).amount);
assertEquals(-3, find(warehousePositions, 2).amount);
assertEquals(-2, find(warehousePositions, 4).amount);
assertEquals(-2, find(warehousePositions, 6).amount);
assertEquals(-3, find(warehousePositions, 7).amount);
// Check the remaining amount of one slot as an example
assertEquals(16, find(warehousePositions, 6).slotEntry.newSumSlot);
}
private List<WarehouseBookingPositionSlotEntry> slots(Article article, int firstSlot, int[] amounts) {
List<WarehouseBookingPositionSlotEntry> entries = new ArrayList<>();
for (int i = 0; i < amounts.length; i++) {
WarehouseBookingPositionSlotEntry entry = new WarehouseBookingPositionSlotEntry();
entry.article = article;
entry.newSumSlot = amounts[i];
entry.slot = new Slot();
entry.slot.slotNum = firstSlot + i;
entries.add(entry);
}
return entries;
}
private WarehouseBookingPosition find(List<WarehouseBookingPosition> positions, int slotNumber) {
for (WarehouseBookingPosition position : positions) {
if (position.slotEntry.slot.slotNum == slotNumber) {
return position;
}
}
return null;
}
}

View File

@ -0,0 +1,41 @@
package org.hso.ecommerce.action.shop;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.hso.ecommerce.entities.shop.Article;
import org.junit.jupiter.api.Test;
class GetRandomArticlesTest {
@Test
void test() {
List<Article> articles = new ArrayList<>();
for (int i = 0; i < 10 ; i++) {
Article article = new Article();
article.id = i;
articles.add(article);
}
int[] counters = new int[10];
// Choose 10000 times 3 articles out of 10
for (int i = 0; i < 10_000; i++) {
List<Article> chosen = GetRandomArticlesAction.getRandomArticles(3, new ArrayList<>(articles));
assertEquals(3, chosen.size());
for (Article chosenArticle : chosen) {
counters[(int) chosenArticle.id]++;
}
}
// Expect each article to be chosen 2400 - 3600 times.
// The probability for this test to fail randomly is below 10^-36
for (int counterValue : counters) {
assertTrue(counterValue >= 2400);
assertTrue(counterValue <= 3600);
}
}
}

View File

@ -0,0 +1,57 @@
package org.hso.ecommerce.action.warehouse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.warehouse.Slot;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.junit.jupiter.api.Test;
class CalculateWarehouseStatsTest {
@Test
void test() {
// articles with different amounts of items that fit in one warehouse slot
Article fanta = new Article();
fanta.id = 1;
fanta.warehouseUnitsPerSlot = 18;
Article cola = new Article();
cola.id = 2;
cola.warehouseUnitsPerSlot = 7;
List<WarehouseBookingPositionSlotEntry> entries = new ArrayList<>();
for (int i=1; i<=20; i++) {
WarehouseBookingPositionSlotEntry entry = new WarehouseBookingPositionSlotEntry();
entry.slot = new Slot();
entry.slot.slotNum = i;
entries.add(entry);
}
entries.get(0).article = fanta;
entries.get(0).newSumSlot = 12;
entries.get(3).article = cola;
entries.get(3).newSumSlot = 7;
entries.get(4).article = fanta;
entries.get(4).newSumSlot = 18;
entries.get(11).article = fanta;
entries.get(11).newSumSlot = 2;
entries.get(15).article = cola;
entries.get(15).newSumSlot = 5;
CalculateWarehouseStatsAction.WarehouseStats result = new CalculateWarehouseStatsAction(entries).finish();
assertEquals(2, result.numArticles);
assertSimilar(5.0 / 20.0, result.ratioUsedSlots);
assertSimilar(32.0 / 360.0 + 12.0 / 140.0, result.efficiency);
}
private void assertSimilar(double expected, double actual) {
double diff = actual - expected;
assertTrue(diff < 1e-5 && diff > -1e-5);
}
}

View File

@ -0,0 +1,88 @@
package org.hso.ecommerce.action.warehouse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Optional;
import org.hso.ecommerce.action.warehouse.CreateManuelBookingAction.ArticleSlotConstraintFailedException;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.warehouse.Slot;
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.junit.jupiter.api.Test;
class CreateManualBookingTest {
@Test
void testIncrease() throws ArticleSlotConstraintFailedException {
Article article = new Article();
article.warehouseUnitsPerSlot = 20;
article.id = 1;
Article previousArticle = new Article();
previousArticle.id = 2;
WarehouseBookingPositionSlotEntry destinationSlot = new WarehouseBookingPositionSlotEntry();
destinationSlot.slot = new Slot();
destinationSlot.slot.slotNum = 5;
destinationSlot.article = previousArticle;
Optional<WarehouseBookingPositionSlotEntry> optSourceSlot = Optional.empty();
WarehouseBooking result = new CreateManuelBookingAction(article, 17, optSourceSlot, Optional.of(destinationSlot), "some reason").finish();
assertEquals(17, result.positions.get(0).amount);
assertEquals(17, result.positions.get(0).slotEntry.newSumSlot);
assertEquals(5, result.positions.get(0).slotEntry.slot.slotNum);
assertTrue(result.reason.isManuel);
assertEquals("some reason", result.reason.comment);
}
@Test
void testDecrease() throws ArticleSlotConstraintFailedException {
Article article = new Article();
article.warehouseUnitsPerSlot = 20;
article.id = 1;
WarehouseBookingPositionSlotEntry sourceSlot = new WarehouseBookingPositionSlotEntry();
sourceSlot.article = article;
sourceSlot.slot = new Slot();
sourceSlot.slot.slotNum = 8;
sourceSlot.newSumSlot = 17;
Optional<WarehouseBookingPositionSlotEntry> optDestinationSlot = Optional.empty();
WarehouseBooking result = new CreateManuelBookingAction(article, 13, Optional.of(sourceSlot), optDestinationSlot, "some other reason").finish();
assertEquals(-13, result.positions.get(0).amount);
assertEquals(4, result.positions.get(0).slotEntry.newSumSlot);
assertEquals(8, result.positions.get(0).slotEntry.slot.slotNum);
assertTrue(result.reason.isManuel);
assertEquals("some other reason", result.reason.comment);
}
@Test
void testTransfer() throws ArticleSlotConstraintFailedException {
Article article = new Article();
article.warehouseUnitsPerSlot = 20;
article.id = 1;
WarehouseBookingPositionSlotEntry sourceSlot = new WarehouseBookingPositionSlotEntry();
sourceSlot.article = article;
sourceSlot.slot = new Slot();
sourceSlot.slot.slotNum = 11;
sourceSlot.newSumSlot = 17;
WarehouseBookingPositionSlotEntry destinationSlot = new WarehouseBookingPositionSlotEntry();
destinationSlot.article = article;
destinationSlot.slot = new Slot();
destinationSlot.slot.slotNum = 15;
destinationSlot.newSumSlot = 2;
WarehouseBooking result = new CreateManuelBookingAction(article, 14, Optional.of(sourceSlot), Optional.of(destinationSlot), "transfer").finish();
assertEquals(-14, result.positions.get(0).amount);
assertEquals(3, result.positions.get(0).slotEntry.newSumSlot);
assertEquals(11, result.positions.get(0).slotEntry.slot.slotNum);
assertEquals(14, result.positions.get(1).amount);
assertEquals(16, result.positions.get(1).slotEntry.newSumSlot);
assertEquals(15, result.positions.get(1).slotEntry.slot.slotNum);
assertTrue(result.reason.isManuel);
assertEquals("transfer", result.reason.comment);
}
}

View File

@ -0,0 +1,57 @@
package org.hso.ecommerce.action.warehouse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.hso.ecommerce.action.warehouse.SupplierOrderArrivedAction.NoSpaceInWarehouseException;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.supplier.SupplierOrder;
import org.hso.ecommerce.entities.warehouse.Slot;
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.junit.jupiter.api.Test;
class SupplierOrderArrivedTest {
@Test
void test() throws NoSpaceInWarehouseException {
Article article = new Article();
article.warehouseUnitsPerSlot = 15;
List<WarehouseBookingPositionSlotEntry> candidates = new ArrayList<>();
addCandidate(candidates, article, 3, 13);
addCandidate(candidates, article, 6, 12);
addCandidate(candidates, article, 7, 0);
addCandidate(candidates, article, 10, 14);
addCandidate(candidates, article, 12, 11);
addCandidate(candidates, article, 16, 0);
SupplierOrder order = new SupplierOrder();
order.numberOfUnits = 17;
SupplierOrderArrivedAction.Result result = new SupplierOrderArrivedAction(candidates, order, article).finish();
WarehouseBooking booking = result.getBooking();
assertEquals(10, booking.positions.get(0).slotEntry.slot.slotNum);
assertEquals(1, booking.positions.get(0).amount);
assertEquals(3, booking.positions.get(1).slotEntry.slot.slotNum);
assertEquals(2, booking.positions.get(1).amount);
assertEquals(6, booking.positions.get(2).slotEntry.slot.slotNum);
assertEquals(3, booking.positions.get(2).amount);
assertEquals(12, booking.positions.get(3).slotEntry.slot.slotNum);
assertEquals(4, booking.positions.get(3).amount);
assertEquals(7, booking.positions.get(4).slotEntry.slot.slotNum);
assertEquals(7, booking.positions.get(4).amount);
}
private void addCandidate(List<WarehouseBookingPositionSlotEntry> candidates, Article article, int slotNum, int amount) {
WarehouseBookingPositionSlotEntry entry = new WarehouseBookingPositionSlotEntry();
entry.article = article;
entry.slot = new Slot();
entry.slot.slotNum = slotNum;
entry.newSumSlot = amount;
candidates.add(entry);
}
}