Files
lunchpick/test/unit/domain/usecases/recommendation_engine_test.dart
2025-11-19 16:36:39 +09:00

193 lines
5.8 KiB
Dart

@Skip(
'RecommendationEngine tests temporarily disabled pending deterministic fixtures',
)
import 'package:flutter_test/flutter_test.dart';
import 'package:lunchpick/domain/usecases/recommendation_engine.dart';
import 'package:lunchpick/domain/entities/restaurant.dart';
import 'package:lunchpick/domain/entities/visit_record.dart';
import 'package:lunchpick/domain/entities/user_settings.dart';
import 'package:uuid/uuid.dart';
void main() {
late RecommendationEngine engine;
late List<Restaurant> testRestaurants;
late List<VisitRecord> testVisitRecords;
setUp(() {
engine = RecommendationEngine();
// 테스트용 맛집 데이터 생성
testRestaurants = [
Restaurant(
id: '1',
name: '가까운 한식당',
category: '한식',
subCategory: '백반',
roadAddress: '서울 중구 세종대로 110',
jibunAddress: '서울 중구 태평로1가 31',
latitude: 37.5666,
longitude: 126.9784,
source: DataSource.USER_INPUT,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
visitCount: 0,
),
Restaurant(
id: '2',
name: '먼 중식당',
category: '중식',
subCategory: '짜장면',
roadAddress: '서울 강남구 테헤란로 123',
jibunAddress: '서울 강남구 역삼동 123',
latitude: 37.5012,
longitude: 127.0396,
source: DataSource.USER_INPUT,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
visitCount: 0,
),
Restaurant(
id: '3',
name: '최근 방문한 일식당',
category: '일식',
subCategory: '스시',
roadAddress: '서울 종로구 종로 123',
jibunAddress: '서울 종로구 종로1가 123',
latitude: 37.5702,
longitude: 126.9842,
source: DataSource.USER_INPUT,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
visitCount: 1,
),
];
// 테스트용 방문 기록 생성
testVisitRecords = [
VisitRecord(
id: const Uuid().v4(),
restaurantId: '3',
visitDate: DateTime.now().subtract(const Duration(days: 2)),
isConfirmed: true,
createdAt: DateTime.now(),
),
];
});
group('RecommendationEngine', () {
test('거리 필터링이 정상 작동해야 함', () async {
final config = RecommendationConfig(
userLatitude: 37.5665,
userLongitude: 126.9780,
maxDistance: 1.0, // 1km
selectedCategories: [],
userSettings: UserSettings(),
);
final result = await engine.generateRecommendation(
allRestaurants: testRestaurants,
recentVisits: [],
config: config,
);
// 1km 이내의 맛집만 추천되어야 함
expect(result, isNotNull);
expect(result!.id, isIn(['1', '3'])); // 가까운 한식당과 일식당만
expect(result.id, isNot('2')); // 먼 중식당은 제외
});
test('재방문 방지가 정상 작동해야 함', () async {
final settings = UserSettings();
final updatedSettings = settings.copyWith(revisitPreventionDays: 7);
final config = RecommendationConfig(
userLatitude: 37.5665,
userLongitude: 126.9780,
maxDistance: 10.0, // 10km
selectedCategories: [],
userSettings: updatedSettings,
);
final result = await engine.generateRecommendation(
allRestaurants: testRestaurants,
recentVisits: testVisitRecords,
config: config,
);
// 최근 방문한 일식당은 제외되어야 함
expect(result, isNotNull);
expect(result!.id, isNot('3'));
});
test('카테고리 필터링이 정상 작동해야 함', () async {
final config = RecommendationConfig(
userLatitude: 37.5665,
userLongitude: 126.9780,
maxDistance: 100.0, // 100km
selectedCategories: ['한식'],
userSettings: UserSettings(),
);
final result = await engine.generateRecommendation(
allRestaurants: testRestaurants,
recentVisits: [],
config: config,
);
// 한식만 추천되어야 함
expect(result, isNotNull);
expect(result!.category, '한식');
});
test('모든 조건을 만족하는 맛집이 없으면 null을 반환해야 함', () async {
final config = RecommendationConfig(
userLatitude: 37.5665,
userLongitude: 126.9780,
maxDistance: 0.1, // 100m - 너무 가까움
selectedCategories: [],
userSettings: UserSettings(),
);
final result = await engine.generateRecommendation(
allRestaurants: testRestaurants,
recentVisits: [],
config: config,
);
expect(result, isNull);
});
test('가중치 시스템이 정상 작동해야 함', () async {
// 한식에 높은 가중치 부여
final settings = UserSettings();
final updatedSettings = settings.copyWith(
categoryWeights: {'한식': 2.0, '중식': 0.5, '일식': 1.0},
);
final config = RecommendationConfig(
userLatitude: 37.5665,
userLongitude: 126.9780,
maxDistance: 100.0,
selectedCategories: [],
userSettings: updatedSettings,
);
// 여러 번 실행하여 한식이 더 자주 추천되는지 확인
final results = <String, int>{};
for (int i = 0; i < 100; i++) {
final result = await engine.generateRecommendation(
allRestaurants: testRestaurants,
recentVisits: [],
config: config,
);
if (result != null) {
results[result.category] = (results[result.category] ?? 0) + 1;
}
}
// 한식이 다른 카테고리보다 더 많이 추천되어야 함
expect(results['한식'] ?? 0, greaterThan(results['중식'] ?? 0));
});
});
}