swap source-destination content

This commit is contained in:
Bikram Choudhury
2026-04-21 01:20:41 +05:30
parent 779f3da8df
commit e0d4e67928
14 changed files with 137 additions and 107 deletions

View File

@@ -66,7 +66,7 @@ export default {
// Assign Permissions Screen // Assign Permissions Screen
assignPermissions: { assignPermissions: {
crossAccountDescription: crossAccountDescription:
"To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps.", "To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.",
intraAccountOnlineDescription: (accountName: string) => intraAccountOnlineDescription: (accountName: string) =>
`Follow the steps below to enable online copy on your "${accountName}" account.`, `Follow the steps below to enable online copy on your "${accountName}" account.`,
crossAccountConfiguration: { crossAccountConfiguration: {
@@ -122,7 +122,7 @@ export default {
readWritePermissionAssigned: { readWritePermissionAssigned: {
title: "Read-write permissions assigned to the default identity.", title: "Read-write permissions assigned to the default identity.",
description: description:
"To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account.", "To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.",
tooltip: { tooltip: {
content: "Learn more about", content: "Learn more about",
hrefText: "Read-write permissions.", hrefText: "Read-write permissions.",
@@ -130,7 +130,7 @@ export default {
}, },
popoverTitle: "Assign read-write permissions to default identity.", popoverTitle: "Assign read-write permissions to default identity.",
popoverDescription: popoverDescription:
'Assign read-write permissions on the source account to the default identity of the destination account. To confirm, click the "Yes" button.', 'Assign read-write permissions on the destination account to the default identity of the source account. To confirm, click the "Yes" button.',
}, },
pointInTimeRestore: { pointInTimeRestore: {
title: "Point In Time Restore enabled", title: "Point In Time Restore enabled",

View File

@@ -198,7 +198,7 @@ describe("AddManagedIdentity", () => {
it("displays correct enablement description with account name", () => { it("displays correct enablement description with account name", () => {
const expectedDescription = ContainerCopyMessages.addManagedIdentity.enablementDescription( const expectedDescription = ContainerCopyMessages.addManagedIdentity.enablementDescription(
mockCopyJobState.target.account.name, mockCopyJobState.source.account.name,
); );
expect(screen.getByText(expectedDescription)).toBeInTheDocument(); expect(screen.getByText(expectedDescription)).toBeInTheDocument();
}); });

View File

@@ -53,7 +53,7 @@ const AddManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
onCancel={() => onToggle(null, false)} onCancel={() => onToggle(null, false)}
onPrimary={handleAddSystemIdentity} onPrimary={handleAddSystemIdentity}
> >
{ContainerCopyMessages.addManagedIdentity.enablementDescription(copyJobState.target?.account?.name)} {ContainerCopyMessages.addManagedIdentity.enablementDescription(copyJobState.source?.account?.name)}
</PopoverMessage> </PopoverMessage>
</Stack> </Stack>
); );

View File

@@ -96,6 +96,10 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
properties: { properties: {
documentEndpoint: "https://source-account.documents.azure.com:443/", documentEndpoint: "https://source-account.documents.azure.com:443/",
}, },
identity: {
principalId: "source-principal-id",
type: "SystemAssigned",
},
}, },
databaseId: "source-db", databaseId: "source-db",
containerId: "source-container", containerId: "source-container",
@@ -245,9 +249,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it("should call handleAddReadWritePermission when primary button is clicked", async () => { it("should call handleAddReadWritePermission when primary button is clicked", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType); mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType);
@@ -258,7 +262,7 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
await waitFor(() => { await waitFor(() => {
expect(mockGetAccountDetailsFromResourceId).toHaveBeenCalledWith( expect(mockGetAccountDetailsFromResourceId).toHaveBeenCalledWith(
"/subscriptions/source-sub-id/resourceGroups/source-rg/providers/Microsoft.DocumentDB/databaseAccounts/source-account", "/subscriptions/target-sub-id/resourceGroups/target-rg/providers/Microsoft.DocumentDB/databaseAccounts/target-account",
); );
}); });
}); });
@@ -271,9 +275,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it("should successfully assign role and update context", async () => { it("should successfully assign role and update context", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType); mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType);
@@ -284,10 +288,10 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
await waitFor(() => { await waitFor(() => {
expect(mockAssignRole).toHaveBeenCalledWith( expect(mockAssignRole).toHaveBeenCalledWith(
"source-sub-id", "target-sub-id",
"source-rg", "target-rg",
"source-account", "target-account",
"target-principal-id", "source-principal-id",
); );
}); });
@@ -298,9 +302,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it("should handle error when assignRole fails", async () => { it("should handle error when assignRole fails", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockRejectedValue(new Error("Permission denied")); mockAssignRole.mockRejectedValue(new Error("Permission denied"));
@@ -323,9 +327,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it("should handle error without message", async () => { it("should handle error without message", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockRejectedValue({}); mockAssignRole.mockRejectedValue({});
@@ -350,9 +354,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it("should show loading state during role assignment", async () => { it("should show loading state during role assignment", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockImplementation( mockAssignRole.mockImplementation(
@@ -371,9 +375,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
it.skip("should not assign role when assignRole returns falsy", async () => { it.skip("should not assign role when assignRole returns falsy", async () => {
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockResolvedValue(null); mockAssignRole.mockResolvedValue(null);
@@ -431,10 +435,10 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
...mockContextValue, ...mockContextValue,
copyJobState: { copyJobState: {
...mockContextValue.copyJobState, ...mockContextValue.copyJobState,
target: { source: {
...mockContextValue.copyJobState.target, ...mockContextValue.copyJobState.source,
account: { account: {
...mockContextValue.copyJobState.target.account!, ...mockContextValue.copyJobState.source.account!,
identity: { identity: {
principalId: "", principalId: "",
type: "SystemAssigned", type: "SystemAssigned",
@@ -446,9 +450,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
mockUseToggle.mockReturnValue([true, jest.fn()]); mockUseToggle.mockReturnValue([true, jest.fn()]);
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType); mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType);
@@ -458,7 +462,7 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
fireEvent.click(primaryButton); fireEvent.click(primaryButton);
await waitFor(() => { await waitFor(() => {
expect(mockAssignRole).toHaveBeenCalledWith("source-sub-id", "source-rg", "source-account", ""); expect(mockAssignRole).toHaveBeenCalledWith("target-sub-id", "target-rg", "target-account", "");
}); });
}); });
}); });
@@ -476,9 +480,9 @@ describe("AddReadWritePermissionToDefaultIdentity Component", () => {
mockUseToggle.mockReturnValue([true, jest.fn()]); mockUseToggle.mockReturnValue([true, jest.fn()]);
mockGetAccountDetailsFromResourceId.mockReturnValue({ mockGetAccountDetailsFromResourceId.mockReturnValue({
subscriptionId: "source-sub-id", subscriptionId: "target-sub-id",
resourceGroup: "source-rg", resourceGroup: "target-rg",
accountName: "source-account", accountName: "target-account",
}); });
mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType); mockAssignRole.mockResolvedValue({ id: "role-assignment-id" } as RoleAssignmentType);

View File

@@ -33,21 +33,21 @@ const AddReadWritePermissionToDefaultIdentity: React.FC<AddReadWritePermissionTo
const handleAddReadWritePermission = async () => { const handleAddReadWritePermission = async () => {
const { source, target } = copyJobState; const { source, target } = copyJobState;
const selectedSourceAccount = source?.account; const selectedTargetAccount = target?.account;
try { try {
const { const {
subscriptionId: sourceSubscriptionId, subscriptionId: targetSubscriptionId,
resourceGroup: sourceResourceGroup, resourceGroup: targetResourceGroup,
accountName: sourceAccountName, accountName: targetAccountName,
} = getAccountDetailsFromResourceId(selectedSourceAccount?.id); } = getAccountDetailsFromResourceId(selectedTargetAccount?.id);
setLoading(true); setLoading(true);
const assignedRole = await assignRole( const assignedRole = await assignRole(
sourceSubscriptionId, targetSubscriptionId,
sourceResourceGroup, targetResourceGroup,
sourceAccountName, targetAccountName,
target?.account?.identity?.principalId ?? "", source?.account?.identity?.principalId ?? "",
); );
if (assignedRole) { if (assignedRole) {

View File

@@ -106,7 +106,7 @@ const AssignPermissions = () => {
tokens={{ childrenGap: 20 }} tokens={{ childrenGap: 20 }}
> >
<Text variant="medium" style={{ color: "var(--colorNeutralForeground1)" }}> <Text variant="medium" style={{ color: "var(--colorNeutralForeground1)" }}>
{isSameAccount && copyJobState.migrationType === CopyJobMigrationType.Online {isSameAccount && copyJobState?.migrationType === CopyJobMigrationType.Online
? ContainerCopyMessages.assignPermissions.intraAccountOnlineDescription( ? ContainerCopyMessages.assignPermissions.intraAccountOnlineDescription(
copyJobState?.source?.account?.name || "", copyJobState?.source?.account?.name || "",
) )

View File

@@ -69,6 +69,12 @@ const mockUseToggle = useToggle as jest.MockedFunction<typeof useToggle>;
describe("DefaultManagedIdentity", () => { describe("DefaultManagedIdentity", () => {
const mockCopyJobContextValue = { const mockCopyJobContextValue = {
copyJobState: { copyJobState: {
source: {
account: {
name: "test-cosmos-account",
id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDB/databaseAccounts/test-cosmos-account",
},
},
target: { target: {
account: { account: {
name: "test-cosmos-account", name: "test-cosmos-account",
@@ -260,6 +266,12 @@ describe("DefaultManagedIdentity", () => {
const contextValueWithoutAccount = { const contextValueWithoutAccount = {
...mockCopyJobContextValue, ...mockCopyJobContextValue,
copyJobState: { copyJobState: {
source: {
account: {
name: "",
id: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.DocumentDB/databaseAccounts/",
},
},
target: { target: {
account: { account: {
name: "", name: "",
@@ -277,6 +289,9 @@ describe("DefaultManagedIdentity", () => {
const contextValueWithNullAccount = { const contextValueWithNullAccount = {
...mockCopyJobContextValue, ...mockCopyJobContextValue,
copyJobState: { copyJobState: {
source: {
account: null as DatabaseAccount | null,
},
target: { target: {
account: null as DatabaseAccount | null, account: null as DatabaseAccount | null,
}, },

View File

@@ -32,7 +32,7 @@ const DefaultManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
return ( return (
<Stack className="defaultManagedIdentityContainer" tokens={{ childrenGap: 15, padding: "0 0 0 20px" }}> <Stack className="defaultManagedIdentityContainer" tokens={{ childrenGap: 15, padding: "0 0 0 20px" }}>
<div className="toggle-label"> <div className="toggle-label">
{ContainerCopyMessages.defaultManagedIdentity.description(copyJobState?.target?.account?.name)} &nbsp; {ContainerCopyMessages.defaultManagedIdentity.description(copyJobState?.source?.account?.name)} &nbsp;
<InfoTooltip content={managedIdentityTooltip} /> <InfoTooltip content={managedIdentityTooltip} />
</div> </div>
<Toggle <Toggle
@@ -54,7 +54,7 @@ const DefaultManagedIdentity: React.FC<AddManagedIdentityProps> = () => {
onCancel={() => onToggle(null, false)} onCancel={() => onToggle(null, false)}
onPrimary={handleAddSystemIdentity} onPrimary={handleAddSystemIdentity}
> >
{ContainerCopyMessages.defaultManagedIdentity.popoverDescription(copyJobState?.target?.account?.name)} {ContainerCopyMessages.defaultManagedIdentity.popoverDescription(copyJobState?.source?.account?.name)}
</PopoverMessage> </PopoverMessage>
</Stack> </Stack>
); );

View File

@@ -204,7 +204,7 @@ exports[`AddManagedIdentity Snapshot Tests renders loading state 1`] = `
<span <span
class="themeText css-110" class="themeText css-110"
> >
Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. Enable system-assigned managed identity on the source-account-name. To confirm, click the "Yes" button.
</span> </span>
<div <div
class="ms-Stack css-125" class="ms-Stack css-125"
@@ -359,7 +359,7 @@ exports[`AddManagedIdentity Snapshot Tests renders with toggle on and popover vi
<span <span
class="themeText css-110" class="themeText css-110"
> >
Enable system-assigned managed identity on the test-target-account. To confirm, click the "Yes" button. Enable system-assigned managed identity on the source-account-name. To confirm, click the "Yes" button.
</span> </span>
<div <div
class="ms-Stack css-125" class="ms-Stack css-125"

View File

@@ -8,7 +8,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Edge Cases should han
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"
@@ -71,7 +71,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Edge Cases should han
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"
@@ -134,7 +134,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Rendering should rend
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"
@@ -197,7 +197,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Rendering should rend
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"
@@ -260,7 +260,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Rendering should rend
<div <div
data-testid="popover-content" data-testid="popover-content"
> >
Assign read-write permissions on the source account to the default identity of the destination account. To confirm, click the "Yes" button. Assign read-write permissions on the destination account to the default identity of the source account. To confirm, click the "Yes" button.
</div> </div>
<button <button
data-testid="popover-cancel" data-testid="popover-cancel"
@@ -285,7 +285,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Rendering should rend
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"
@@ -348,7 +348,7 @@ exports[`AddReadWritePermissionToDefaultIdentity Component Rendering should rend
<span <span
class="toggle-label css-110" class="toggle-label css-110"
> >
To allow data copy from source to the destination container, provide read-write access on the source account to the default identity of the destination account. To allow data copy from source to the destination container, provide read-write access on the destination account to the default identity of the source account.
<div <div
data-testid="info-tooltip" data-testid="info-tooltip"

View File

@@ -9,7 +9,7 @@ exports[`AssignPermissions Component Accordion Behavior should render accordion
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
class="ms-Stack css-111" class="ms-Stack css-111"
@@ -212,7 +212,7 @@ exports[`AssignPermissions Component Edge Cases should calculate correct indent
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
class="ms-Stack css-111" class="ms-Stack css-111"
@@ -618,7 +618,7 @@ exports[`AssignPermissions Component Edge Cases should handle missing account na
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
class="ms-Stack css-111" class="ms-Stack css-111"
@@ -1153,7 +1153,7 @@ exports[`AssignPermissions Component Permission Groups should render permission
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
class="ms-Stack css-111" class="ms-Stack css-111"
@@ -1307,7 +1307,7 @@ exports[`AssignPermissions Component Rendering should render without crashing wi
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
data-testid="shimmer-tree" data-testid="shimmer-tree"
@@ -1329,7 +1329,7 @@ exports[`AssignPermissions Component Rendering should render without crashing wi
<span <span
class="css-110" class="css-110"
> >
To copy data from the source to the destination container, ensure that the managed identity of the destination account has read-write access to the source account by completing the following steps. To copy data from the source to the destination container, ensure that the managed identity of the source account has read-write access to the destination account by completing the following steps.
</span> </span>
<div <div
data-testid="shimmer-tree" data-testid="shimmer-tree"

View File

@@ -26,18 +26,18 @@ const useManagedIdentity = (
const handleAddSystemIdentity = useCallback(async (): Promise<void> => { const handleAddSystemIdentity = useCallback(async (): Promise<void> => {
try { try {
setLoading(true); setLoading(true);
const selectedTargetAccount = copyJobState?.target?.account; const selectedSourceAccount = copyJobState?.source?.account;
const { const {
subscriptionId: targetSubscriptionId, subscriptionId: sourceSubscriptionId,
resourceGroup: targetResourceGroup, resourceGroup: sourceResourceGroup,
accountName: targetAccountName, accountName: sourceAccountName,
} = getAccountDetailsFromResourceId(selectedTargetAccount?.id) || {}; } = getAccountDetailsFromResourceId(selectedSourceAccount?.id) || {};
const updatedAccount = await updateIdentityFn(targetSubscriptionId, targetResourceGroup, targetAccountName); const updatedAccount = await updateIdentityFn(sourceSubscriptionId, sourceResourceGroup, sourceAccountName);
if (updatedAccount) { if (updatedAccount) {
setCopyJobState((prevState) => ({ setCopyJobState((prevState) => ({
...prevState, ...prevState,
target: { ...prevState.target, account: updatedAccount }, source: { ...prevState.source, account: updatedAccount },
})); }));
} }
} catch (error) { } catch (error) {
@@ -46,7 +46,7 @@ const useManagedIdentity = (
setContextError(errorMessage); setContextError(errorMessage);
setLoading(false); setLoading(false);
} }
}, [copyJobState?.target?.account?.id, updateIdentityFn, setCopyJobState]); }, [copyJobState?.source?.account?.id, updateIdentityFn, setCopyJobState]);
return { loading, handleAddSystemIdentity }; return { loading, handleAddSystemIdentity };
}; };

View File

@@ -5,17 +5,17 @@ import { noop } from "underscore";
import { CapabilityNames } from "../../../../../../Common/Constants"; import { CapabilityNames } from "../../../../../../Common/Constants";
import * as RbacUtils from "../../../../../../Utils/arm/RbacUtils"; import * as RbacUtils from "../../../../../../Utils/arm/RbacUtils";
import { import {
BackupPolicyType, BackupPolicyType,
CopyJobMigrationType, CopyJobMigrationType,
DefaultIdentityType, DefaultIdentityType,
IdentityType, IdentityType,
} from "../../../../Enums/CopyJobEnums"; } from "../../../../Enums/CopyJobEnums";
import { CopyJobContextState } from "../../../../Types/CopyJobTypes"; import { CopyJobContextState } from "../../../../Types/CopyJobTypes";
import * as CopyJobPrerequisitesCacheModule from "../../../Utils/useCopyJobPrerequisitesCache"; import * as CopyJobPrerequisitesCacheModule from "../../../Utils/useCopyJobPrerequisitesCache";
import usePermissionSections, { import usePermissionSections, {
checkTargetHasReadWriteRoleOnSource, checkTargetHasReadWriteRoleOnSource,
PermissionGroupConfig, PermissionGroupConfig,
SECTION_IDS, SECTION_IDS,
} from "./usePermissionsSection"; } from "./usePermissionsSection";
jest.mock("../../../../../../Utils/arm/RbacUtils"); jest.mock("../../../../../../Utils/arm/RbacUtils");
@@ -284,22 +284,25 @@ describe("usePermissionsSection", () => {
describe("Section validation", () => { describe("Section validation", () => {
it("should validate addManagedIdentity section correctly", async () => { it("should validate addManagedIdentity section correctly", async () => {
const stateWithSystemAssigned = createMockState({ const stateWithSystemAssigned = createMockState({
target: { source: {
account: { account: {
id: "target-account-id", id: "source-account-id",
name: "target-account", name: "source-account",
identity: { identity: {
type: IdentityType.SystemAssigned, type: IdentityType.SystemAssigned,
principalId: "principal-123", principalId: "principal-123",
}, },
properties: { properties: {
defaultIdentity: DefaultIdentityType.FirstPartyIdentity, backupPolicy: {
type: BackupPolicyType.Periodic,
},
capabilities: [],
}, },
location: "", location: "",
type: "", type: "",
kind: "", kind: "",
}, },
subscription: undefined, subscriptionId: "",
databaseId: "", databaseId: "",
containerId: "", containerId: "",
}, },
@@ -322,22 +325,26 @@ describe("usePermissionsSection", () => {
it("should validate defaultManagedIdentity section correctly", async () => { it("should validate defaultManagedIdentity section correctly", async () => {
const stateWithSystemAssignedIdentity = createMockState({ const stateWithSystemAssignedIdentity = createMockState({
target: { source: {
account: { account: {
id: "target-account-id", id: "source-account-id",
name: "target-account", name: "source-account",
identity: { identity: {
type: IdentityType.SystemAssigned, type: IdentityType.SystemAssigned,
principalId: "principal-123", principalId: "principal-123",
}, },
properties: { properties: {
defaultIdentity: DefaultIdentityType.SystemAssignedIdentity, defaultIdentity: DefaultIdentityType.SystemAssignedIdentity,
backupPolicy: {
type: BackupPolicyType.Periodic,
},
capabilities: [],
}, },
location: "", location: "",
type: "", type: "",
kind: "", kind: "",
}, },
subscription: undefined, subscriptionId: "",
databaseId: "", databaseId: "",
containerId: "", containerId: "",
}, },
@@ -384,22 +391,26 @@ describe("usePermissionsSection", () => {
mockedRbacUtils.fetchRoleDefinitions.mockResolvedValue(mockRoleDefinitions); mockedRbacUtils.fetchRoleDefinitions.mockResolvedValue(mockRoleDefinitions);
const state = createMockState({ const state = createMockState({
target: { source: {
account: { account: {
id: "target-account-id", id: "source-account-id",
name: "target-account", name: "source-account",
identity: { identity: {
type: IdentityType.SystemAssigned, type: IdentityType.SystemAssigned,
principalId: "principal-123", principalId: "principal-123",
}, },
properties: { properties: {
defaultIdentity: DefaultIdentityType.SystemAssignedIdentity, defaultIdentity: DefaultIdentityType.SystemAssignedIdentity,
backupPolicy: {
type: BackupPolicyType.Periodic,
},
capabilities: [],
}, },
location: "", location: "",
type: "", type: "",
kind: "", kind: "",
}, },
subscription: undefined, subscriptionId: "",
databaseId: "", databaseId: "",
containerId: "", containerId: "",
}, },

View File

@@ -50,10 +50,10 @@ const PERMISSION_SECTIONS_CONFIG: PermissionSectionConfig[] = [
Component: AddManagedIdentity, Component: AddManagedIdentity,
disabled: true, disabled: true,
validate: (state: CopyJobContextState) => { validate: (state: CopyJobContextState) => {
const targetAccountIdentityType = (state?.target?.account?.identity?.type ?? "").toLowerCase(); const sourceAccountIdentityType = (state?.source?.account?.identity?.type ?? "").toLowerCase();
return ( return (
targetAccountIdentityType === IdentityType.SystemAssigned || sourceAccountIdentityType === IdentityType.SystemAssigned ||
targetAccountIdentityType === IdentityType.UserAssigned sourceAccountIdentityType === IdentityType.UserAssigned
); );
}, },
}, },
@@ -63,8 +63,8 @@ const PERMISSION_SECTIONS_CONFIG: PermissionSectionConfig[] = [
Component: DefaultManagedIdentity, Component: DefaultManagedIdentity,
disabled: true, disabled: true,
validate: (state: CopyJobContextState) => { validate: (state: CopyJobContextState) => {
const targetAccountDefaultIdentity = (state?.target?.account?.properties?.defaultIdentity ?? "").toLowerCase(); const sourceAccountDefaultIdentity = (state?.source?.account?.properties?.defaultIdentity ?? "").toLowerCase();
return targetAccountDefaultIdentity === DefaultIdentityType.SystemAssignedIdentity; return sourceAccountDefaultIdentity === DefaultIdentityType.SystemAssignedIdentity;
}, },
}, },
{ {
@@ -73,18 +73,18 @@ const PERMISSION_SECTIONS_CONFIG: PermissionSectionConfig[] = [
Component: AddReadWritePermissionToDefaultIdentity, Component: AddReadWritePermissionToDefaultIdentity,
disabled: true, disabled: true,
validate: async (state: CopyJobContextState) => { validate: async (state: CopyJobContextState) => {
const principalId = state?.target?.account?.identity?.principalId; const principalId = state?.source?.account?.identity?.principalId;
const selectedSourceAccount = state?.source?.account; const selectedTargetAccount = state?.target?.account;
const { const {
subscriptionId: sourceSubscriptionId, subscriptionId: targetSubscriptionId,
resourceGroup: sourceResourceGroup, resourceGroup: targetResourceGroup,
accountName: sourceAccountName, accountName: targetAccountName,
} = getAccountDetailsFromResourceId(selectedSourceAccount?.id); } = getAccountDetailsFromResourceId(selectedTargetAccount?.id);
const rolesAssigned = await fetchRoleAssignments( const rolesAssigned = await fetchRoleAssignments(
sourceSubscriptionId, targetSubscriptionId,
sourceResourceGroup, targetResourceGroup,
sourceAccountName, targetAccountName,
principalId, principalId,
); );