Commit 38c4b24e authored by Dylan Bernardi's avatar Dylan Bernardi Committed by Enrique Alcántara
Browse files

fix(diag): Ensure DAP sections shows correct feature state

parent 2b73af05
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -102,11 +102,16 @@ const createMockState = (engaged: boolean): AllFeaturesState => {
      engagedChecks: engaged
        ? [
            createCheck('authentication-required', 'Authentication required.'),
            createCheck(
              'agentic-chat-feature-flag-disabled' as StateCheckId,
              'Feature flag disabled',
            ),
            createCheck('agentic-chat-no-support', 'Not supported'),
          ]
        : [],
      allChecks: [
        createCheck('authentication-required', 'Authentication required.'),
        createCheck('agentic-chat-feature-flag-disabled' as StateCheckId, 'Feature flag disabled'),
        createCheck('agentic-chat-no-support', 'Not supported'),
      ],
    },
@@ -115,12 +120,12 @@ const createMockState = (engaged: boolean): AllFeaturesState => {
      engagedChecks: engaged
        ? [
            createCheck('authentication-required', 'Authentication required.'),
            createCheck('agentic-chat-no-support', 'Not supported'),
            createCheck('agent-platform-disabled-by-user', 'Agent Platform disabled by user'),
          ]
        : [],
      allChecks: [
        createCheck('authentication-required', 'Authentication required.'),
        createCheck('agentic-chat-no-support', 'Not supported'),
        createCheck('agent-platform-disabled-by-user', 'Agent Platform disabled by user'),
      ],
    },
    [AGENT_PLATFORM_GA_ROLLOUT]: {
@@ -131,9 +136,15 @@ const createMockState = (engaged: boolean): AllFeaturesState => {
    [FLOWS]: {
      featureId: FLOWS,
      engagedChecks: engaged
        ? [createCheck('authentication-required', 'Authentication required.')]
        ? [
            createCheck('authentication-required', 'Authentication required.'),
            createCheck('agentic-chat-no-support', 'Not supported'),
          ]
        : [],
      allChecks: [createCheck('authentication-required', 'Authentication required.')],
      allChecks: [
        createCheck('authentication-required', 'Authentication required.'),
        createCheck('agentic-chat-no-support', 'Not supported'),
      ],
    },
  };
};
@@ -179,8 +190,15 @@ describe('FeatureStateDiagnosticsRenderer', () => {

      const expectedTerminalContext = `- ${checkStatusPre} Include terminal context is enabled for user ${checkStatusAppend}`;

      // Note: Only checks with labels in STATE_CHECK_USER_READABLE_LABELS will appear
      // The 'agentic-chat-feature-flag-disabled' check doesn't have a label, so it's filtered out
      const expectedAgenticChat = `- ${checkStatusPre} User is authenticated ${checkStatusAppend}
- ${checkStatusPre} Agentic Chat is supported for the current project ${checkStatusAppend}`;
- ${checkStatusPre} Agentic Chat is supported for the current project ${checkStatusAppend}
- ${checkStatusPre} Agent Platform is enabled in settings ${checkStatusAppend}`;

      const expectedFlows = `- ${checkStatusPre} User is authenticated ${checkStatusAppend}
- ${checkStatusPre} Agentic Chat is supported for the current project ${checkStatusAppend}
- ${checkStatusPre} Agent Platform is enabled in settings ${checkStatusAppend}`;

      expect(result[0].title).toBe(`GitLab Duo Code Suggestions (${expectedStatus})`);
      expect(result[0].content).toBe(expectedCodeSuggestions);
@@ -190,6 +208,8 @@ describe('FeatureStateDiagnosticsRenderer', () => {
      expect(result[2].content).toBe(expectedTerminalContext);
      expect(result[3].title).toBe(`GitLab Agentic Chat (${expectedStatus})`);
      expect(result[3].content).toBe(expectedAgenticChat);
      expect(result[4].title).toBe(`GitLab Flows (${expectedStatus})`);
      expect(result[4].content).toBe(expectedFlows);
    },
  );

+23 −4
Original line number Diff line number Diff line
import {
  AGENT_PLATFORM,
  CHAT,
  CODE_SUGGESTIONS,
  FeatureState,
@@ -22,16 +23,23 @@ const checkEnabledMapper = ({ engaged, checkId }: FeatureStateCheck<StateCheckId
const createFeatureStateDiagnosticsSection = (
  title: string,
  checks: FeatureState,
  additionalChecks?: FeatureStateCheck<StateCheckId>[],
): DiagnosticsSection => {
  // UNSUPPORTED_LANGUAGE check returns false by default on markdown files
  const diagnosticsChecks = checks.allChecks.filter(
    ch => STATE_CHECK_USER_READABLE_LABELS[ch.checkId] && ch.checkId !== UNSUPPORTED_LANGUAGE,
  );
  const onOff = diagnosticsChecks.find(ch => ch.engaged) ? 'Off' : 'On';

  // Merge additional checks if provided
  const allChecks = additionalChecks
    ? [...diagnosticsChecks, ...additionalChecks]
    : diagnosticsChecks;

  const onOff = allChecks.find(ch => ch.engaged) ? 'Off' : 'On';

  return {
    title: `${title} (${onOff})`,
    content: diagnosticsChecks.map(checkEnabledMapper).join('\n') || '',
    content: allChecks.map(checkEnabledMapper).join('\n') || '',
  };
};

@@ -43,12 +51,23 @@ export class FeatureStateDiagnosticsRenderer implements DiagnosticsRenderer<[All
      return [];
    }

    // Get only the "Agent Platform is enabled in settings" check to merge into Agentic Chat and Flows
    // We filter out the authentication check and only include the platform-specific check
    const agentPlatformEnabledCheck = state[AGENT_PLATFORM].allChecks.filter(
      ch =>
        STATE_CHECK_USER_READABLE_LABELS[ch.checkId] && ch.checkId !== 'authentication-required',
    );

    return [
      createFeatureStateDiagnosticsSection('GitLab Duo Code Suggestions', state[CODE_SUGGESTIONS]),
      createFeatureStateDiagnosticsSection('GitLab Duo Chat', state[CHAT]),
      createFeatureStateDiagnosticsSection('Terminal Context', state[CHAT_TERMINAL_CONTEXT]),
      createFeatureStateDiagnosticsSection('GitLab Agentic Chat', state[AGENTIC_CHAT]),
      createFeatureStateDiagnosticsSection('GitLab Flows', state[FLOWS]),
      createFeatureStateDiagnosticsSection(
        'GitLab Agentic Chat',
        state[AGENTIC_CHAT],
        agentPlatformEnabledCheck,
      ),
      createFeatureStateDiagnosticsSection('GitLab Flows', state[FLOWS], agentPlatformEnabledCheck),
    ];
  }
}
+11 −0
Original line number Diff line number Diff line
@@ -5,8 +5,10 @@ import {
import {
  DuoChatConfiguration,
  DuoCodeSuggestionsConfiguration,
  DuoAgentPlatformConfiguration,
  getDuoChatConfiguration,
  getDuoCodeSuggestionsConfiguration,
  getAgentPlatformConfiguration,
  getHttpAgentConfiguration,
  getSecurityScannerConfiguration,
  httpAgentConfiguration,
@@ -18,6 +20,7 @@ import { SettingsStateProvider } from './settings_state_provider';
jest.mock('../utils/extension_configuration', () => ({
  getDuoCodeSuggestionsConfiguration: jest.fn(),
  getDuoChatConfiguration: jest.fn(),
  getAgentPlatformConfiguration: jest.fn(),
  getHttpAgentConfiguration: jest.fn(),
  getSecurityScannerConfiguration: jest.fn(),
}));
@@ -39,6 +42,12 @@ describe('SettingsStateProvider', () => {
    duoChat: createFakePartial<DuoChatConfiguration>({
      enabled: true,
    }),
    duoAgentPlatform: createFakePartial<DuoAgentPlatformConfiguration>({
      enabled: true,
      connectionType: 'websocket',
      defaultNamespace: '',
      editFileDiffBehavior: 'foreground',
    }),
    http: createFakePartial<httpAgentConfiguration>({
      ca: 'ca',
      cert: 'cert',
@@ -54,6 +63,7 @@ describe('SettingsStateProvider', () => {
    extensionConfiguration: mockConfigs.extension,
    duoCodeSuggestionsConfiguration: mockConfigs.duo,
    duoChatConfiguration: mockConfigs.duoChat,
    duoAgentPlatformConfiguration: mockConfigs.duoAgentPlatform,
    httpProxyConfiguration: mockConfigs.http,
    securityScannerConfiguration: mockConfigs.security,
  };
@@ -67,6 +77,7 @@ describe('SettingsStateProvider', () => {
  beforeAll(() => {
    jest.mocked(getDuoCodeSuggestionsConfiguration).mockReturnValue(mockConfigs.duo);
    jest.mocked(getDuoChatConfiguration).mockReturnValue(mockConfigs.duoChat);
    jest.mocked(getAgentPlatformConfiguration).mockReturnValue(mockConfigs.duoAgentPlatform);
    jest.mocked(getHttpAgentConfiguration).mockReturnValue(mockConfigs.http);
    jest.mocked(getSecurityScannerConfiguration).mockReturnValue(mockConfigs.security);
  });
+4 −0
Original line number Diff line number Diff line
@@ -6,8 +6,10 @@ import {
import {
  DuoChatConfiguration,
  DuoCodeSuggestionsConfiguration,
  DuoAgentPlatformConfiguration,
  getDuoChatConfiguration,
  getDuoCodeSuggestionsConfiguration,
  getAgentPlatformConfiguration,
  getHttpAgentConfiguration,
  getSecurityScannerConfiguration,
  httpAgentConfiguration,
@@ -19,6 +21,7 @@ export interface SettingsDetails {
  extensionConfiguration: ExtensionConfiguration;
  duoCodeSuggestionsConfiguration: DuoCodeSuggestionsConfiguration;
  duoChatConfiguration: DuoChatConfiguration;
  duoAgentPlatformConfiguration: DuoAgentPlatformConfiguration;
  httpProxyConfiguration: httpAgentConfiguration;
  securityScannerConfiguration: SecurityScannerConfiguration;
}
@@ -44,6 +47,7 @@ export class SettingsStateProvider implements ExtensionStateProvider<SettingsDet
      extensionConfiguration: this.#configurationService.getConfiguration(),
      duoCodeSuggestionsConfiguration: getDuoCodeSuggestionsConfiguration(),
      duoChatConfiguration: getDuoChatConfiguration(),
      duoAgentPlatformConfiguration: getAgentPlatformConfiguration(),
      httpProxyConfiguration: getHttpAgentConfiguration(),
      securityScannerConfiguration: getSecurityScannerConfiguration(),
    };
+7 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ import { SettingsDetails } from '../state/settings_state_provider';
import {
  DuoChatConfiguration,
  DuoCodeSuggestionsConfiguration,
  DuoAgentPlatformConfiguration,
  httpAgentConfiguration,
  SecurityScannerConfiguration,
} from '../utils/extension_configuration';
@@ -35,6 +36,12 @@ export const createMockSettingsDetails = (): SettingsDetails => ({
  duoChatConfiguration: createFakePartial<DuoChatConfiguration>({
    enabled: true,
  }),
  duoAgentPlatformConfiguration: createFakePartial<DuoAgentPlatformConfiguration>({
    enabled: true,
    connectionType: 'websocket',
    defaultNamespace: '',
    editFileDiffBehavior: 'foreground',
  }),
  httpProxyConfiguration: createFakePartial<httpAgentConfiguration>({
    ca: 'ca-cert',
    cert: 'cert-file',