// Copyright 2019 The Flutter Authors. 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:convert';

import 'package:codesign/codesign.dart' as cs;
import 'package:codesign/src/log.dart';
import 'package:codesign/src/utils.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:logging/logging.dart';
import 'package:test/test.dart';

import './src/fake_process_manager.dart';

void main() {
  const String randomString = 'abcd1234';
  const String appSpecificPasswordFilePath = '/tmp/passwords.txt';
  const String codesignAppstoreIDFilePath = '/tmp/appID.txt';
  const String codesignTeamIDFilePath = '/tmp/teamID.txt';
  const String inputZipPath = '/tmp/input.zip';
  const String outputZipPath = '/tmp/output.zip';
  final List<LogRecord> records = <LogRecord>[];

  late MemoryFileSystem fileSystem;
  late FakeProcessManager processManager;
  late cs.FileCodesignVisitor codesignVisitor;
  late Directory rootDirectory;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    rootDirectory = fileSystem.systemTempDirectory.createTempSync('conductor_codesign');
    processManager = FakeProcessManager.list(<FakeCommand>[]);
    records.clear();
    log.onRecord.listen((LogRecord record) => records.add(record));
  });

  group('test reading in passwords: ', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        notarizationTimerDuration: const Duration(seconds: 0),
        dryrun: false,
      );
      codesignVisitor.directoriesVisited.clear();
    });

    test('lacking password file throws exception', () async {
      expect(
        () async {
          await codesignVisitor.readPassword(appSpecificPasswordFilePath);
        },
        throwsA(
          isA<CodesignException>(),
        ),
      );
    });

    test('providing correctly formatted password returns normally', () async {
      fileSystem.file(appSpecificPasswordFilePath)
        ..createSync(recursive: true, exclusive: true)
        ..writeAsStringSync(
          '123',
          mode: FileMode.write,
          encoding: utf8,
        );

      expect(
        () async {
          await codesignVisitor.readPassword(appSpecificPasswordFilePath);
          await fileSystem.file(appSpecificPasswordFilePath).delete();
        },
        returnsNormally,
      );
    });
  });

  group('test utils function to join virtual entitlement path: ', () {
    test('omits slash for the first path', () async {
      expect(joinEntitlementPaths("", randomString), randomString);
    });

    test('concat with slash', () async {
      expect(joinEntitlementPaths(randomString, randomString), '$randomString/$randomString');
    });
  });

  group('test google cloud storage and processRemoteZip workflow', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        notarizationTimerDuration: const Duration(seconds: 0),
        dryrun: false,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
      );
      codesignVisitor.directoriesVisited.clear();
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
    });

    test('procesRemotezip triggers correct workflow', () async {
      final String zipFileName = '${rootDirectory.path}/remote_zip_4/folder_1/zip_1';
      fileSystem.file(zipFileName).createSync(recursive: true);
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'unzip',
            codesignVisitor.inputZipPath,
            '-d',
            '${rootDirectory.absolute.path}/single_artifact',
          ],
          onRun: () => fileSystem
            ..file('${rootDirectory.path}/single_artifact/entitlements.txt').createSync(recursive: true)
            ..file('${rootDirectory.path}/single_artifact/without_entitlements.txt').createSync(recursive: true),
        ),
        FakeCommand(
          command: <String>[
            'zip',
            '--symlinks',
            '--recurse-paths',
            codesignVisitor.outputZipPath,
            '.',
            '--include',
            '*',
          ],
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            codesignVisitor.outputZipPath,
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'id: $randomString',
        ),
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'status: Accepted',
        ),
      ]);

      await codesignVisitor.processRemoteZip();
      final Set<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toSet();
      expect(
        messages,
        contains(
          'The downloaded file is unzipped from ${codesignVisitor.inputZipPath} to ${rootDirectory.path}/single_artifact',
        ),
      );
      expect(
        messages,
        contains('Visiting directory ${rootDirectory.absolute.path}/single_artifact'),
      );
      expect(
        messages,
        contains('parsed binaries with entitlements are {}'),
      );
      expect(
        messages,
        contains('parsed binaries without entitlements are {}'),
      );
      expect(
        messages,
        contains(
          'uploading xcrun notarytool submit ${codesignVisitor.outputZipPath} --apple-id $randomString --password $randomString --team-id $randomString',
        ),
      );
      expect(
        messages,
        contains('RequestUUID for ${codesignVisitor.outputZipPath} is: $randomString'),
      );
      expect(
        messages,
        contains(
          'checking notary status with xcrun notarytool info $randomString --password $randomString --apple-id $randomString --team-id $randomString',
        ),
      );
      expect(
        messages,
        contains('successfully notarized ${codesignVisitor.outputZipPath}'),
      );
    });
  });

  group('visit directory/zip api calls: ', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        notarizationTimerDuration: Duration.zero,
      );
      codesignVisitor.directoriesVisited.clear();
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
    });

    test('visitDirectory correctly list files', () async {
      fileSystem
        ..file('${rootDirectory.path}/remote_zip_0/file_a').createSync(recursive: true)
        ..file('${rootDirectory.path}/remote_zip_0/file_b').createSync(recursive: true)
        ..file('${rootDirectory.path}/remote_zip_0/file_c').createSync(recursive: true);
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_0/file_a',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_0/file_b',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_0/file_c',
          ],
          stdout: 'other_files',
        ),
      ]);
      final Directory testDirectory = fileSystem.directory('${rootDirectory.path}/remote_zip_0');
      await codesignVisitor.visitDirectory(
        directory: testDirectory,
        parentVirtualPath: 'a.zip',
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(messages, contains('Visiting directory ${rootDirectory.path}/remote_zip_0'));
      expect(messages, contains('Child file of directory remote_zip_0 is file_a'));
      expect(messages, contains('Child file of directory remote_zip_0 is file_b'));
      expect(messages, contains('Child file of directory remote_zip_0 is file_c'));
    });

    test('visitDirectory recursively visits directory', () async {
      fileSystem
        ..file('${rootDirectory.path}/remote_zip_1/file_a').createSync(recursive: true)
        ..file('${rootDirectory.path}/remote_zip_1/folder_a/file_b').createSync(recursive: true);
      final Directory testDirectory = fileSystem.directory('${rootDirectory.path}/remote_zip_1');
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_1/file_a',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_1/folder_a/file_b',
          ],
          stdout: 'other_files',
        ),
      ]);
      await codesignVisitor.visitDirectory(
        directory: testDirectory,
        parentVirtualPath: '',
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(messages, contains('Visiting directory ${rootDirectory.path}/remote_zip_1'));
      expect(messages, contains('Visiting directory ${rootDirectory.path}/remote_zip_1/folder_a'));
      expect(messages, contains('Child file of directory remote_zip_1 is file_a'));
      expect(messages, contains('Child file of directory folder_a is file_b'));
    });

    test('visit directory inside a zip', () async {
      final String zipFileName = '${rootDirectory.path}/remote_zip_2/zip_1';
      fileSystem.file(zipFileName).createSync(recursive: true);
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'unzip',
            '${rootDirectory.absolute.path}/remote_zip_2/zip_1',
            '-d',
            '${rootDirectory.absolute.path}/embedded_zip_${zipFileName.hashCode}',
          ],
          onRun: () => fileSystem
            ..file('${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}/file_1').createSync(recursive: true)
            ..file('${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}/file_2').createSync(recursive: true),
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/embedded_zip_${zipFileName.hashCode}/file_1',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/embedded_zip_${zipFileName.hashCode}/file_2',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'zip',
            '--symlinks',
            '--recurse-paths',
            '${rootDirectory.absolute.path}/remote_zip_2/zip_1',
            '.',
            '--include',
            '*'
          ],
          onRun: () => fileSystem.file('${rootDirectory.path}/remote_zip_2/zip_1').createSync(recursive: true),
        ),
      ]);

      await codesignVisitor.visitEmbeddedZip(
        zipEntity: fileSystem.file('${rootDirectory.path}/remote_zip_2/zip_1'),
        parentVirtualPath: 'a.zip',
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(
        messages,
        contains(
          'The downloaded file is unzipped from ${rootDirectory.path}/remote_zip_2/zip_1 to ${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}',
        ),
      );
      expect(messages, contains('Visiting directory ${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}'));
      expect(messages, contains('Child file of directory embedded_zip_${zipFileName.hashCode} is file_1'));
      expect(messages, contains('Child file of directory embedded_zip_${zipFileName.hashCode} is file_2'));
    });

    test('visit zip inside a directory', () async {
      final String zipFileName = '${rootDirectory.path}/remote_zip_4/folder_1/zip_1';
      fileSystem.file(zipFileName).createSync(recursive: true);
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_4/folder_1/zip_1',
          ],
          stdout: 'application/zip',
        ),
        FakeCommand(
          command: <String>[
            'unzip',
            '${rootDirectory.absolute.path}/remote_zip_4/folder_1/zip_1',
            '-d',
            '${rootDirectory.absolute.path}/embedded_zip_${zipFileName.hashCode}',
          ],
          onRun: () => fileSystem
              .directory('${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}')
              .createSync(recursive: true),
        ),
        FakeCommand(
          command: <String>[
            'zip',
            '--symlinks',
            '--recurse-paths',
            '${rootDirectory.absolute.path}/remote_zip_4/folder_1/zip_1',
            '.',
            '--include',
            '*'
          ],
        ),
      ]);

      await codesignVisitor.visitDirectory(
        directory: fileSystem.directory('${rootDirectory.path}/remote_zip_4'),
        parentVirtualPath: 'a.zip',
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(messages, contains('Visiting directory ${rootDirectory.absolute.path}/remote_zip_4'));
      expect(messages, contains('Visiting directory ${rootDirectory.absolute.path}/remote_zip_4/folder_1'));
      expect(
        messages,
        contains(
          'The downloaded file is unzipped from ${rootDirectory.path}/remote_zip_4/folder_1/zip_1 to ${rootDirectory.path}/embedded_zip_${zipFileName.hashCode}',
        ),
      );
      expect(
        messages,
        contains('Visiting directory ${rootDirectory.absolute.path}/embedded_zip_${zipFileName.hashCode}'),
      );
    });

    test('throw exception when the same directory is visited', () async {
      fileSystem.file('${rootDirectory.path}/parent_1/child_1/file_1').createSync(recursive: true);
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/parent_1/child_1/file_1',
          ],
          stdout: 'other_files',
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/parent_1/child_1/file_1',
          ],
          stdout: 'other_files',
        ),
      ]);

      await codesignVisitor.visitDirectory(
        directory: fileSystem.directory('${rootDirectory.path}/parent_1/child_1'),
        parentVirtualPath: 'a.zip',
      );
      List<String> warnings = records
          .where((LogRecord record) => record.level == Level.WARNING)
          .map((LogRecord record) => record.message)
          .toList();
      expect(warnings, isEmpty);

      await codesignVisitor.visitDirectory(
        directory: fileSystem.directory('${rootDirectory.path}/parent_1'),
        parentVirtualPath: 'a.zip',
      );
      warnings = records
          .where((LogRecord record) => record.level == Level.WARNING)
          .map((LogRecord record) => record.message)
          .toList();
      expect(
        warnings,
        contains(
          'Warning! You are visiting a directory that has been visited before, the directory is ${rootDirectory.path}/parent_1/child_1',
        ),
      );
    });

    test('visitBinary codesigns binary with / without entitlement', () async {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        dryrun: false,
        notarizationTimerDuration: const Duration(seconds: 0),
      );
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
      codesignVisitor.fileWithEntitlements = <String>{'root/folder_a/file_a'};
      codesignVisitor.fileWithoutEntitlements = <String>{'root/folder_b/file_b'};
      fileSystem
        ..file('${rootDirectory.path}/remote_zip_5/folder_a/file_a').createSync(recursive: true)
        ..file('${rootDirectory.path}/remote_zip_5/folder_b/file_b').createSync(recursive: true);
      final Directory testDirectory = fileSystem.directory('${rootDirectory.path}/remote_zip_5');
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_5/folder_a/file_a',
          ],
          stdout: 'application/x-mach-binary',
        ),
        FakeCommand(
          command: <String>[
            'codesign',
            '-f',
            '-s',
            randomString,
            '${rootDirectory.absolute.path}/remote_zip_5/folder_a/file_a',
            '--timestamp',
            '--options=runtime',
            '--entitlements',
            '${rootDirectory.absolute.path}/Entitlements.plist'
          ],
        ),
        FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '${rootDirectory.absolute.path}/remote_zip_5/folder_b/file_b',
          ],
          stdout: 'application/x-mach-binary',
        ),
        FakeCommand(
          command: <String>[
            'codesign',
            '-f',
            '-s',
            randomString,
            '${rootDirectory.absolute.path}/remote_zip_5/folder_b/file_b',
            '--timestamp',
            '--options=runtime',
          ],
        ),
      ]);
      await codesignVisitor.visitDirectory(
        directory: testDirectory,
        parentVirtualPath: 'root',
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(messages, contains('signing file at path ${rootDirectory.absolute.path}/remote_zip_5/folder_a/file_a'));
      expect(messages, contains('the virtual entitlement path associated with file is root/folder_a/file_a'));
      expect(messages, contains('the decision to sign with entitlement is true'));

      expect(messages, contains('signing file at path ${rootDirectory.absolute.path}/remote_zip_5/folder_b/file_b'));
      expect(messages, contains('the virtual entitlement path associated with file is root/folder_b/file_b'));
      expect(messages, contains('the decision to sign with entitlement is false'));
    });
  });

  group('parse entitlement configs: ', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
      );
      codesignVisitor.directoriesVisited.clear();
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
    });

    test('correctly store file paths', () async {
      fileSystem.file('${rootDirectory.absolute.path}/test_entitlement/entitlements.txt')
        ..createSync(recursive: true)
        ..writeAsStringSync(
          '''file_a
file_b
file_c''',
          mode: FileMode.append,
          encoding: utf8,
        );

      fileSystem.file('${rootDirectory.absolute.path}/test_entitlement/without_entitlements.txt')
        ..createSync(recursive: true)
        ..writeAsStringSync(
          '''file_d
file_e''',
          mode: FileMode.append,
          encoding: utf8,
        );
      final Set<String> fileWithEntitlements = await codesignVisitor.parseEntitlements(
        fileSystem.directory('${rootDirectory.absolute.path}/test_entitlement'),
        true,
      );
      final Set<String> fileWithoutEntitlements = await codesignVisitor.parseEntitlements(
        fileSystem.directory('${rootDirectory.absolute.path}/test_entitlement'),
        false,
      );
      expect(fileWithEntitlements.length, 3);
      expect(
        fileWithEntitlements,
        containsAll(<String>[
          'file_a',
          'file_b',
          'file_c',
        ]),
      );
      expect(fileWithoutEntitlements.length, 2);
      expect(
        fileWithoutEntitlements,
        containsAll(<String>[
          'file_d',
          'file_e',
        ]),
      );
    });

    test('throw exception when configuration file is missing', () async {
      fileSystem.file('${rootDirectory.absolute.path}/test_entitlement_2/entitlements.txt')
        ..createSync(recursive: true)
        ..writeAsStringSync(
          '''file_a
file_b
file_c''',
          mode: FileMode.append,
          encoding: utf8,
        );

      final Set<String> fileWithEntitlements = await codesignVisitor.parseEntitlements(
        fileSystem.directory('${rootDirectory.absolute.path}/test_entitlement_2'),
        true,
      );
      expect(fileWithEntitlements.length, 3);
      expect(
        fileWithEntitlements,
        containsAll(<String>[
          'file_a',
          'file_b',
          'file_c',
        ]),
      );
      expect(
        () => codesignVisitor.parseEntitlements(
          fileSystem.directory('/Users/xilaizhang/Desktop/test_entitlement_2'),
          false,
        ),
        throwsA(
          isA<CodesignException>(),
        ),
      );
    });
  });

  group('notarization tests: ', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
      );
      codesignVisitor.directoriesVisited.clear();
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
    });

    test('successful notarization check returns true', () async {
      processManager.addCommands(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''createdDate: 2021-04-29T01:38:09.498Z
id: 2efe2717-52ef-43a5-96dc-0797e4ca1041
name: OvernightTextEditor_11.6.8.zip
status: Accepted''',
        ),
      ]);

      expect(
        codesignVisitor.checkNotaryJobFinished(randomString),
        true,
      );
    });

    test('wrong format (such as altool) check throws exception', () async {
      processManager.addCommands(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''RequestUUID: 2EFE2717-52EF-43A5-96DC-0797E4CA1041
Date: 2021-07-02 20:32:01 +0000
Status: invalid
LogFileURL: https://osxapps.itunes.apple.com/...
Status Code: 2
Status Message: Package Invalid''',
        ),
      ]);

      expect(
        () => codesignVisitor.checkNotaryJobFinished(randomString),
        throwsA(
          isA<CodesignException>(),
        ),
      );
    });

    test('in progress notarization check returns false', () async {
      processManager.addCommands(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''createdDate: 2021-04-29T01:38:09.498Z
id: 2efe2717-52ef-43a5-96dc-0797e4ca1041
name: OvernightTextEditor_11.6.8.zip
status: In Progress''',
        ),
      ]);

      expect(
        codesignVisitor.checkNotaryJobFinished(randomString),
        false,
      );
    });

    test('invalid status check throws exception', () async {
      processManager.addCommands(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''createdDate: 2021-04-29T01:38:09.498Z
id: 2efe2717-52ef-43a5-96dc-0797e4ca1041
name: OvernightTextEditor_11.6.8.zip
status: Invalid''',
        ),
      ]);

      expect(
        () => codesignVisitor.checkNotaryJobFinished(randomString),
        throwsA(
          isA<CodesignException>(),
        ),
      );
    });

    test('upload notary retries upon failure', () async {
      fileSystem.file('${rootDirectory.absolute.path}/temp').createSync();
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Error uploading file.
 Id: something that causes failure
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Successfully uploaded file.
 id: 2efe2717-52ef-43a5-96dc-0797e4ca1041
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
        ),
      ]);

      final String uuid = codesignVisitor.uploadZipToNotary(
        fileSystem.file('${rootDirectory.absolute.path}/temp'),
        3,
        0,
      );
      expect(uuid, '2efe2717-52ef-43a5-96dc-0797e4ca1041');
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.WARNING)
          .map((LogRecord record) => record.message)
          .toList();
      expect(
        messages,
        contains('Failed to upload to the notary service with args: '
            'xcrun notarytool submit ${rootDirectory.absolute.path}/temp '
            '--apple-id abcd1234 --password abcd1234 --team-id abcd1234'),
      );
      expect(
        messages,
        contains('Trying again 2 more times...'),
      );
    });

    test('upload notary throws exception if exit code is unnormal', () async {
      fileSystem.file('${rootDirectory.absolute.path}/temp').createSync();
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Error uploading file.
 Id: something that causes failure
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
          exitCode: -1,
        ),
      ]);

      expect(
        () => codesignVisitor.uploadZipToNotary(
          fileSystem.file('${rootDirectory.absolute.path}/temp'),
          1,
          0,
        ),
        throwsA(
          isA<CodesignException>(),
        ),
      );
    });

    test('upload notary throws exception after 3 default tries', () async {
      fileSystem.file('${rootDirectory.absolute.path}/temp').createSync();
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Error uploading file.
 Id: something that causes failure
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Error uploading file.
 Id: something that causes failure
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            '${rootDirectory.absolute.path}/temp',
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: '''Error uploading file.
 Id: something that causes failure
 path: /Users/flutter/Desktop/OvernightTextEditor_11.6.8.zip''',
        ),
      ]);

      expect(
        () => codesignVisitor.uploadZipToNotary(
          fileSystem.file('${rootDirectory.absolute.path}/temp'),
          3,
          0,
        ),
        throwsA(
          isA<CodesignException>(),
        ),
      );
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.WARNING)
          .map((LogRecord record) => record.message)
          .toList();
      expect(
        messages,
        contains('The upload to notary service failed after retries, and'
            '  the output format does not match the current notary tool version.'
            ' If after inspecting the output, you believe the process finished '
            'successfully but was not detected, please contact flutter release engineers'),
      );
    });
  });

  group('support optional switches and dryrun :', () {
    setUp(() {
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        notarizationTimerDuration: const Duration(seconds: 0),
      );
      codesignVisitor.directoriesVisited.clear();
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
      fileSystem.file(codesignAppstoreIDFilePath)
        ..createSync(recursive: true)
        ..writeAsStringSync(randomString);
      fileSystem.file(codesignTeamIDFilePath)
        ..createSync(recursive: true)
        ..writeAsStringSync(randomString);
      fileSystem.file(appSpecificPasswordFilePath)
        ..createSync(recursive: true)
        ..writeAsStringSync(randomString);
    });

    test('codesign optional switches artifacts when dryrun is true', () async {
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'unzip',
            codesignVisitor.inputZipPath,
            '-d',
            '${rootDirectory.absolute.path}/single_artifact'
          ],
          onRun: () => fileSystem
            ..file('${rootDirectory.path}/single_artifact/entitlements.txt').createSync(recursive: true)
            ..file('${rootDirectory.path}/single_artifact/without_entitlements.txt').createSync(recursive: true),
        ),
        FakeCommand(
          command: <String>[
            'zip',
            '--symlinks',
            '--recurse-paths',
            codesignVisitor.outputZipPath,
            '.',
            '--include',
            '*'
          ],
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            codesignVisitor.outputZipPath,
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'id: $randomString',
        ),
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'status: Accepted',
        ),
      ]);
      await codesignVisitor.validateAll();
      final List<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toList();
      expect(
        messages,
        contains('code signing dry run has completed, this is a quick sanity check without'
            'going through the notary service. To run the full codesign process, use --no-dryrun flag.'),
      );
    });

    test('upload optional switch artifacts when dryrun is false', () async {
      processManager.addCommands(<FakeCommand>[
        FakeCommand(
          command: <String>[
            'unzip',
            codesignVisitor.inputZipPath,
            '-d',
            '${rootDirectory.absolute.path}/single_artifact'
          ],
          onRun: () => fileSystem
            ..file('${rootDirectory.path}/single_artifact/entitlements.txt').createSync(recursive: true)
            ..file('${rootDirectory.path}/single_artifact/without_entitlements.txt').createSync(recursive: true),
        ),
        FakeCommand(
          command: <String>[
            'zip',
            '--symlinks',
            '--recurse-paths',
            codesignVisitor.outputZipPath,
            '.',
            '--include',
            '*'
          ],
        ),
        FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'submit',
            codesignVisitor.outputZipPath,
            '--apple-id',
            randomString,
            '--password',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'id: $randomString',
        ),
        const FakeCommand(
          command: <String>[
            'xcrun',
            'notarytool',
            'info',
            randomString,
            '--password',
            randomString,
            '--apple-id',
            randomString,
            '--team-id',
            randomString,
          ],
          stdout: 'status: Accepted',
        ),
      ]);
      codesignVisitor = cs.FileCodesignVisitor(
        codesignCertName: randomString,
        inputZipPath: inputZipPath,
        outputZipPath: outputZipPath,
        fileSystem: fileSystem,
        appSpecificPasswordFilePath: appSpecificPasswordFilePath,
        codesignAppstoreIDFilePath: codesignAppstoreIDFilePath,
        codesignTeamIDFilePath: codesignTeamIDFilePath,
        processManager: processManager,
        rootDirectory: rootDirectory,
        notarizationTimerDuration: const Duration(seconds: 0),
        dryrun: false,
      );
      codesignVisitor.appSpecificPassword = randomString;
      codesignVisitor.codesignAppstoreId = randomString;
      codesignVisitor.codesignTeamId = randomString;
      codesignVisitor.directoriesVisited.clear();
      await codesignVisitor.validateAll();
      final Set<String> messages = records
          .where((LogRecord record) => record.level == Level.INFO)
          .map((LogRecord record) => record.message)
          .toSet();
      expect(
        messages,
        contains('Codesign completed. Codesigned zip is located at ${codesignVisitor.outputZipPath}.'
            'If you have uploaded the artifacts back to google cloud storage, please delete'
            ' the folder ${codesignVisitor.outputZipPath} and ${codesignVisitor.inputZipPath}.'),
      );
      expect(
        messages,
        isNot(
          contains('code signing dry run has completed, this is a quick sanity check without'
              'going through the notary service. To run the full codesign process, use --no-dryrun flag.'),
        ),
      );
    });
  });
}
