diff --git a/src/Common/dataAccess/createTrigger.ts b/src/Common/dataAccess/createTrigger.ts index dd4ec1af5..c1cda22be 100644 --- a/src/Common/dataAccess/createTrigger.ts +++ b/src/Common/dataAccess/createTrigger.ts @@ -3,7 +3,7 @@ import { AuthType } from "../../AuthType"; import { userContext } from "../../UserContext"; import { createUpdateSqlTrigger, getSqlTrigger } from "../../Utils/arm/generatedClients/cosmos/sqlResources"; import { SqlTriggerCreateUpdateParameters, SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types"; -import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { client } from "../CosmosClient"; import { handleError } from "../ErrorHandlingUtils"; @@ -14,6 +14,7 @@ export async function createTrigger( ): Promise { const clearMessage = logConsoleProgress(`Creating trigger ${trigger.id}`); try { + let resource: SqlTriggerResource | TriggerDefinition; if ( userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations && @@ -52,14 +53,16 @@ export async function createTrigger( trigger.id, createTriggerParams, ); - return rpResponse && rpResponse.properties?.resource; + resource = rpResponse && rpResponse.properties?.resource; + } else { + const sdkResponse = await client() + .database(databaseId) + .container(collectionId) + .scripts.triggers.create(trigger as unknown as TriggerDefinition); // TODO: TypeScript does not like the SQL SDK trigger type + resource = sdkResponse.resource; } - - const response = await client() - .database(databaseId) - .container(collectionId) - .scripts.triggers.create(trigger as unknown as TriggerDefinition); // TODO: TypeScript does not like the SQL SDK trigger type - return response.resource; + logConsoleInfo(`Successfully created trigger ${trigger.id}`); + return resource; } catch (error) { handleError(error, "CreateTrigger", `Error while creating trigger ${trigger.id}`); throw error; diff --git a/src/Common/dataAccess/createUserDefinedFunction.ts b/src/Common/dataAccess/createUserDefinedFunction.ts index 3d1bca86e..c2ac4c489 100644 --- a/src/Common/dataAccess/createUserDefinedFunction.ts +++ b/src/Common/dataAccess/createUserDefinedFunction.ts @@ -9,7 +9,7 @@ import { SqlUserDefinedFunctionCreateUpdateParameters, SqlUserDefinedFunctionResource, } from "../../Utils/arm/generatedClients/cosmos/types"; -import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; +import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { client } from "../CosmosClient"; import { handleError } from "../ErrorHandlingUtils"; @@ -20,6 +20,7 @@ export async function createUserDefinedFunction( ): Promise { const clearMessage = logConsoleProgress(`Creating user defined function ${userDefinedFunction.id}`); try { + let resource: UserDefinedFunctionDefinition & Resource; if ( userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations && @@ -60,14 +61,17 @@ export async function createUserDefinedFunction( userDefinedFunction.id, createUDFParams, ); - return rpResponse && (rpResponse.properties?.resource as UserDefinedFunctionDefinition & Resource); - } - const response = await client() - .database(databaseId) - .container(collectionId) - .scripts.userDefinedFunctions.create(userDefinedFunction); - return response?.resource; + resource = rpResponse && (rpResponse.properties?.resource as UserDefinedFunctionDefinition & Resource); + } else { + const response = await client() + .database(databaseId) + .container(collectionId) + .scripts.userDefinedFunctions.create(userDefinedFunction); + resource = response.resource; + } + logConsoleInfo(`Successfully created user defined function ${userDefinedFunction.id}`); + return resource; } catch (error) { handleError( error, diff --git a/test/sql/scripts/trigger.spec.ts b/test/sql/scripts/trigger.spec.ts new file mode 100644 index 000000000..23f37c2c4 --- /dev/null +++ b/test/sql/scripts/trigger.spec.ts @@ -0,0 +1,64 @@ +import { expect, test } from "@playwright/test"; +import { CommandBarButton, DataExplorer, ONE_MINUTE_MS, TestAccount } from "../../fx"; +import { createTestSQLContainer, TestContainerContext } from "../../testData"; + +test.describe("Triggers", () => { + let context: TestContainerContext = null!; + let explorer: DataExplorer = null!; + const triggerBody = `function validateToDoItemTimestamp() { + var context = getContext(); + var request = context.getRequest(); + + var itemToCreate = request.getBody(); + + if (!("timestamp" in itemToCreate)) { + var ts = new Date(); + itemToCreate["timestamp"] = ts.getTime(); + } + + request.setBody(itemToCreate); + }`; + test.beforeAll("Create Test Database", async () => { + context = await createTestSQLContainer(true); + }); + + test.beforeEach("Open container", async ({ page }) => { + explorer = await DataExplorer.open(page, TestAccount.SQL); + }); + + if (!process.env.CI) { + test.afterAll("Delete Test Database", async () => { + await context?.dispose(); + }); + } + + test("Add and delete trigger", async ({ page }) => { + // Open container context menu and click New Trigger + const containerNode = await explorer.waitForContainerNode(context.database.id, context.container.id); + await containerNode.openContextMenu(); + await containerNode.contextMenuItem("New Trigger").click(); + + // Assign Trigger id + const triggerIdTextBox = explorer.frame.getByLabel("Trigger Id"); + const triggerId: string = "validateItemTimestamp"; + await triggerIdTextBox.fill(triggerId); + + // Create Trigger body that validates item timestamp + const triggerBodyTextArea = explorer.frame.getByTestId("EditorReact/Host/Loaded"); + await triggerBodyTextArea.click(); + + // Clear existing content + const isMac: boolean = process.platform === "darwin"; + await page.keyboard.press(isMac ? "Meta+A" : "Control+A"); + await page.keyboard.press("Backspace"); + + await page.keyboard.type(triggerBody); + + // Save changes + const saveButton = explorer.commandBarButton(CommandBarButton.Save); + await saveButton.click(); + await expect(explorer.getConsoleMessage()).toContainText(`Successfully created trigger ${triggerId}`, { + timeout: 2 * ONE_MINUTE_MS, + }); + }); +}); diff --git a/test/sql/scripts/userDefinedFunction.spec.ts b/test/sql/scripts/userDefinedFunction.spec.ts index 7b048898a..615f0391c 100644 --- a/test/sql/scripts/userDefinedFunction.spec.ts +++ b/test/sql/scripts/userDefinedFunction.spec.ts @@ -5,11 +5,11 @@ import { createTestSQLContainer, TestContainerContext } from "../../testData"; test.describe("User Defined Functions", () => { let context: TestContainerContext = null!; let explorer: DataExplorer = null!; - const udfBody = `function extractDocumentId(doc) { + const udfBody: string = `function extractDocumentId(doc) { return { - id: doc.id + id: doc.id }; - }`; + }`; test.beforeAll("Create Test Database", async () => { context = await createTestSQLContainer(true); @@ -19,9 +19,11 @@ test.describe("User Defined Functions", () => { explorer = await DataExplorer.open(page, TestAccount.SQL); }); - test.afterAll("Delete Test Database", async () => { - await context?.dispose(); - }); + if (!process.env.CI) { + test.afterAll("Delete Test Database", async () => { + await context?.dispose(); + }); + } test("Add, execute, and delete user defined function", async ({ page }) => { // Open container context menu and click New UDF @@ -31,8 +33,8 @@ test.describe("User Defined Functions", () => { // Assign UDF id const udfIdTextBox = explorer.frame.getByLabel("User Defined Function Id"); - const udfName: string = "extractDocumentId"; - await udfIdTextBox.fill(udfName); + const udfId: string = "extractDocumentId"; + await udfIdTextBox.fill(udfId); // Create UDF body that extracts the document id from a document const udfBodyTextArea = explorer.frame.getByTestId("EditorReact/Host/Loaded"); @@ -49,7 +51,7 @@ test.describe("User Defined Functions", () => { const saveButton = explorer.commandBarButton(CommandBarButton.Save); await expect(saveButton).toBeEnabled(); await saveButton.click(); - await expect(explorer.getConsoleMessage()).toContainText(`Sucessfully created user defined function ${udfName}`, { + await expect(explorer.getConsoleMessage()).toContainText(`Successfully created user defined function ${udfId}`, { timeout: ONE_MINUTE_MS, }); @@ -60,14 +62,14 @@ test.describe("User Defined Functions", () => { ); await udfsNode.expand(); const udfNode = await explorer.waitForNode( - `${context.database.id}/${context.container.id}/User Defined Functions/${udfName}`, + `${context.database.id}/${context.container.id}/User Defined Functions/${udfId}`, ); await udfNode.openContextMenu(); await udfNode.contextMenuItem("Delete User Defined Function").click(); const deleteUserDefinedFunctionButton = explorer.frame.getByTestId("DialogButton:Delete"); await deleteUserDefinedFunctionButton.click(); - await expect(explorer.getConsoleMessage()).toContainText(`Successfully deleted user defined function ${udfName}`, { + await expect(explorer.getConsoleMessage()).toContainText(`Successfully deleted user defined function ${udfId}`, { timeout: ONE_MINUTE_MS, }); });