-
Notifications
You must be signed in to change notification settings - Fork 760
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove experimental warning from deploy pane, add tests (#16173)
As previously discussed, the only reason to maintain the "experimental" warning in the deploy pane was to ensure that the feature was fully tested before being released. Thanks to @shenglol's refactoring, I'm now able to add react tests for the frontend logic. ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/16173)
- Loading branch information
1 parent
c64428c
commit 8ae4324
Showing
18 changed files
with
2,301 additions
and
459 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
163 changes: 163 additions & 0 deletions
163
src/vscode-bicep-ui/apps/deploy-pane/src/__tests__/App.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import { beforeEach, describe, expect, it, vi } from 'vitest' | ||
import { render, waitFor, fireEvent, screen, act } from '@testing-library/react' | ||
import { App } from '../components/App' | ||
import { vscode } from '../vscode' | ||
import { createDeploymentDataMessage, createGetAccessTokenMessage, createGetAccessTokenResultMessage, createGetDeploymentScopeMessage, createGetDeploymentScopeResultMessage, createGetStateMessage, createGetStateResultMessage, createReadyMessage, type VscodeMessage } from '../messages'; | ||
import { fileUri, getDeploymentOperations, getDeployResponse, getValidateResponse, getWhatIfResponse, parametersJson, scope, templateJson } from './mockData'; | ||
|
||
const mockClient = { | ||
deployments: { | ||
beginCreateOrUpdateAtScope: vi.fn(async () => { | ||
return { | ||
isDone: vi.fn(() => true), | ||
getResult: vi.fn(getDeployResponse), | ||
}; | ||
}), | ||
beginValidateAtScopeAndWait: vi.fn(async () => getValidateResponse()), | ||
beginWhatIfAndWait: vi.fn(async () => getWhatIfResponse()), | ||
}, | ||
deploymentOperations: { | ||
listAtScope: vi.fn(getDeploymentOperations), | ||
} | ||
} | ||
|
||
beforeEach(() => { | ||
vi.mock('@azure/arm-resources', async (importOriginal) => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const mod: any = await importOriginal(); | ||
return { | ||
...mod, | ||
ResourceManagementClient: vi.fn(() => mockClient), | ||
}; | ||
}) | ||
vi.mock('../components/hooks/time', () => ({ | ||
getDate: () => '1737601964200', | ||
})); | ||
}); | ||
|
||
describe('App', () => { | ||
it('renders the loading spinner before initialization', async () => { | ||
const { container } = render(<App />); | ||
expect(container).toMatchSnapshot(); | ||
}); | ||
|
||
it('renders the App component with deployment state', async () => { | ||
const { container } = render(<App />); | ||
|
||
await initialize(); | ||
|
||
expect(container).toMatchSnapshot(); | ||
}); | ||
|
||
it('runs a deployment', async () => { | ||
const { container } = render(<App />); | ||
|
||
const scope = await initialize(); | ||
|
||
const deployButton = screen.getByText('Deploy'); | ||
fireEvent.click(deployButton); | ||
|
||
await act(async () => { | ||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createGetAccessTokenMessage(scope))); | ||
sendMessage(getAccessTokenResultMessage()); | ||
}) | ||
|
||
expect(container).toMatchSnapshot(); | ||
}); | ||
|
||
it('validates a deployment', async () => { | ||
const { container } = render(<App />); | ||
|
||
const scope = await initialize(); | ||
|
||
const validateButton = screen.getByText('Validate'); | ||
fireEvent.click(validateButton); | ||
|
||
await act(async () => { | ||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createGetAccessTokenMessage(scope))); | ||
sendMessage(getAccessTokenResultMessage()); | ||
}) | ||
|
||
expect(container).toMatchSnapshot(); | ||
}); | ||
|
||
it('what-ifs a deployment', async () => { | ||
const { container } = render(<App />); | ||
|
||
const scope = await initialize(); | ||
|
||
const whatIfButton = screen.getByText('What-If'); | ||
fireEvent.click(whatIfButton); | ||
|
||
await act(async () => { | ||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createGetAccessTokenMessage(scope))); | ||
sendMessage(getAccessTokenResultMessage()); | ||
}) | ||
|
||
expect(container).toMatchSnapshot(); | ||
}); | ||
|
||
it('supports the scope picker', async () => { | ||
const { container } = render(<App />); | ||
|
||
const scope = await initialize(); | ||
|
||
const changeScopeButton = screen.getByText('Change Scope'); | ||
fireEvent.click(changeScopeButton); | ||
|
||
await act(async () => { | ||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createGetDeploymentScopeMessage("resourceGroup"))); | ||
sendMessage(createGetDeploymentScopeResultMessage({ | ||
...scope, | ||
tenantId: 'newTenantId', | ||
subscriptionId: 'newSubscriptionId', | ||
resourceGroup: 'newResourceGroup', | ||
})); | ||
}) | ||
|
||
expect(container).toMatchSnapshot(); | ||
}); | ||
}) | ||
|
||
async function initialize() { | ||
const stateResult = getStateResultMessage(); | ||
await act(async () => { | ||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createReadyMessage())); | ||
sendMessage(getDeploymentDataMessage()); | ||
|
||
await waitFor(() => expect(vscode.postMessage).toBeCalledWith(createGetStateMessage())); | ||
sendMessage(stateResult); | ||
}) | ||
|
||
return scope; | ||
} | ||
|
||
function sendMessage(message: VscodeMessage) { | ||
fireEvent( | ||
window, | ||
new MessageEvent<VscodeMessage>("message", { data: message })); | ||
} | ||
|
||
function getDeploymentDataMessage() { | ||
return createDeploymentDataMessage( | ||
fileUri, | ||
false, | ||
templateJson, | ||
parametersJson); | ||
} | ||
|
||
function getStateResultMessage() { | ||
return createGetStateResultMessage({ | ||
scope: scope, | ||
}); | ||
} | ||
|
||
function getAccessTokenResultMessage() { | ||
return createGetAccessTokenResultMessage({ | ||
expiresOnTimestamp: 1737601964200, | ||
token: 'mockAccessToken' | ||
}); | ||
} |
Oops, something went wrong.