import { describe, it, expect } from 'vitest'; import { CheckoutState, CheckoutStateEnum } from '../../../../packages/domain/value-objects/CheckoutState'; /** * CheckoutState Value Object - GREEN PHASE * * Tests for checkout button state detection. */ describe('CheckoutState Value Object', () => { describe('READY state', () => { it('should create READY state from btn-success class', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); it('should detect ready state correctly', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); expect(state.isReady()).toBe(true); expect(state.hasInsufficientFunds()).toBe(false); }); it('should handle additional classes with btn-success', () => { const state = CheckoutState.fromButtonClasses('btn btn-lg btn-success pull-right'); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); it('should be case-insensitive for btn-success', () => { const state = CheckoutState.fromButtonClasses('btn BTN-SUCCESS'); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); }); describe('INSUFFICIENT_FUNDS state', () => { it('should create INSUFFICIENT_FUNDS from btn-default without btn-success', () => { const state = CheckoutState.fromButtonClasses('btn btn-default'); expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS); }); it('should detect insufficient funds correctly', () => { const state = CheckoutState.fromButtonClasses('btn btn-default'); expect(state.isReady()).toBe(false); expect(state.hasInsufficientFunds()).toBe(true); }); it('should handle btn-primary as insufficient funds', () => { const state = CheckoutState.fromButtonClasses('btn btn-primary'); expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS); }); it('should handle btn-warning as insufficient funds', () => { const state = CheckoutState.fromButtonClasses('btn btn-warning'); expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS); }); it('should handle disabled button as insufficient funds', () => { const state = CheckoutState.fromButtonClasses('btn btn-default disabled'); expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS); }); }); describe('UNKNOWN state', () => { it('should create UNKNOWN when no btn class exists', () => { const state = CheckoutState.fromButtonClasses('some-other-class'); expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN); }); it('should create UNKNOWN from empty string', () => { const state = CheckoutState.fromButtonClasses(''); expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN); }); it('should detect unknown state correctly', () => { const state = CheckoutState.fromButtonClasses(''); expect(state.isReady()).toBe(false); expect(state.hasInsufficientFunds()).toBe(false); }); }); describe('Edge Cases', () => { it('should handle whitespace in class names', () => { const state = CheckoutState.fromButtonClasses(' btn btn-success '); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); it('should handle multiple spaces between classes', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); it('should be immutable after creation', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); const originalState = state.getValue(); expect(originalState).toBe(CheckoutStateEnum.READY); // Verify no setters exist expect(typeof (state as any).setState).toBe('undefined'); }); }); describe('BDD Scenarios', () => { it('Given button with btn-success, When checking state, Then state is READY', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); expect(state.getValue()).toBe(CheckoutStateEnum.READY); }); it('Given button without btn-success, When checking state, Then state is INSUFFICIENT_FUNDS', () => { const state = CheckoutState.fromButtonClasses('btn btn-default'); expect(state.getValue()).toBe(CheckoutStateEnum.INSUFFICIENT_FUNDS); }); it('Given no button classes, When checking state, Then state is UNKNOWN', () => { const state = CheckoutState.fromButtonClasses(''); expect(state.getValue()).toBe(CheckoutStateEnum.UNKNOWN); }); it('Given READY state, When checking isReady, Then returns true', () => { const state = CheckoutState.fromButtonClasses('btn btn-success'); expect(state.isReady()).toBe(true); }); it('Given INSUFFICIENT_FUNDS state, When checking hasInsufficientFunds, Then returns true', () => { const state = CheckoutState.fromButtonClasses('btn btn-default'); expect(state.hasInsufficientFunds()).toBe(true); }); }); });