+ + Db()
+ + findAccountByUser(user : User) : Account
+ + findProductByItemName(itemName : String) : Product
+ + findUserByUserName(userName : String) : User
+ + getInstance() : Db {static}
+ + seedItem(itemName : String, price : Double)
+ + seedUser(userName : String, amount : Double)
+ }
+ class Account {
+ - amount : Double
+ + Account(this$0 : Double)
+ + getAmount() : Double
+ + withdraw(price : Double) : MoneyTransaction
+ }
+ class Product {
+ - price : Double
+ + Product(this$0 : Double)
+ + getPrice() : Double
+ }
+ class User {
+ - userName : String
+ + User(this$0 : String)
+ + getUserName() : String
+ + purchase(item : Product) : ReceiptDto
+ }
+ interface DomainServices {
+ }
+ class DomainServicesImpl {
+ + DomainServicesImpl()
+ - purchase(user : User, account : Account, itemName : String) : ReceiptViewModel
+ + purchase(userName : String, itemName : String) : ReceiptViewModel
+ }
+ class DownForMaintenance {
+ - LOGGER : Logger {static}
+ + DownForMaintenance()
+ + show()
+ }
+ class InsufficientFunds {
+ - LOGGER : Logger {static}
+ - amount : Double
+ - itemName : String
+ - userName : String
+ + InsufficientFunds(userName : String, amount : Double, itemName : String)
+ + show()
+ }
+ class InvalidUser {
+ - LOGGER : Logger {static}
+ - userName : String
+ + InvalidUser(userName : String)
+ + show()
+ }
+ class MaintenanceLock {
+ - LOGGER : Logger {static}
+ - instance : MaintenanceLock {static}
+ - lock : boolean
+ + MaintenanceLock()
+ + getInstance() : MaintenanceLock {static}
+ + isLock() : boolean
+ + setLock(lock : boolean)
+ }
+ class MoneyTransaction {
+ - amount : Double
+ - price : Double
+ + MoneyTransaction(amount : Double, price : Double)
+ }
+ class OutOfStock {
+ - LOGGER : Logger {static}
+ - itemName : String
+ - userName : String
+ + OutOfStock(userName : String, itemName : String)
+ + show()
+ }
+ class ReceiptDto {
+ - LOGGER : Logger {static}
+ - price : Double
+ + ReceiptDto(price : Double)
+ + getPrice() : Double
+ + show()
+ }
+ interface ReceiptViewModel {
+ + show() {abstract}
+ }
+}
+User --+ Db
+Product --+ Db
+MaintenanceLock --> "-instance" MaintenanceLock
+Db --> "-instance" Db
+ApplicationServicesImpl --> "-domain" DomainServicesImpl
+Account --+ Db
+ApplicationServicesImpl ..|> ApplicationServices
+DomainServicesImpl ..|> DomainServices
+DownForMaintenance ..|> ReceiptViewModel
+InsufficientFunds ..|> ReceiptViewModel
+InvalidUser ..|> ReceiptViewModel
+OutOfStock ..|> ReceiptViewModel
+ReceiptDto ..|> ReceiptViewModel
+@enduml
diff --git a/special-case/etc/special_case_urm.png b/special-case/etc/special_case_urm.png
new file mode 100644
index 000000000..03ca646f3
Binary files /dev/null and b/special-case/etc/special_case_urm.png differ
diff --git a/special-case/pom.xml b/special-case/pom.xml
new file mode 100644
index 000000000..c62b9e759
--- /dev/null
+++ b/special-case/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ java-design-patterns
+ com.iluwatar
+ 1.24.0-SNAPSHOT
+
+ 4.0.0
+
+ special-case
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+
+
+
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/App.java b/special-case/src/main/java/com/iluwatar/specialcase/App.java
new file mode 100644
index 000000000..276b1dd85
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/App.java
@@ -0,0 +1,47 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Special Case Pattern is a software design pattern that encapsulates particular cases
+ * into subclasses that provide special behaviors.
+ *
+ * In this example ({@link ReceiptViewModel}) encapsulates all particular cases.
+ */
+public class App {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+
+ /**
+ * Program entry point.
+ */
+ public static void main(String[] args) {
+ // DB seeding
+ LOGGER.info("Db seeding: " + "1 user: {\"ignite1771\", amount = 1000.0}, "
+ + "2 products: {\"computer\": price = 800.0, \"car\": price = 20000.0}");
+ Db.getInstance().seedUser("ignite1771", 1000.0);
+ Db.getInstance().seedItem("computer", 800.0);
+ Db.getInstance().seedItem("car", 20000.0);
+
+ final var applicationServices = new ApplicationServicesImpl();
+ ReceiptViewModel receipt;
+
+ LOGGER.info("[REQUEST] User: " + "abc123" + " buy product: " + "tv");
+ receipt = applicationServices.loggedInUserPurchase("abc123", "tv");
+ receipt.show();
+ MaintenanceLock.getInstance().setLock(false);
+ LOGGER.info("[REQUEST] User: " + "abc123" + " buy product: " + "tv");
+ receipt = applicationServices.loggedInUserPurchase("abc123", "tv");
+ receipt.show();
+ LOGGER.info("[REQUEST] User: " + "ignite1771" + " buy product: " + "tv");
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "tv");
+ receipt.show();
+ LOGGER.info("[REQUEST] User: " + "ignite1771" + " buy product: " + "car");
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "car");
+ receipt.show();
+ LOGGER.info("[REQUEST] User: " + "ignite1771" + " buy product: " + "computer");
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "computer");
+ receipt.show();
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServices.java b/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServices.java
new file mode 100644
index 000000000..f756ccc43
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServices.java
@@ -0,0 +1,6 @@
+package com.iluwatar.specialcase;
+
+public interface ApplicationServices {
+
+ ReceiptViewModel loggedInUserPurchase(String userName, String itemName);
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServicesImpl.java b/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServicesImpl.java
new file mode 100644
index 000000000..ebb9109bc
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/ApplicationServicesImpl.java
@@ -0,0 +1,18 @@
+package com.iluwatar.specialcase;
+
+public class ApplicationServicesImpl implements ApplicationServices {
+
+ private DomainServicesImpl domain = new DomainServicesImpl();
+
+ @Override
+ public ReceiptViewModel loggedInUserPurchase(String userName, String itemName) {
+ if (isDownForMaintenance()) {
+ return new DownForMaintenance();
+ }
+ return this.domain.purchase(userName, itemName);
+ }
+
+ private boolean isDownForMaintenance() {
+ return MaintenanceLock.getInstance().isLock();
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/Db.java b/special-case/src/main/java/com/iluwatar/specialcase/Db.java
new file mode 100644
index 000000000..847330ece
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/Db.java
@@ -0,0 +1,150 @@
+package com.iluwatar.specialcase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Db {
+
+ private static Db instance;
+ private Map userName2User;
+ private Map user2Account;
+ private Map itemName2Product;
+
+ /**
+ * Get the instance of Db.
+ *
+ * @return singleton instance of Db class
+ */
+ public static Db getInstance() {
+ if (instance == null) {
+ synchronized (Db.class) {
+ if (instance == null) {
+ instance = new Db();
+ instance.userName2User = new HashMap<>();
+ instance.user2Account = new HashMap<>();
+ instance.itemName2Product = new HashMap<>();
+ }
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * Seed a user into Db.
+ *
+ * @param userName of the user
+ * @param amount of the user's account
+ */
+ public void seedUser(String userName, Double amount) {
+ User user = new User(userName);
+ instance.userName2User.put(userName, user);
+ Account account = new Account(amount);
+ instance.user2Account.put(user, account);
+ }
+
+ /**
+ * Seed an item into Db.
+ *
+ * @param itemName of the item
+ * @param price of the item
+ */
+ public void seedItem(String itemName, Double price) {
+ Product item = new Product(price);
+ itemName2Product.put(itemName, item);
+ }
+
+ /**
+ * Find a user with the userName.
+ *
+ * @param userName of the user
+ * @return instance of User
+ */
+ public User findUserByUserName(String userName) {
+ if (!userName2User.containsKey(userName)) {
+ return null;
+ }
+ return userName2User.get(userName);
+ }
+
+ /**
+ * Find an account of the user.
+ *
+ * @param user in Db
+ * @return instance of Account of the user
+ */
+ public Account findAccountByUser(User user) {
+ if (!user2Account.containsKey(user)) {
+ return null;
+ }
+ return user2Account.get(user);
+ }
+
+ /**
+ * Find a product with the itemName.
+ *
+ * @param itemName of the item
+ * @return instance of Product
+ */
+ public Product findProductByItemName(String itemName) {
+ if (!itemName2Product.containsKey(itemName)) {
+ return null;
+ }
+ return itemName2Product.get(itemName);
+ }
+
+ public class User {
+
+ private String userName;
+
+ public User(String userName) {
+ this.userName = userName;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public ReceiptDto purchase(Product item) {
+ return new ReceiptDto(item.getPrice());
+ }
+ }
+
+ public class Account {
+
+ private Double amount;
+
+ public Account(Double amount) {
+ this.amount = amount;
+ }
+
+ /**
+ * Withdraw the price of the item from the account.
+ *
+ * @param price of the item
+ * @return instance of MoneyTransaction
+ */
+ public MoneyTransaction withdraw(Double price) {
+ if (price > amount) {
+ return null;
+ }
+ return new MoneyTransaction(amount, price);
+ }
+
+ public Double getAmount() {
+ return amount;
+ }
+ }
+
+ public class Product {
+
+ private Double price;
+
+ public Product(Double price) {
+ this.price = price;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/DomainServices.java b/special-case/src/main/java/com/iluwatar/specialcase/DomainServices.java
new file mode 100644
index 000000000..a052eb20b
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/DomainServices.java
@@ -0,0 +1,4 @@
+package com.iluwatar.specialcase;
+
+public interface DomainServices {
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/DomainServicesImpl.java b/special-case/src/main/java/com/iluwatar/specialcase/DomainServicesImpl.java
new file mode 100644
index 000000000..400689ed9
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/DomainServicesImpl.java
@@ -0,0 +1,46 @@
+package com.iluwatar.specialcase;
+
+public class DomainServicesImpl implements DomainServices {
+
+ /**
+ * Domain purchase with userName and itemName, with validation for userName.
+ *
+ * @param userName of the user
+ * @param itemName of the item
+ * @return instance of ReceiptViewModel
+ */
+ public ReceiptViewModel purchase(String userName, String itemName) {
+ Db.User user = Db.getInstance().findUserByUserName(userName);
+ if (user == null) {
+ return new InvalidUser(userName);
+ }
+
+ Db.Account account = Db.getInstance().findAccountByUser(user);
+ return purchase(user, account, itemName);
+ }
+
+ /**
+ * Domain purchase with user, account and itemName,
+ * with validation for whether product is out of stock
+ * and whether user has insufficient funds in the account.
+ *
+ * @param user in Db
+ * @param account in Db
+ * @param itemName of the item
+ * @return instance of ReceiptViewModel
+ */
+ private ReceiptViewModel purchase(Db.User user, Db.Account account, String itemName) {
+ Db.Product item = Db.getInstance().findProductByItemName(itemName);
+ if (item == null) {
+ return new OutOfStock(user.getUserName(), itemName);
+ }
+
+ ReceiptDto receipt = user.purchase(item);
+ MoneyTransaction transaction = account.withdraw(receipt.getPrice());
+ if (transaction == null) {
+ return new InsufficientFunds(user.getUserName(), account.getAmount(), itemName);
+ }
+
+ return receipt;
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/DownForMaintenance.java b/special-case/src/main/java/com/iluwatar/specialcase/DownForMaintenance.java
new file mode 100644
index 000000000..98a2cf89c
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/DownForMaintenance.java
@@ -0,0 +1,14 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DownForMaintenance implements ReceiptViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DownForMaintenance.class);
+
+ @Override
+ public void show() {
+ LOGGER.info("Down for maintenance");
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/InsufficientFunds.java b/special-case/src/main/java/com/iluwatar/specialcase/InsufficientFunds.java
new file mode 100644
index 000000000..8fe714f80
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/InsufficientFunds.java
@@ -0,0 +1,32 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InsufficientFunds implements ReceiptViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(InsufficientFunds.class);
+
+ private String userName;
+ private Double amount;
+ private String itemName;
+
+ /**
+ * Constructor of InsufficientFunds.
+ *
+ * @param userName of the user
+ * @param amount of the user's account
+ * @param itemName of the item
+ */
+ public InsufficientFunds(String userName, Double amount, String itemName) {
+ this.userName = userName;
+ this.amount = amount;
+ this.itemName = itemName;
+ }
+
+ @Override
+ public void show() {
+ LOGGER.info("Insufficient funds: " + amount + " of user: " + userName
+ + " for buying item: " + itemName);
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/InvalidUser.java b/special-case/src/main/java/com/iluwatar/specialcase/InvalidUser.java
new file mode 100644
index 000000000..443fdc7bf
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/InvalidUser.java
@@ -0,0 +1,20 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InvalidUser implements ReceiptViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(InvalidUser.class);
+
+ private final String userName;
+
+ public InvalidUser(String userName) {
+ this.userName = userName;
+ }
+
+ @Override
+ public void show() {
+ LOGGER.info("Invalid user: " + userName);
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/MaintenanceLock.java b/special-case/src/main/java/com/iluwatar/specialcase/MaintenanceLock.java
new file mode 100644
index 000000000..29a5b4f81
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/MaintenanceLock.java
@@ -0,0 +1,37 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MaintenanceLock {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MaintenanceLock.class);
+
+ private static MaintenanceLock instance;
+ private boolean lock = true;
+
+ /**
+ * Get the instance of MaintenanceLock.
+ *
+ * @return singleton instance of MaintenanceLock
+ */
+ public static MaintenanceLock getInstance() {
+ if (instance == null) {
+ synchronized (MaintenanceLock.class) {
+ if (instance == null) {
+ instance = new MaintenanceLock();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public boolean isLock() {
+ return lock;
+ }
+
+ public void setLock(boolean lock) {
+ this.lock = lock;
+ LOGGER.info("Maintenance lock is set to: " + lock);
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/MoneyTransaction.java b/special-case/src/main/java/com/iluwatar/specialcase/MoneyTransaction.java
new file mode 100644
index 000000000..e3904964f
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/MoneyTransaction.java
@@ -0,0 +1,12 @@
+package com.iluwatar.specialcase;
+
+public class MoneyTransaction {
+
+ private Double amount;
+ private Double price;
+
+ public MoneyTransaction(Double amount, Double price) {
+ this.amount = amount;
+ this.price = price;
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/OutOfStock.java b/special-case/src/main/java/com/iluwatar/specialcase/OutOfStock.java
new file mode 100644
index 000000000..5359bed31
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/OutOfStock.java
@@ -0,0 +1,22 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OutOfStock implements ReceiptViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OutOfStock.class);
+
+ private String userName;
+ private String itemName;
+
+ public OutOfStock(String userName, String itemName) {
+ this.userName = userName;
+ this.itemName = itemName;
+ }
+
+ @Override
+ public void show() {
+ LOGGER.info("Out of stock: " + itemName + " for user = " + userName + " to buy");
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/ReceiptDto.java b/special-case/src/main/java/com/iluwatar/specialcase/ReceiptDto.java
new file mode 100644
index 000000000..81fc46bbe
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/ReceiptDto.java
@@ -0,0 +1,24 @@
+package com.iluwatar.specialcase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReceiptDto implements ReceiptViewModel {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ReceiptDto.class);
+
+ private Double price;
+
+ public ReceiptDto(Double price) {
+ this.price = price;
+ }
+
+ public Double getPrice() {
+ return price;
+ }
+
+ @Override
+ public void show() {
+ LOGGER.info("Receipt: " + price + " paid");
+ }
+}
diff --git a/special-case/src/main/java/com/iluwatar/specialcase/ReceiptViewModel.java b/special-case/src/main/java/com/iluwatar/specialcase/ReceiptViewModel.java
new file mode 100644
index 000000000..482eef21f
--- /dev/null
+++ b/special-case/src/main/java/com/iluwatar/specialcase/ReceiptViewModel.java
@@ -0,0 +1,6 @@
+package com.iluwatar.specialcase;
+
+public interface ReceiptViewModel {
+
+ void show();
+}
diff --git a/special-case/src/test/java/com/iluwatar/specialcase/AppTest.java b/special-case/src/test/java/com/iluwatar/specialcase/AppTest.java
new file mode 100644
index 000000000..25799368b
--- /dev/null
+++ b/special-case/src/test/java/com/iluwatar/specialcase/AppTest.java
@@ -0,0 +1,16 @@
+package com.iluwatar.specialcase;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Application test.
+ */
+public class AppTest {
+
+ @Test
+ void shouldExecuteWithoutException() {
+ assertDoesNotThrow(() -> App.main(new String[]{}));
+ }
+}
diff --git a/special-case/src/test/java/com/iluwatar/specialcase/SpecialCasesTest.java b/special-case/src/test/java/com/iluwatar/specialcase/SpecialCasesTest.java
new file mode 100644
index 000000000..5e83aa8d6
--- /dev/null
+++ b/special-case/src/test/java/com/iluwatar/specialcase/SpecialCasesTest.java
@@ -0,0 +1,120 @@
+package com.iluwatar.specialcase;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.slf4j.LoggerFactory;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.read.ListAppender;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * Special cases unit tests. (including the successful scenario {@link ReceiptDto})
+ */
+public class SpecialCasesTest {
+ private static ApplicationServices applicationServices;
+ private static ReceiptViewModel receipt;
+
+ @BeforeAll
+ static void beforeAll() {
+ Db.getInstance().seedUser("ignite1771", 1000.0);
+ Db.getInstance().seedItem("computer", 800.0);
+ Db.getInstance().seedItem("car", 20000.0);
+
+ applicationServices = new ApplicationServicesImpl();
+ }
+
+ @BeforeEach
+ public void beforeEach() {
+ MaintenanceLock.getInstance().setLock(false);
+ }
+
+ @Test
+ public void testDownForMaintenance() {
+ final Logger LOGGER = (Logger) LoggerFactory.getLogger(DownForMaintenance.class);
+
+ ListAppender listAppender = new ListAppender<>();
+ listAppender.start();
+ LOGGER.addAppender(listAppender);
+
+ MaintenanceLock.getInstance().setLock(true);
+ receipt = applicationServices.loggedInUserPurchase(null, null);
+ receipt.show();
+
+ List loggingEventList = listAppender.list;
+ assertEquals("Down for maintenance", loggingEventList.get(0).getMessage());
+ assertEquals(Level.INFO, loggingEventList.get(0).getLevel());
+ }
+
+ @Test
+ public void testInvalidUser() {
+ final Logger LOGGER = (Logger) LoggerFactory.getLogger(InvalidUser.class);
+
+ ListAppender listAppender = new ListAppender<>();
+ listAppender.start();
+ LOGGER.addAppender(listAppender);
+
+ receipt = applicationServices.loggedInUserPurchase("a", null);
+ receipt.show();
+
+ List loggingEventList = listAppender.list;
+ assertEquals("Invalid user: a", loggingEventList.get(0).getMessage());
+ assertEquals(Level.INFO, loggingEventList.get(0).getLevel());
+ }
+
+ @Test
+ public void testOutOfStock() {
+ final Logger LOGGER = (Logger) LoggerFactory.getLogger(OutOfStock.class);
+
+ ListAppender listAppender = new ListAppender<>();
+ listAppender.start();
+ LOGGER.addAppender(listAppender);
+
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "tv");
+ receipt.show();
+
+ List loggingEventList = listAppender.list;
+ assertEquals("Out of stock: tv for user = ignite1771 to buy"
+ , loggingEventList.get(0).getMessage());
+ assertEquals(Level.INFO, loggingEventList.get(0).getLevel());
+ }
+
+ @Test
+ public void testInsufficientFunds() {
+ final Logger LOGGER = (Logger) LoggerFactory.getLogger(InsufficientFunds.class);
+
+ ListAppender listAppender = new ListAppender<>();
+ listAppender.start();
+ LOGGER.addAppender(listAppender);
+
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "car");
+ receipt.show();
+
+ List loggingEventList = listAppender.list;
+ assertEquals("Insufficient funds: 1000.0 of user: ignite1771 for buying item: car"
+ , loggingEventList.get(0).getMessage());
+ assertEquals(Level.INFO, loggingEventList.get(0).getLevel());
+ }
+
+ @Test
+ public void testReceiptDto() {
+ final Logger LOGGER = (Logger) LoggerFactory.getLogger(ReceiptDto.class);
+
+ ListAppender listAppender = new ListAppender<>();
+ listAppender.start();
+ LOGGER.addAppender(listAppender);
+
+ receipt = applicationServices.loggedInUserPurchase("ignite1771", "computer");
+ receipt.show();
+
+ List loggingEventList = listAppender.list;
+ assertEquals("Receipt: 800.0 paid"
+ , loggingEventList.get(0).getMessage());
+ assertEquals(Level.INFO, loggingEventList.get(0).getLevel());
+ }
+}