import 'package:flutter_test/flutter_test.dart'; import 'package:ponshu_room_lite/models/sake_item.dart'; void main() { group('SakeItem - Construction', () { test('should create SakeItem with required fields', () { final sake = SakeItem( id: 'test-001', displayData: DisplayData( name: '獺祭 純米大吟醸', brewery: '旭酒造', prefecture: '山口県', imagePaths: ['/path/to/image.jpg'], ), hiddenSpecs: HiddenSpecs( description: 'フルーティーで華やかな香りが特徴', tasteStats: {'aroma': 5, 'sweetness': 3, 'acidity': 2, 'bitterness': 2, 'body': 3}, flavorTags: ['フルーティー', '華やか'], ), ); expect(sake.id, 'test-001'); expect(sake.displayData.name, '獺祭 純米大吟醸'); expect(sake.displayData.brewery, '旭酒造'); expect(sake.displayData.prefecture, '山口県'); expect(sake.displayData.imagePaths.length, 1); }); test('should create SakeItem with default values for optional fields', () { final sake = SakeItem( id: 'test-002', displayData: DisplayData( name: 'テスト銘柄', brewery: 'テスト蔵元', prefecture: '東京都', imagePaths: [], ), ); expect(sake.hiddenSpecs.tasteStats, isEmpty); expect(sake.hiddenSpecs.flavorTags, isEmpty); expect(sake.userData.isFavorite, false); expect(sake.userData.isUserEdited, false); }); }); group('SakeItem - DisplayData getters', () { test('should use primary name when sakenowa data is not set', () { final sake = SakeItem( id: 'test-003', displayData: DisplayData( name: 'AI解析名', brewery: 'AI蔵元', prefecture: 'AI県', imagePaths: [], ), ); expect(sake.displayData.displayName, 'AI解析名'); expect(sake.displayData.displayBrewery, 'AI蔵元'); expect(sake.displayData.displayPrefecture, 'AI県'); expect(sake.displayData.hasSakenowaData, false); }); test('should prioritize sakenowa data over primary data', () { final sake = SakeItem( id: 'test-004', displayData: DisplayData( name: 'AI解析名', brewery: 'AI蔵元', prefecture: 'AI県', imagePaths: [], sakenowaName: 'さけのわ統一名', sakenowaBrewery: 'さけのわ蔵元', sakenowaPrefecture: 'さけのわ県', ), ); expect(sake.displayData.displayName, 'さけのわ統一名'); expect(sake.displayData.displayBrewery, 'さけのわ蔵元'); expect(sake.displayData.displayPrefecture, 'さけのわ県'); expect(sake.displayData.hasSakenowaData, true); }); }); group('SakeItem - copyWith', () { late SakeItem baseSake; setUp(() { baseSake = SakeItem( id: 'test-005', displayData: DisplayData( name: '元の銘柄', brewery: '元の蔵元', prefecture: '元の県', imagePaths: ['/path/original.jpg'], catchCopy: '元のキャッチコピー', ), hiddenSpecs: HiddenSpecs( description: '元の説明', tasteStats: {'aroma': 3, 'sweetness': 3, 'acidity': 3, 'bitterness': 3, 'body': 3}, flavorTags: ['元のタグ'], ), ); }); test('should update name while keeping other fields', () { final updated = baseSake.copyWith(name: '新しい銘柄'); expect(updated.displayData.name, '新しい銘柄'); expect(updated.displayData.brewery, '元の蔵元'); expect(updated.displayData.prefecture, '元の県'); expect(updated.id, 'test-005'); }); test('should update tasteStats while keeping other fields', () { final newStats = {'aroma': 5, 'sweetness': 1, 'acidity': 4, 'sharpness': 2, 'body': 5}; final updated = baseSake.copyWith(tasteStats: newStats); expect(updated.hiddenSpecs.tasteStats, newStats); expect(updated.displayData.name, '元の銘柄'); }); test('should update favorite status', () { final updated = baseSake.copyWith(isFavorite: true); expect(updated.userData.isFavorite, true); expect(updated.displayData.name, '元の銘柄'); }); test('should update imagePaths', () { final newPaths = ['/path/new1.jpg', '/path/new2.jpg']; final updated = baseSake.copyWith(imagePaths: newPaths); expect(updated.displayData.imagePaths, newPaths); expect(updated.displayData.imagePaths.length, 2); }); }); group('SakeItem - HiddenSpecs / TasteStats', () { test('should return SakeTasteStats from tasteStats map', () { final sake = SakeItem( id: 'test-006', displayData: DisplayData( name: 'テスト', brewery: 'テスト蔵', prefecture: 'テスト県', imagePaths: [], ), hiddenSpecs: HiddenSpecs( description: '', tasteStats: {'aroma': 5, 'sweetness': 3, 'acidity': 2, 'bitterness': 4, 'body': 1}, flavorTags: [], ), ); final stats = sake.hiddenSpecs.sakeTasteStats; expect(stats.aroma, 5); expect(stats.sweetness, 3); expect(stats.acidity, 2); expect(stats.bitterness, 4); expect(stats.body, 1); }); test('should return zero stats for empty tasteStats', () { final sake = SakeItem( id: 'test-007', displayData: DisplayData( name: 'テスト', brewery: 'テスト蔵', prefecture: 'テスト県', imagePaths: [], ), hiddenSpecs: HiddenSpecs( description: '', tasteStats: {}, flavorTags: [], ), ); final stats = sake.hiddenSpecs.sakeTasteStats; expect(stats.aroma, 0); expect(stats.sweetness, 0); expect(stats.acidity, 0); expect(stats.bitterness, 0); expect(stats.body, 0); }); }); }