import 'package:asciineverdie/src/core/model/monetization_state.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('MonetizationState', () { // ========================================================================= // initial 팩토리(factory) 테스트 // ========================================================================= group('initial', () { test('무료 사용자(free user) 기본 상태', () { final state = MonetizationState.initial(); expect(state.undoRemaining, equals(1)); expect(state.adRemovalPurchased, isFalse); expect(state.rollsRemaining, equals(5)); expect(state.pendingChests, equals(0)); expect(state.rollHistory, isNull); }); test('유료 사용자(paid user) 기본 상태', () { final state = MonetizationState.initial(isPaidUser: true); expect(state.undoRemaining, equals(3)); expect(state.adRemovalPurchased, isTrue); expect(state.rollsRemaining, equals(5)); expect(state.pendingChests, equals(0)); }); }); // ========================================================================= // isPaidUser / isFreeUser 게터(getter) 테스트 // ========================================================================= group('isPaidUser / isFreeUser', () { test('광고 제거 구매 시 isPaidUser true', () { final state = MonetizationState.initial(isPaidUser: true); expect(state.isPaidUser, isTrue); expect(state.isFreeUser, isFalse); }); test('광고 제거 미구매 시 isFreeUser true', () { final state = MonetizationState.initial(); expect(state.isPaidUser, isFalse); expect(state.isFreeUser, isTrue); }); }); // ========================================================================= // isAutoReviveActive 테스트 // ========================================================================= group('isAutoReviveActive', () { test('autoReviveEndMs가 null이면 false 반환', () { final state = MonetizationState.initial(); expect(state.isAutoReviveActive(1000), isFalse); }); test('elapsedMs가 종료 시점 이내면 true 반환', () { final state = MonetizationState.initial().copyWith( autoReviveEndMs: 5000, ); expect(state.isAutoReviveActive(3000), isTrue); }); test('elapsedMs가 종료 시점을 초과하면 false 반환', () { final state = MonetizationState.initial().copyWith( autoReviveEndMs: 5000, ); expect(state.isAutoReviveActive(6000), isFalse); }); test('elapsedMs가 종료 시점과 정확히 같으면 false 반환 (경계값)', () { final state = MonetizationState.initial().copyWith( autoReviveEndMs: 5000, ); expect(state.isAutoReviveActive(5000), isFalse); }); }); // ========================================================================= // isSpeedBoostActive 테스트 // ========================================================================= group('isSpeedBoostActive', () { test('유료 사용자는 항상 true 반환', () { final state = MonetizationState.initial(isPaidUser: true); // speedBoostEndMs가 null이어도 유료 사용자는 항상 활성 expect(state.isSpeedBoostActive(0), isTrue); expect(state.isSpeedBoostActive(999999), isTrue); }); test('무료 사용자 - 종료 시점 이내면 true 반환', () { final state = MonetizationState.initial().copyWith( speedBoostEndMs: 10000, ); expect(state.isSpeedBoostActive(5000), isTrue); }); test('무료 사용자 - 종료 시점 초과 시 false 반환', () { final state = MonetizationState.initial().copyWith( speedBoostEndMs: 10000, ); expect(state.isSpeedBoostActive(15000), isFalse); }); test('무료 사용자 - speedBoostEndMs가 null이면 false 반환', () { final state = MonetizationState.initial(); expect(state.isSpeedBoostActive(1000), isFalse); }); }); // ========================================================================= // isLuckyCharmActive 테스트 // ========================================================================= group('isLuckyCharmActive', () { test('종료 시점 이내면 true 반환', () { final state = MonetizationState.initial().copyWith( luckyCharmEndMs: 8000, ); expect(state.isLuckyCharmActive(4000), isTrue); }); test('종료 시점 초과 시 false 반환', () { final state = MonetizationState.initial().copyWith( luckyCharmEndMs: 8000, ); expect(state.isLuckyCharmActive(9000), isFalse); }); test('luckyCharmEndMs가 null이면 false 반환', () { final state = MonetizationState.initial(); expect(state.isLuckyCharmActive(1000), isFalse); }); }); // ========================================================================= // canRoll 테스트 // ========================================================================= group('canRoll', () { test('rollsRemaining > 0이면 true 반환', () { final state = MonetizationState.initial(); // rollsRemaining=5 expect(state.canRoll, isTrue); }); test('rollsRemaining == 0이면 false 반환', () { final state = MonetizationState.initial().copyWith(rollsRemaining: 0); expect(state.canRoll, isFalse); }); }); // ========================================================================= // maxChests 테스트 // ========================================================================= group('maxChests', () { test('유료 사용자는 최대 10개', () { final state = MonetizationState.initial(isPaidUser: true); expect(state.maxChests, equals(10)); }); test('무료 사용자는 최대 5개', () { final state = MonetizationState.initial(); expect(state.maxChests, equals(5)); }); }); // ========================================================================= // isChestsFull 테스트 // ========================================================================= group('isChestsFull', () { test('무료 사용자 - pendingChests가 maxChests 이상이면 true', () { final state = MonetizationState.initial().copyWith(pendingChests: 5); expect(state.isChestsFull, isTrue); }); test('무료 사용자 - pendingChests가 maxChests 미만이면 false', () { final state = MonetizationState.initial().copyWith(pendingChests: 3); expect(state.isChestsFull, isFalse); }); test('유료 사용자 - pendingChests가 maxChests 이상이면 true', () { final state = MonetizationState.initial( isPaidUser: true, ).copyWith(pendingChests: 10); expect(state.isChestsFull, isTrue); }); test('유료 사용자 - pendingChests가 maxChests 초과해도 true', () { final state = MonetizationState.initial( isPaidUser: true, ).copyWith(pendingChests: 12); expect(state.isChestsFull, isTrue); }); }); }); }