async function generateBlankCodefulUnitTest()

in apps/vs-code-designer/src/app/commands/workflows/unitTest/saveBlankUnitTest.ts [201:313]


async function generateBlankCodefulUnitTest(
  context: IActionContext,
  projectPath: string,
  workflowName: string,
  unitTestName: string,
  mockClassContent: Record<string, string>,
  foundActionMocks: Record<string, string>,
  foundTriggerMocks: Record<string, string>
): Promise<void> {
  try {
    // Get required paths
    const { testsDirectory, logicAppName, logicAppTestFolderPath, workflowTestFolderPath, mocksFolderPath, unitTestFolderPath } =
      getUnitTestPaths(projectPath, workflowName, unitTestName);

    ext.outputChannel.appendLog(
      localize(
        'pathsResolved',
        'Resolved paths for unit test generation. Workflow Name: {0}, Unit Test Name: {1}',
        workflowName,
        unitTestName
      )
    );

    // Get cleaned versions of strings
    const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
    const cleanedWorkflowName = workflowName.replace(/-/g, '_');
    const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

    // Ensure directories exist
    ext.outputChannel.appendLog(localize('ensuringDirectories', 'Ensuring required directories exist...'));
    await Promise.all([
      fse.ensureDir(logicAppTestFolderPath),
      fse.ensureDir(workflowTestFolderPath),
      fse.ensureDir(unitTestFolderPath),
      fse.ensureDir(mocksFolderPath),
    ]);

    // Create the testSettings.config and TestExecutor.cs files
    ext.outputChannel.appendLog(localize('creatingTestSettingsConfig', 'Creating testSettings.config file for unit test...'));
    await createTestSettingsConfigFile(workflowTestFolderPath, workflowName, logicAppName);
    await createTestExecutorFile(logicAppTestFolderPath, cleanedLogicAppName);

    const [actionName, actionOutputClassName] = Object.entries(foundActionMocks)[0] || [];
    const [, triggerOutputClassName] = Object.entries(foundTriggerMocks)[0] || [];

    // Create actionMockClassName by replacing "Output" with "Mock" in actionOutputClassName
    const actionMockClassName = actionOutputClassName?.replace(/(.*)Output$/, '$1Mock');
    const triggerMockClassName = triggerOutputClassName.replace(/(.*)Output$/, '$1Mock');

    // Create the mock files
    for (const [mockClassName, classContent] of Object.entries(mockClassContent)) {
      const mockFilePath = path.join(mocksFolderPath, `${mockClassName}.cs`);
      await fse.writeFile(mockFilePath, classContent, 'utf-8');
      ext.outputChannel.appendLog(localize('csMockFileCreated', 'Created .cs file for mock at: {0}', mockFilePath));
    }

    // Create the .cs file for the unit test
    await createTestCsFile(
      unitTestFolderPath,
      unitTestName,
      cleanedUnitTestName,
      workflowName,
      cleanedWorkflowName,
      logicAppName,
      cleanedLogicAppName,
      actionName,
      actionOutputClassName,
      actionMockClassName,
      triggerOutputClassName,
      triggerMockClassName,
      true
    );
    logTelemetry(context, { csFileCreated: 'true' });

    // Ensure .csproj file exists
    ext.outputChannel.appendLog(localize('ensuringCsproj', 'Ensuring .csproj file exists...'));
    await ensureCsproj(testsDirectory, logicAppTestFolderPath, logicAppName);
    logTelemetry(context, { csprojValid: 'true' });
    ext.outputChannel.appendLog(localize('csprojEnsured', 'Ensured .csproj file.'));

    // Update .csproj file with content include for the workflow
    const csprojFilePath = path.join(logicAppTestFolderPath, `${logicAppName}.csproj`);
    const isCsprojUpdated = await updateCsprojFile(csprojFilePath, workflowName);
    logTelemetry(context, { csprojUpdated: isCsprojUpdated ? 'true' : 'false' });

    // Add testsDirectory to workspace if not already included
    ext.outputChannel.appendLog(localize('checkingWorkspace', 'Checking if tests directory is already part of the workspace...'));
    try {
      await ensureDirectoryInWorkspace(testsDirectory);
      ext.outputChannel.appendLog(localize('workspaceUpdated', 'Tests directory added to workspace if not already included.'));
      logTelemetry(context, {
        workspaceUpdatedStatus: 'true',
      });
    } catch (workspaceError) {
      const reason = parseError(workspaceError).message;
      logTelemetry(context, {
        workspaceUpdated: 'false',
        workspaceUpdatedStatus: 'false',
        workspaceUpdateFailureReason: reason,
      });
      throw workspaceError;
    }
    vscode.window.showInformationMessage(
      localize('info.generateCodefulUnitTest', 'Generated unit test "{0}" in "{1}"', unitTestName, unitTestFolderPath)
    );

    const successMessage = localize('info.generateCodefulUnitTest', 'Generated unit test "{0}" in "{1}"', unitTestName, unitTestFolderPath);
    logSuccess(context, 'unitTestGenerationStatus', successMessage);
    vscode.window.showInformationMessage(successMessage);
  } catch (error: any) {
    logError(context, error, 'generateBlankCodefulUnitTest');
  }
}