LCOV - code coverage report
Current view: top level - edit_story/bloc - edit_story_bloc.dart (source / functions) Hit Total Coverage
Test: SWE574 - Fall2023 - Group1 - Mobile Test Coverage Lines: 112 122 91.8 %
Date: 2023-12-31 10:28:05 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : // ignore_for_file: avoid_bool_literals_in_conditional_expressions, always_specify_types
       2             : 
       3             : import 'dart:async';
       4             : import 'dart:io';
       5             : 
       6             : import 'package:flutter_map/flutter_map.dart';
       7             : import 'package:equatable/equatable.dart';
       8             : import 'package:flutter_bloc/flutter_bloc.dart';
       9             : import 'package:latlong2/latlong.dart';
      10             : import 'package:memories_app/routes/create_story/model/story_request_model.dart';
      11             : import 'package:memories_app/routes/edit_story/model/edit_story_repository.dart';
      12             : import 'package:memories_app/routes/edit_story/model/edit_story_response_model.dart';
      13             : import 'package:memories_app/routes/story_detail/model/tag_model.dart';
      14             : 
      15             : part 'edit_story_event.dart';
      16             : 
      17             : part 'edit_story_state.dart';
      18             : 
      19             : class _Constants {
      20             :   static const String offlineMessage =
      21             :       'You are currently offline.\n Please check your internet connection!';
      22             : }
      23             : 
      24             : class EditStoryBloc extends Bloc<EditStoryEvent, EditStoryState> {
      25             :   final EditStoryRepository _repository;
      26             : 
      27           1 :   EditStoryBloc({required EditStoryRepository repository})
      28             :       : _repository = repository,
      29           1 :         super(const EditStoryState()) {
      30           2 :     on<EditStoryUpdateStoryEvent>(_updateStoryEvent);
      31           2 :     on<EditStoryErrorPopupClosedEvent>(_onErrorPopupClosed);
      32             :   }
      33             :   late StoryRequestModel storyModel;
      34             : 
      35           1 :   Future<void> _updateStoryEvent(
      36             :       EditStoryUpdateStoryEvent event, Emitter<EditStoryState> emit) async {
      37           2 :     storyModel = _createStoryModel(event);
      38             :     EditStoryResponseModel? response;
      39             :     try {
      40           4 :       response = await _repository.editStory(storyModel, event.id);
      41           0 :     } on SocketException {
      42           0 :       emit(const EditStoryOffline(offlineMessage: _Constants.offlineMessage));
      43             :     } catch (error) {
      44           0 :       emit(EditStoryFailure(error: error.toString()));
      45             :     }
      46             :     if (response != null) {
      47           2 :       if (response.success == true) {
      48           1 :         emit(const EditStorySuccess());
      49             :       } else {
      50           4 :         emit(EditStoryFailure(error: response.msg.toString()));
      51             :       }
      52             :     }
      53             :   }
      54             : 
      55           1 :   void _onErrorPopupClosed(
      56             :       EditStoryErrorPopupClosedEvent event, Emitter<EditStoryState> emit) {
      57           1 :     emit(const EditStoryState());
      58             :   }
      59             : 
      60           1 :   StoryRequestModel _createStoryModel(EditStoryUpdateStoryEvent event) {
      61           3 :     final String dateType = mapDateTypeToValue(event.dateType.toLowerCase());
      62           1 :     StoryRequestModel createStoryModel = StoryRequestModel(
      63           1 :       title: event.title,
      64           1 :       content: event.content,
      65           1 :       storyTags: event.storyTags,
      66           1 :       locationIds: createLocationId(
      67           1 :           event.markersForPoint,
      68           1 :           event.circleMarkers,
      69           1 :           event.polygons,
      70           1 :           event.polyLines,
      71           1 :           event.pointAdresses,
      72           1 :           event.circleAdresses,
      73           1 :           event.polylineAdresses),
      74             :       dateType: dateType,
      75           1 :       date: dateType == "normal_date" ? event.date : null,
      76           1 :       decade: dateType == "decade" ? extractDecade(event.decade) : null,
      77           1 :       endDate: dateType == "interval_date" ? event.endDate : null,
      78           1 :       endYear: dateType == "year_interval" ? event.endYear : null,
      79           1 :       includeTime: _includeTime(dateType, event) ? true : false,
      80           1 :       seasonName: dateType == "year" || dateType == "year_interval"
      81           1 :           ? event.seasonName
      82             :           : null,
      83           1 :       startDate: dateType == "interval_date" ? event.startDate : null,
      84           1 :       startYear: dateType == "year_interval" ? event.startYear : null,
      85           2 :       year: dateType == "year" ? event.year : null,
      86             :     );
      87             :     return createStoryModel;
      88             :   }
      89             : 
      90           1 :   bool _includeTime(String dateType, EditStoryUpdateStoryEvent event) {
      91           1 :     return dateType.contains("normal_date") &&
      92           0 :             (event.startDate != null &&
      93           0 :                 event.startDate!.isNotEmpty &&
      94           0 :                 event.startDate!.contains(" ")) ||
      95           1 :         (event.date != null &&
      96           0 :             event.date!.isNotEmpty &&
      97           0 :             event.date!.contains(" ")) ||
      98           1 :         (event.endDate != null &&
      99           0 :             event.endDate!.isNotEmpty &&
     100           0 :             event.endDate!.contains(" "));
     101             :   }
     102             : 
     103           1 :   List<LocationId> createLocationId(
     104             :       List<Marker>? markersForPoint,
     105             :       List<CircleMarker>? circleMarkers,
     106             :       List<Polygon>? polygons,
     107             :       List<Polyline>? polyLines,
     108             :       List<String>? pointAdresses,
     109             :       List<String>? circleAdresses,
     110             :       List<String>? polylineAdresses) {
     111           1 :     List<LocationId> locationIds = [];
     112           1 :     if (markersForPoint != null && markersForPoint.isNotEmpty) {
     113           1 :       createPointLocations(markersForPoint, pointAdresses, locationIds);
     114             :     }
     115             : 
     116           1 :     if (circleMarkers != null && circleMarkers.isNotEmpty) {
     117           1 :       createCircleLocations(circleMarkers, circleAdresses, locationIds);
     118             :     }
     119           1 :     if (polygons != null && polygons.isNotEmpty) {
     120           1 :       createPolygonLocations(polygons, locationIds);
     121             :     }
     122             : 
     123           1 :     if (polyLines != null && polyLines.isNotEmpty) {
     124           1 :       createPolylineLocations(polyLines, polylineAdresses, locationIds);
     125             :     }
     126             : 
     127             :     return locationIds;
     128             :   }
     129             : 
     130           1 :   void createPolylineLocations(List<Polyline> polyLines,
     131             :       List<String>? polylineAdresses, List<LocationId> locationIds) {
     132           3 :     for (int i = 0; i < polyLines.length; i++) {
     133           1 :       List<List<double>> coordinates = [];
     134             : 
     135           3 :       if (polyLines[i].points.isNotEmpty) {
     136           3 :         for (LatLng point in polyLines[i].points) {
     137           3 :           List<double> coordinatesList = [point.longitude, point.latitude];
     138           1 :           coordinates.add(coordinatesList);
     139             :         }
     140             :       }
     141             : 
     142           1 :       LocationId locationId = LocationId(
     143           1 :         name: polylineAdresses != null && polylineAdresses.isNotEmpty
     144           1 :             ? polylineAdresses[i]
     145             :             : "Address not found",
     146           1 :         line: LineStringLocation(coordinates: coordinates),
     147             :       );
     148             : 
     149           1 :       locationIds.add(locationId);
     150             :     }
     151             :   }
     152             : 
     153           1 :   void createPolygonLocations(
     154             :       List<Polygon> polygons, List<LocationId> locationIds) {
     155           3 :     for (int i = 0; i < polygons.length; i++) {
     156           1 :       List<List<List<double>>> coordinates = [];
     157             : 
     158           3 :       if (polygons[i].points.isNotEmpty) {
     159           1 :         List<List<double>> singlePolygon = [];
     160             : 
     161           3 :         LatLng firstPoint = polygons[i].points.first;
     162           1 :         List<double> firstCoordinates = [
     163           1 :           firstPoint.longitude,
     164           1 :           firstPoint.latitude
     165             :         ];
     166             : 
     167           3 :         for (LatLng point in polygons[i].points) {
     168           3 :           List<double> coordinatesList = [point.longitude, point.latitude];
     169           1 :           singlePolygon.add(coordinatesList);
     170             :         }
     171             : 
     172             :         // Add the first coordinate again to close the polygon
     173           1 :         singlePolygon.add(firstCoordinates);
     174             : 
     175           1 :         coordinates.add(singlePolygon);
     176             :       }
     177             : 
     178           1 :       LocationId polygon = LocationId(
     179           2 :         name: polygons[i].label ?? "Address not found",
     180           1 :         polygon: PolygonLocation(coordinates: coordinates),
     181             :       );
     182             : 
     183           1 :       locationIds.add(polygon);
     184             :     }
     185             :   }
     186             : 
     187           1 :   void createCircleLocations(List<CircleMarker> circleMarkers,
     188             :       List<String>? circleAdresses, List<LocationId> locationIds) {
     189           3 :     for (int i = 0; i < circleMarkers.length; i++) {
     190           1 :       LocationId circleLocation = LocationId(
     191           1 :         name: circleAdresses != null && circleAdresses.isNotEmpty
     192           1 :             ? circleAdresses[i]
     193             :             : "Adress not found",
     194           1 :         circle: PointLocation(
     195           1 :           coordinates: [
     196           3 :             circleMarkers[i].point.longitude,
     197           3 :             circleMarkers[i].point.latitude
     198             :           ],
     199             :         ),
     200           4 :         radius: double.parse((circleMarkers[i].radius).toStringAsFixed(10)),
     201             :       );
     202           1 :       locationIds.add(circleLocation);
     203             :     }
     204             :   }
     205             : 
     206           1 :   void createPointLocations(List<Marker> markersForPoint,
     207             :       List<String>? pointAdresses, List<LocationId> locationIds) {
     208           3 :     for (int i = 0; i < markersForPoint.length; i++) {
     209           1 :       LocationId pointLocation = LocationId(
     210           1 :         name: pointAdresses != null && pointAdresses.isNotEmpty
     211           1 :             ? pointAdresses[i]
     212             :             : "Adress not found",
     213           1 :         point: PointLocation(
     214           1 :           coordinates: [
     215           3 :             markersForPoint[i].point.longitude,
     216           3 :             markersForPoint[i].point.latitude
     217             :           ],
     218             :         ),
     219             :       );
     220           1 :       locationIds.add(pointLocation);
     221             :     }
     222             :   }
     223             : 
     224           1 :   int? extractDecade(String? decade) {
     225           1 :     if (decade == null || decade.isEmpty) {
     226             :       return null;
     227             :     }
     228             : 
     229             :     // Remove trailing 's' and parse the remaining part as an integer
     230           3 :     String numericPart = decade.substring(0, decade.length - 1);
     231           1 :     return int.tryParse(numericPart);
     232             :   }
     233             : 
     234           1 :   String mapDateTypeToValue(String selectedDateType) {
     235           1 :     switch (selectedDateType.toLowerCase()) {
     236           1 :       case "year":
     237             :         return "year";
     238           1 :       case "interval year":
     239             :         return "year_interval";
     240           1 :       case "normal date":
     241             :         return "normal_date";
     242           1 :       case "interval date":
     243             :         return "interval_date";
     244           1 :       case "decade":
     245             :         return "decade";
     246             :       default:
     247             :         return "year";
     248             :     }
     249             :   }
     250             : }
     251             : 
     252             : enum StoryDateType {
     253             :   year,
     254             :   yearInterval,
     255             :   normalDate,
     256             :   intervalDate,
     257             :   decade,
     258             : }

Generated by: LCOV version 1.14