package com.bookshop.behavioral.observer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.bookshop.domain.Book;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("Observer -- inventory announces restocks without knowing who is listening")
class InventoryObserverTest {
private final Inventory inventory = new Inventory();
private final Book book = new Book("978-0201633610", "Design Patterns",
"Gamma, Helm, Johnson, Vlissides", new BigDecimal("42.00"));
@Test
@DisplayName("every subscriber hears about a restock -- email and lambda alike")
void allSubscribersAreNotified() {
EmailAlerts email = new EmailAlerts();
List<String> smsLog = new ArrayList<>();
inventory.subscribe(email);
inventory.subscribe(b -> smsLog.add("SMS: " + b.title() + " available"));
inventory.restock(book);
assertEquals(List.of("To waitlist: \"Design Patterns\" is back in stock!"), email.outbox());
assertEquals(List.of("SMS: Design Patterns available"), smsLog);
}
@Test
@DisplayName("unsubscribed listeners stop receiving events")
void unsubscribeStopsNotifications() {
EmailAlerts email = new EmailAlerts();
inventory.subscribe(email);
inventory.unsubscribe(email);
inventory.restock(book);
assertTrue(email.outbox().isEmpty());
}
@Test
@DisplayName("the subject needs no changes to support a brand-new reaction")
void newReactionsAreJustNewSubscribers() {
List<String> dashboardEvents = new ArrayList<>();
inventory.subscribe(b -> dashboardEvents.add(b.isbn()));
inventory.restock(book);
assertEquals(List.of("978-0201633610"), dashboardEvents);
}
}