mockIntercept method

FutureOr<Response> mockIntercept(
  1. Request request
)

Implementation

FutureOr<Response> mockIntercept(Request request) async {
  // Collect data from Request
  var action = request.url.path;
  if (request.url.path.contains('/_matrix')) {
    action =
        '${request.url.path.split('/_matrix').last}?${request.url.query}';
  }

  // ignore: avoid_print
  if (_trace) print('called $action');

  if (action.endsWith('?')) {
    action = action.substring(0, action.length - 1);
  }
  if (action.endsWith('?server_name')) {
    // This can be removed after matrix_api_lite is released with:
    // https://gitlab.com/famedly/libraries/matrix_api_lite/-/merge_requests/16
    action = action.substring(0, action.length - 12);
  }
  if (action.endsWith('/')) {
    action = action.substring(0, action.length - 1);
  }
  final method = request.method;
  final dynamic data =
      method == 'GET' ? request.url.queryParameters : request.body;
  dynamic res = {};
  var statusCode = 200;

  //print('\$method request to $action with Data: $data');

  if (!servers.contains(request.url.origin)) {
    return Response(
      '<html><head></head><body>Not found ${request.url.origin}...</body></html>',
      404,
    );
  }

  if (!{
        '/client/v3/refresh',
        '/client/v3/login',
        '/client/v3/register',
      }.contains(action) &&
      expectedAccessToken != null &&
      request.headers['Authorization'] != 'Bearer $expectedAccessToken') {
    return Response(
      jsonEncode({
        'errcode': 'M_UNKNOWN_TOKEN',
        'error': 'Soft logged out',
        'soft_logout': true,
      }),
      401,
    );
  }

  // Call API
  (_calledEndpoints[action] ??= <dynamic>[]).add(data);
  if (request.url.origin ==
          'https://fakeserverpriortoauthmedia.notexisting' &&
      action.contains('/client/versions')) {
    res = {
      'versions': [
        'r0.0.1',
        'ra.b.c',
        'v0.1',
        'v1.1',
        'v1.9',
        'v1.10.1',
      ],
      'unstable_features': {'m.lazy_load_members': true},
    };
  } else {
    final act = api[method]?[action];
    if (act != null) {
      res = act(data);
      if (res is Map && res.containsKey('errcode')) {
        if (res['errcode'] == 'M_NOT_FOUND') {
          statusCode = 404;
        } else {
          statusCode = 405;
        }
      }
    } else if (method == 'PUT' &&
        action.contains('/client/v3/sendToDevice/')) {
      res = {};
      if (_failToDevice) {
        statusCode = 500;
      }
    } else if (method == 'GET' &&
        action.contains('/client/v3/rooms/') &&
        action.contains('/state/m.room.member/') &&
        !action.endsWith('%40alicyy%3Aexample.com') &&
        !action.contains('%40getme')) {
      res = {'displayname': '', 'membership': 'ban'};
    } else if (method == 'PUT' &&
        action.contains(
          '/client/v3/rooms/!1234%3AfakeServer.notExisting/send/',
        )) {
      res = {'event_id': '\$event${_eventCounter++}'};
    } else if (method == 'PUT' &&
        action.contains(
          '/client/v3/rooms/!1234%3AfakeServer.notExisting/state/',
        )) {
      res = {'event_id': '\$event${_eventCounter++}'};
    } else if (action.contains('/client/v3/sync')) {
      // Sync requests with timeout
      final timeout = request.url.queryParameters['timeout'];
      if (timeout != null && timeout != '0') {
        await Future.delayed(Duration(milliseconds: 50));
      }
      res = {
        // So that it is clear which sync we are processing prefix it with 'empty_'
        'next_batch': 'empty_${DateTime.now().millisecondsSinceEpoch}',
        // ensure we don't generate new keys for no reason
        'device_one_time_keys_count': {
          'curve25519': 10,
          'signed_curve25519': 100,
        },
      };
    } else if (method == 'PUT' &&
        _client != null &&
        action.contains('/account_data/') &&
        !action.contains('/rooms/')) {
      final type = Uri.decodeComponent(action.split('/').last);
      final syncUpdate = sdk.SyncUpdate(
        nextBatch: '',
        accountData: [sdk.BasicEvent(content: decodeJson(data), type: type)],
      );
      if (_client?.database != null) {
        await _client?.database?.transaction(() async {
          await _client?.handleSync(syncUpdate);
        });
      } else {
        await _client?.handleSync(syncUpdate);
      }
      res = {};
    } else if (method == 'PUT' &&
        _client != null &&
        action.contains('/account_data/') &&
        action.contains('/rooms/')) {
      final segments = action.split('/');
      final type = Uri.decodeComponent(segments.last);
      final roomId = Uri.decodeComponent(segments[segments.length - 3]);
      final syncUpdate = sdk.SyncUpdate(
        nextBatch: '',
        rooms: RoomsUpdate(
          join: {
            roomId: JoinedRoomUpdate(
              accountData: [
                sdk.BasicRoomEvent(
                  content: decodeJson(data),
                  type: type,
                  roomId: roomId,
                ),
              ],
            ),
          },
        ),
      );
      if (_client?.database != null) {
        await _client?.database?.transaction(() async {
          await _client?.handleSync(syncUpdate);
        });
      } else {
        await _client?.handleSync(syncUpdate);
      }
      res = {};
    } else {
      res = {
        'errcode': 'M_UNRECOGNIZED',
        'error': 'Unrecognized request: $action',
      };
      statusCode = 405;
    }
  }

  unawaited(
    Future.delayed(Duration(milliseconds: 1)).then((_) async {
      _apiCallStream.add(action);
    }),
  );
  return Response.bytes(utf8.encode(json.encode(res)), statusCode);
}