@@ -1150,6 +1150,307 @@ void main() {
11501150 });
11511151 });
11521152
1153+ group ('My Festival methods' , () {
1154+ test ('getFavoriteStatus returns status from repository' , () async {
1155+ provider = BeerProvider (
1156+ drinkRepository: mockDrinkRepository,
1157+ festivalRepository: mockFestivalRepository,
1158+ analyticsService: mockAnalyticsService,
1159+ );
1160+ await provider.initialize ();
1161+
1162+ final sampleDrinks = createSampleDrinks ();
1163+ when (mockDrinkRepository.getDrinks (any))
1164+ .thenAnswer ((_) async => sampleDrinks);
1165+ await provider.loadDrinks ();
1166+
1167+ when (mockDrinkRepository.getFavoriteStatus (any, any))
1168+ .thenAnswer ((_) async => 'want_to_try' );
1169+
1170+ final status = await provider.getFavoriteStatus (sampleDrinks[0 ]);
1171+ expect (status, 'want_to_try' );
1172+ verify (mockDrinkRepository.getFavoriteStatus ('cbf2025' , 'drink-1' )).called (1 );
1173+ });
1174+
1175+ test ('getFavoriteStatus returns null when no repository' , () async {
1176+ provider = BeerProvider (
1177+ drinkRepository: mockDrinkRepository,
1178+ festivalRepository: mockFestivalRepository,
1179+ analyticsService: mockAnalyticsService,
1180+ );
1181+
1182+ final drink = createSampleDrinks ()[0 ];
1183+ final status = await provider.getFavoriteStatus (drink);
1184+ expect (status, isNull);
1185+ });
1186+
1187+ test ('getTryCount returns count from repository' , () async {
1188+ provider = BeerProvider (
1189+ drinkRepository: mockDrinkRepository,
1190+ festivalRepository: mockFestivalRepository,
1191+ analyticsService: mockAnalyticsService,
1192+ );
1193+ await provider.initialize ();
1194+
1195+ final sampleDrinks = createSampleDrinks ();
1196+ when (mockDrinkRepository.getDrinks (any))
1197+ .thenAnswer ((_) async => sampleDrinks);
1198+ await provider.loadDrinks ();
1199+
1200+ when (mockDrinkRepository.getTryCount (any, any))
1201+ .thenAnswer ((_) async => 3 );
1202+
1203+ final count = await provider.getTryCount (sampleDrinks[0 ]);
1204+ expect (count, 3 );
1205+ verify (mockDrinkRepository.getTryCount ('cbf2025' , 'drink-1' )).called (1 );
1206+ });
1207+
1208+ test ('getTryCount returns 0 when no repository' , () async {
1209+ provider = BeerProvider (
1210+ drinkRepository: mockDrinkRepository,
1211+ festivalRepository: mockFestivalRepository,
1212+ analyticsService: mockAnalyticsService,
1213+ );
1214+
1215+ final drink = createSampleDrinks ()[0 ];
1216+ final count = await provider.getTryCount (drink);
1217+ expect (count, 0 );
1218+ });
1219+
1220+ test ('markAsTasted updates drink state and notifies listeners' , () async {
1221+ provider = BeerProvider (
1222+ drinkRepository: mockDrinkRepository,
1223+ festivalRepository: mockFestivalRepository,
1224+ analyticsService: mockAnalyticsService,
1225+ );
1226+ await provider.initialize ();
1227+
1228+ final sampleDrinks = createSampleDrinks ();
1229+ when (mockDrinkRepository.getDrinks (any))
1230+ .thenAnswer ((_) async => sampleDrinks);
1231+ await provider.loadDrinks ();
1232+
1233+ when (mockDrinkRepository.markAsTasted (any, any))
1234+ .thenAnswer ((_) async {});
1235+ when (mockDrinkRepository.getTryCount (any, any))
1236+ .thenAnswer ((_) async => 1 );
1237+
1238+ final drink = sampleDrinks[0 ];
1239+ expect (drink.isFavorite, isFalse);
1240+
1241+ var notified = false ;
1242+ provider.addListener (() {
1243+ notified = true ;
1244+ });
1245+
1246+ await provider.markAsTasted (drink);
1247+
1248+ expect (drink.isFavorite, isTrue);
1249+ expect (notified, isTrue);
1250+ verify (mockDrinkRepository.markAsTasted ('cbf2025' , 'drink-1' )).called (1 );
1251+ });
1252+
1253+ test ('markAsTasted logs first tasting event' , () async {
1254+ provider = BeerProvider (
1255+ drinkRepository: mockDrinkRepository,
1256+ festivalRepository: mockFestivalRepository,
1257+ analyticsService: mockAnalyticsService,
1258+ );
1259+ await provider.initialize ();
1260+
1261+ final sampleDrinks = createSampleDrinks ();
1262+ when (mockDrinkRepository.getDrinks (any))
1263+ .thenAnswer ((_) async => sampleDrinks);
1264+ await provider.loadDrinks ();
1265+
1266+ when (mockDrinkRepository.markAsTasted (any, any))
1267+ .thenAnswer ((_) async {});
1268+ when (mockDrinkRepository.getTryCount (any, any))
1269+ .thenAnswer ((_) async => 1 );
1270+
1271+ await provider.markAsTasted (sampleDrinks[0 ]);
1272+
1273+ await Future .delayed (const Duration (milliseconds: 10 ));
1274+
1275+ verify (mockAnalyticsService.logFestivalLogMarkTasted ('drink-1' , 1 )).called (1 );
1276+ verifyNever (mockAnalyticsService.logFestivalLogMultipleTasting (any, any));
1277+ });
1278+
1279+ test ('markAsTasted logs multiple tasting event when count > 1' , () async {
1280+ provider = BeerProvider (
1281+ drinkRepository: mockDrinkRepository,
1282+ festivalRepository: mockFestivalRepository,
1283+ analyticsService: mockAnalyticsService,
1284+ );
1285+ await provider.initialize ();
1286+
1287+ final sampleDrinks = createSampleDrinks ();
1288+ when (mockDrinkRepository.getDrinks (any))
1289+ .thenAnswer ((_) async => sampleDrinks);
1290+ await provider.loadDrinks ();
1291+
1292+ when (mockDrinkRepository.markAsTasted (any, any))
1293+ .thenAnswer ((_) async {});
1294+ when (mockDrinkRepository.getTryCount (any, any))
1295+ .thenAnswer ((_) async => 3 );
1296+
1297+ await provider.markAsTasted (sampleDrinks[0 ]);
1298+
1299+ await Future .delayed (const Duration (milliseconds: 10 ));
1300+
1301+ verify (mockAnalyticsService.logFestivalLogMultipleTasting ('drink-1' , 3 )).called (1 );
1302+ verifyNever (mockAnalyticsService.logFestivalLogMarkTasted (any, any));
1303+ });
1304+
1305+ test ('markAsTasted does nothing when no repository' , () async {
1306+ provider = BeerProvider (
1307+ drinkRepository: null ,
1308+ festivalRepository: mockFestivalRepository,
1309+ analyticsService: mockAnalyticsService,
1310+ );
1311+
1312+ final drink = createSampleDrinks ()[0 ];
1313+ final initialFavorite = drink.isFavorite;
1314+
1315+ await provider.markAsTasted (drink);
1316+
1317+ expect (drink.isFavorite, initialFavorite);
1318+ });
1319+
1320+ test ('deleteTry removes timestamp and updates drink state' , () async {
1321+ provider = BeerProvider (
1322+ drinkRepository: mockDrinkRepository,
1323+ festivalRepository: mockFestivalRepository,
1324+ analyticsService: mockAnalyticsService,
1325+ );
1326+ await provider.initialize ();
1327+
1328+ final sampleDrinks = createSampleDrinks ();
1329+ when (mockDrinkRepository.getDrinks (any))
1330+ .thenAnswer ((_) async => sampleDrinks);
1331+ await provider.loadDrinks ();
1332+
1333+ final timestamp = DateTime .now ();
1334+ when (mockDrinkRepository.deleteTry (any, any, any))
1335+ .thenAnswer ((_) async {});
1336+ when (mockDrinkRepository.getFavoriteStatus (any, any))
1337+ .thenAnswer ((_) async => 'tasted' );
1338+
1339+ final drink = sampleDrinks[0 ];
1340+ drink.isFavorite = true ;
1341+
1342+ var notified = false ;
1343+ provider.addListener (() {
1344+ notified = true ;
1345+ });
1346+
1347+ await provider.deleteTry (drink, timestamp);
1348+
1349+ expect (drink.isFavorite, isTrue);
1350+ expect (notified, isTrue);
1351+ verify (mockDrinkRepository.deleteTry ('cbf2025' , 'drink-1' , timestamp)).called (1 );
1352+ });
1353+
1354+ test ('deleteTry updates isFavorite to false when status becomes null' , () async {
1355+ provider = BeerProvider (
1356+ drinkRepository: mockDrinkRepository,
1357+ festivalRepository: mockFestivalRepository,
1358+ analyticsService: mockAnalyticsService,
1359+ );
1360+ await provider.initialize ();
1361+
1362+ final sampleDrinks = createSampleDrinks ();
1363+ when (mockDrinkRepository.getDrinks (any))
1364+ .thenAnswer ((_) async => sampleDrinks);
1365+ await provider.loadDrinks ();
1366+
1367+ final timestamp = DateTime .now ();
1368+ when (mockDrinkRepository.deleteTry (any, any, any))
1369+ .thenAnswer ((_) async {});
1370+ when (mockDrinkRepository.getFavoriteStatus (any, any))
1371+ .thenAnswer ((_) async => null );
1372+
1373+ final drink = sampleDrinks[0 ];
1374+ drink.isFavorite = true ;
1375+
1376+ await provider.deleteTry (drink, timestamp);
1377+
1378+ expect (drink.isFavorite, isFalse);
1379+ });
1380+
1381+ test ('deleteTry reapplies filters when showing favorites only' , () async {
1382+ provider = BeerProvider (
1383+ drinkRepository: mockDrinkRepository,
1384+ festivalRepository: mockFestivalRepository,
1385+ analyticsService: mockAnalyticsService,
1386+ );
1387+ await provider.initialize ();
1388+
1389+ final sampleDrinks = createSampleDrinks ();
1390+ when (mockDrinkRepository.getDrinks (any))
1391+ .thenAnswer ((_) async => sampleDrinks);
1392+ await provider.loadDrinks ();
1393+
1394+ // Mark first drink as favorite
1395+ sampleDrinks[0 ].isFavorite = true ;
1396+ provider.setShowFavoritesOnly (true );
1397+
1398+ final timestamp = DateTime .now ();
1399+ when (mockDrinkRepository.deleteTry (any, any, any))
1400+ .thenAnswer ((_) async {});
1401+ when (mockDrinkRepository.getFavoriteStatus (any, any))
1402+ .thenAnswer ((_) async => null );
1403+
1404+ expect (provider.drinks.length, 1 );
1405+
1406+ await provider.deleteTry (sampleDrinks[0 ], timestamp);
1407+
1408+ expect (provider.drinks.length, 0 );
1409+ });
1410+
1411+ test ('deleteTry logs analytics event' , () async {
1412+ provider = BeerProvider (
1413+ drinkRepository: mockDrinkRepository,
1414+ festivalRepository: mockFestivalRepository,
1415+ analyticsService: mockAnalyticsService,
1416+ );
1417+ await provider.initialize ();
1418+
1419+ final sampleDrinks = createSampleDrinks ();
1420+ when (mockDrinkRepository.getDrinks (any))
1421+ .thenAnswer ((_) async => sampleDrinks);
1422+ await provider.loadDrinks ();
1423+
1424+ final timestamp = DateTime .now ();
1425+ when (mockDrinkRepository.deleteTry (any, any, any))
1426+ .thenAnswer ((_) async {});
1427+ when (mockDrinkRepository.getFavoriteStatus (any, any))
1428+ .thenAnswer ((_) async => 'tasted' );
1429+
1430+ await provider.deleteTry (sampleDrinks[0 ], timestamp);
1431+
1432+ await Future .delayed (const Duration (milliseconds: 10 ));
1433+
1434+ verify (mockAnalyticsService.logFestivalLogDeleteTimestamp ('drink-1' )).called (1 );
1435+ });
1436+
1437+ test ('deleteTry does nothing when no repository' , () async {
1438+ provider = BeerProvider (
1439+ drinkRepository: null ,
1440+ festivalRepository: mockFestivalRepository,
1441+ analyticsService: mockAnalyticsService,
1442+ );
1443+
1444+ final drink = createSampleDrinks ()[0 ];
1445+ drink.isFavorite = true ;
1446+ final timestamp = DateTime .now ();
1447+
1448+ await provider.deleteTry (drink, timestamp);
1449+
1450+ expect (drink.isFavorite, isTrue);
1451+ });
1452+ });
1453+
11531454 group ('automatic refresh' , () {
11541455 test ('isDrinksDataStale returns true when no data loaded' , () {
11551456 provider = BeerProvider (
0 commit comments