mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-22 19:23:22 +00:00
Compare commits
2 Commits
master
...
users/saks
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56bc65f5fb | ||
|
|
6c2ad8b001 |
169
test/sql/scaleAndSettings/dataMasking.spec.ts
Normal file
169
test/sql/scaleAndSettings/dataMasking.spec.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import { expect, Page, test } from "@playwright/test";
|
||||
import { CommandBarButton, DataExplorer, ONE_MINUTE_MS, TestAccount } from "../../fx";
|
||||
import { createTestSQLContainer, TestContainerContext } from "../../testData";
|
||||
|
||||
/**
|
||||
* Tests for Dynamic Data Masking (DDM) feature.
|
||||
*
|
||||
* Prerequisites:
|
||||
* - Test account must have the EnableDynamicDataMasking capability enabled
|
||||
* - If the capability is not enabled, the DataMaskingTab will not be visible and tests will be skipped
|
||||
*
|
||||
* Important Notes:
|
||||
* - Once DDM is enabled on a container, it cannot be disabled (isPolicyEnabled cannot be set to false)
|
||||
* - Tests focus on enabling DDM and modifying the masking policy configuration
|
||||
*/
|
||||
test.describe("Data Masking under Scale & Settings", () => {
|
||||
let context: TestContainerContext = null!;
|
||||
let explorer: DataExplorer = null!;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open Data Masking tab under Scale & Settings", async ({ page }) => {
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
|
||||
// Click Scale & Settings
|
||||
await explorer.openScaleAndSettings(context);
|
||||
|
||||
// Check if Data Masking tab is available (requires EnableDynamicDataMasking capability)
|
||||
const dataMaskingTab = explorer.frame.getByTestId("settings-tab-header/DataMaskingTab");
|
||||
const isTabVisible = await dataMaskingTab.isVisible().catch(() => false);
|
||||
|
||||
if (!isTabVisible) {
|
||||
test.skip(
|
||||
true,
|
||||
"Data Masking tab is not available. Test account may not have EnableDynamicDataMasking capability.",
|
||||
);
|
||||
}
|
||||
|
||||
await dataMaskingTab.click();
|
||||
});
|
||||
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
|
||||
test("Data Masking editor should be visible", async () => {
|
||||
// Verify the Data Masking editor is visible
|
||||
const dataMaskingEditor = explorer.frame.locator(".settingsV2Editor");
|
||||
await expect(dataMaskingEditor).toBeVisible();
|
||||
});
|
||||
|
||||
test("Enable data masking policy with valid JSON", async ({ page }) => {
|
||||
await clearDataMaskingEditorContent({ page });
|
||||
|
||||
// Type a valid data masking policy
|
||||
// Note: Once DDM is enabled on a container, it cannot be disabled
|
||||
const validPolicy = JSON.stringify(
|
||||
{
|
||||
includedPaths: [
|
||||
{
|
||||
path: "/email",
|
||||
strategy: "Default",
|
||||
startPosition: 0,
|
||||
length: -1,
|
||||
},
|
||||
],
|
||||
excludedPaths: [],
|
||||
isPolicyEnabled: true,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
|
||||
await page.keyboard.type(validPolicy);
|
||||
|
||||
// Wait a moment for the changes to be processed
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Click Save button
|
||||
const saveButton = explorer.commandBarButton(CommandBarButton.Save);
|
||||
await expect(saveButton).toBeEnabled();
|
||||
await saveButton.click();
|
||||
|
||||
// Verify success message
|
||||
await expect(explorer.getConsoleHeaderStatus()).toContainText(
|
||||
`Successfully updated container ${context.container.id}`,
|
||||
{
|
||||
timeout: 2 * ONE_MINUTE_MS,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("Show validation error for invalid JSON", async ({ page }) => {
|
||||
await clearDataMaskingEditorContent({ page });
|
||||
|
||||
// Type invalid JSON
|
||||
await page.keyboard.type("{invalid json}");
|
||||
|
||||
// Wait a moment for validation
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Save button should be disabled due to invalid JSON
|
||||
const saveButton = explorer.commandBarButton(CommandBarButton.Save);
|
||||
await expect(saveButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test("Update data masking policy with multiple paths", async ({ page }) => {
|
||||
await clearDataMaskingEditorContent({ page });
|
||||
|
||||
// Type a policy with multiple included paths and excluded paths
|
||||
const multiPathPolicy = JSON.stringify(
|
||||
{
|
||||
includedPaths: [
|
||||
{
|
||||
path: "/email",
|
||||
strategy: "Default",
|
||||
startPosition: 0,
|
||||
length: -1,
|
||||
},
|
||||
{
|
||||
path: "/phoneNumber",
|
||||
strategy: "Default",
|
||||
startPosition: 0,
|
||||
length: -1,
|
||||
},
|
||||
],
|
||||
excludedPaths: ["/id", "/timestamp"],
|
||||
isPolicyEnabled: true,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
|
||||
await page.keyboard.type(multiPathPolicy);
|
||||
|
||||
// Wait a moment for the changes to be processed
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Click Save button
|
||||
const saveButton = explorer.commandBarButton(CommandBarButton.Save);
|
||||
await expect(saveButton).toBeEnabled();
|
||||
await saveButton.click();
|
||||
|
||||
// Verify success message
|
||||
await expect(explorer.getConsoleHeaderStatus()).toContainText(
|
||||
`Successfully updated container ${context.container.id}`,
|
||||
{
|
||||
timeout: 2 * ONE_MINUTE_MS,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper function to clear the data masking editor content.
|
||||
*/
|
||||
const clearDataMaskingEditorContent = async ({ page }: { page: Page }): Promise<void> => {
|
||||
// Wait for the Monaco editor to be visible
|
||||
await explorer.frame.waitForSelector(".settingsV2Editor", { state: "visible" });
|
||||
const dataMaskingEditor = explorer.frame.locator(".settingsV2Editor");
|
||||
await dataMaskingEditor.click();
|
||||
|
||||
// Clear existing content (Ctrl+A + Backspace does not work reliably with webkit)
|
||||
for (let i = 0; i < 100; i++) {
|
||||
await page.keyboard.press("Backspace");
|
||||
}
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user