From 7c136ce3e94277e02d956381dc4cdc999f7b9bce Mon Sep 17 00:00:00 2001 From: Vichym Date: Mon, 3 Mar 2025 21:03:46 -0800 Subject: [PATCH 1/7] test(lambda): add integration for Serverless Land integration --- .../appBuilder/serverlessLand/main.test.ts | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts new file mode 100644 index 00000000000..c25b56c6417 --- /dev/null +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -0,0 +1,141 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import assert from 'assert' +import * as vscode from 'vscode' +import path from 'path' +import { PrompterTester } from '../../../test/shared/wizards/prompterTester' +import { describe } from 'mocha' +import { ProjectMetadata } from '../../../awsService/appBuilder/serverlessLand/metadataManager' +import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports +import fs from '../../../shared/fs/fs' +import { AppBuilderRootNode } from '../../../awsService/appBuilder/explorer/nodes/rootNode' +import * as sinon from 'sinon' +import { AppNode } from '../../../awsService/appBuilder/explorer/nodes/appNode' +import { ResourceNode } from '../../../awsService/appBuilder/explorer/nodes/resourceNode' +import { getTestWindow } from '../../../test/shared/vscode/window' + +describe('Serverless Land Integration', async () => { + const metadataPath = path.resolve( + __dirname, + '../../../../../src/awsService/appBuilder/serverlessLand/metadata.json' + ) + const metadataContent = nodefs.readFileSync(metadataPath, { encoding: 'utf-8' }) + const parseMetadata = JSON.parse(metadataContent) as ProjectMetadata + const workspaceFolder = vscode.workspace.workspaceFolders![0] + const projectFolder = 'my-project-from-Serverless-Land' + let rootNode: sinon.SinonSpiedInstance + let sandbox: sinon.SinonSandbox + + beforeEach(async () => { + sandbox = sinon.createSandbox() + await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) + rootNode = sandbox.spy(AppBuilderRootNode.instance) + }) + + afterEach(async () => { + await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) + }) + + describe(':) Path', async () => { + it('creates an AppBuilderRootNode with correct label', async () => { + /** + * Selection: + * - pattern : [Select] 2 apigw-rest-api-lambda-sam + * - runtime : [Select] 3 dotnet + * - iac : [Select] 1 sam + * - location : [Input] From TestFolder.uri + * - name : [Input] "my-project-from-Serverless-Land" + */ + + const testWindow = getTestWindow() + const prompterTester = PrompterTester.init({ testWindow }) + .handleQuickPick('Select a Pattern for your application', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + Object.entries(parseMetadata.patterns).map(([key, pattern]) => { + options.find((option) => option.label === key && option.detail === pattern.description) + }) + quickPick.acceptItem(quickPick.items[1]) + }) + .handleQuickPick('Select Runtime', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, 'python') + assert.strictEqual(options[1].label, 'javascript') + assert.strictEqual(options[2].label, 'java') + assert.strictEqual(options[3].label, 'dotnet') + quickPick.acceptItem(options[3]) + }) + .handleQuickPick('Select IaC', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, 'sam') + quickPick.acceptItem(options[0]) + }) + .handleQuickPick('Select Project Location', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, '$(folder) workspaceFolder') + assert.strictEqual(options[1].label, '$(folder-opened) Select a folder...') + quickPick.acceptItem(options[0]) + }) + .handleInputBox('Enter Project Name', (inputBox) => { + inputBox.acceptValue('my-project-from-Serverless-Land') + }) + .build() + + // Validate that the README.md is shown. + testWindow.onDidChangeActiveTextEditor((editors) => { + assert(editors) + const readMe = path.join(workspaceFolder.uri.fsPath, projectFolder, 'README.md') + assert.strictEqual(editors?.document.fileName, readMe) + }) + + await vscode.commands.executeCommand('aws.toolkit.lambda.createServerlessLandProject') + + // projectNodes set from previous step + + const projectNode = await rootNode + .getChildren() + .then( + (children) => + children.find( + (node) => + node instanceof AppNode && + node.label === 'workspaceFolder/my-project-from-Serverless-Land' + ) as AppNode | undefined + ) + + assert.ok(projectNode) + + // Check App Builder resources + const resourceNodes = await projectNode.getChildren() + assert.strictEqual(resourceNodes.length, 1) + assert.ok(resourceNodes[0] instanceof ResourceNode) + + // Validate Lambda resource configuration + const lamdaResource = resourceNodes[0] as ResourceNode + assert.strictEqual(lamdaResource.resource.resource.Type, 'AWS::Serverless::Function') + assert.strictEqual(lamdaResource.resource.resource.Runtime, 'dotnet8') + assert.strictEqual(lamdaResource.resource.resource.Id, 'HelloWorldFunction') + assert.deepStrictEqual(lamdaResource.resource.resource.Events, [ + { + Id: 'HelloWorld', + Type: 'Api', + Path: '/hello', + Method: 'get', + }, + ]) + assert.deepStrictEqual(lamdaResource.resource.resource.Environment, { + Variables: { + PARAM1: 'VALUE', + }, + }) + + prompterTester.assertCallAll() + }) + }) +}) From d7ae430dac498cd1a9184838651e724032a02706 Mon Sep 17 00:00:00 2001 From: Vichym Date: Tue, 4 Mar 2025 12:29:00 -0800 Subject: [PATCH 2/7] replace nodefs with fs for parsing file --- .../src/testInteg/appBuilder/serverlessLand/main.test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index c25b56c6417..1431acdf825 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -9,7 +9,6 @@ import path from 'path' import { PrompterTester } from '../../../test/shared/wizards/prompterTester' import { describe } from 'mocha' import { ProjectMetadata } from '../../../awsService/appBuilder/serverlessLand/metadataManager' -import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports import fs from '../../../shared/fs/fs' import { AppBuilderRootNode } from '../../../awsService/appBuilder/explorer/nodes/rootNode' import * as sinon from 'sinon' @@ -22,7 +21,7 @@ describe('Serverless Land Integration', async () => { __dirname, '../../../../../src/awsService/appBuilder/serverlessLand/metadata.json' ) - const metadataContent = nodefs.readFileSync(metadataPath, { encoding: 'utf-8' }) + const metadataContent = await fs.readFileText(metadataPath) const parseMetadata = JSON.parse(metadataContent) as ProjectMetadata const workspaceFolder = vscode.workspace.workspaceFolders![0] const projectFolder = 'my-project-from-Serverless-Land' @@ -109,7 +108,7 @@ describe('Serverless Land Integration', async () => { ) as AppNode | undefined ) - assert.ok(projectNode) + assert.ok(projectNode, 'Expect Serverless Landa project as a project node in Application Builder') // Check App Builder resources const resourceNodes = await projectNode.getChildren() From 290cb509f4d3e7fdf62bcd75b6a060a7710bc391 Mon Sep 17 00:00:00 2001 From: vicheey Date: Tue, 4 Mar 2025 13:52:09 -0800 Subject: [PATCH 3/7] Apply suggestions from code review --- .../core/src/testInteg/appBuilder/serverlessLand/main.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index 1431acdf825..183442a1352 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -108,7 +108,7 @@ describe('Serverless Land Integration', async () => { ) as AppNode | undefined ) - assert.ok(projectNode, 'Expect Serverless Landa project as a project node in Application Builder') + assert.ok(projectNode, 'Expect Serverless Land project node in Application Builder') // Check App Builder resources const resourceNodes = await projectNode.getChildren() From 18054cc3e8366f5357dda407076810b5c49d6510 Mon Sep 17 00:00:00 2001 From: vicheey Date: Tue, 4 Mar 2025 14:59:43 -0800 Subject: [PATCH 4/7] Update packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts --- .../core/src/testInteg/appBuilder/serverlessLand/main.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index 183442a1352..2f6017d01a0 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -38,7 +38,7 @@ describe('Serverless Land Integration', async () => { await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) }) - describe(':) Path', async () => { + describe('Happy Path', async () => { it('creates an AppBuilderRootNode with correct label', async () => { /** * Selection: From 6cfe2c1659feb6f14701a06ee7a5c05d8017d0bb Mon Sep 17 00:00:00 2001 From: Vichym Date: Tue, 4 Mar 2025 15:12:58 -0800 Subject: [PATCH 5/7] fix integration test failure --- .../appBuilder/serverlessLand/main.test.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index 2f6017d01a0..e9210b0cb2c 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -36,10 +36,11 @@ describe('Serverless Land Integration', async () => { afterEach(async () => { await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) + sandbox.restore() }) describe('Happy Path', async () => { - it('creates an AppBuilderRootNode with correct label', async () => { + it('creates project from Serverless Land integration', async () => { /** * Selection: * - pattern : [Select] 2 apigw-rest-api-lambda-sam @@ -116,11 +117,11 @@ describe('Serverless Land Integration', async () => { assert.ok(resourceNodes[0] instanceof ResourceNode) // Validate Lambda resource configuration - const lamdaResource = resourceNodes[0] as ResourceNode - assert.strictEqual(lamdaResource.resource.resource.Type, 'AWS::Serverless::Function') - assert.strictEqual(lamdaResource.resource.resource.Runtime, 'dotnet8') - assert.strictEqual(lamdaResource.resource.resource.Id, 'HelloWorldFunction') - assert.deepStrictEqual(lamdaResource.resource.resource.Events, [ + const lambdaResource = resourceNodes[0] as ResourceNode + assert.strictEqual(lambdaResource.resource.resource.Type, 'AWS::Serverless::Function') + assert.strictEqual(lambdaResource.resource.resource.Runtime, 'dotnet8') + assert.strictEqual(lambdaResource.resource.resource.Id, 'HelloWorldFunction') + assert.deepStrictEqual(lambdaResource.resource.resource.Events, [ { Id: 'HelloWorld', Type: 'Api', @@ -128,7 +129,7 @@ describe('Serverless Land Integration', async () => { Method: 'get', }, ]) - assert.deepStrictEqual(lamdaResource.resource.resource.Environment, { + assert.deepStrictEqual(lambdaResource.resource.resource.Environment, { Variables: { PARAM1: 'VALUE', }, From 2efef68f94628769fceacf14c484196ff6c80956 Mon Sep 17 00:00:00 2001 From: Vichym Date: Tue, 4 Mar 2025 17:15:32 -0800 Subject: [PATCH 6/7] prevent integ test transient failure due to spying AppBuilder node --- .../appBuilder/serverlessLand/main.test.ts | 19 +++++++++++++------ .../appBuilder/sidebar/appBuilderNode.test.ts | 11 +++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index e9210b0cb2c..4752f631d87 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -26,20 +26,27 @@ describe('Serverless Land Integration', async () => { const workspaceFolder = vscode.workspace.workspaceFolders![0] const projectFolder = 'my-project-from-Serverless-Land' let rootNode: sinon.SinonSpiedInstance - let sandbox: sinon.SinonSandbox - beforeEach(async () => { - sandbox = sinon.createSandbox() + before(async () => { + sinon.createSandbox() await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) - rootNode = sandbox.spy(AppBuilderRootNode.instance) + // rootNode = sinon.spy(AppBuilderRootNode.instance) }) - afterEach(async () => { + after(async () => { await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) - sandbox.restore() + // sinon.restore() }) describe('Happy Path', async () => { + beforeEach(async () => { + rootNode = sinon.spy(AppBuilderRootNode.instance) + }) + + afterEach(() => { + sinon.restore() + }) + it('creates project from Serverless Land integration', async () => { /** * Selection: diff --git a/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts b/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts index c18f28b47d2..7d7c3f4ec89 100644 --- a/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts +++ b/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts @@ -10,7 +10,7 @@ import { detectSamProjects } from '../../../awsService/appBuilder/explorer/detec import { SamAppLocation } from '../../../awsService/appBuilder/explorer/samProject' import { AppNode } from '../../../awsService/appBuilder/explorer/nodes/appNode' import { ResourceNode } from '../../../awsService/appBuilder/explorer/nodes/resourceNode' -import sinon from 'sinon' +import * as sinon from 'sinon' import { writeSamconfigGlobal, SamConfig } from '../../../shared/sam/config' import { globals, sleep } from '../../../shared' import path from 'path' @@ -18,21 +18,20 @@ import path from 'path' describe('Application Builder', async () => { let rootNode: sinon.SinonSpiedInstance let projects: SamAppLocation[] - let sandbox: sinon.SinonSandbox let originalWalkThroughState: boolean let projectNodes: any[] before(async () => { - sandbox = sinon.createSandbox() // Set the workspace to the testFixtures folder to avoid side effects from other tests. - sandbox.stub(vscode.workspace, 'workspaceFolders').value([ + sinon.stub(vscode.workspace, 'workspaceFolders').value([ { index: 0, name: 'workspaceFolder', uri: vscode.Uri.file(path.join(__dirname, '../../../../src/testFixtures/workspaceFolder')), }, ]) - rootNode = sandbox.spy(AppBuilderRootNode.instance) + rootNode = sinon.spy(AppBuilderRootNode.instance) + projects = await detectSamProjects() // Set the walkthrough status to true to ensure the root node has a walkthrough node @@ -41,9 +40,9 @@ describe('Application Builder', async () => { }) after(async () => { - sandbox.restore() // Restore original status of walkthroughCompleted status await globals.globalState.update('aws.toolkit.lambda.walkthroughCompleted', originalWalkThroughState) + sinon.restore() }) describe('root node', async () => { From 92735e35e44c2e82a66a4dd5910eb832ac6b8fa7 Mon Sep 17 00:00:00 2001 From: Vichym Date: Wed, 5 Mar 2025 10:37:43 -0800 Subject: [PATCH 7/7] use sandbox instance instead of sinon --- .../appBuilder/serverlessLand/main.test.ts | 202 +++++++++--------- .../appBuilder/sidebar/appBuilderNode.test.ts | 8 +- 2 files changed, 101 insertions(+), 109 deletions(-) diff --git a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts index 4752f631d87..7b2154ecf30 100644 --- a/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts +++ b/packages/core/src/testInteg/appBuilder/serverlessLand/main.test.ts @@ -26,123 +26,113 @@ describe('Serverless Land Integration', async () => { const workspaceFolder = vscode.workspace.workspaceFolders![0] const projectFolder = 'my-project-from-Serverless-Land' let rootNode: sinon.SinonSpiedInstance + let sandbox: sinon.SinonSandbox - before(async () => { - sinon.createSandbox() + beforeEach(async () => { + sandbox = sinon.createSandbox() await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) - // rootNode = sinon.spy(AppBuilderRootNode.instance) + rootNode = sandbox.spy(AppBuilderRootNode.instance) }) - after(async () => { + afterEach(async () => { await fs.delete(path.join(workspaceFolder.uri.fsPath, projectFolder), { recursive: true }) - // sinon.restore() + sandbox.restore() }) - describe('Happy Path', async () => { - beforeEach(async () => { - rootNode = sinon.spy(AppBuilderRootNode.instance) - }) - - afterEach(() => { - sinon.restore() - }) - - it('creates project from Serverless Land integration', async () => { - /** - * Selection: - * - pattern : [Select] 2 apigw-rest-api-lambda-sam - * - runtime : [Select] 3 dotnet - * - iac : [Select] 1 sam - * - location : [Input] From TestFolder.uri - * - name : [Input] "my-project-from-Serverless-Land" - */ - - const testWindow = getTestWindow() - const prompterTester = PrompterTester.init({ testWindow }) - .handleQuickPick('Select a Pattern for your application', async (quickPick) => { - await quickPick.untilReady() - const options = quickPick.items - Object.entries(parseMetadata.patterns).map(([key, pattern]) => { - options.find((option) => option.label === key && option.detail === pattern.description) - }) - quickPick.acceptItem(quickPick.items[1]) - }) - .handleQuickPick('Select Runtime', async (quickPick) => { - await quickPick.untilReady() - const options = quickPick.items - assert.strictEqual(options[0].label, 'python') - assert.strictEqual(options[1].label, 'javascript') - assert.strictEqual(options[2].label, 'java') - assert.strictEqual(options[3].label, 'dotnet') - quickPick.acceptItem(options[3]) + it('creates project from Serverless Land integration', async () => { + /** + * Selection: + * - pattern : [Select] 2 apigw-rest-api-lambda-sam + * - runtime : [Select] 3 dotnet + * - iac : [Select] 1 sam + * - location : [Input] From TestFolder.uri + * - name : [Input] "my-project-from-Serverless-Land" + */ + + const testWindow = getTestWindow() + const prompterTester = PrompterTester.init({ testWindow }) + .handleQuickPick('Select a Pattern for your application', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + Object.entries(parseMetadata.patterns).map(([key, pattern]) => { + options.find((option) => option.label === key && option.detail === pattern.description) }) - .handleQuickPick('Select IaC', async (quickPick) => { - await quickPick.untilReady() - const options = quickPick.items - assert.strictEqual(options[0].label, 'sam') - quickPick.acceptItem(options[0]) - }) - .handleQuickPick('Select Project Location', async (quickPick) => { - await quickPick.untilReady() - const options = quickPick.items - assert.strictEqual(options[0].label, '$(folder) workspaceFolder') - assert.strictEqual(options[1].label, '$(folder-opened) Select a folder...') - quickPick.acceptItem(options[0]) - }) - .handleInputBox('Enter Project Name', (inputBox) => { - inputBox.acceptValue('my-project-from-Serverless-Land') - }) - .build() - - // Validate that the README.md is shown. - testWindow.onDidChangeActiveTextEditor((editors) => { - assert(editors) - const readMe = path.join(workspaceFolder.uri.fsPath, projectFolder, 'README.md') - assert.strictEqual(editors?.document.fileName, readMe) + quickPick.acceptItem(quickPick.items[1]) }) - - await vscode.commands.executeCommand('aws.toolkit.lambda.createServerlessLandProject') - - // projectNodes set from previous step - - const projectNode = await rootNode - .getChildren() - .then( - (children) => - children.find( - (node) => - node instanceof AppNode && - node.label === 'workspaceFolder/my-project-from-Serverless-Land' - ) as AppNode | undefined - ) - - assert.ok(projectNode, 'Expect Serverless Land project node in Application Builder') - - // Check App Builder resources - const resourceNodes = await projectNode.getChildren() - assert.strictEqual(resourceNodes.length, 1) - assert.ok(resourceNodes[0] instanceof ResourceNode) - - // Validate Lambda resource configuration - const lambdaResource = resourceNodes[0] as ResourceNode - assert.strictEqual(lambdaResource.resource.resource.Type, 'AWS::Serverless::Function') - assert.strictEqual(lambdaResource.resource.resource.Runtime, 'dotnet8') - assert.strictEqual(lambdaResource.resource.resource.Id, 'HelloWorldFunction') - assert.deepStrictEqual(lambdaResource.resource.resource.Events, [ - { - Id: 'HelloWorld', - Type: 'Api', - Path: '/hello', - Method: 'get', - }, - ]) - assert.deepStrictEqual(lambdaResource.resource.resource.Environment, { - Variables: { - PARAM1: 'VALUE', - }, + .handleQuickPick('Select Runtime', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, 'python') + assert.strictEqual(options[1].label, 'javascript') + assert.strictEqual(options[2].label, 'java') + assert.strictEqual(options[3].label, 'dotnet') + quickPick.acceptItem(options[3]) + }) + .handleQuickPick('Select IaC', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, 'sam') + quickPick.acceptItem(options[0]) }) + .handleQuickPick('Select Project Location', async (quickPick) => { + await quickPick.untilReady() + const options = quickPick.items + assert.strictEqual(options[0].label, '$(folder) workspaceFolder') + assert.strictEqual(options[1].label, '$(folder-opened) Select a folder...') + quickPick.acceptItem(options[0]) + }) + .handleInputBox('Enter Project Name', (inputBox) => { + inputBox.acceptValue('my-project-from-Serverless-Land') + }) + .build() - prompterTester.assertCallAll() + // Validate that the README.md is shown. + testWindow.onDidChangeActiveTextEditor((editors) => { + assert(editors) + const readMe = path.join(workspaceFolder.uri.fsPath, projectFolder, 'README.md') + assert.strictEqual(editors?.document.fileName, readMe) }) + + await vscode.commands.executeCommand('aws.toolkit.lambda.createServerlessLandProject') + + // projectNodes set from previous step + + const projectNode = await rootNode + .getChildren() + .then( + (children) => + children.find( + (node) => + node instanceof AppNode && node.label === 'workspaceFolder/my-project-from-Serverless-Land' + ) as AppNode | undefined + ) + + assert.ok(projectNode, 'Expect Serverless Land project node in Application Builder') + + // Check App Builder resources + const resourceNodes = await projectNode.getChildren() + assert.strictEqual(resourceNodes.length, 1) + assert.ok(resourceNodes[0] instanceof ResourceNode) + + // Validate Lambda resource configuration + const lambdaResource = resourceNodes[0] as ResourceNode + assert.strictEqual(lambdaResource.resource.resource.Type, 'AWS::Serverless::Function') + assert.strictEqual(lambdaResource.resource.resource.Runtime, 'dotnet8') + assert.strictEqual(lambdaResource.resource.resource.Id, 'HelloWorldFunction') + assert.deepStrictEqual(lambdaResource.resource.resource.Events, [ + { + Id: 'HelloWorld', + Type: 'Api', + Path: '/hello', + Method: 'get', + }, + ]) + assert.deepStrictEqual(lambdaResource.resource.resource.Environment, { + Variables: { + PARAM1: 'VALUE', + }, + }) + + prompterTester.assertCallAll() }) }) diff --git a/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts b/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts index 7d7c3f4ec89..bb5cdc4cc34 100644 --- a/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts +++ b/packages/core/src/testInteg/appBuilder/sidebar/appBuilderNode.test.ts @@ -20,17 +20,19 @@ describe('Application Builder', async () => { let projects: SamAppLocation[] let originalWalkThroughState: boolean let projectNodes: any[] + let sandbox: sinon.SinonSandbox before(async () => { + sandbox = sinon.createSandbox() // Set the workspace to the testFixtures folder to avoid side effects from other tests. - sinon.stub(vscode.workspace, 'workspaceFolders').value([ + sandbox.stub(vscode.workspace, 'workspaceFolders').value([ { index: 0, name: 'workspaceFolder', uri: vscode.Uri.file(path.join(__dirname, '../../../../src/testFixtures/workspaceFolder')), }, ]) - rootNode = sinon.spy(AppBuilderRootNode.instance) + rootNode = sandbox.spy(AppBuilderRootNode.instance) projects = await detectSamProjects() @@ -42,7 +44,7 @@ describe('Application Builder', async () => { after(async () => { // Restore original status of walkthroughCompleted status await globals.globalState.update('aws.toolkit.lambda.walkthroughCompleted', originalWalkThroughState) - sinon.restore() + sandbox.restore() }) describe('root node', async () => {