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

Generated by: LCOV version 1.14