LCOV - code coverage report
Current view: top level - core/api - feed_api.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 138 138 100.0 %
Date: 2021-04-14 08:03:52 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:dio/dio.dart';
       2             : import 'package:stream_feed_dart/src/core/http/stream_http_client.dart';
       3             : import 'package:stream_feed_dart/src/core/http/token.dart';
       4             : import 'package:stream_feed_dart/src/core/models/activity.dart';
       5             : import 'package:stream_feed_dart/src/core/models/activity_update.dart';
       6             : import 'package:stream_feed_dart/src/core/models/feed_id.dart';
       7             : import 'package:stream_feed_dart/src/core/models/follow.dart';
       8             : import 'package:stream_feed_dart/src/core/util/default.dart';
       9             : import 'package:stream_feed_dart/src/core/util/extension.dart';
      10             : import 'package:stream_feed_dart/src/core/util/routes.dart';
      11             : 
      12             : class FeedApi {
      13             :   // TODO: uppercase API?
      14             : 
      15           3 :   const FeedApi(this.client);
      16             : 
      17             :   final StreamHttpClient client;
      18             : 
      19           1 :   Future<List<Activity>> addActivities(
      20             :       Token token, FeedId feed, Iterable<Activity> activities) async {
      21           2 :     checkArgument(activities.isNotEmpty, 'No activities to add');
      22           3 :     final result = await client.post<Map>(
      23           1 :       Routes.buildFeedUrl(feed),
      24           2 :       headers: {'Authorization': '$token'},
      25           1 :       data: {'activities': activities},
      26             :     );
      27           2 :     final data = (result.data!['activities'] as List)
      28           3 :         .map((e) => Activity.fromJson(e))
      29           1 :         .toList(growable: false);
      30             :     return data;
      31             :   }
      32             : 
      33           1 :   Future<Activity> addActivity(
      34             :       Token token, FeedId feed, Activity activity) async {
      35           3 :     final result = await client.post<Map>(
      36           1 :       Routes.buildFeedUrl(feed),
      37           2 :       headers: {'Authorization': '$token'},
      38             :       data: activity,
      39             :     );
      40           2 :     final data = Activity.fromJson(result.data as Map<String, dynamic>?);
      41             :     return data;
      42             :   }
      43             : 
      44           1 :   Future<Response> follow(Token token, Token targetToken, FeedId sourceFeed,
      45             :       FeedId targetFeed, int activityCopyLimit) async {
      46           2 :     checkArgument(sourceFeed != targetFeed, "Feed can't follow itself");
      47           2 :     checkArgument(activityCopyLimit >= 0,
      48             :         'Activity copy limit should be a non-negative number');
      49           1 :     checkArgument(
      50           1 :       activityCopyLimit <= Default.maxActivityCopyLimit,
      51           1 :       'Activity copy limit should be less then ${Default.maxActivityCopyLimit}',
      52             :     );
      53           2 :     return client.post(
      54           1 :       Routes.buildFeedUrl(sourceFeed, 'following'),
      55           2 :       headers: {'Authorization': '$token'},
      56           1 :       data: {
      57           1 :         'target': '$targetFeed',
      58             :         'activity_copy_limit': activityCopyLimit,
      59           1 :         'target_token': '$targetToken',
      60             :       },
      61             :     );
      62             :   }
      63             : 
      64           1 :   Future<Response<Map>> getActivities(
      65             :           Token token, FeedId feed, Map<String, Object?> options) =>
      66           2 :       client.get<Map>(
      67           1 :         Routes.buildFeedUrl(feed),
      68           2 :         headers: {'Authorization': '$token'},
      69             :         queryParameters: options,
      70             :       );
      71             : 
      72           1 :   Future<Response> getEnrichedActivities(
      73             :           //TODO; hmm I think we can type this
      74             :           Token token,
      75             :           FeedId feed,
      76             :           Map<String, Object?> options) =>
      77           2 :       client.get(
      78           1 :         Routes.buildEnrichedFeedUrl(feed),
      79           2 :         headers: {'Authorization': '$token'},
      80             :         queryParameters: options,
      81             :       );
      82             : 
      83           1 :   Future<List<Follow>> getFollowed(Token token, FeedId feed, int limit,
      84             :       int offset, Iterable<FeedId> feedIds) async {
      85           2 :     checkArgument(limit >= 0, 'Limit should be a non-negative number');
      86           2 :     checkArgument(offset >= 0, 'Offset should be a non-negative number');
      87             : 
      88           3 :     final result = await client.get<Map>(
      89           1 :       Routes.buildFeedUrl(feed, 'following'),
      90           2 :       headers: {'Authorization': '$token'},
      91           1 :       queryParameters: {
      92           1 :         'limit': limit,
      93           1 :         'offset': offset,
      94           1 :         if (feedIds.isNotEmpty)
      95           5 :           'filter': feedIds.map((it) => it.toString()).join(',')
      96             :       },
      97             :     );
      98           2 :     final data = (result.data!['results'] as List)
      99           3 :         .map((e) => Follow.fromJson(e))
     100           1 :         .toList(growable: false);
     101             :     return data;
     102             :   }
     103             : 
     104           1 :   Future<List<Follow>> getFollowers(Token token, FeedId feed, int limit,
     105             :       int offset, Iterable<FeedId> feedIds) async {
     106           2 :     checkArgument(limit >= 0, 'Limit should be a non-negative number');
     107           2 :     checkArgument(offset >= 0, 'Offset should be a non-negative number');
     108             : 
     109           3 :     final result = await client.get(
     110           1 :       Routes.buildFeedUrl(feed, 'followers'),
     111           2 :       headers: {'Authorization': '$token'},
     112           1 :       queryParameters: {
     113           1 :         'limit': limit,
     114           1 :         'offset': offset,
     115           1 :         if (feedIds.isNotEmpty)
     116           5 :           'filter': feedIds.map((it) => it.toString()).join(',')
     117             :       },
     118             :     );
     119           2 :     final data = (result.data['results'] as List)
     120           3 :         .map((e) => Follow.fromJson(e))
     121           1 :         .toList(growable: false);
     122             :     return data;
     123             :   }
     124             : 
     125           1 :   Future<Response> removeActivityByForeignId(
     126             :           Token token, FeedId feed, String foreignId) =>
     127           2 :       client.delete(
     128           1 :         Routes.buildFeedUrl(feed, foreignId),
     129           2 :         headers: {'Authorization': '$token'},
     130           1 :         queryParameters: {'foreign_id': '1'},
     131             :       );
     132             : 
     133           1 :   Future<Response> removeActivityById(Token token, FeedId feed, String id) =>
     134           2 :       client.delete(
     135           1 :         Routes.buildFeedUrl(feed, id),
     136           2 :         headers: {'Authorization': '$token'},
     137             :       );
     138             : 
     139           1 :   Future<Response> unfollow(
     140             :           Token token, FeedId source, FeedId target, bool keepHistory) =>
     141           2 :       client.delete(
     142           2 :         Routes.buildFeedUrl(source, 'following/$target'),
     143           2 :         headers: {'Authorization': '$token'},
     144           1 :         queryParameters: {'keep_history': keepHistory},
     145             :       );
     146             : 
     147           1 :   Future<List<Activity>> updateActivitiesByForeignId(
     148             :       Token token, Iterable<ActivityUpdate> updates) async {
     149           2 :     checkArgument(updates.isNotEmpty, 'No updates');
     150           3 :     checkArgument(updates.length <= 100, 'Maximum length is 100');
     151           2 :     for (final update in updates) {
     152           2 :       checkNotNull(update.foreignId, 'No activity to update');
     153           2 :       checkNotNull(update.time, 'Missing timestamp');
     154           3 :       checkArgument(update.set.isNotEmpty || update.unset.isNotEmpty,
     155             :           'No activity properties to set or unset');
     156             :     }
     157           3 :     final result = await client.post<Map>(
     158           1 :       Routes.activityUpdateUrl,
     159           2 :       headers: {'Authorization': '$token'},
     160           1 :       data: {'changes': updates},
     161             :     );
     162           2 :     final data = (result.data!['activities'] as List)
     163           3 :         .map((e) => Activity.fromJson(e))
     164           1 :         .toList(growable: false);
     165             :     return data;
     166             :   }
     167             : 
     168           1 :   Future<List<Activity>> updateActivitiesById(
     169             :       Token token, Iterable<ActivityUpdate> updates) async {
     170           2 :     checkArgument(updates.isNotEmpty, 'No updates');
     171           3 :     checkArgument(updates.length <= 100, 'Maximum length is 100');
     172           2 :     for (final update in updates) {
     173           2 :       checkNotNull(update.id, 'No activity to update');
     174           3 :       checkArgument(update.set.isNotEmpty || update.unset.isNotEmpty,
     175             :           'No activity properties to set or unset');
     176             :     }
     177           3 :     final result = await client.post<Map>(
     178           1 :       Routes.activityUpdateUrl,
     179           2 :       headers: {'Authorization': '$token'},
     180           1 :       data: {'changes': updates},
     181             :     );
     182           2 :     final data = (result.data!['activities'] as List)
     183           3 :         .map((e) => Activity.fromJson(e))
     184           1 :         .toList(growable: false);
     185             :     return data;
     186             :   }
     187             : 
     188           1 :   Future<Activity> updateActivityByForeignId(
     189             :       Token token, ActivityUpdate update) async {
     190           3 :     final result = await client.post<Map>(
     191           1 :       Routes.activityUpdateUrl,
     192           2 :       headers: {'Authorization': '$token'},
     193             :       data: update,
     194             :     );
     195           2 :     final data = Activity.fromJson(result.data as Map<String, dynamic>?);
     196             :     return data;
     197             :   }
     198             : 
     199           1 :   Future<Activity> updateActivityById(
     200             :       Token token, ActivityUpdate update) async {
     201           2 :     checkNotNull(update.foreignId, 'No activity to update');
     202           2 :     checkNotNull(update.time, 'Missing timestamp');
     203           3 :     checkArgument(update.set.isNotEmpty || update.unset.isNotEmpty,
     204             :         'No activity properties to set or unset');
     205           3 :     final result = await client.post<Map>(
     206           1 :       Routes.activityUpdateUrl,
     207           2 :       headers: {'Authorization': '$token'},
     208             :       data: update,
     209             :     );
     210           2 :     final data = Activity.fromJson(result.data as Map<String, dynamic>?);
     211             :     return data;
     212             :   }
     213             : 
     214           1 :   Future<Response> updateActivityToTargets(
     215             :     Token token,
     216             :     FeedId feed,
     217             :     ActivityUpdate update, {
     218             :     Iterable<FeedId> add = const [],
     219             :     Iterable<FeedId> remove = const [],
     220             :     Iterable<FeedId> replace = const [],
     221             :   }) async {
     222           2 :     checkNotNull(update.id, 'No activity to update');
     223           3 :     checkArgument(update.set.isNotEmpty || update.unset.isNotEmpty,
     224             :         'No activity properties to set or unset');
     225           1 :     checkNotNull(
     226           1 :         update.foreignId, 'Activity is required to have foreign ID attribute');
     227           2 :     checkNotNull(update.time, 'Activity is required to have time attribute');
     228           1 :     checkNotNull(add, 'No targets to add');
     229           1 :     checkNotNull(remove, 'No targets to remove');
     230           1 :     checkNotNull(replace, 'No targets to set');
     231             :     final modification =
     232           2 :         replace.isEmpty && (add.isNotEmpty || remove.isNotEmpty);
     233           1 :     final replacement = replace.isNotEmpty && add.isEmpty && remove.isEmpty;
     234           1 :     checkArgument(modification || replacement,
     235             :         "Can't replace and modify activity to targets at the same time");
     236             : 
     237           2 :     return client.post(
     238           1 :       Routes.activityUpdateUrl,
     239           2 :       headers: {'Authorization': '$token'},
     240           1 :       data: {
     241           1 :         'foreign_id': update.foreignId,
     242           2 :         'time': update.time!.toIso8601String(),
     243           4 :         'added_targets': add.map((it) => it.toString()).toList(),
     244           4 :         'removed_targets': remove.map((it) => it.toString()).toList(),
     245           2 :         'new_targets': replace.map((it) => it.toString()).toList(),
     246             :       },
     247             :     );
     248             :   }
     249             : }

Generated by: LCOV version 1.15