198 lines
6.4 KiB
Dart
198 lines
6.4 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:mockito/mockito.dart';
|
|
import 'package:mockito/annotations.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:lanebow/services/subscription_service.dart';
|
|
import 'package:lanebow/models/subscription_model.dart';
|
|
import 'package:lanebow/config/api_config.dart';
|
|
import 'package:lanebow/services/in_app_purchase_service.dart';
|
|
|
|
// 모킹 클래스 생성
|
|
@GenerateMocks([http.Client, InAppPurchaseService])
|
|
import 'subscription_service_test.mocks.dart';
|
|
|
|
void main() {
|
|
late SubscriptionService subscriptionService;
|
|
late MockClient mockClient;
|
|
late MockInAppPurchaseService mockPurchaseService;
|
|
final testToken = 'test_token';
|
|
final testClubId = 'test_club_id';
|
|
final testUserId = 'test_user_id';
|
|
|
|
// 테스트 구독 데이터
|
|
final testSubscription = {
|
|
'id': 'test_subscription_id',
|
|
'userId': testUserId,
|
|
'clubId': testClubId,
|
|
'planType': 'premium',
|
|
'status': 'active',
|
|
'startDate': DateTime.now().toIso8601String(),
|
|
'endDate': DateTime.now().add(Duration(days: 30)).toIso8601String(),
|
|
'price': 19900.0,
|
|
'currency': 'KRW',
|
|
'autoRenew': true,
|
|
'features': {
|
|
'maxMembers': 100,
|
|
'maxEvents': 100,
|
|
},
|
|
'paymentMethod': 'card',
|
|
'transactionId': 'test_transaction_id',
|
|
'createdAt': DateTime.now().subtract(Duration(days: 10)).toIso8601String(),
|
|
'updatedAt': DateTime.now().toIso8601String(),
|
|
};
|
|
|
|
// 테스트 구독 플랜 데이터
|
|
final testPlans = [
|
|
{
|
|
'type': 'basic',
|
|
'name': '기본',
|
|
'description': '중소규모 클럽을 위한 확장 기능',
|
|
'monthlyPrice': 9900.0,
|
|
'yearlyPrice': 99000.0,
|
|
'currency': 'KRW',
|
|
'features': [
|
|
'최대 30명 회원 관리',
|
|
'상세 점수 분석',
|
|
'이벤트 관리',
|
|
'회원 통계',
|
|
],
|
|
'maxMembers': 30,
|
|
'maxEvents': 20,
|
|
'hasAdvancedStats': true,
|
|
'hasCustomization': false,
|
|
'hasPriority': false,
|
|
},
|
|
{
|
|
'type': 'premium',
|
|
'name': '프리미엄',
|
|
'description': '대규모 클럽을 위한 고급 기능',
|
|
'monthlyPrice': 19900.0,
|
|
'yearlyPrice': 199000.0,
|
|
'currency': 'KRW',
|
|
'features': [
|
|
'무제한 회원 관리',
|
|
'고급 통계 및 분석',
|
|
'무제한 이벤트',
|
|
'맞춤형 보고서',
|
|
'우선 지원',
|
|
],
|
|
'maxMembers': 100,
|
|
'maxEvents': 100,
|
|
'hasAdvancedStats': true,
|
|
'hasCustomization': true,
|
|
'hasPriority': true,
|
|
}
|
|
];
|
|
|
|
setUp(() {
|
|
// HTTP 클라이언트 모킹
|
|
mockClient = MockClient();
|
|
|
|
// InAppPurchaseService 모킹
|
|
mockPurchaseService = MockInAppPurchaseService();
|
|
|
|
// HTTP 클라이언트 요청 모킹
|
|
when(mockClient.post(
|
|
any,
|
|
headers: anyNamed('headers'),
|
|
body: anyNamed('body'),
|
|
)).thenAnswer((_) async => http.Response(jsonEncode(testSubscription), 200));
|
|
|
|
when(mockClient.get(
|
|
any,
|
|
headers: anyNamed('headers'),
|
|
)).thenAnswer((_) async => http.Response(jsonEncode(testPlans), 200));
|
|
|
|
// 모킹 서비스에 대한 기본 동작 정의
|
|
when(mockPurchaseService.isLoading).thenReturn(false);
|
|
when(mockPurchaseService.error).thenReturn(null);
|
|
when(mockPurchaseService.products).thenReturn([]);
|
|
when(mockPurchaseService.restorePurchases()).thenAnswer((_) async => true);
|
|
|
|
// SubscriptionService 초기화 - 테스트용 생성자 사용
|
|
subscriptionService = SubscriptionService.forTest(
|
|
client: mockClient,
|
|
purchaseService: mockPurchaseService,
|
|
userId: testUserId,
|
|
token: testToken,
|
|
clubId: testClubId,
|
|
);
|
|
});
|
|
|
|
group('SubscriptionService 기본 기능 테스트', () {
|
|
test('SubscriptionService 초기화 테스트', () {
|
|
// 초기화 후 기본 상태 확인
|
|
expect(subscriptionService, isNotNull);
|
|
expect(subscriptionService.currentSubscription, isNull);
|
|
expect(subscriptionService.isLoading, isNotNull);
|
|
expect(subscriptionService.availablePlans, isNotNull);
|
|
});
|
|
|
|
test('loadCurrentSubscription 메서드가 현재 구독 정보를 가져와야 함', () async {
|
|
// given
|
|
when(mockClient.post(
|
|
any,
|
|
headers: anyNamed('headers'),
|
|
body: anyNamed('body'),
|
|
)).thenAnswer((_) async => http.Response(jsonEncode(testSubscription), 200));
|
|
|
|
// when
|
|
await subscriptionService.loadCurrentSubscription();
|
|
|
|
// then
|
|
expect(subscriptionService.currentSubscription, isNotNull);
|
|
expect(subscriptionService.isLoading, isFalse);
|
|
expect(subscriptionService.error, isNull);
|
|
});
|
|
|
|
test('canUseFeature 메서드가 기능 사용 가능 여부를 확인해야 함', () {
|
|
// 구독이 없는 경우 기능 사용 가능 여부 확인
|
|
expect(subscriptionService.canUseFeature('advancedStats'), isA<bool>());
|
|
});
|
|
|
|
test('getMaxMembers 메서드가 최대 회원 수를 반환해야 함', () {
|
|
// 구독이 없는 경우 기본 무료 플랜의 최대 회원 수 반환
|
|
final maxMembers = subscriptionService.getMaxMembers();
|
|
expect(maxMembers, isNotNull);
|
|
expect(maxMembers, isA<int>());
|
|
});
|
|
|
|
test('getMaxEvents 메서드가 최대 이벤트 수를 반환해야 함', () {
|
|
// 구독이 없는 경우 기본 무료 플랜의 최대 이벤트 수 반환
|
|
final maxEvents = subscriptionService.getMaxEvents();
|
|
expect(maxEvents, isNotNull);
|
|
expect(maxEvents, isA<int>());
|
|
});
|
|
|
|
test('purchaseService getter가 null이 아니어야 함', () {
|
|
expect(subscriptionService.purchaseService, isNotNull);
|
|
});
|
|
|
|
test('hasSubscription getter가 동작해야 함', () {
|
|
expect(subscriptionService.hasSubscription, isA<bool>());
|
|
});
|
|
|
|
test('isActive getter가 동작해야 함', () {
|
|
expect(subscriptionService.isActive, isA<bool>());
|
|
});
|
|
|
|
test('restoreSubscriptions 메서드가 구독을 복원해야 함', () async {
|
|
// given
|
|
when(mockPurchaseService.restorePurchases()).thenAnswer((_) async => true);
|
|
when(mockClient.post(
|
|
any,
|
|
headers: anyNamed('headers'),
|
|
body: anyNamed('body'),
|
|
)).thenAnswer((_) async => http.Response(jsonEncode(testSubscription), 200));
|
|
|
|
// when
|
|
final result = await subscriptionService.restoreSubscriptions();
|
|
|
|
// then
|
|
expect(result, isTrue);
|
|
expect(subscriptionService.isLoading, isFalse);
|
|
});
|
|
});
|
|
}
|