invokeApiWithDelegate method

Future<Response> invokeApiWithDelegate(
  1. APIProvider delegate,
  2. BuildContext context,
  3. YamlMap api,
  4. DataContext eContext,
  5. String apiName,
)

Implementation

Future<Response> invokeApiWithDelegate(
  APIProvider delegate,
  BuildContext context,
  YamlMap api,
  DataContext eContext,
  String apiName,
) async {
  final String type;
  final delegateTypeStr = delegate.runtimeType.toString();
  if (delegateTypeStr.contains('Firestore')) {
    type = 'firestore';
  } else if (delegateTypeStr.contains('Functions') ||
      delegateTypeStr.contains('Function')) {
    type = 'functions';
  } else {
    type = 'api';
  }

  final String? resolvedUrl;
  if (type == 'firestore') {
    final rawPath = api['path'] ?? api['firestore']?['path'] ?? '';
    resolvedUrl = eContext.eval(rawPath)?.toString();
  } else if (type == 'functions') {
    final rawName = api['name'] ?? api['function']?['name'] ?? '';
    resolvedUrl = eContext.eval(rawName)?.toString();
  } else {
    final rawUrl = api['url'] ?? api['uri'] ?? '';
    resolvedUrl = HTTPAPIProvider.resolveUrl(eContext, rawUrl.toString());
  }

  final rawHeaders = api['headers'] ??
      api['firestore']?['headers'] ??
      api['function']?['headers'];
  final rawParams = api['parameters'] ??
      api['query'] ??
      api['firestore']?['parameters'] ??
      api['firestore']?['query'] ??
      api['function']?['parameters'] ??
      api['function']?['query'];
  final rawBody = api['body'] ??
      api['data'] ??
      api['firestore']?['body'] ??
      api['firestore']?['data'] ??
      api['function']?['body'] ??
      api['function']?['data'];

  final resolvedHeaders =
      _resolveValue(rawHeaders, eContext) as Map<String, dynamic>?;
  final resolvedParameters =
      _resolveValue(rawParams, eContext) as Map<String, dynamic>?;
  final resolvedBody = _resolveValue(rawBody, eContext);

  final stepIndex = stepIndexProvider?.call();
  final forced = _forcedExceptions[apiName];
  if (forced != null) {
    recorder.record(APICallRecord(
      name: apiName,
      apiDefinition: api,
      timestamp: DateTime.now(),
      stepIndex: stepIndex,
      mocked: false,
      error: forced.toString(),
      type: type,
      resolvedUrl: resolvedUrl,
      resolvedHeaders: resolvedHeaders,
      resolvedParameters: resolvedParameters,
      resolvedBody: resolvedBody,
    ));
    throw forced;
  }

  final record = APICallRecord(
    name: apiName,
    apiDefinition: api,
    timestamp: DateTime.now(),
    stepIndex: stepIndex,
    type: type,
    resolvedUrl: resolvedUrl,
    resolvedHeaders: resolvedHeaders,
    resolvedParameters: resolvedParameters,
    resolvedBody: resolvedBody,
  );
  recorder.record(record);

  final mock = _mocks[apiName];
  if (mock == null) {
    final response = await _invokeLiveDelegate(
      delegate,
      context,
      api,
      eContext,
      apiName,
    );
    _completeRecord(record, response, mocked: false);
    return response;
  }

  final response = _nextMockResponse(apiName, mock);
  if (response.delayMs != null && response.delayMs! > 0) {
    await Future<void>.delayed(Duration(milliseconds: response.delayMs!));
  }

  if (delegate is HTTPAPIProvider) {
    final runtimeResponse = await delegate.invokeMockAPI(
        eContext, _toRuntimeMockResponse(response));
    _completeRecord(record, runtimeResponse, mocked: true);
    return runtimeResponse;
  }
  final runtimeResponse = HttpResponse.fromBody(
    response.body,
    response.headers,
    response.statusCode,
    null,
    APIState.success,
  );
  _completeRecord(record, runtimeResponse, mocked: true);
  return runtimeResponse;
}