mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-21 18:54:22 +00:00
Compare commits
2 Commits
users/aisa
...
copilot/su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
752fe5259d | ||
|
|
b8bf30551d |
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -189,9 +189,6 @@ jobs:
|
||||
NOSQL_TESTACCOUNT_TOKEN=$(az account get-access-token --scope "https://github-e2etests-sql.documents.azure.com/.default" -o tsv --query accessToken)
|
||||
echo "::add-mask::$NOSQL_TESTACCOUNT_TOKEN"
|
||||
echo NOSQL_TESTACCOUNT_TOKEN=$NOSQL_TESTACCOUNT_TOKEN >> $GITHUB_ENV
|
||||
NOSQL2_TESTACCOUNT_TOKEN=$(az account get-access-token --scope "https://github-e2etests-sql-2.documents.azure.com/.default" -o tsv --query accessToken)
|
||||
echo "::add-mask::$NOSQL2_TESTACCOUNT_TOKEN"
|
||||
echo NOSQL2_TESTACCOUNT_TOKEN=$NOSQL2_TESTACCOUNT_TOKEN >> $GITHUB_ENV
|
||||
NOSQL_READONLY_TESTACCOUNT_TOKEN=$(az account get-access-token --scope "https://github-e2etests-sql-readonly.documents.azure.com/.default" -o tsv --query accessToken)
|
||||
echo "::add-mask::$NOSQL_READONLY_TESTACCOUNT_TOKEN"
|
||||
echo NOSQL_READONLY_TESTACCOUNT_TOKEN=$NOSQL_READONLY_TESTACCOUNT_TOKEN >> $GITHUB_ENV
|
||||
|
||||
@@ -46,10 +46,6 @@ export type DataExploreMessageV3 =
|
||||
params: {
|
||||
updateType: "created" | "deleted" | "settings";
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: FabricMessageTypes.RestoreContainer;
|
||||
params: [];
|
||||
};
|
||||
export interface GetCosmosTokenMessageOptions {
|
||||
verb: "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace";
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
AddGlobalSecondaryIndexPanelProps,
|
||||
} from "Explorer/Panes/AddGlobalSecondaryIndexPanel/AddGlobalSecondaryIndexPanel";
|
||||
import { useDatabases } from "Explorer/useDatabases";
|
||||
import { isFabric, isFabricNative, openRestoreContainerDialog } from "Platform/Fabric/FabricUtil";
|
||||
import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||
@@ -35,7 +35,6 @@ import StoredProcedure from "./Tree/StoredProcedure";
|
||||
import Trigger from "./Tree/Trigger";
|
||||
import UserDefinedFunction from "./Tree/UserDefinedFunction";
|
||||
import { useSelectedNode } from "./useSelectedNode";
|
||||
import { extractFeatures } from "../Platform/Hosted/extractFeatures";
|
||||
|
||||
export interface CollectionContextMenuButtonParams {
|
||||
databaseId: string;
|
||||
@@ -61,17 +60,6 @@ export const createDatabaseContextMenu = (container: Explorer, databaseId: strin
|
||||
},
|
||||
];
|
||||
|
||||
if (isFabricNative() && !userContext.fabricContext?.isReadOnly) {
|
||||
const features = extractFeatures();
|
||||
if (features?.enableRestoreContainer) {
|
||||
items.push({
|
||||
iconSrc: AddCollectionIcon,
|
||||
onClick: () => openRestoreContainerDialog(),
|
||||
label: `Restore ${getCollectionName()}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFabricNative() && (userContext.apiType !== "Tables" || userContext.features.enableSDKoperations)) {
|
||||
items.push({
|
||||
iconSrc: DeleteDatabaseIcon,
|
||||
|
||||
@@ -54,6 +54,6 @@
|
||||
.mainButtonsContainer {
|
||||
display: flex;
|
||||
gap: 0 16px;
|
||||
margin: 40px auto
|
||||
margin-bottom: 10px
|
||||
}
|
||||
|
||||
@@ -105,12 +105,6 @@ const requestAndStoreAccessToken = async (): Promise<void> => {
|
||||
});
|
||||
};
|
||||
|
||||
export const openRestoreContainerDialog = (): void => {
|
||||
if (isFabricNative()) {
|
||||
sendCachedDataMessage(FabricMessageTypes.RestoreContainer, []);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check token validity and schedule a refresh if necessary
|
||||
* @param tokenTimestamp
|
||||
|
||||
@@ -40,7 +40,6 @@ export type Features = {
|
||||
readonly disableConnectionStringLogin: boolean;
|
||||
readonly enableContainerCopy: boolean;
|
||||
readonly enableCloudShell: boolean;
|
||||
readonly enableRestoreContainer: boolean; // only for Fabric
|
||||
|
||||
// can be set via both flight and feature flag
|
||||
autoscaleDefault: boolean;
|
||||
@@ -112,7 +111,6 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
|
||||
enablePriorityBasedExecution: "true" === get("enableprioritybasedexecution"),
|
||||
disableConnectionStringLogin: "true" === get("disableconnectionstringlogin"),
|
||||
enableContainerCopy: "true" === get("enablecontainercopy"),
|
||||
enableRestoreContainer: "true" === get("enablerestorecontainer"),
|
||||
enableCloudShell: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ describe("AuthorizationUtils", () => {
|
||||
partitionKeyDefault: false,
|
||||
partitionKeyDefault2: false,
|
||||
notebooksDownBanner: false,
|
||||
enableRestoreContainer: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
13
test/fx.ts
13
test/fx.ts
@@ -39,7 +39,6 @@ export enum TestAccount {
|
||||
MongoReadonly = "MongoReadOnly",
|
||||
Mongo32 = "Mongo32",
|
||||
SQL = "SQL",
|
||||
SQL2 = "SQL2",
|
||||
SQLReadOnly = "SQLReadOnly",
|
||||
SQLContainerCopyOnly = "SQLContainerCopyOnly",
|
||||
}
|
||||
@@ -52,7 +51,6 @@ export const defaultAccounts: Record<TestAccount, string> = {
|
||||
[TestAccount.MongoReadonly]: "github-e2etests-mongo-readonly",
|
||||
[TestAccount.Mongo32]: "github-e2etests-mongo32",
|
||||
[TestAccount.SQL]: "github-e2etests-sql",
|
||||
[TestAccount.SQL2]: "github-e2etests-sql-2",
|
||||
[TestAccount.SQLReadOnly]: "github-e2etests-sql-readonly",
|
||||
[TestAccount.SQLContainerCopyOnly]: "github-e2etests-sql-containercopyonly",
|
||||
};
|
||||
@@ -74,9 +72,6 @@ function tryGetStandardName(accountType: TestAccount) {
|
||||
}
|
||||
|
||||
export function getAccountName(accountType: TestAccount) {
|
||||
if (accountType === TestAccount.SQL2 && !process.env.CI) {
|
||||
accountType = TestAccount.SQL;
|
||||
}
|
||||
return (
|
||||
process.env[`DE_TEST_ACCOUNT_NAME_${accountType.toLocaleUpperCase()}`] ??
|
||||
tryGetStandardName(accountType) ??
|
||||
@@ -106,7 +101,6 @@ export async function getTestExplorerUrl(accountType: TestAccount, options?: Tes
|
||||
params.set("feature.enableCopilot", "false");
|
||||
|
||||
const nosqlRbacToken = process.env.NOSQL_TESTACCOUNT_TOKEN;
|
||||
const nosql2RbacToken = process.env.NOSQL2_TESTACCOUNT_TOKEN;
|
||||
const nosqlReadOnlyRbacToken = process.env.NOSQL_READONLY_TESTACCOUNT_TOKEN;
|
||||
const nosqlContainerCopyRbacToken = process.env.NOSQL_CONTAINERCOPY_TESTACCOUNT_TOKEN;
|
||||
const tableRbacToken = process.env.TABLE_TESTACCOUNT_TOKEN;
|
||||
@@ -123,12 +117,7 @@ export async function getTestExplorerUrl(accountType: TestAccount, options?: Tes
|
||||
params.set("enableaaddataplane", "true");
|
||||
}
|
||||
break;
|
||||
case TestAccount.SQL2:
|
||||
if (nosql2RbacToken) {
|
||||
params.set("nosql2RbacToken", nosql2RbacToken);
|
||||
params.set("enableaaddataplane", "true");
|
||||
}
|
||||
break;
|
||||
|
||||
case TestAccount.SQLContainerCopyOnly:
|
||||
if (nosqlContainerCopyRbacToken) {
|
||||
params.set("nosqlRbacToken", nosqlContainerCopyRbacToken);
|
||||
|
||||
@@ -30,9 +30,12 @@ test.beforeEach("Open new query tab", async ({ page }) => {
|
||||
await explorer.frame.getByTestId("NotificationConsole/Contents").waitFor();
|
||||
});
|
||||
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
test("Query results", async () => {
|
||||
// Run the query and verify the results
|
||||
|
||||
@@ -10,13 +10,11 @@ test.describe("Change Partition Key", () => {
|
||||
let previousJobName: string | undefined;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer({
|
||||
testAccount: TestAccount.SQL2,
|
||||
});
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open container settings", async ({ page }) => {
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL2);
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
|
||||
// Click Scale & Settings and open Partition Key tab
|
||||
await explorer.openScaleAndSettings(context);
|
||||
|
||||
@@ -8,9 +8,7 @@ test.describe("Computed Properties", () => {
|
||||
let explorer: DataExplorer = null!;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer({
|
||||
testAccount: TestAccount.SQL2,
|
||||
});
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open Settings tab under Scale & Settings", async ({ page }) => {
|
||||
@@ -24,12 +22,9 @@ test.describe("Computed Properties", () => {
|
||||
await computedPropertiesTab.click();
|
||||
});
|
||||
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterEach("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
|
||||
test("Add valid computed property", async ({ page }) => {
|
||||
await clearComputedPropertiesTextBoxContent({ page });
|
||||
|
||||
@@ -19,7 +19,7 @@ test.describe("Settings under Scale & Settings", () => {
|
||||
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterEach("Delete Test Database", async () => {
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,21 +7,16 @@ test.describe("Stored Procedures", () => {
|
||||
let explorer: DataExplorer = null!;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer({
|
||||
testAccount: TestAccount.SQL2,
|
||||
});
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open container", async ({ page }) => {
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL2);
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
});
|
||||
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterEach("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
|
||||
test("Add, execute, and delete stored procedure", async ({ page }, testInfo) => {
|
||||
void page;
|
||||
|
||||
@@ -19,18 +19,15 @@ test.describe("Triggers", () => {
|
||||
request.setBody(itemToCreate);
|
||||
}`;
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer({
|
||||
testAccount: TestAccount.SQL2,
|
||||
});
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open container", async ({ page }) => {
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL2);
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
});
|
||||
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterEach("Delete Test Database", async () => {
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,18 +12,15 @@ test.describe("User Defined Functions", () => {
|
||||
}`;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer({
|
||||
testAccount: TestAccount.SQL2,
|
||||
});
|
||||
context = await createTestSQLContainer();
|
||||
});
|
||||
|
||||
test.beforeEach("Open container", async ({ page }) => {
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL2);
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
});
|
||||
|
||||
// Delete database only if not running in CI
|
||||
if (!process.env.CI) {
|
||||
test.afterEach("Delete Test Database", async () => {
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,14 +86,13 @@ type createTestSqlContainerConfig = {
|
||||
includeTestData?: boolean;
|
||||
partitionKey?: string;
|
||||
databaseName?: string;
|
||||
testAccount?: TestAccount;
|
||||
};
|
||||
|
||||
type createMultipleTestSqlContainerConfig = {
|
||||
containerCount?: number;
|
||||
partitionKey?: string;
|
||||
databaseName?: string;
|
||||
accountType: TestAccount.SQLContainerCopyOnly | TestAccount.SQL | TestAccount.SQL2;
|
||||
accountType: TestAccount.SQLContainerCopyOnly | TestAccount.SQL;
|
||||
};
|
||||
|
||||
export async function createMultipleTestContainers({
|
||||
@@ -115,7 +114,12 @@ export async function createMultipleTestContainers({
|
||||
endpoint: account.documentEndpoint!,
|
||||
};
|
||||
|
||||
const rbacToken = getRbacToken(accountType);
|
||||
const rbacToken =
|
||||
accountType === TestAccount.SQL
|
||||
? process.env.NOSQL_TESTACCOUNT_TOKEN
|
||||
: accountType === TestAccount.SQLContainerCopyOnly
|
||||
? process.env.NOSQL_CONTAINERCOPY_TESTACCOUNT_TOKEN
|
||||
: "";
|
||||
if (rbacToken) {
|
||||
clientOptions.tokenProvider = async (): Promise<string> => {
|
||||
const AUTH_PREFIX = `type=aad&ver=1.0&sig=`;
|
||||
@@ -151,21 +155,20 @@ export async function createTestSQLContainer({
|
||||
includeTestData = false,
|
||||
partitionKey = "/partitionKey",
|
||||
databaseName = "",
|
||||
testAccount = TestAccount.SQL,
|
||||
}: createTestSqlContainerConfig = {}) {
|
||||
const databaseId = databaseName ? databaseName : generateUniqueName("db");
|
||||
const containerId = "testcontainer"; // A unique container name isn't needed because the database is unique
|
||||
const credentials = getAzureCLICredentials();
|
||||
const adaptedCredentials = new AzureIdentityCredentialAdapter(credentials);
|
||||
const armClient = new CosmosDBManagementClient(adaptedCredentials, subscriptionId);
|
||||
const accountName = getAccountName(testAccount);
|
||||
const accountName = getAccountName(TestAccount.SQL);
|
||||
const account = await armClient.databaseAccounts.get(resourceGroupName, accountName);
|
||||
|
||||
const clientOptions: CosmosClientOptions = {
|
||||
endpoint: account.documentEndpoint!,
|
||||
};
|
||||
|
||||
const nosqlAccountRbacToken = getRbacToken(testAccount);
|
||||
const nosqlAccountRbacToken = process.env.NOSQL_TESTACCOUNT_TOKEN;
|
||||
if (nosqlAccountRbacToken) {
|
||||
clientOptions.tokenProvider = async (): Promise<string> => {
|
||||
const AUTH_PREFIX = `type=aad&ver=1.0&sig=`;
|
||||
@@ -249,16 +252,3 @@ export async function retry<T>(fn: () => Promise<T>, retries = 3, delayMs = 1000
|
||||
}
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
function getRbacToken(accountType: TestAccount): string | undefined {
|
||||
switch (accountType) {
|
||||
case TestAccount.SQL:
|
||||
return process.env.NOSQL_TESTACCOUNT_TOKEN;
|
||||
case TestAccount.SQL2:
|
||||
return process.env.NOSQL2_TESTACCOUNT_TOKEN;
|
||||
case TestAccount.SQLContainerCopyOnly:
|
||||
return process.env.NOSQL_CONTAINERCOPY_TESTACCOUNT_TOKEN;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user