package com.bookshop.creational.singleton;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("Singleton -- one shared ShopConfig via the enum idiom")
class ShopConfigTest {

    @AfterEach
    void resetGlobalState() {
        ShopConfig.INSTANCE.reset();
    }

    @Test
    @DisplayName("every access point sees the exact same instance")
    void singleInstance() {
        ShopConfig fromCheckout = ShopConfig.INSTANCE;
        ShopConfig fromShipping = ShopConfig.INSTANCE;

        assertSame(fromCheckout, fromShipping);
    }

    @Test
    @DisplayName("state set in one part of the shop is visible everywhere else")
    void sharedStateIsConsistent() {
        assertFalse(ShopConfig.INSTANCE.isEnabled("gift-wrap"));

        ShopConfig.INSTANCE.enable("gift-wrap");

        assertTrue(ShopConfig.INSTANCE.isEnabled("gift-wrap"));
    }

    @Test
    @DisplayName("the caveat in action: global state needs an explicit reset between tests")
    void globalStateMustBeReset() {
        ShopConfig.INSTANCE.enable("dark-mode");

        ShopConfig.INSTANCE.reset();

        assertFalse(ShopConfig.INSTANCE.isEnabled("dark-mode"));
    }
}
