VB10 / vexana

Vexana is network manager project with dio.
https://pub.dev/packages/vexana
MIT License
147 stars 42 forks source link

updated response model to return error message if parsed model is null #75

Closed behzodfaiziev closed 1 year ago

behzodfaiziev commented 1 year ago

Case

I faced a problem in a project, where parsed model had wrong type, so the logger printed that it was waiting type of intbut String is received. But in response model error and data were returned as null

      final response =
          await manager.send<ExampleModel, ExampleModel>(
              'anyExampleAPI',
              parseModel: ExampleModel(),
              method: RequestType.GET);

Expected result

After update:

Expected result

behzodfaiziev commented 1 year ago

In order to make sure that if (responseBody is List and it is empty) and returned value is [], I wrote some tests. Since _parseBody was private I had to copy it to test file:

import 'package:flutter_test/flutter_test.dart';
import 'package:vexana/src/utility/custom_logger.dart';
import 'package:vexana/vexana.dart';

import '../json=place=holder/todo.dart';

void main() {
  test('_parseBody single TODO', () async {
    final dynamic responseBody = {"userId": 1};
    final parsedBody = _parseBody<Todo, Todo>(responseBody, Todo());

    expect(parsedBody?.toJson(), Todo(userId: 1).toJson());
  });

  test('_parseBody simple TODO - wrong field', () async {
    final dynamic responseBody = {"ws": 1};
    final parsedBody = _parseBody<Todo, Todo>(responseBody, Todo());

    expect(parsedBody?.toJson(), Todo().toJson());
  });
  test('_parseBody simple TODO - wrong type in userId', () async {
    final dynamic responseBody = {"userId": "1"};

    final parsedBody = _parseBody<Todo, Todo>(responseBody, Todo());

    expect(parsedBody?.toJson(), null);
  });

  /// Making sure that parsed body is []
  test('_parseBody empty list', () async {
    final dynamic responseBody = [];

    final parsedBody = _parseBody<List<Todo>, Todo>(responseBody, Todo());

    expect(parsedBody, []);
  });

  test('_parseBody simple LIST TODO 1 length', () async {
    final dynamic responseBody = [
      {"userId": 1}
    ];

    final parsedBody = _parseBody<List<Todo>, Todo>(responseBody, Todo());
    final expected = Todo(userId: 1);
    expect(parsedBody?[0].toJson(), expected.toJson());
  });

  test('_parseBody simple LIST with wrong type in userId', () async {
    final dynamic responseBody = [
      {"userId": "1"}
    ];

    final parsedBody = _parseBody<List<Todo>, Todo>(responseBody, Todo());

    expect(parsedBody?[0].toJson(), null);
  });
}

/// Set isEnableLogger  true
bool isEnableLogger = true;

/// Copied from network_model_parser.dart
R? _parseBody<R, T extends INetworkModel>(dynamic responseBody, T model) {
  try {
    if (responseBody is List) {
      return responseBody
          .map(
            (data) => model.fromJson(data is Map<String, dynamic> ? data : {}),
      )
          .cast<T>()
          .toList() as R;
    } else if (responseBody is Map<String, dynamic>) {
      return model.fromJson(responseBody) as R;
    } else {
      if (R is EmptyModel || R == EmptyModel) {
        return EmptyModel(name: responseBody.toString()) as R;
      } else {
        CustomLogger(
          isEnabled: isEnableLogger ?? false,
          data: 'Be careful your data $responseBody, I could not parse it',
        );
        return null;
      }
    }
  } catch (e) {
    CustomLogger(
      isEnabled: isEnableLogger ?? false,
      data: 'Parse Error: $e - response body: $responseBody T model: $T , R model: $R ',
    );
  }
  return null;
}
behzodfaiziev commented 1 year ago

Successfully merging this PR will be able to close issue #76