Path: blob/main/extensions/github-authentication/src/test/flows.test.ts
5221 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as assert from 'assert';6import { ExtensionHost, GitHubTarget, IFlowQuery, getFlows } from '../flows';7import { Config } from '../config';8import * as vscode from 'vscode';910const enum Flows {11UrlHandlerFlow = 'url handler',12LocalServerFlow = 'local server',13DeviceCodeFlow = 'device code',14PatFlow = 'personal access token'15}1617suite('getFlows', () => {18let lastClientSecret: string | undefined = undefined;19suiteSetup(() => {20lastClientSecret = Config.gitHubClientSecret;21Config.gitHubClientSecret = 'asdf';22});2324suiteTeardown(() => {25Config.gitHubClientSecret = lastClientSecret;26});2728const testCases: Array<{ label: string; query: IFlowQuery; expectedFlows: Flows[] }> = [29{30label: 'VS Code Desktop. Local filesystem. GitHub.com',31query: {32extensionHost: ExtensionHost.Local,33isSupportedClient: true,34target: GitHubTarget.DotCom35},36expectedFlows: [37Flows.LocalServerFlow,38Flows.UrlHandlerFlow,39Flows.DeviceCodeFlow40]41},42{43label: 'VS Code Desktop. Local filesystem. GitHub Hosted Enterprise',44query: {45extensionHost: ExtensionHost.Local,46isSupportedClient: true,47target: GitHubTarget.HostedEnterprise48},49expectedFlows: [50Flows.LocalServerFlow,51Flows.UrlHandlerFlow,52Flows.DeviceCodeFlow,53Flows.PatFlow54]55},56{57label: 'VS Code Desktop. Local filesystem. GitHub Enterprise Server',58query: {59extensionHost: ExtensionHost.Local,60isSupportedClient: true,61target: GitHubTarget.Enterprise62},63expectedFlows: [64Flows.DeviceCodeFlow,65Flows.PatFlow66]67},68{69label: 'vscode.dev. serverful. GitHub.com',70query: {71extensionHost: ExtensionHost.Remote,72isSupportedClient: true,73target: GitHubTarget.DotCom74},75expectedFlows: [76Flows.UrlHandlerFlow,77Flows.DeviceCodeFlow78]79},80{81label: 'vscode.dev. serverful. GitHub Hosted Enterprise',82query: {83extensionHost: ExtensionHost.Remote,84isSupportedClient: true,85target: GitHubTarget.HostedEnterprise86},87expectedFlows: [88Flows.UrlHandlerFlow,89Flows.DeviceCodeFlow,90Flows.PatFlow91]92},93{94label: 'vscode.dev. serverful. GitHub Enterprise',95query: {96extensionHost: ExtensionHost.Remote,97isSupportedClient: true,98target: GitHubTarget.Enterprise99},100expectedFlows: [101Flows.DeviceCodeFlow,102Flows.PatFlow103]104},105{106label: 'vscode.dev. serverless. GitHub.com',107query: {108extensionHost: ExtensionHost.WebWorker,109isSupportedClient: true,110target: GitHubTarget.DotCom111},112expectedFlows: [113Flows.UrlHandlerFlow114]115},116{117label: 'vscode.dev. serverless. GitHub Hosted Enterprise',118query: {119extensionHost: ExtensionHost.WebWorker,120isSupportedClient: true,121target: GitHubTarget.HostedEnterprise122},123expectedFlows: [124Flows.UrlHandlerFlow,125Flows.PatFlow126]127},128{129label: 'vscode.dev. serverless. GitHub Enterprise Server',130query: {131extensionHost: ExtensionHost.WebWorker,132isSupportedClient: true,133target: GitHubTarget.Enterprise134},135expectedFlows: [136Flows.PatFlow137]138},139{140label: 'Code - OSS. Local filesystem. GitHub.com',141query: {142extensionHost: ExtensionHost.Local,143isSupportedClient: false,144target: GitHubTarget.DotCom145},146expectedFlows: [147Flows.LocalServerFlow,148Flows.DeviceCodeFlow,149Flows.PatFlow150]151},152{153label: 'Code - OSS. Local filesystem. GitHub Hosted Enterprise',154query: {155extensionHost: ExtensionHost.Local,156isSupportedClient: false,157target: GitHubTarget.HostedEnterprise158},159expectedFlows: [160Flows.LocalServerFlow,161Flows.DeviceCodeFlow,162Flows.PatFlow163]164},165{166label: 'Code - OSS. Local filesystem. GitHub Enterprise Server',167query: {168extensionHost: ExtensionHost.Local,169isSupportedClient: false,170target: GitHubTarget.Enterprise171},172expectedFlows: [173Flows.DeviceCodeFlow,174Flows.PatFlow175]176},177];178179for (const testCase of testCases) {180test(`gives the correct flows - ${testCase.label}`, () => {181const flows = getFlows(testCase.query);182183assert.strictEqual(184flows.length,185testCase.expectedFlows.length,186`Unexpected number of flows: ${flows.map(f => f.label).join(',')}`187);188189for (let i = 0; i < flows.length; i++) {190const flow = flows[i];191192assert.strictEqual(flow.label, testCase.expectedFlows[i]);193}194});195}196197suite('preferDeviceCodeFlow configuration', () => {198let originalConfig: boolean | undefined;199200suiteSetup(async () => {201const config = vscode.workspace.getConfiguration('github-authentication');202originalConfig = config.get<boolean>('preferDeviceCodeFlow');203});204205suiteTeardown(async () => {206const config = vscode.workspace.getConfiguration('github-authentication');207await config.update('preferDeviceCodeFlow', originalConfig, vscode.ConfigurationTarget.Global);208});209210test('returns device code flow first when preferDeviceCodeFlow is true - VS Code Desktop', async () => {211const config = vscode.workspace.getConfiguration('github-authentication');212await config.update('preferDeviceCodeFlow', true, vscode.ConfigurationTarget.Global);213214const flows = getFlows({215extensionHost: ExtensionHost.Local,216isSupportedClient: true,217target: GitHubTarget.DotCom218});219220// Should return device code flow first, then other flows221assert.strictEqual(flows.length, 3, `Expected 3 flows, got ${flows.length}: ${flows.map(f => f.label).join(',')}`);222assert.strictEqual(flows[0].label, Flows.DeviceCodeFlow);223// Other flows should still be available224assert.strictEqual(flows[1].label, Flows.LocalServerFlow);225assert.strictEqual(flows[2].label, Flows.UrlHandlerFlow);226});227228test('returns device code flow first when preferDeviceCodeFlow is true - Remote', async () => {229const config = vscode.workspace.getConfiguration('github-authentication');230await config.update('preferDeviceCodeFlow', true, vscode.ConfigurationTarget.Global);231232const flows = getFlows({233extensionHost: ExtensionHost.Remote,234isSupportedClient: true,235target: GitHubTarget.DotCom236});237238// Should return device code flow first, then other flows239assert.strictEqual(flows.length, 2, `Expected 2 flows, got ${flows.length}: ${flows.map(f => f.label).join(',')}`);240assert.strictEqual(flows[0].label, Flows.DeviceCodeFlow);241assert.strictEqual(flows[1].label, Flows.UrlHandlerFlow);242});243244test('returns normal flows when preferDeviceCodeFlow is true but device code flow is not supported - WebWorker', async () => {245const config = vscode.workspace.getConfiguration('github-authentication');246await config.update('preferDeviceCodeFlow', true, vscode.ConfigurationTarget.Global);247248const flows = getFlows({249extensionHost: ExtensionHost.WebWorker,250isSupportedClient: true,251target: GitHubTarget.DotCom252});253254// WebWorker doesn't support DeviceCodeFlow, so should return normal flows255// Based on the original logic, WebWorker + DotCom should return UrlHandlerFlow256assert.strictEqual(flows.length, 1, `Expected 1 flow for WebWorker configuration, got ${flows.length}: ${flows.map(f => f.label).join(',')}`);257assert.strictEqual(flows[0].label, Flows.UrlHandlerFlow);258});259});260});261262263