Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ vi.mock('path', () => ({

vi.mock('../../../../utils/vsCodeConfig/settings', () => ({
getGlobalSetting: vi.fn(),
isManagedIdentityAuthEnabled: vi.fn(() => true),
}));

// Import actual path for test setup (not affected by mock)
Expand Down Expand Up @@ -1416,10 +1417,11 @@ describe('createLocalConfigurationFiles', () => {
FUNCTIONS_WORKER_RUNTIME: 'dotnet',
APP_KIND: 'workflowapp',
ProjectDirectoryPath: path.join('test', 'workspace', 'TestLogicApp'),
WORKFLOWS_AUTHENTICATION_METHOD: 'managedServiceIdentity',
});

// Verify no other properties exist
expect(Object.keys(localSettingsData.Values)).toHaveLength(5);
expect(Object.keys(localSettingsData.Values)).toHaveLength(6);
});

it('should include global.json in .funcignore for custom code projects', async () => {
Expand Down Expand Up @@ -1461,11 +1463,12 @@ describe('createLocalConfigurationFiles', () => {
FUNCTIONS_WORKER_RUNTIME: 'dotnet',
APP_KIND: 'workflowapp',
ProjectDirectoryPath: path.join('test', 'workspace', 'TestLogicApp'),
WORKFLOWS_AUTHENTICATION_METHOD: 'managedServiceIdentity',
AzureWebJobsFeatureFlags: 'EnableMultiLanguageWorker',
});

// Verify exactly 6 properties exist (5 standard + 1 feature flag)
expect(Object.keys(localSettingsData.Values)).toHaveLength(6);
// Verify exactly 7 properties exist (5 standard + auth method + 1 feature flag)
expect(Object.keys(localSettingsData.Values)).toHaveLength(7);
});

it('should include global.json in .funcignore for rules engine projects', async () => {
Expand Down Expand Up @@ -1507,11 +1510,12 @@ describe('createLocalConfigurationFiles', () => {
FUNCTIONS_WORKER_RUNTIME: 'dotnet',
APP_KIND: 'workflowapp',
ProjectDirectoryPath: path.join('test', 'workspace', 'TestLogicApp'),
WORKFLOWS_AUTHENTICATION_METHOD: 'managedServiceIdentity',
AzureWebJobsFeatureFlags: 'EnableMultiLanguageWorker',
});

// Verify exactly 6 properties exist (5 standard + 1 feature flag)
expect(Object.keys(localSettingsData.Values)).toHaveLength(6);
// Verify exactly 7 properties exist (5 standard + auth method + 1 feature flag)
expect(Object.keys(localSettingsData.Values)).toHaveLength(7);
});

it('should create local.settings.json with exact required values for codeful projects', async () => {
Expand All @@ -1531,12 +1535,13 @@ describe('createLocalConfigurationFiles', () => {
FUNCTIONS_WORKER_RUNTIME: 'dotnet',
APP_KIND: 'workflowapp',
ProjectDirectoryPath: path.join('test', 'workspace', 'TestLogicApp'),
WORKFLOWS_AUTHENTICATION_METHOD: 'managedServiceIdentity',
AzureWebJobsFeatureFlags: 'EnableMultiLanguageWorker',
WORKFLOW_CODEFUL_ENABLED: 'true',
});

// Verify exactly 7 properties exist (5 standard + feature flag + codeful-enabled).
expect(Object.keys(localSettingsData.Values)).toHaveLength(7);
// Verify exactly 8 properties exist (5 standard + auth method + feature flag + codeful-enabled).
expect(Object.keys(localSettingsData.Values)).toHaveLength(8);
});

it('should include extension bundle configuration in host.json', async () => {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import {
defaultMsiAudience,
workflowAuthenticationMethodKey,
workflowLocationKey,
workflowManagementBaseURIKey,
workflowResourceGroupNameKey,
Expand Down Expand Up @@ -65,15 +64,13 @@ describe('createAzureWizard', () => {
} as any;
});

it('defaults cancelled connector selection to disabled raw keys', async () => {
it('defaults cancelled connector selection to disabled', async () => {
vi.mocked(context.ui.showQuickPick).mockRejectedValue({ isUserCancelledError: true });
const wizard = createAzureWizard(context, projectPath) as any;

await wizard.options.promptSteps[0].prompt(context);

expect(context.enabled).toBe(false);
expect(context.authenticationMethod).toBe('rawKeys');
expect(context.telemetry.properties.azureConnectorsDefaulted).toBe('rawKeys');
});

it('surfaces non-cancel connector selection failures', async () => {
Expand Down Expand Up @@ -105,23 +102,20 @@ describe('createAzureWizard', () => {
expect(azureConnectorStep.shouldPrompt({ ...context, enabled: false })).toBe(false);
});

it('persists disabled raw-key settings when Azure connectors are skipped', async () => {
it('persists empty subscription when Azure connectors are skipped', async () => {
context.enabled = false;
context.authenticationMethod = 'rawKeys';
const wizard = createAzureWizard(context, projectPath) as any;

await wizard.options.executeSteps[0].execute(context);

expect(addOrUpdateLocalAppSettings).toHaveBeenCalledWith(context, projectPath, {
[workflowSubscriptionIdKey]: '',
[workflowAuthenticationMethodKey]: 'rawKeys',
});
});

it('persists Azure connector settings and notifies the language client when enabled', async () => {
Object.assign(context, {
enabled: true,
authenticationMethod: 'managedServiceIdentity',
tenantId: 'tenant-id',
subscriptionId: 'subscription-id',
resourceGroup: { name: 'rg', location: 'westus' },
Expand All @@ -137,7 +131,6 @@ describe('createAzureWizard', () => {
[workflowResourceGroupNameKey]: 'rg',
[workflowLocationKey]: 'westus',
[workflowManagementBaseURIKey]: 'https://management.azure.com/',
[workflowAuthenticationMethodKey]: 'managedServiceIdentity',
[workflowsDynamicConnectionDefaultAuthAudienceKey]: defaultMsiAudience,
});
expect(ext.languageClient.sendNotification).toHaveBeenCalledWith('custom/updateApiConfig', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest';
import { localSettingsFileName, workflowAuthenticationMethodKey, workflowSubscriptionIdKey } from '../../../../constants';
import { localSettingsFileName, workflowSubscriptionIdKey } from '../../../../constants';
import { getLocalSettingsJson } from '../../../utils/appSettings/localSettings';
import { getAzureConnectorDetailsForLocalProject, invalidateAzureDetailsCache } from '../../../utils/codeless/common';
import { getLogicAppProjectRoot } from '../../../utils/codeless/connection';
Expand Down Expand Up @@ -68,11 +68,10 @@ describe('enableAzureConnectors', () => {
expect(ext.outputChannel.appendLog).toHaveBeenCalledWith('Azure connectors are enabled for the workflow.');
});

it('shows already-enabled information when subscription and auth settings exist', async () => {
it('shows already-enabled information when subscription setting exists', async () => {
(getLocalSettingsJson as Mock).mockResolvedValue({
Values: {
[workflowSubscriptionIdKey]: 'subscription-id',
[workflowAuthenticationMethodKey]: 'ActiveDirectoryOAuth',
},
});

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type { IProjectWizardContext } from '@microsoft/vscode-extension-logic-ap
import * as path from 'path';
import {
defaultMsiAudience,
workflowAuthenticationMethodKey,
workflowLocationKey,
workflowManagementBaseURIKey,
workflowResourceGroupNameKey,
Expand All @@ -20,7 +19,6 @@ import {
import { ext } from '../../../extensionVariables';
import { localize } from '../../../localize';
import { addOrUpdateLocalAppSettings } from '../../utils/appSettings/localSettings';
import { AuthenticationMethodSelectionStep, type AuthenticationMethodType } from './authenticationMethodStep';

export interface IAzureConnectorsContext extends IActionContext, IProjectWizardContext {
credentials: any;
Expand All @@ -29,14 +27,13 @@ export interface IAzureConnectorsContext extends IActionContext, IProjectWizardC
enabled: boolean;
tenantId: any;
environment: any;
authenticationMethod?: AuthenticationMethodType;
MSIenabled?: boolean;
}

//TODO: Update to be in webview after ignite redesign is done
export function createAzureWizard(wizardContext: IAzureConnectorsContext, projectPath: string): AzureWizard<IAzureConnectorsContext> {
return new AzureWizard(wizardContext, {
promptSteps: [new GetSubscriptionDetailsStep(projectPath), new AuthenticationMethodSelectionStep<IAzureConnectorsContext>()],
promptSteps: [new GetSubscriptionDetailsStep(projectPath)],
executeSteps: [new SaveAzureContext(projectPath)],
});
}
Expand All @@ -59,17 +56,13 @@ class GetSubscriptionDetailsStep extends AzureWizardPromptStep<IAzureConnectorsC
];
const selectedAction = await context.ui.showQuickPick(picks, { placeHolder }).catch((error) => {
if (parseError(error).isUserCancelledError) {
context.telemetry.properties.azureConnectorsDefaulted = 'rawKeys';
return { data: 'no' };
}

throw error;
});

context.enabled = selectedAction.data === 'yes';
if (!context.enabled) {
context.authenticationMethod = 'rawKeys';
}
}

public shouldPrompt(context: IAzureConnectorsContext): boolean {
Expand Down Expand Up @@ -106,19 +99,14 @@ class SaveAzureContext extends AzureWizardExecuteStep<IAzureConnectorsContext> {
const valuesToUpdateInSettings: Record<string, string> = {};
if (context.enabled === false) {
valuesToUpdateInSettings[workflowSubscriptionIdKey] = '';
valuesToUpdateInSettings[workflowAuthenticationMethodKey] = 'rawKeys';
} else {
const { resourceGroup, subscriptionId, tenantId, environment } = context;
valuesToUpdateInSettings[workflowTenantIdKey] = tenantId;
valuesToUpdateInSettings[workflowSubscriptionIdKey] = subscriptionId;
valuesToUpdateInSettings[workflowResourceGroupNameKey] = resourceGroup?.name || '';
valuesToUpdateInSettings[workflowLocationKey] = resourceGroup?.location || '';
valuesToUpdateInSettings[workflowManagementBaseURIKey] = environment.resourceManagerEndpointUrl;
// Save the authentication method to local settings
if (context.authenticationMethod) {
valuesToUpdateInSettings[workflowAuthenticationMethodKey] = context.authenticationMethod;
valuesToUpdateInSettings[workflowsDynamicConnectionDefaultAuthAudienceKey] = defaultMsiAudience;
}
valuesToUpdateInSettings[workflowsDynamicConnectionDefaultAuthAudienceKey] = defaultMsiAudience;

// Then send notifications for runtime updates
ext?.languageClient?.sendNotification('custom/updateApiConfig', {
Expand Down
Loading
Loading