feat: Redesign container-copy flow to select destination account and enable cross-account container creation (#2436)

* feat: Redesign container-copy flow to select destination account and enable cross-account container creation

* upgrade RBAC permissions from read only to read-write

* fix copyjob playwright tests

* swap source-destination content

* fix formating

* use targetAccountOverride for capability checks in AddCollectionPanel

* feat: localize ContainerCopy hardcoded strings using i18next and refactor readDatabasesWithARM

* removed container copy messages json file
This commit is contained in:
BChoudhury-ms
2026-05-11 17:24:51 +05:30
committed by GitHub
parent 762e12a3f9
commit d374458e1b
81 changed files with 1810 additions and 1076 deletions
@@ -10,13 +10,14 @@ test.describe("Container Copy - Permission Screen Verification", () => {
let wrapper: Locator;
let panel: Locator;
let frame: Frame;
let sourceAccountName: string;
let targetAccountName: string;
let expectedSourceAccountName: string;
test.beforeEach("Setup for each test", async ({ browser }) => {
page = await browser.newPage();
({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly));
({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQL));
targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly);
sourceAccountName = getAccountName(TestAccount.SQL);
});
test.afterEach("Cleanup after each test", async () => {
@@ -80,22 +81,14 @@ test.describe("Container Copy - Permission Screen Verification", () => {
const allDropdownItems = await dropdownItemsWrapper.locator(`button.ms-Dropdown-item[role='option']`).all();
const filteredItems = [];
for (const item of allDropdownItems) {
const testContent = (await item.textContent()) ?? "";
if (testContent.trim() !== targetAccountName.trim()) {
filteredItems.push(item);
if (testContent.trim() === targetAccountName.trim()) {
await item.click();
break;
}
}
if (filteredItems.length > 0) {
const firstDropdownItem = filteredItems[0];
expectedSourceAccountName = (await firstDropdownItem.textContent()) ?? "";
await firstDropdownItem.click();
} else {
throw new Error("No dropdown items available after filtering");
}
// Enable online migration mode
const migrationTypeContainer = panel.getByTestId("migration-type");
const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i });
@@ -111,7 +104,7 @@ test.describe("Container Copy - Permission Screen Verification", () => {
await expect(permissionScreen.getByText("Cross-account container copy", { exact: true })).toBeVisible();
// Setup API mocking for the source account
await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}**`, async (route) => {
await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}**`, async (route) => {
const mockData = {
identity: {
type: "SystemAssigned",
@@ -169,7 +162,7 @@ test.describe("Container Copy - Permission Screen Verification", () => {
// Verify new page opens with correct URL pattern
page.context().on("page", async (newPage) => {
const expectedUrlEndPattern = new RegExp(
`/providers/Microsoft.(DocumentDB|DocumentDb)/databaseAccounts/${expectedSourceAccountName}/backupRestore`,
`/providers/Microsoft.(DocumentDB|DocumentDb)/databaseAccounts/${sourceAccountName}/backupRestore`,
);
expect(newPage.url()).toMatch(expectedUrlEndPattern);
await newPage.close();
@@ -188,8 +181,10 @@ test.describe("Container Copy - Permission Screen Verification", () => {
await expect(pitrBtn).not.toBeVisible();
// Setup additional API mocks for role assignments and permissions
// In the redesigned flow, role assignments are checked on the SOURCE account (current account = sourceAccountName).
// The destination account (selectedAccountName) manages identity; source account holds the role assignments.
await page.route(
`**/Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}/sqlRoleAssignments*`,
`**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}/sqlRoleAssignments*`,
async (route) => {
await route.fulfill({
status: 200,
@@ -198,7 +193,7 @@ test.describe("Container Copy - Permission Screen Verification", () => {
value: [
{
principalId: "00-11-22-33",
roleDefinitionId: `Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}/77-88-99`,
roleDefinitionId: `Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}/77-88-99`,
},
],
}),
@@ -213,14 +208,15 @@ test.describe("Container Copy - Permission Screen Verification", () => {
body: JSON.stringify({
value: [
{
name: "00000000-0000-0000-0000-000000000001",
// Built-in Cosmos DB Data Contributor role (read-write), required by checkTargetHasReadWriteRoleOnSource
name: "00000000-0000-0000-0000-000000000002",
},
],
}),
});
});
await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${targetAccountName}**`, async (route) => {
await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}**`, async (route) => {
const mockData = {
identity: {
type: "SystemAssigned",