Some checks failed
CI / analyze-and-test (push) Has been cancelled
- speedBoostEndMs: elapsedMs(게임 시간) → DateTime.now()(실제 시간) - autoReviveEndMs: elapsedMs → DateTime.now() - MonetizationState: isAutoReviveActive/isSpeedBoostActive 실제 시간 기준 - 5배속에서 5분 버프가 1분에 만료되던 문제 해결 - bossLevelingEndTime은 이미 DateTime.now() 기준 (변경 불필요)
230 lines
7.6 KiB
Dart
230 lines
7.6 KiB
Dart
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(), isFalse);
|
|
});
|
|
|
|
test('종료 시점이 미래면 true 반환', () {
|
|
final futureMs =
|
|
DateTime.now().millisecondsSinceEpoch + 60000; // 1분 후
|
|
final state = MonetizationState.initial().copyWith(
|
|
autoReviveEndMs: futureMs,
|
|
);
|
|
|
|
expect(state.isAutoReviveActive(), isTrue);
|
|
});
|
|
|
|
test('종료 시점이 과거면 false 반환', () {
|
|
final pastMs =
|
|
DateTime.now().millisecondsSinceEpoch - 1000; // 1초 전
|
|
final state = MonetizationState.initial().copyWith(
|
|
autoReviveEndMs: pastMs,
|
|
);
|
|
|
|
expect(state.isAutoReviveActive(), isFalse);
|
|
});
|
|
|
|
test('종료 시점이 현재와 거의 같으면 false 반환 (경계값)', () {
|
|
final nowMs = DateTime.now().millisecondsSinceEpoch - 1;
|
|
final state = MonetizationState.initial().copyWith(
|
|
autoReviveEndMs: nowMs,
|
|
);
|
|
|
|
expect(state.isAutoReviveActive(), isFalse);
|
|
});
|
|
});
|
|
|
|
// =========================================================================
|
|
// isSpeedBoostActive 테스트
|
|
// =========================================================================
|
|
|
|
group('isSpeedBoostActive', () {
|
|
test('유료 사용자는 항상 true 반환', () {
|
|
final state = MonetizationState.initial(isPaidUser: true);
|
|
|
|
// speedBoostEndMs가 null이어도 유료 사용자는 항상 활성
|
|
expect(state.isSpeedBoostActive(), isTrue);
|
|
});
|
|
|
|
test('무료 사용자 - 종료 시점이 미래면 true 반환', () {
|
|
final futureMs =
|
|
DateTime.now().millisecondsSinceEpoch + 60000;
|
|
final state = MonetizationState.initial().copyWith(
|
|
speedBoostEndMs: futureMs,
|
|
);
|
|
|
|
expect(state.isSpeedBoostActive(), isTrue);
|
|
});
|
|
|
|
test('무료 사용자 - 종료 시점이 과거면 false 반환', () {
|
|
final pastMs =
|
|
DateTime.now().millisecondsSinceEpoch - 1000;
|
|
final state = MonetizationState.initial().copyWith(
|
|
speedBoostEndMs: pastMs,
|
|
);
|
|
|
|
expect(state.isSpeedBoostActive(), isFalse);
|
|
});
|
|
|
|
test('무료 사용자 - speedBoostEndMs가 null이면 false 반환', () {
|
|
final state = MonetizationState.initial();
|
|
|
|
expect(state.isSpeedBoostActive(), 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);
|
|
});
|
|
});
|
|
});
|
|
}
|