LCOV - code coverage report
Current view: top level - app\data\datasources\local\favorites_service.dart - favorites_service.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 34 100.0 %
Date: Wed Aug 6 23:43:55 2025 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : 
       3             : import 'dts_user_pref.dart';
       4             : 
       5             : import '../../../domain/entities/models/mdl_the_movie.dart';
       6             : 
       7             : /// Service for managing favorite movies using [SharedPreferences].
       8             : ///
       9             : /// The [FavoritesService] class provides methods to store, retrieve, and manage favorite movies locally.
      10             : /// Movies are persisted as JSON strings in [SharedPreferences] via [UserPref].
      11             : ///
      12             : /// ### Usage
      13             : /// Create an instance by passing a [UserPref] object, then use the provided methods to manage favorites.
      14             : ///
      15             : /// ### Methods
      16             : /// - [getFavoriteMovies]: Returns all favorite movies as a list of [TheMovie].
      17             : /// - [addToFavorites]: Adds a movie to favorites.
      18             : /// - [removeFromFavorites]: Removes a movie from favorites by ID.
      19             : /// - [isFavorite]: Checks if a movie is in favorites.
      20             : /// - [toggleFavorite]: Adds or removes a movie depending on its current state.
      21             : /// - [getFavoritesCount]: Returns the count of favorite movies.
      22             : /// - [clearAllFavorites]: Removes all favorites.
      23             : /// - [getFavoriteIds]: Returns a set of favorite movie IDs.
      24             : ///
      25             : /// ### Example
      26             : /// ```dart
      27             : /// final service = FavoritesService(UserPref());
      28             : /// await service.addToFavorites(movie);
      29             : /// final favorites = await service.getFavoriteMovies();
      30             : /// print(favorites.length);
      31             : /// ```
      32             : class FavoritesService {
      33           2 :   FavoritesService(this._userPref);
      34             : 
      35             :   /// SharedPreferences instance
      36             :   final UserPref _userPref;
      37             : 
      38             :   /// Key for storing favorite movies in SharedPreferences
      39             :   static const String _favoritesKey = 'favorite_movies';
      40             : 
      41             :   /// Get all favorite movies.
      42             :   ///
      43             :   /// **Returns:**
      44             :   /// - A `Future` that resolves to a list of `TheMovie` objects.
      45           1 :   Future<List<TheMovie>> getFavoriteMovies() async {
      46             :     try {
      47           2 :       final List<String> favoritesJson = _userPref.favorites;
      48             : 
      49             :       return favoritesJson
      50           3 :           .map((movieJson) => TheMovie.fromRaw(movieJson))
      51           1 :           .toList();
      52             :     } catch (e) {
      53             :       // If there's an error parsing, return empty list
      54           1 :       return [];
      55             :     }
      56             :   }
      57             : 
      58             :   /// Add a movie to favorites.
      59             :   ///
      60             :   /// **Parameters:**
      61             :   /// - `movie` (TheMovie): The movie to add to favorites.
      62             :   ///
      63             :   /// **Returns:**
      64             :   /// - A `Future` that resolves to `true` if the movie was added successfully, or `false` if it was already in favorites.
      65           1 :   Future<bool> addToFavorites(TheMovie movie) async {
      66             :     try {
      67           1 :       final List<TheMovie> favorites = await getFavoriteMovies();
      68             : 
      69             :       /// Check if movie is already in favorites
      70           5 :       if (favorites.any((favMovie) => favMovie.id == movie.id)) {
      71             :         return false; // Already in favorites
      72             :       }
      73             : 
      74             :       /// Add movie to favorites
      75           1 :       favorites.add(movie);
      76           1 :       await _saveFavorites(favorites);
      77             :       return true;
      78             :     } catch (e) {
      79             :       return false;
      80             :     }
      81             :   }
      82             : 
      83             :   /// Remove a movie from favorites.
      84             :   ///
      85             :   /// **Parameters:**
      86             :   /// - `movieId` (int): The ID of the movie to remove.
      87             :   ///
      88             :   /// **Returns:**
      89             :   /// - A `Future` that resolves to `true` if the movie was removed successfully, or `false` otherwise.
      90           1 :   Future<bool> removeFromFavorites(int movieId) async {
      91             :     try {
      92           1 :       final List<TheMovie> favorites = await getFavoriteMovies();
      93             : 
      94             :       /// Remove movie with matching ID
      95           4 :       favorites.removeWhere((movie) => movie.id == movieId);
      96           1 :       await _saveFavorites(favorites);
      97             :       return true;
      98             :     } catch (e) {
      99             :       return false;
     100             :     }
     101             :   }
     102             : 
     103             :   /// Check if a movie is in favorites.
     104             :   ///
     105             :   /// **Parameters:**
     106             :   /// - `movieId` (int): The ID of the movie to check.
     107             :   ///
     108             :   /// **Returns:**
     109             :   /// - A `Future` that resolves to `true` if the movie is in favorites, or `false` otherwise.
     110           1 :   Future<bool> isFavorite(int movieId) async {
     111             :     try {
     112           1 :       final List<TheMovie> favorites = await getFavoriteMovies();
     113           4 :       return favorites.any((movie) => movie.id == movieId);
     114             :     } catch (e) {
     115             :       return false;
     116             :     }
     117             :   }
     118             : 
     119             :   /// Toggle favorite status of a movie.
     120             :   ///
     121             :   /// **Parameters:**
     122             :   /// - `movie` (TheMovie): The movie to toggle.
     123             :   ///
     124             :   /// **Returns:**
     125             :   /// - A `Future` that resolves to `true` if the movie was added to favorites, or `false` if it was removed.
     126           1 :   Future<bool> toggleFavorite(TheMovie movie) async {
     127           2 :     final bool isCurrentlyFavorite = await isFavorite(movie.id);
     128             : 
     129             :     if (isCurrentlyFavorite) {
     130           2 :       return await removeFromFavorites(movie.id);
     131             :     } else {
     132           1 :       return await addToFavorites(movie);
     133             :     }
     134             :   }
     135             : 
     136             :   /// Get count of favorite movies.
     137             :   ///
     138             :   /// **Returns:**
     139             :   /// - A `Future` that resolves to the count of favorite movies.
     140           1 :   Future<int> getFavoritesCount() async {
     141           1 :     final List<TheMovie> favorites = await getFavoriteMovies();
     142           1 :     return favorites.length;
     143             :   }
     144             : 
     145             :   /// Clear all favorites.
     146             :   ///
     147             :   /// **Returns:**
     148             :   /// - A `Future` that resolves to `true` if all favorites were cleared successfully, or `false` otherwise.
     149           1 :   Future<bool> clearAllFavorites() async {
     150             :     try {
     151           3 :       _userPref.favorites.remove(_favoritesKey);
     152             :       return true;
     153             :     } catch (e) {
     154             :       return false;
     155             :     }
     156             :   }
     157             : 
     158             :   /// Private method to save favorites list to SharedPreferences.
     159             :   ///
     160             :   /// **Parameters:**
     161             :   /// - `favorites` (List<TheMovie>): The list of favorite movies to save.
     162           1 :   Future<void> _saveFavorites(List<TheMovie> favorites) async {
     163             :     final List<String> favoritesJson = favorites
     164           4 :         .map((movie) => json.encode(movie.toMap()))
     165           1 :         .toList();
     166             : 
     167           2 :     _userPref.favorites = favoritesJson;
     168             :   }
     169             : 
     170             :   /// Get favorite movie IDs only (for quick checks).
     171             :   ///
     172             :   /// **Returns:**
     173             :   /// - A `Future` that resolves to a `Set` of movie IDs.
     174           1 :   Future<Set<int>> getFavoriteIds() async {
     175             :     try {
     176           1 :       final List<TheMovie> favorites = await getFavoriteMovies();
     177           4 :       return favorites.map((movie) => movie.id).toSet();
     178             :     } catch (e) {
     179             :       return <int>{};
     180             :     }
     181             :   }
     182             : }

Generated by: LCOV version 1.15.alpha0w