createDataDataSourceTest method

void createDataDataSourceTest(
  1. String pathTestPage,
  2. String featureName,
  3. String pageName,
  4. List<Map<String, String>> resultModelUnitTest,
)

Implementation

void createDataDataSourceTest(
  String pathTestPage,
  String featureName,
  String pageName,
  List<Map<String, String>> resultModelUnitTest,
) {
  final path = join(pathTestPage, 'data', 'datasources');
  DirectoryHelper.createDir(path);
  join(path, '${pageName}_remote_data_source_test.dart').write(
      '''// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, unused_import, unused_local_variable, require_trailing_commas, prefer_single_quotes, prefer_double_quotes

import 'dart:convert';
${resultModelUnitTest.any((element) => element['returnData'] == 'body_bytes') ? '''import 'dart:typed_data';''' : ''}

import 'package:${featureName.snakeCase}/$pageName/data/datasources/${pageName}_remote_data_source.dart';
${resultModelUnitTest.map((e) => '''import 'package:${featureName.snakeCase}/$pageName/data/models/body/${e['apiName']?.snakeCase}_body.dart' as body_${e['apiName']?.snakeCase};
${isReturnDataModel(e['returnData']!) ? '''import 'package:${featureName.snakeCase}/$pageName/data/models/response/${e['apiName']?.snakeCase}_response.dart' as response_${e['apiName']?.snakeCase};''' : ''}''').join('\n')}
import 'package:core/core.dart';
import 'package:dev_dependency_manager/dev_dependency_manager.dart';

class MockMorphemeHttp extends Mock implements MorphemeHttp {}

Future<void> main() async {
initializeDateFormatting();

late MockMorphemeHttp http;
late ${pageName.pascalCase}RemoteDataSource remoteDataSource;

${resultModelUnitTest.map((e) => '''${e['endpoint']}
${getConstOrFinalValue(e['body'] ?? '')} body${e['apiName']?.pascalCase} = ${e['body']}''').join('\n')}

setUp(() {
  http = MockMorphemeHttp();
  remoteDataSource = ${pageName.pascalCase}RemoteDataSourceImpl(http: http);
});

${resultModelUnitTest.map((e) {
    final className = e['apiName']?.pascalCase;
    final methodName = e['apiName']?.camelCase;
    final returnData = e['returnData'] ?? 'model';

    final isMultipart =
        e['method']?.toLowerCase().contains('multipart') ?? false;
    final isSse = e['method']?.toLowerCase().contains('sse') ?? false;
    final httpMethod = isMultipart
        ? e['method'] == 'multipart'
            ? 'postMultipart'
            : e['method']
        : e['method'];
    final header = e['header']?.isEmpty ?? true ? '' : '${e['header']},';
    final body = (e['isBodyList'] == 'true' && !isMultipart)
        ? 'jsonEncode(body$className.map((e) => e.toMap()).toList()),'
        : 'body$className.toMap()${isMultipart ? '.map((key, value) => MapEntry(key, value.toString()))' : ''},';
    final cacheStrategy = e['cacheStrategy']?.isEmpty ?? true
        ? null
        : CacheStrategy.fromString(e['cacheStrategy']!);
    final ttl =
        e['ttl']?.isEmpty ?? true ? null : int.tryParse(e['ttl'] ?? '');
    final keepExpiredCache = e['keepExpiredCache']?.isEmpty ?? true
        ? null
        : e['keepExpiredCache'] == 'true';

    final paramCacheStrategy = isSse || isMultipart
        ? ''
        : cacheStrategy.toParamCacheStrategyTest(
            ttl: ttl, keepExpiredCache: keepExpiredCache);

    final expectSuccess = switch (returnData) {
      'header' => '''expect(result, isA<Map<String, String>>());''',
      'body_bytes' => '''expect(result, isA<Uint8List>());''',
      'body_string' => '''expect(result, isA<String>());''',
      'status_code' => '''expect(result, isA<int>());''',
      'raw' => '''expect(result, isA<Response>());''',
      'model' =>
        '''expect(result, isA<${'response_${className?.snakeCase}'}.${className}Response>());''',
      _ => "''",
    };

    final isCreateTest = whenMethodHttp<bool>(
      httpMethod ?? '',
      onStream: () => false,
      onFuture: () => true,
    );

    if (!isCreateTest) {
      return '';
    }

    return '''group('$className Api Remote Data Source', () {
  test(
    'should peform fetch & return response',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenAnswer((_) async => Response('{}', 200));
      // act
      final result = await remoteDataSource.$methodName(body$className);
      // assert
      verify(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy));
      $expectSuccess
    },
  );

  test(
    'should throw a RedirectionException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(RedirectionException(statusCode: 300, jsonBody: '{}'));
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<RedirectionException>()));
    },
  );

  test(
    'should throw a ClientException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(ClientException(statusCode: 400, jsonBody: '{}'));
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<ClientException>()));
    },
  );

  test(
    'should throw a ServerException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(ServerException(statusCode: 500, jsonBody: '{}'));
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<ServerException>()));
    },
  );

  test(
    'should throw a TimeoutException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(TimeoutException());
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<TimeoutException>()));
    },
  );

  test(
    'should throw a UnauthorizedException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(UnauthorizedException(statusCode: 401, jsonBody: '{}'));
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<UnauthorizedException>()));
    },
  );

  test(
    'should throw a RefreshTokenException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(RefreshTokenException(statusCode: 401, jsonBody: '{}'));
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<RefreshTokenException>()));
    },
  );

  test(
    'should throw a NoInternetException when the server error',
    () async {
      // arrange
      when(() => http.$httpMethod(url$className, body: $body$header$paramCacheStrategy)).thenThrow(NoInternetException());
      // act
      final call = remoteDataSource.$methodName;
      // assert
      expect(() => call(body$className), throwsA(isA<NoInternetException>()));
    },
  );
});
''';
  }).join('\n')}
}''');

  StatusHelper.generated(
      join(path, '${pageName}_remote_data_source_test.dart'));
}