// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:angel3_mock_request/angel3_mock_request.dart';
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/common_server_api.dart';
import 'package:dart_services/src/common_server_impl.dart';
import 'package:dart_services/src/protos/dart_services.pb.dart' as proto;
import 'package:dart_services/src/sdk.dart';
import 'package:dart_services/src/server_cache.dart';
import 'package:logging/logging.dart';
import 'package:protobuf/protobuf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart';

const preFormattedCode = r'''
void main()
{
int i = 0;
}
''';

const postFormattedCode = r'''
void main() {
  int i = 0;
}
''';

const formatBadCode = r'''
void main()
{
  print('foo')
}
''';

void main() => defineTests();

void defineTests() {
  late CommonServerApi commonServerApi;
  late CommonServerImpl commonServerImpl;

  Future<MockHttpResponse> sendPostRequest(
    String path,
    GeneratedMessage? message,
  ) async {
    final uri = Uri.parse('/api/$path');
    final request = MockHttpRequest('POST', uri);
    request.headers.add('content-type', jsonContentType);
    if (message != null) {
      request.add(utf8.encode(json.encode(message.toProto3Json())));
    }
    await request.close();
    await shelf_io.handleRequest(request, commonServerApi.router.call);
    return request.response;
  }

  Future<MockHttpResponse> sendGetRequest(
    String path,
  ) async {
    final uri = Uri.parse('/api/$path');
    final request = MockHttpRequest('GET', uri);
    request.headers.add('content-type', jsonContentType);
    await request.close();
    await shelf_io.handleRequest(request, commonServerApi.router.call);
    return request.response;
  }

  group('CommonServerProto JSON', () {
    final sdk =
        Sdk.create(Platform.environment['FLUTTER_CHANNEL'] ?? stableChannel);
    setUpAll(() async {
      final cache = MockCache();
      commonServerImpl = CommonServerImpl(cache, sdk);
      commonServerApi = CommonServerApi(commonServerImpl);
      await commonServerImpl.init();

      // Some piece of initialization doesn't always happen fast enough for this
      // request to work in time for the test. So try it here until the server
      // returns something valid.
      // TODO(jcollins-g): determine which piece of initialization isn't
      // happening and deal with that in warmup/init.
      {
        var decodedJson = <dynamic, dynamic>{};
        final jsonData = proto.SourceRequest()..source = sampleCodeError;
        while (decodedJson.isEmpty) {
          final response =
              await sendPostRequest('dartservices/v2/analyze', jsonData);
          expect(response.statusCode, 200);
          expect(response.headers['content-type'],
              ['application/json; charset=utf-8']);
          final data = await response.transform(utf8.decoder).join();
          decodedJson = json.decode(data) as Map<dynamic, dynamic>;
        }
      }
    });

    tearDownAll(() async {
      await commonServerImpl.shutdown();
    });

    setUp(() {
      log.onRecord.listen((LogRecord rec) {
        print('${rec.level.name}: ${rec.time}: ${rec.message}');
      });
    });

    tearDown(log.clearListeners);

    test('analyze Dart', () async {
      final request = proto.SourceRequest()..source = sampleCode;
      final response =
          await sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, isEmpty);
    });

    test('analyze Flutter', () async {
      final request = proto.SourceRequest()..source = sampleCodeFlutter;
      final response =
          await sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, ['flutter']);
    });

    test('analyze errors', () async {
      final request = proto.SourceRequest()..source = sampleCodeError;
      late proto.AnalysisResults reply;
      final response =
          await sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 200);
      expect(response.headers['content-type'],
          ['application/json; charset=utf-8']);
      final data = json.decode(await response.transform(utf8.decoder).join());
      reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, hasLength(1));
      expect(reply.issues[0].kind, 'error');
      expect(reply.issues[0].line, 2);
      expect(reply.issues[0].sourceName, 'main.dart');
      expect(reply.issues[0].message, "Expected to find ';'.");
      expect(reply.issues[0].hasFixes, true);
      expect(reply.issues[0].charStart, 29);
      expect(reply.issues[0].charLength, 1);
    });

    test('analyze negative-test noSource', () async {
      final request = proto.SourceRequest();
      final response =
          await sendPostRequest('dartservices/v2/analyze', request);
      expect(response.statusCode, 400);
    });

    test('compile', () async {
      final request = proto.CompileRequest()..source = sampleCode;
      final response =
          await sendPostRequest('dartservices/v2/compile', request);

      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('compile error', () async {
      final request = proto.CompileRequest()..source = sampleCodeError;
      final response =
          await sendPostRequest('dartservices/v2/compile', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, contains('Error: Expected'));
    });

    test('compile negative-test noSource', () async {
      final request = proto.CompileRequest();
      final response =
          await sendPostRequest('dartservices/v2/compile', request);
      expect(response.statusCode, 400);
    });

    test('compileDDC', () async {
      final request = proto.CompileRequest()..source = sampleCode;
      final response =
          await sendPostRequest('dartservices/v2/compileDDC', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('complete', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 1;
      final response =
          await sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.completions, isNotEmpty);
    });

    test('complete no data', () async {
      final request = await sendPostRequest(
          'dartservices/v2/complete', proto.SourceRequest());
      expect(request.statusCode, 400);
    });

    test('complete param missing', () async {
      final request = proto.SourceRequest()..offset = 1;
      final response =
          await sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'source\'');
    });

    test('complete param missing 2', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}';
      final response =
          await sendPostRequest('dartservices/v2/complete', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'offset\'');
    });

    test('document', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 17;
      final response =
          await sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isNotEmpty);
    });

    test('document little data', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 2;
      final response =
          await sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('document no data', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}'
        ..offset = 12;
      final response =
          await sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('document negative-test noSource', () async {
      final request = proto.SourceRequest()..offset = 12;
      final response =
          await sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 400);
    });

    test('document negative-test noOffset', () async {
      final request = proto.SourceRequest()
        ..source = 'void main() {print("foo");}';
      final response =
          await sendPostRequest('dartservices/v2/document', request);
      expect(response.statusCode, 400);
    });

    test('format', () async {
      final request = proto.SourceRequest()..source = preFormattedCode;
      final response = await sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, postFormattedCode);
    });

    test('format bad code', () async {
      final request = proto.SourceRequest()..source = formatBadCode;
      final response = await sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, formatBadCode);
    });

    test('format position', () async {
      final request = proto.SourceRequest()
        ..source = preFormattedCode
        ..offset = 21;
      final response = await sendPostRequest('dartservices/v2/format', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FormatResponse()..mergeFromProto3Json(data);
      expect(reply.newString, postFormattedCode);
      expect(reply.offset, 24);
    });

    test('fix', () async {
      final quickFixesCode = '''
import 'dart:async';
void main() {
  int i = 0;
}
''';
      final request = proto.SourceRequest()
        ..source = quickFixesCode
        ..offset = 10;
      final response = await sendPostRequest('dartservices/v2/fixes', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      final fixes = reply.fixes;
      expect(fixes.length, 1);
      final problemAndFix = fixes[0];
      expect(problemAndFix.problemMessage, isNotNull);
    });

    test('fixes completeness', () async {
      final request = proto.SourceRequest()
        ..source = '''
void main() {
  for (int i = 0; i < 4; i++) {
    print('hello \$i')
  }
}
'''
        ..offset = 67;
      final response = await sendPostRequest('dartservices/v2/fixes', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      expect(reply.fixes[0].fixes[0].message, "Insert ';'");
      expect(reply.fixes[0].fixes[0].edits[0].offset, 67);
      expect(reply.fixes[0].fixes[0].edits[0].length, 0);
      expect(reply.fixes[0].fixes[0].edits[0].replacement, ';');
      expect(reply.fixes[0].problemMessage, "Expected to find ';'.");
      expect(reply.fixes[0].offset, 66);
      expect(reply.fixes[0].length, 1);
    });

    test('assist', () async {
      final assistCode = '''
main() {
  int v = 0;
}
''';
      final request = proto.SourceRequest()
        ..source = assistCode
        ..offset = 15;
      final response =
          await sendPostRequest('dartservices/v2/assists', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AssistsResponse()..mergeFromProto3Json(data);
      final assists = reply.assists;
      if (sdk.masterChannel || sdk.betaChannel) {
        expect(assists, hasLength(3));
      } else {
        expect(assists, hasLength(2));
      }
      expect(assists.first.edits, isNotNull);
      expect(assists.first.edits, hasLength(1));
      expect(
          assists.where((candidateFix) =>
              candidateFix.message == 'Remove type annotation'),
          isNotEmpty);
    });

    test('version', () async {
      final response = await sendPostRequest('dartservices/v2/version', null);
      expect(response.statusCode, 200);
      final encoded = await response.transform(utf8.decoder).join();
      final data = json.decode(encoded) as Map<String, dynamic>;
      expect(data['sdkVersion'], isNotNull);
      expect(data['runtimeVersion'], isNotNull);
    });

    test('version', () async {
      final response = await sendGetRequest('dartservices/v2/version');
      expect(response.statusCode, 200);
      final encoded = await response.transform(utf8.decoder).join();
      final data = json.decode(encoded) as Map<String, dynamic>;
      expect(data['sdkVersion'], isNotNull);
      expect(data['runtimeVersion'], isNotNull);
    });
  });

  //-----------------------------------------------------------------
  // Beginning of multi file files={} group tests:
  group('CommonServerProto JSON Multi File Group files={}', () {
    final sdk =
        Sdk.create(Platform.environment['FLUTTER_CHANNEL'] ?? stableChannel);
    setUpAll(() async {
      final cache = MockCache();
      commonServerImpl = CommonServerImpl(cache, sdk);
      commonServerApi = CommonServerApi(commonServerImpl);
      await commonServerImpl.init();

      // Some piece of initialization doesn't always happen fast enough for this
      // request to work in time for the test. So try it here until the server
      // returns something valid.
      // TODO(jcollins-g): determine which piece of initialization isn't
      // happening and deal with that in warmup/init.
      {
        var decodedJson = <dynamic, dynamic>{};
        final jsonData = proto.SourceRequest()..source = sampleCodeError;
        while (decodedJson.isEmpty) {
          final response =
              await sendPostRequest('dartservices/v2/analyze', jsonData);
          expect(response.statusCode, 200);
          expect(response.headers['content-type'],
              ['application/json; charset=utf-8']);
          final data = await response.transform(utf8.decoder).join();
          decodedJson = json.decode(data) as Map<dynamic, dynamic>;
        }
      }
    });

    tearDownAll(() async {
      await commonServerImpl.shutdown();
    });

    setUp(() {
      log.onRecord.listen((LogRecord rec) {
        print('${rec.level.name}: ${rec.time}: ${rec.message}');
      });
    });

    tearDown(log.clearListeners);

    test('analyzeFiles Dart files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: sampleCode});
      final response =
          await sendPostRequest('dartservices/v2/analyzeFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, isEmpty);
    });

    test('analyzeFiles Flutter files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: sampleCodeFlutter});
      final response =
          await sendPostRequest('dartservices/v2/analyzeFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, isEmpty);
      expect(reply.packageImports, ['flutter']);
    });

    test('analyzeFiles errors files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: sampleCodeError});
      late proto.AnalysisResults reply;
      final response =
          await sendPostRequest('dartservices/v2/analyzeFiles', request);
      expect(response.statusCode, 200);
      expect(response.headers['content-type'],
          ['application/json; charset=utf-8']);
      final data = json.decode(await response.transform(utf8.decoder).join());
      reply = proto.AnalysisResults()..mergeFromProto3Json(data);
      expect(reply.issues, hasLength(1));
      expect(reply.issues[0].kind, 'error');
      expect(reply.issues[0].line, 2);
      expect(reply.issues[0].sourceName, 'main.dart');
      expect(reply.issues[0].message, "Expected to find ';'.");
      expect(reply.issues[0].hasFixes, true);
      expect(reply.issues[0].charStart, 29);
      expect(reply.issues[0].charLength, 1);
    });

    test('analyzeFiles negative-test noSource files={}', () async {
      final request = proto.SourceFilesRequest();
      final response =
          await sendPostRequest('dartservices/v2/analyzeFiles', request);
      expect(response.statusCode, 400);
    });

    test('compileFiles files={}', () async {
      final request = proto.CompileFilesRequest()
        ..files.addAll({kMainDart: sampleCode});
      final response =
          await sendPostRequest('dartservices/v2/compileFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('compileFiles 2 simple import files set in files={}', () async {
      final request = proto.CompileFilesRequest()
        ..files.addAll({
          kMainDart: sampleCodeMultiFoo,
          'bar.dart': sampleCodeMultiBar,
        })
        ..returnSourceMap = false;
      final response =
          await sendPostRequest('dartservices/v2/compileFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('compileFiles error files={}', () async {
      final request = proto.CompileFilesRequest()
        ..files.addAll({kMainDart: sampleCodeError});
      final response =
          await sendPostRequest('dartservices/v2/compileFiles', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, contains('Error: Expected'));
    });

    test('compileFiles negative-test noSource files={}', () async {
      final request = proto.CompileFilesRequest();
      final response =
          await sendPostRequest('dartservices/v2/compileFiles', request);
      expect(response.statusCode, 400);
    });

    test('compileFilesDDC mymain.dart files={}', () async {
      final request = proto.CompileFilesDDCRequest()
        ..files.addAll({'mymain.dart': sampleCode});
      final response =
          await sendPostRequest('dartservices/v2/compileFilesDDC', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('compileFilesDDC 3 files set in files={}', () async {
      final request = proto.CompileFilesDDCRequest()
        ..files.addAll({
          kMainDart: sampleCode3PartLibraryMain,
          'discdata.dart': sampleCode3PartDiscDataPartOfTestAnim,
          'various.dart': sampleCode3PartVariousPartOfTestAnim
        });
      final response =
          await sendPostRequest('dartservices/v2/compileFilesDDC', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
      expect(reply.result, isNotEmpty);
    });

    test('completeFiles files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'})
        ..activeSourceName = kMainDart
        ..offset = 1;
      final response =
          await sendPostRequest('dartservices/v2/completeFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.completions, isNotEmpty);
    });

    test('completeFiles no data files={}', () async {
      final request = await sendPostRequest(
          'dartservices/v2/completeFiles', proto.SourceFilesRequest());
      expect(request.statusCode, 400);
    });

    test('completeFiles param missing files={}', () async {
      final request = proto.SourceFilesRequest()..offset = 1;
      final response =
          await sendPostRequest('dartservices/v2/completeFiles', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'files\'');
    });

    test('completeFiles param missing 2 files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'});
      final response =
          await sendPostRequest('dartservices/v2/completeFiles', request);
      expect(response.statusCode, 400);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
      expect(reply.error.message, 'Missing parameter: \'activeSourceName\'');
    });

    test('documentFiles files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'})
        ..activeSourceName = kMainDart
        ..offset = 17;
      final response =
          await sendPostRequest('dartservices/v2/documentFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isNotEmpty);
    });

    test('documentFiles little data files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'})
        ..activeSourceName = kMainDart
        ..offset = 2;
      final response =
          await sendPostRequest('dartservices/v2/documentFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('documentFiles no data files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'})
        ..activeSourceName = kMainDart
        ..offset = 12;
      final response =
          await sendPostRequest('dartservices/v2/documentFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
      expect(reply.info, isEmpty);
    });

    test('documentFiles negative-test noSource files={}', () async {
      final request = proto.SourceFilesRequest()..offset = 12;
      final response =
          await sendPostRequest('dartservices/v2/documentFiles', request);
      expect(response.statusCode, 400);
    });

    test('documentFiles negative-test noActiveSource noOffset files={}',
        () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: 'void main() {print("foo");}'});
      final response =
          await sendPostRequest('dartservices/v2/documentFiles', request);
      expect(response.statusCode, 400);
    });

    test('fix2 files={}', () async {
      final quickFixesCode = '''
import 'dart:async';
void main() {
  int i = 0;
}
''';
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: quickFixesCode})
        ..activeSourceName = kMainDart
        ..offset = 10;
      final response =
          await sendPostRequest('dartservices/v2/fixesFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      final fixes = reply.fixes;
      expect(fixes.length, 1);
      final problemAndFix = fixes[0];
      expect(problemAndFix.problemMessage, isNotNull);
    });

    test('fixesFiles completeness files={}', () async {
      final request = proto.SourceFilesRequest()
        ..files.addAll({
          kMainDart: '''
void main() {
  for (int i = 0; i < 4; i++) {
    print('hello \$i')
  }
}
'''
        })
        ..activeSourceName = kMainDart
        ..offset = 67;
      final response =
          await sendPostRequest('dartservices/v2/fixesFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.FixesResponse()..mergeFromProto3Json(data);
      expect(reply.fixes[0].fixes[0].message, "Insert ';'");
      expect(reply.fixes[0].fixes[0].edits[0].offset, 67);
      expect(reply.fixes[0].fixes[0].edits[0].length, 0);
      expect(reply.fixes[0].fixes[0].edits[0].replacement, ';');
      expect(reply.fixes[0].problemMessage, "Expected to find ';'.");
      expect(reply.fixes[0].offset, 66);
      expect(reply.fixes[0].length, 1);
    });

    test('assist2 files={}', () async {
      final assistCode = '''
main() {
  int v = 0;
}
''';
      final request = proto.SourceFilesRequest()
        ..files.addAll({kMainDart: assistCode})
        ..activeSourceName = kMainDart
        ..offset = 15;
      final response =
          await sendPostRequest('dartservices/v2/assistsFiles', request);
      expect(response.statusCode, 200);
      final data = json.decode(await response.transform(utf8.decoder).join());
      final reply = proto.AssistsResponse()..mergeFromProto3Json(data);
      final assists = reply.assists;
      if (sdk.masterChannel || sdk.betaChannel) {
        expect(assists, hasLength(3));
      } else {
        expect(assists, hasLength(2));
      }
      expect(assists.first.edits, isNotNull);
      expect(assists.first.edits, hasLength(1));
      expect(
          assists.where((candidateFix) =>
              candidateFix.message == 'Remove type annotation'),
          isNotEmpty);
    });
  });
  // End of multi file files={} tests group.
}

class MockCache implements ServerCache {
  @override
  Future<String?> get(String key) => Future.value(null);

  @override
  Future<void> set(String key, String value, {Duration? expiration}) =>
      Future.value();

  @override
  Future<void> remove(String key) => Future.value();

  @override
  Future<void> shutdown() => Future.value();
}
