package com.bookshop.solid.lsp;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.math.BigDecimal;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("LSP -- every Purchasable behaves like one, so the till needs no guards")
class TillLspTest {

    @Test
    @DisplayName("any mix of subtypes totals correctly with no instanceof checks")
    void subtypesAreFullySubstitutable() {
        List<Purchasable> basket = List.of(
                new PrintedBook("Refactoring", new BigDecimal("47.99"), 850),
                new Ebook("Effective Java", new BigDecimal("29.99"), 12));

        assertEquals(new BigDecimal("77.98"), Till.totalOf(basket));
    }

    @Test
    @DisplayName("the unbuyable item is kept out by the type system, not a runtime exception")
    void freeSamplesCannotReachTheTill() {
        FreeSampleChapter sample = new FreeSampleChapter("Refactoring -- Chapter 1", "https://example.com/ch1");

        // List.of(sample) would not compile as a List<Purchasable> -- the violation
        // is impossible to write, which is the whole point.
        assertEquals("Refactoring -- Chapter 1", sample.title());
    }
}
