diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index 2fc15d114..709fbf898 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -5,10 +5,6 @@
"Edit the site": "Edit the site",
"Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.": "Be careful making changes. Anyone can see the changes you make immediately. Choose Edit the site to make edits, or close the editor tab to cancel without editing.",
"You are editing a live, public site ": "You are editing a live, public site ",
- "Fetching environment information ...": "Fetching environment information ...",
- "Unable to fetch environment information": "Unable to fetch environment information",
- "Fetching website details ...": "Fetching website details ...",
- "Unable to fetch website details": "Unable to fetch website details",
"Microsoft wants your feedback": "Microsoft wants your feedback",
"Preview site": "Preview site",
"Open in Power Pages studio": "Open in Power Pages studio",
@@ -24,6 +20,7 @@
"Update Extension": "Update Extension",
"Failed to generate VS Code Desktop URL: {0}": "Failed to generate VS Code Desktop URL: {0}",
"Failed to open in VS Code Desktop: {0}": "Failed to open in VS Code Desktop: {0}",
+ "Check the URL and verify the parameters are correct": "Check the URL and verify the parameters are correct",
"Unable to complete the request": "Unable to complete the request",
"One or more attribute names have been changed or removed. Contact your admin.": "One or more attribute names have been changed or removed. Contact your admin.",
"Authorization Failed. Please run again to authorize it": "Authorization Failed. Please run again to authorize it",
@@ -35,7 +32,6 @@
"Failed to fetch some files.": "Failed to fetch some files.",
"Failed to get file ready for edit: {0}": "Failed to get file ready for edit: {0}",
"Saving your file ...": "Saving your file ...",
- "Check the URL and verify the parameters are correct": "Check the URL and verify the parameters are correct",
"Enter Organization ID": "Enter Organization ID",
"Power Pages Copilot is now connected to the environment: {0} : {1}/{0} represents the environment name": {
"message": "Power Pages Copilot is now connected to the environment: {0} : {1}",
diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf
index 9cef50f57..5238c4521 100644
--- a/loc/translations-export/vscode-powerplatform.xlf
+++ b/loc/translations-export/vscode-powerplatform.xlf
@@ -422,12 +422,6 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Feedback
-
- Fetching environment information ...
-
-
- Fetching website details ...
-
Fetching your file ...
@@ -942,12 +936,6 @@ The {3} represents Dataverse Environment's Organization ID (GUID)
Unable to complete the request
-
- Unable to fetch environment information
-
-
- Unable to fetch website details
-
Unable to find that app
diff --git a/src/common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents.ts b/src/common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents.ts
index 1037b1204..67160796d 100644
--- a/src/common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents.ts
+++ b/src/common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents.ts
@@ -71,13 +71,18 @@ export enum webExtensionTelemetryEventNames {
WEB_EXTENSION_FETCH_DATAVERSE_AND_CREATE_FILES_SYSTEM_ERROR = 'webExtensionFetchDataverseCreateFilesSystemError',
WEB_EXTENSION_SAVE_DATA_TO_DATAVERSE_API_ERROR = 'webExtensionSaveDataToDataverseAPIError',
WEB_EXTENSION_GET_SAVE_PARAMETERS_ERROR = 'webExtensionGetSaveParametersError',
+ WEB_EXTENSION_MULTI_FILE_FEATURE_FLAG_ENABLED = "WebExtensionMultiFileFeatureFlagEnabled",
+ WEB_EXTENSION_MULTI_FILE_FEATURE_FLAG_DISABLED = "WebExtensionMultiFileFeatureFlagDisabled",
+ WEB_EXTENSION_MULTI_FILE_MANDATORY_PARAMETERS_MISSING = "WebExtensionMultiFileMandatoryParametersMissing",
WEB_EXTENSION_WEBSITE_PREVIEW_URL_VALIDATION_SITE_DETAILS_FETCH_FAILED = "WebExtensionWebsitePreviewUrlValidationSiteDetailsFetchFailed",
WEB_EXTENSION_WEBSITE_PREVIEW_URL_VALIDATION_INSUFFICIENT_PARAMETERS = "WebExtensionWebsitePreviewUrlValidationInsufficientParameters",
WEB_EXTENSION_MULTI_FILE_INVALID_DATAVERSE_URL = "WebExtensionMultiFileInvalidDataverseUrl",
+ WEB_EXTENSION_MULTI_FILE_INVALID_WEBSITE_PREVIEW_URL = "WebExtensionMultiFileInvalidWebsitePreviewUrl",
WEB_EXTENSION_CO_PRESENCE_FEATURE_FLAG_DISABLED = "WebExtensionCoPresenceFeatureFlagDisabled",
WEB_EXTENSION_CO_PRESENCE_FEATURE_FLAG_ENABLED = "WebExtensionCoPresenceFeatureFlagEnabled",
WEB_EXTENSION_FILES_LOAD_SUCCESS = "WebExtensionFilesLoadSuccess",
WEB_EXTENSION_PREPARE_WORKSPACE_SUCCESS = "webExtensionPrepareWorkspaceSuccess",
+ WEB_EXTENSION_MULTI_FILE_FEATURE_AVAILABILITY = "WebExtensionMultiFileFeatureAvailability",
WEB_EXTENSION_APP_NAME_NOT_FOUND = "WebExtensionAppNameNotFound",
WEB_EXTENSION_SET_VSCODE_WORKSPACE_STATE_FAILED = "WebExtensionSetVscodeWorkspaceStateFailed",
WEB_EXTENSION_SET_VSCODE_WORKSPACE_STATE_SUCCESS = "WebExtensionGetVscodeWorkspaceStateSuccess",
diff --git a/src/common/ecs-features/ecsFeatureGates.ts b/src/common/ecs-features/ecsFeatureGates.ts
index a2288a47e..54545a10f 100644
--- a/src/common/ecs-features/ecsFeatureGates.ts
+++ b/src/common/ecs-features/ecsFeatureGates.ts
@@ -6,6 +6,16 @@
import { COPILOT_GOVERNANCE_SETTING_NAME, PowerPagesClientName } from './constants';
import { getFeatureConfigs } from './ecsFeatureUtil';
+export const {
+ feature: EnableMultifileVscodeWeb
+} = getFeatureConfigs({
+ teamName: PowerPagesClientName,
+ description: 'Enable multiple file view in Visual Studio Code Web',
+ fallback: {
+ enableMultifileVscodeWeb: false,
+ },
+});
+
export const {
feature: CopilotDisableList
} = getFeatureConfigs({
diff --git a/src/common/services/BAPService.ts b/src/common/services/BAPService.ts
index d8ccf2b3c..e16fa87e6 100644
--- a/src/common/services/BAPService.ts
+++ b/src/common/services/BAPService.ts
@@ -15,7 +15,7 @@ export class BAPService {
try {
const accessToken = await bapServiceAuthentication(true);
- const response = await fetch(BAPService.getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp, environmentId), {
+ const response = await fetch(await BAPService.getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp, environmentId), {
method: 'GET',
headers: getCommonHeaders(accessToken)
});
@@ -33,12 +33,13 @@ export class BAPService {
return false;
}
- static getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp: ServiceEndpointCategory, environmentId: string): string {
+ static async getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp: ServiceEndpointCategory, environmentId: string): Promise {
- const bapEndpoint = getBAPEndpoint(serviceEndpointStamp);
+ const bapEndpoint = await getBAPEndpoint(serviceEndpointStamp);
return BAP_SERVICE_ENDPOINT.replace('{rootURL}', bapEndpoint) +
BAP_SERVICE_COPILOT_CROSS_GEO_FLAG_RELATIVE_URL.replace('{environmentID}', environmentId).replace('{apiVersion}', BAP_API_VERSION);
}
}
+
diff --git a/src/web/client/WebExtensionContext.ts b/src/web/client/WebExtensionContext.ts
index f227113fb..c81493ced 100644
--- a/src/web/client/WebExtensionContext.ts
+++ b/src/web/client/WebExtensionContext.ts
@@ -22,20 +22,19 @@ import {
getWebsiteLanguageIdToPortalLanguageIdMap,
} from "./utilities/schemaHelperUtil";
import { getCustomRequestURL, getOrCreateSharedWorkspace } from "./utilities/urlBuilderUtil";
-import { SchemaEntityMetadata } from "./schema/constants";
+import { SchemaEntityMetadata, schemaKey } from "./schema/constants";
import { webExtensionTelemetryEventNames } from "../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
import { EntityDataMap } from "./context/entityDataMap";
import { FileDataMap } from "./context/fileDataMap";
import { IAttributePath, IEntityInfo } from "./common/interfaces";
import { ConcurrencyHandler } from "./dal/concurrencyHandler";
-import { getEnvironmentIdFromUrl, getMailToPath, getTeamChatURL } from "./utilities/commonUtil";
+import { getEnvironmentIdFromUrl, getMailToPath, getTeamChatURL, isMultifileEnabled } from "./utilities/commonUtil";
import { IConnectionData, UserDataMap } from "./context/userDataMap";
import { EntityForeignKeyDataMap } from "./context/entityForeignKeyDataMap";
import { QuickPickProvider } from "./webViews/QuickPickProvider";
import { UserCollaborationProvider } from "./webViews/userCollaborationProvider";
import { GraphClientService } from "./services/graphClientService";
import { ServiceEndpointCategory } from "../../common/services/Constants";
-import { SiteVisibility } from "../../client/power-pages/actions-hub/models/SiteVisibility";
export interface IWebExtensionContext {
// From portalSchema properties
@@ -61,13 +60,15 @@ export interface IWebExtensionContext {
defaultEntityId: string;
defaultEntityType: string;
defaultFileUri: vscode.Uri; // This will default to home page or current page in multifile scenario
+ showMultifileInVSCode: boolean;
extensionActivationTime: number;
- extensionUri: vscode.Uri;
+ extensionUri: vscode.Uri
// Org specific details
dataverseAccessToken: string;
entityDataMap: EntityDataMap;
isContextSet: boolean;
+ currentSchemaVersion: string;
websiteLanguageCode: string;
geoName: string;
geoLongName: string;
@@ -96,14 +97,6 @@ export interface IWebExtensionContext {
webpageNames: Set;
getWebpageNames(): Set;
-
- websiteName: string;
- tenantId: string;
- websiteId: string;
- schema: Constants.portalSchemaVersion | undefined;
- siteVisibility: SiteVisibility | undefined;
- orgUrl: string;
- region: string;
}
class WebExtensionContext implements IWebExtensionContext {
@@ -121,12 +114,14 @@ class WebExtensionContext implements IWebExtensionContext {
private _defaultEntityId: string;
private _defaultEntityType: string;
private _defaultFileUri: vscode.Uri;
+ private _showMultifileInVSCode: boolean;
private _extensionActivationTime: number;
private _extensionUri: vscode.Uri;
private _dataverseAccessToken: string;
private _entityDataMap: EntityDataMap;
private _entityForeignKeyDataMap: EntityForeignKeyDataMap;
private _isContextSet: boolean;
+ private _currentSchemaVersion: string;
private _websiteLanguageCode: string;
private _geoName: string;
private _geoLongName: string;
@@ -148,13 +143,6 @@ class WebExtensionContext implements IWebExtensionContext {
private _userCollaborationProvider: UserCollaborationProvider;
private _graphClientService: GraphClientService;
private _webpageNames: Set;
- private _websiteName: string;
- private _tenantId: string;
- private _websiteId: string;
- private _schema: Constants.portalSchemaVersion | undefined;
- private _siteVisibility: SiteVisibility | undefined;
- private _orgUrl: string;
- private _region: string;
public get schemaDataSourcePropertiesMap() {
return this._schemaDataSourcePropertiesMap;
@@ -198,6 +186,9 @@ class WebExtensionContext implements IWebExtensionContext {
public get defaultFileUri() {
return this._defaultFileUri;
}
+ public get showMultifileInVSCode() {
+ return this._showMultifileInVSCode;
+ }
public get extensionActivationTime() {
return this._extensionActivationTime
}
@@ -216,6 +207,9 @@ class WebExtensionContext implements IWebExtensionContext {
public get isContextSet() {
return this._isContextSet;
}
+ public get currentSchemaVersion() {
+ return this._currentSchemaVersion;
+ }
public get websiteLanguageCode() {
return this._websiteLanguageCode;
}
@@ -300,48 +294,6 @@ class WebExtensionContext implements IWebExtensionContext {
public get webpageNames() {
return this._webpageNames;
}
- public get websiteName() {
- return this._websiteName;
- }
- public set websiteName(name: string) {
- this._websiteName = name;
- }
- public get tenantId() {
- return this._tenantId;
- }
- public set tenantId(id: string) {
- this._tenantId = id;
- }
- public get websiteId() {
- return this._websiteId;
- }
- public set websiteId(id: string) {
- this._websiteId = id;
- }
- public get schema() {
- return this._schema;
- }
- public set schema(schema: Constants.portalSchemaVersion | undefined) {
- this._schema = schema;
- }
- public get siteVisibility() {
- return this._siteVisibility;
- }
- public set siteVisibility(visibility: SiteVisibility | undefined) {
- this._siteVisibility = visibility;
- }
- public get orgUrl() {
- return this._orgUrl;
- }
- public set orgUrl(url: string) {
- this._orgUrl = url;
- }
- public get region() {
- return this._region;
- }
- public set region(region: string) {
- this._region = region;
- }
constructor() {
this._schemaDataSourcePropertiesMap = new Map();
@@ -361,9 +313,11 @@ class WebExtensionContext implements IWebExtensionContext {
this._entityDataMap = new EntityDataMap();
this._entityForeignKeyDataMap = new EntityForeignKeyDataMap();
this._defaultFileUri = vscode.Uri.parse(``);
+ this._showMultifileInVSCode = false;
this._extensionActivationTime = new Date().getTime();
this._extensionUri = vscode.Uri.parse("");
this._isContextSet = false;
+ this._currentSchemaVersion = "";
this._websiteLanguageCode = "";
this._geoName = "";
this._geoLongName = "";
@@ -384,13 +338,6 @@ class WebExtensionContext implements IWebExtensionContext {
this._userCollaborationProvider = new UserCollaborationProvider();
this._graphClientService = new GraphClientService();
this._webpageNames = new Set();
- this._websiteName = "";
- this._tenantId = "";
- this._websiteId = "";
- this._schema = undefined;
- this._siteVisibility = undefined;
- this._orgUrl = "";
- this._region = "";
}
public setWebExtensionContext(
@@ -399,20 +346,37 @@ class WebExtensionContext implements IWebExtensionContext {
queryParamsMap: Map,
extensionUri?: vscode.Uri
) {
+ const schema = queryParamsMap.get(schemaKey.SCHEMA_VERSION) as string;
// Initialize context from URL params
+ this._currentSchemaVersion = schema;
this._defaultEntityType = (entityName && entityName.toLowerCase()) ?? queryParamsMap.get(Constants.queryParameters.ENTITY) as string ?? "";
this._defaultEntityId = entityId ?? queryParamsMap.get(Constants.queryParameters.ENTITY_ID) as string ?? "";
this._urlParametersMap = queryParamsMap;
- this._rootDirectory = vscode.Uri.parse(`${Constants.PORTALS_URI_SCHEME}:/${this._websiteName}/`, true);
- this._extensionUri = extensionUri as vscode.Uri
+ this._rootDirectory = vscode.Uri.parse(
+ `${Constants.PORTALS_URI_SCHEME}:/${queryParamsMap.get(
+ Constants.queryParameters.WEBSITE_NAME
+ ) as string
+ }/`,
+ true
+ );
+ this._extensionUri = extensionUri as vscode.Uri;
+
+ // Initialize multifile FF here
+ const enableMultifile = queryParamsMap?.get(Constants.queryParameters.ENABLE_MULTIFILE);
+ const isEnableMultifile = (String(enableMultifile).toLowerCase() === 'true');
+ this._showMultifileInVSCode = isMultifileEnabled() && isEnableMultifile;
+
+ this.telemetry.sendInfoTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_FEATURE_AVAILABILITY,
+ { showMultifileInVSCode: this._showMultifileInVSCode.toString() }
+ );
// Initialize context from schema values
- if (this.schema) {
- this._schemaEntitiesMap = getEntitiesSchemaMap(this.schema);
- this._schemaDataSourcePropertiesMap = getDataSourcePropertiesMap(this.schema);
- }
+ this._schemaEntitiesMap = getEntitiesSchemaMap(schema);
+ this._schemaDataSourcePropertiesMap =
+ getDataSourcePropertiesMap(schema);
this._entitiesFolderNameMap = getEntitiesFolderNameMap(
- this._schemaEntitiesMap
+ this.schemaEntitiesMap
);
this._isContextSet = true;
@@ -441,42 +405,51 @@ class WebExtensionContext implements IWebExtensionContext {
public async authenticateAndUpdateDataverseProperties() {
await this.dataverseAuthentication(true);
- if (!this._schema) {
- this.telemetry.sendErrorTelemetry(
- webExtensionTelemetryEventNames.WEB_EXTENSION_DATAVERSE_AUTHENTICATION_MISSING,
- this.authenticateAndUpdateDataverseProperties.name,
- "Schema is not defined"
- );
- return;
- }
+ const dataverseOrgUrl = this.urlParametersMap.get(
+ Constants.queryParameters.ORG_URL
+ ) as string;
+ const schema = this.urlParametersMap
+ .get(schemaKey.SCHEMA_VERSION)
+ ?.toLowerCase() as string;
await this.populateWebsiteIdToLanguageMap(
this._dataverseAccessToken,
- this._orgUrl,
- this._schema
+ dataverseOrgUrl,
+ schema
);
await this.populateWebsiteLanguageIdToPortalLanguageMap(
this._dataverseAccessToken,
- this._orgUrl,
- this._schema
+ dataverseOrgUrl,
+ schema
);
await this.populateLanguageIdToCode(
this._dataverseAccessToken,
- this._orgUrl,
- this._schema
+ dataverseOrgUrl,
+ schema
);
await this.setWebsiteLanguageCode();
+ // Getting website Id to populate shared workspace for Co-Presence
+ const websiteId = this.urlParametersMap.get(
+ Constants.queryParameters.WEBSITE_ID
+ ) as string;
+
const headers = getCommonHeadersForDataverse(this._dataverseAccessToken);
// Populate shared workspace for Co-Presence
- await this.populateSharedWorkspace(headers, this._orgUrl, this._websiteId);
+ await this.populateSharedWorkspace(headers, dataverseOrgUrl, websiteId);
}
public async dataverseAuthentication(firstTimeAuth = false) {
- const { accessToken, userId } = await dataverseAuthentication(this._orgUrl, firstTimeAuth);
+ const dataverseOrgUrl = this.urlParametersMap.get(
+ Constants.queryParameters.ORG_URL
+ ) as string;
+ const { accessToken, userId } = await dataverseAuthentication(
+ dataverseOrgUrl,
+ firstTimeAuth
+ );
if (accessToken.length === 0) {
// re-set all properties to default values
@@ -719,7 +692,6 @@ class WebExtensionContext implements IWebExtensionContext {
dataverseOrgUrl,
websiteEntityName
);
-
this.telemetry.sendAPITelemetry(
requestUrl,
websiteEntityName,
@@ -769,7 +741,12 @@ class WebExtensionContext implements IWebExtensionContext {
}
private async setWebsiteLanguageCode() {
- const lcid = this.websiteIdToLanguage.get(this._websiteId) ?? "";
+ const lcid =
+ this.websiteIdToLanguage.get(
+ this.urlParametersMap.get(
+ Constants.queryParameters.WEBSITE_ID
+ ) as string
+ ) ?? "";
this.telemetry.sendInfoTelemetry(
webExtensionTelemetryEventNames.WEB_EXTENSION_EDIT_LCID,
{ lcid: lcid ? lcid.toString() : "" }
diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts
index ddd2535bd..b6f33f43f 100644
--- a/src/web/client/common/constants.ts
+++ b/src/web/client/common/constants.ts
@@ -5,6 +5,7 @@
// Default and constants
export const PORTAL_LANGUAGE_DEFAULT = "1033";
+export const PORTALS_FOLDER_NAME_DEFAULT = "site";
export const PORTALS_URI_SCHEME = "powerplatform-vfs";
export const DEFAULT_LANGUAGE_CODE = " ";
export const NO_CONTENT = " ";
@@ -49,6 +50,9 @@ export const ALL_APPLICATION_MIME_TYPE = 'application/';
export const VERSION_CONTROL_FOR_WEB_EXTENSION_SETTING_NAME =
"enableVersionControl";
+// Multi-file feature constants
+export const MULTI_FILE_FEATURE_SETTING_NAME = "enableMultiFileFeature";
+
// Co-presence feature constants
export const CO_PRESENCE_FEATURE_SETTING_NAME = "enableCoPresenceFeature";
@@ -78,16 +82,25 @@ export enum initializationEntityName {
// Query parameters passed in url to vscode extension
export enum queryParameters {
ORG_ID = "organizationid",
+ TENANT_ID = "tenantid",
PORTAL_ID = "websitepreviewid",
- ENV_ID = "envid",
+ WEBSITE_ID = "websiteid",
+ SCHEMA = "schema",
+ DATA_SOURCE = "datasource",
REFERRER_SESSION_ID = "referrersessionid",
REFERRER = "referrer",
- REFERRER_SOURCE = "referrersource",
+ SITE_VISIBILITY = "sitevisibility",
+ WEBSITE_NAME = "websitename",
+ ORG_URL = "orgurl",
+ REGION = "region",
+ ENV_ID = "envid",
+ GEO = "geo", // User geo location
+ ENABLE_MULTIFILE = "enablemultifile",
ENTITY = "entity",
ENTITY_ID = "entityid",
+ REFERRER_SOURCE = "referrersource",
SKU = "sku",
- SOURCE_ATTRIBUTE = "source_attribute",
- GEO = "geo"
+ SOURCE_ATTRIBUTE = "source_attribute"
}
export enum sourceAttribute {
diff --git a/src/web/client/common/errorHandler.ts b/src/web/client/common/errorHandler.ts
index 441fe825e..d65d8ccfa 100644
--- a/src/web/client/common/errorHandler.ts
+++ b/src/web/client/common/errorHandler.ts
@@ -5,17 +5,37 @@
import * as vscode from "vscode";
import WebExtensionContext from "../WebExtensionContext";
+import { schemaKey } from "../schema/constants";
import { webExtensionTelemetryEventNames } from "../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
-import { queryParameters } from "./constants";
+import { PORTALS_FOLDER_NAME_DEFAULT, queryParameters } from "./constants";
+import { isMultifileEnabled } from "../utilities/commonUtil";
import { showErrorDialog } from "../../../common/utilities/errorHandlerUtil";
+export function removeEncodingFromParameters(
+ queryParamsMap: Map
+) {
+ //NOTE: From extensibility perspective split attributes and attributes may contain encoded string which must be decoded before use.
+ const schemaFileName = decodeURI(
+ queryParamsMap.get(schemaKey.SCHEMA_VERSION) as string
+ );
+ queryParamsMap.set(schemaKey.SCHEMA_VERSION, schemaFileName);
+ const websiteName = decodeURI(
+ queryParamsMap.get(queryParameters.WEBSITE_NAME) as string
+ );
+ const portalFolderName = websiteName
+ ? websiteName
+ : PORTALS_FOLDER_NAME_DEFAULT;
+ queryParamsMap.set(queryParameters.WEBSITE_NAME, portalFolderName);
+}
+
export function checkMandatoryParameters(
appName: string,
queryParamsMap: Map
): boolean {
return (
checkMandatoryPathParameters(appName) &&
- checkMandatoryQueryParameters(appName, queryParamsMap)
+ checkMandatoryQueryParameters(appName, queryParamsMap) &&
+ checkMandatoryMultifileParameters(appName, queryParamsMap)
);
}
@@ -44,20 +64,23 @@ export function checkMandatoryQueryParameters(
appName // remove switch cases and use polymorphism
) {
case "portal": {
- const orgId = queryParamsMap?.get(queryParameters.ORG_ID);
- const portalId = queryParamsMap?.get(queryParameters.PORTAL_ID);
- const envId = queryParamsMap?.get(queryParameters.ENV_ID);
- if (orgId && portalId && envId) {
+ const orgURL = queryParamsMap?.get(queryParameters.ORG_URL);
+ const dataSource = queryParamsMap?.get(queryParameters.DATA_SOURCE);
+ const schemaName = queryParamsMap?.get(schemaKey.SCHEMA_VERSION);
+ const websiteId = queryParamsMap?.get(queryParameters.WEBSITE_ID);
+ if (orgURL && dataSource && schemaName && websiteId && isDynamicsCRMUrl(orgURL)) {
return true;
} else {
WebExtensionContext.telemetry.sendErrorTelemetry(
webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
checkMandatoryQueryParameters.name,
- `orgId:${orgId}, portalId:${portalId}, envId:${envId}`
+ `orgURL:${orgURL ? orgURL : ``}, dataSource:${dataSource}, schemaName:${schemaName} ,websiteId:${websiteId}`
);
showErrorDialog(
vscode.l10n.t("There was a problem opening the workspace"),
- vscode.l10n.t("Check the URL and verify the parameters are correct")
+ vscode.l10n.t(
+ "Check the URL and verify the parameters are correct"
+ )
);
return false;
}
@@ -70,3 +93,60 @@ export function checkMandatoryQueryParameters(
return false;
}
}
+
+export function checkMandatoryMultifileParameters(
+ appName: string,
+ queryParametersMap: Map
+): boolean {
+ switch (
+ appName // remove switch cases and use polymorphism
+ ) {
+ case "portal": {
+ const enableMultifile = queryParametersMap?.get(queryParameters.ENABLE_MULTIFILE);
+ const isEnableMultifile = (String(enableMultifile).toLowerCase() === 'true');
+ const websiteId = queryParametersMap.get(queryParameters.WEBSITE_ID);
+ if ((isMultifileEnabled() && isEnableMultifile && websiteId)
+ || (isMultifileEnabled() && !isEnableMultifile)
+ || !isMultifileEnabled()) {
+ return true;
+ } else {
+ WebExtensionContext.telemetry.sendErrorTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_MANDATORY_PARAMETERS_MISSING,
+ checkMandatoryMultifileParameters.name,
+ `enableMultifile:${enableMultifile}, websiteId:${websiteId}`
+ );
+ showErrorDialog(
+ vscode.l10n.t("There was a problem opening the workspace"),
+ vscode.l10n.t(
+ "Check the URL and verify the parameters are correct"
+ )
+ );
+ return false;
+ }
+ }
+ default:
+ showErrorDialog(
+ vscode.l10n.t("There was a problem opening the workspace"),
+ vscode.l10n.t("Unable to find that app")
+ );
+ return false;
+ }
+}
+
+// Query Param value checks
+export function isDynamicsCRMUrl(url: string) {
+ // Updated pattern to match both conditions: with and without digits after "crm"
+ // We are in public cloud currently - ignoring the gov cloud for now
+ const pattern = /^https?:\/\/[^.]+\.crm(\d{1,2})?\.dynamics\.com/;
+ const result = pattern.test(url);
+
+ if (!result) {
+ WebExtensionContext.telemetry.sendErrorTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_INVALID_DATAVERSE_URL,
+ isDynamicsCRMUrl.name,
+ `orgURL:${url}`
+ );
+ }
+
+ return result;
+}
diff --git a/src/web/client/dal/fileSystemProvider.ts b/src/web/client/dal/fileSystemProvider.ts
index 975750d0c..abf7d001b 100644
--- a/src/web/client/dal/fileSystemProvider.ts
+++ b/src/web/client/dal/fileSystemProvider.ts
@@ -610,7 +610,11 @@ export class PortalsFS implements vscode.FileSystemProvider {
// --- Dataverse calls
private async _loadFromDataverseToVFS() {
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- await this.createFileSystem(WebExtensionContext.websiteName);
+ await this.createFileSystem(
+ WebExtensionContext.urlParametersMap.get(
+ queryParameters.WEBSITE_NAME
+ ) as string
+ );
// Try Loading default file first
const referrer = WebExtensionContext.urlParametersMap.get(queryParameters.REFERRER) as string
@@ -637,17 +641,21 @@ export class PortalsFS implements vscode.FileSystemProvider {
type: "file",
entityId: WebExtensionContext.defaultEntityId,
entityName: WebExtensionContext.defaultEntityType,
+ isMultifileEnabled: WebExtensionContext.showMultifileInVSCode.toString(),
duration: (new Date().getTime() - WebExtensionContext.extensionActivationTime).toString(),
}
);
}
- // load rest of the files
- await fetchDataFromDataverseAndUpdateVFS(this);
+ if (WebExtensionContext.showMultifileInVSCode) {
+ // load rest of the files
+ await fetchDataFromDataverseAndUpdateVFS(this);
+ }
WebExtensionContext.telemetry.sendInfoTelemetry(
webExtensionTelemetryEventNames.WEB_EXTENSION_PREPARE_WORKSPACE_SUCCESS,
{
+ isMultifileEnabled: WebExtensionContext.showMultifileInVSCode.toString(),
duration: (new Date().getTime() - WebExtensionContext.extensionActivationTime).toString(),
}
);
@@ -660,7 +668,11 @@ export class PortalsFS implements vscode.FileSystemProvider {
if (entityId && entityName && fileName) {
await WebExtensionContext.dataverseAuthentication();
- await this.createFileSystem(WebExtensionContext.websiteName);
+ await this.createFileSystem(
+ WebExtensionContext.urlParametersMap.get(
+ queryParameters.WEBSITE_NAME
+ ) as string
+ );
await fetchDataFromDataverseAndUpdateVFS(
this,
diff --git a/src/web/client/dal/remoteFetchProvider.ts b/src/web/client/dal/remoteFetchProvider.ts
index 9cefcd8ef..ebe024621 100644
--- a/src/web/client/dal/remoteFetchProvider.ts
+++ b/src/web/client/dal/remoteFetchProvider.ts
@@ -29,7 +29,7 @@ import {
} from "../utilities/schemaHelperUtil";
import WebExtensionContext from "../WebExtensionContext";
import { webExtensionTelemetryEventNames } from "../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
-import { EntityMetadataKeyCore, SchemaEntityMetadata, folderExportType, schemaEntityKey, schemaEntityName, WEBPAGE_FOLDER_CONSTANTS } from "../schema/constants";
+import { EntityMetadataKeyCore, SchemaEntityMetadata, folderExportType, schemaEntityKey, schemaEntityName, schemaKey, WEBPAGE_FOLDER_CONSTANTS } from "../schema/constants";
import { getEntityNameForExpandedEntityContent, getRequestUrlForEntities } from "../utilities/folderHelperUtility";
import { IAttributePath, IFileInfo } from "../common/interfaces";
import { portal_schema_V2 } from "../schema/portalSchema";
@@ -47,7 +47,9 @@ export async function fetchDataFromDataverseAndUpdateVFS(
WebExtensionContext.getWebpageNames().clear();
const entityRequestURLs = getRequestUrlForEntities(defaultFileInfo?.entityId, defaultFileInfo?.entityName);
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ Constants.queryParameters.ORG_URL
+ ) as string;
const { enableServerLogicChanges } = ECSFeaturesClient.getConfig(EnableServerLogicChanges);
await Promise.all(entityRequestURLs.map(async (entity) => {
const startTime = new Date().getTime();
@@ -209,7 +211,9 @@ async function createContentFiles(
schemaEntityKey.MAPPING_ENTITY_FETCH_QUERY
);
const exportType = entityDetails?.get(schemaEntityKey.EXPORT_TYPE);
- const portalFolderName = decodeURI(WebExtensionContext.websiteName);
+ const portalFolderName = WebExtensionContext.urlParametersMap.get(
+ Constants.queryParameters.WEBSITE_NAME
+ ) as string;
const subUri = entityDetails?.get(schemaEntityKey.FILE_FOLDER_NAME);
const fetchedFileName = entityDetails?.get(
schemaEntityKey.FILE_NAME_FIELD
@@ -649,12 +653,16 @@ export async function preprocessData(
entityType: string
) {
try {
- const schema = WebExtensionContext.schema;
+ const schema = WebExtensionContext.urlParametersMap
+ .get(schemaKey.SCHEMA_VERSION)
+ ?.toLowerCase() as string;
- if (entityType === schemaEntityName.ADVANCEDFORMS && schema &&
+ if (entityType === schemaEntityName.ADVANCEDFORMS &&
schema.toLowerCase() === portal_schema_V2.entities.dataSourceProperties.schema) {
entityType = schemaEntityName.ADVANCEDFORMSTEPS;
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ Constants.queryParameters.ORG_URL
+ ) as string;
const entityDetails = getEntity(entityType);
const fetchedFileId = entityDetails?.get(schemaEntityKey.FILE_ID_FIELD);
const formsData = await fetchFromDataverseAndCreateFiles(entityType, getCustomRequestURL(dataverseOrgUrl, entityType));
diff --git a/src/web/client/dal/remoteSaveProvider.ts b/src/web/client/dal/remoteSaveProvider.ts
index 0778e3b74..3ef4d0816 100644
--- a/src/web/client/dal/remoteSaveProvider.ts
+++ b/src/web/client/dal/remoteSaveProvider.ts
@@ -6,7 +6,7 @@
import { RequestInit } from "node-fetch";
import * as vscode from "vscode";
import { getCommonHeadersForDataverse } from "../../../common/services/AuthenticationProvider";
-import { BAD_REQUEST, MIMETYPE } from "../common/constants";
+import { BAD_REQUEST, MIMETYPE, queryParameters } from "../common/constants";
import { showErrorDialog } from "../../../common/utilities/errorHandlerUtil";
import { FileData } from "../context/fileData";
import { httpMethod } from "../common/constants";
@@ -19,7 +19,7 @@ import { getPatchRequestUrl, getRequestURL } from "../utilities/urlBuilderUtil";
import WebExtensionContext from "../WebExtensionContext";
import { IAttributePath } from "../common/interfaces";
import { webExtensionTelemetryEventNames } from "../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
-import { schemaEntityName, schemaEntityKey } from "../schema/constants";
+import { MultiFileSupportedEntityName, schemaEntityKey } from "../schema/constants";
import { getEntityMappingEntityId } from "../utilities/fileAndEntityUtil";
interface ISaveCallParameters {
@@ -30,7 +30,9 @@ interface ISaveCallParameters {
export async function saveData(fileUri: vscode.Uri) {
const dataMap: Map =
WebExtensionContext.fileDataMap.getFileMap;
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ queryParameters.ORG_URL
+ ) as string;
const entityName = dataMap.get(fileUri.fsPath)?.entityName as string;
const mappedEntity = getEntity(entityName)?.get(
schemaEntityKey.MAPPING_ENTITY
@@ -91,7 +93,7 @@ async function getSaveParameters(
);
if (webFileV2) {
let fileName = fileDataMap.get(fileUri.fsPath)?.fileName as string;
- if (entityName === schemaEntityName.SERVERLOGICS && fileName && !fileName.endsWith('.sl')) {
+ if (entityName === MultiFileSupportedEntityName.SERVERLOGICS && fileName && !fileName.endsWith('.sl')) {
const baseName = fileName.endsWith('.js') ? fileName.slice(0, -3) : fileName;
fileName = `${baseName}.sl`;
}
@@ -162,7 +164,7 @@ async function saveDataToDataverse(
let fileExtensionType = fileDataMap.get(
fileUri.fsPath
)?.entityFileExtensionType;
- if (entityName == schemaEntityName.SERVERLOGICS ) {
+ if(entityName == MultiFileSupportedEntityName.SERVERLOGICS ) {
fileExtensionType = 'sl';
}
diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts
index 9d8ae64a5..9152f2e59 100644
--- a/src/web/client/extension.ts
+++ b/src/web/client/extension.ts
@@ -13,7 +13,10 @@ import {
ARTEMIS_RESPONSE_FAILED,
} from "./common/constants";
import { PortalsFS } from "./dal/fileSystemProvider";
-import { checkMandatoryParameters } from "./common/errorHandler";
+import {
+ checkMandatoryParameters,
+ removeEncodingFromParameters,
+} from "./common/errorHandler";
import { WebExtensionTelemetry } from "./telemetry/webExtensionTelemetry";
import { getEnvironmentIdFromUrl, isCoPresenceEnabled, updateFileContentInFileDataMap } from "./utilities/commonUtil";
import { NPSService } from "./services/NPSService";
@@ -44,9 +47,6 @@ import { authenticateUserInVSCode } from "../../common/services/AuthenticationPr
import { activateServerApiAutocomplete } from "../../common/intellisense";
import { EnableServerLogicChanges } from "../../common/ecs-features/ecsFeatureGates";
import { setServerApiTelemetryContext } from "../../common/intellisense/ServerApiTelemetryContext";
-import { PPAPIService } from "../../common/services/PPAPIService";
-import { SiteVisibility } from "../../client/power-pages/actions-hub/models/SiteVisibility";
-import { WebsiteDataModel } from "../../common/services/Constants";
let serverApiAutocompleteInitialized = false;
@@ -100,18 +100,7 @@ export async function activate(context: vscode.ExtensionContext): Promise
return;
}
- const orgId = queryParamsMap.get(Constants.queryParameters.ORG_ID) as string;
-
- const isSuccess = await fetchArtemisData(orgId);
- if (!isSuccess) {
- return;
- }
-
- const isWebsiteFetchSuccessful = await initializeWebsiteDetails(queryParamsMap);
- if (!isWebsiteFetchSuccessful) {
- return;
- }
-
+ removeEncodingFromParameters(queryParamsMap);
WebExtensionContext.setWebExtensionContext(
entity,
entityId,
@@ -119,7 +108,9 @@ export async function activate(context: vscode.ExtensionContext): Promise
context.extensionUri
);
- WebExtensionContext.telemetry.sendInfoTelemetry(webExtensionTelemetryEventNames.WEB_EXTENSION_ORG_GEO, { orgId: WebExtensionContext.organizationId, orgGeo: WebExtensionContext.geoName });
+ const orgId = queryParamsMap.get(queryParameters.ORG_ID) as string;
+ await fetchArtemisData(orgId);
+ WebExtensionContext.telemetry.sendInfoTelemetry(webExtensionTelemetryEventNames.WEB_EXTENSION_ORG_GEO, { orgId: orgId, orgGeo: WebExtensionContext.geoName });
oneDSLoggerWrapper.instantiate(WebExtensionContext.geoName, WebExtensionContext.geoLongName, WebExtensionContext.serviceEndpointCategory);
WebExtensionContext.telemetry.sendExtensionInitPathParametersTelemetry(
@@ -154,9 +145,9 @@ export async function activate(context: vscode.ExtensionContext): Promise
AppName: PowerPagesAppName,
EnvID: WebExtensionContext.environmentId,
UserID: WebExtensionContext.userId,
- TenantID: WebExtensionContext.tenantId,
- Region: WebExtensionContext.region,
- Location: WebExtensionContext.urlParametersMap.get(queryParameters.GEO) ?? ""
+ TenantID: queryParamsMap.get(queryParameters.TENANT_ID) as string,
+ Region: queryParamsMap.get(queryParameters.REGION) as string,
+ Location: queryParamsMap.get(queryParameters.GEO) as string
},
PowerPagesClientName);
@@ -167,10 +158,10 @@ export async function activate(context: vscode.ExtensionContext): Promise
if (!serverApiAutocompleteInitialized && enableServerLogicChanges) {
// Set telemetry context for Server API autocomplete events
setServerApiTelemetryContext({
- tenantId: WebExtensionContext.tenantId,
+ tenantId: queryParamsMap.get(queryParameters.TENANT_ID) as string,
envId: WebExtensionContext.environmentId,
userId: WebExtensionContext.userId,
- orgId: WebExtensionContext.organizationId,
+ orgId: orgId,
geo: WebExtensionContext.geoName,
});
activateServerApiAutocomplete(context, [
@@ -292,7 +283,7 @@ export function processWalkthroughFirstRunExperience(context: vscode.ExtensionCo
IS_MULTIFILE_FIRST_RUN_EXPERIENCE,
true
);
- if (isMultifileFirstRun) {
+ if (isMultifileFirstRun && WebExtensionContext.showMultifileInVSCode) {
vscode.commands.executeCommand(
`workbench.action.openWalkthrough`,
`microsoft-IsvExpTools.powerplatform-vscode#PowerPage-gettingStarted-multiFile`,
@@ -483,7 +474,11 @@ export function createWebWorkerInstance(
}
export async function showSiteVisibilityDialog() {
- if (WebExtensionContext.siteVisibility === PUBLIC) {
+ if (
+ WebExtensionContext.urlParametersMap.get(
+ queryParameters.SITE_VISIBILITY
+ ) === PUBLIC
+ ) {
const edit: vscode.MessageItem = {
isCloseAffordance: true,
title: vscode.l10n.t("Edit the site"),
@@ -604,18 +599,24 @@ export function showWalkthrough(
export function registerCopilot(context: vscode.ExtensionContext) {
try {
const orgInfo = {
- orgId: WebExtensionContext.organizationId,
+ orgId: WebExtensionContext.urlParametersMap.get(
+ queryParameters.ORG_ID
+ ) as string,
environmentId: getEnvironmentIdFromUrl(),
environmentName: "",
- activeOrgUrl: WebExtensionContext.orgUrl,
- tenantId: WebExtensionContext.tenantId,
+ activeOrgUrl: WebExtensionContext.urlParametersMap.get(queryParameters.ORG_URL) as string,
+ tenantId: WebExtensionContext.urlParametersMap.get(queryParameters.TENANT_ID) as string,
} as IOrgInfo;
+ const websiteId = WebExtensionContext.urlParametersMap.get(
+ queryParameters.WEBSITE_ID
+ ) as string
+
const copilotPanel = new copilot.PowerPagesCopilot(context.extensionUri,
context,
undefined,
orgInfo,
- WebExtensionContext.websiteId);
+ websiteId);
context.subscriptions.push(vscode.window.registerWebviewViewProvider(copilot.PowerPagesCopilot.viewType, copilotPanel, {
webviewOptions: {
@@ -678,73 +679,19 @@ function isActiveDocument(fileFsPath: string): boolean {
);
}
-async function fetchArtemisData(orgId: string): Promise {
- let isSuccess = true;
- await vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- cancellable: true,
- title: vscode.l10n.t("Fetching environment information ..."),
- },
- async () => {
- const artemisResponse = await ArtemisService.getArtemisResponse(orgId, "");
- if (artemisResponse === null || artemisResponse.response === null) {
- WebExtensionContext.telemetry.sendErrorTelemetry(
- webExtensionTelemetryEventNames.WEB_EXTENSION_ARTEMIS_RESPONSE_FAILED,
- fetchArtemisData.name,
- ARTEMIS_RESPONSE_FAILED
- );
- showErrorDialog(
- vscode.l10n.t("There was a problem opening the workspace"),
- vscode.l10n.t("Unable to fetch environment information")
- );
- isSuccess = false;
- return;
- }
-
- WebExtensionContext.region = artemisResponse.stamp;
- WebExtensionContext.geoName = artemisResponse.response.geoName;
- WebExtensionContext.geoLongName = artemisResponse.response.geoLongName;
- WebExtensionContext.serviceEndpointCategory = artemisResponse.stamp;
- WebExtensionContext.clusterLocation = getECSOrgLocationValue(artemisResponse.response.clusterName, artemisResponse.response.clusterNumber);
- }
- );
- return isSuccess;
-}
-
-async function initializeWebsiteDetails(queryParamsMap: Map) {
- let isSuccess = true;
-
- await vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- cancellable: true,
- title: vscode.l10n.t("Fetching website details ..."),
- },
- async () => {
- const portalId = queryParamsMap.get(queryParameters.PORTAL_ID) as string;
- const envId = queryParamsMap.get(queryParameters.ENV_ID)?.split("/")?.pop() as string;
- const websiteDetails = await PPAPIService.getWebsiteDetailsById(WebExtensionContext.serviceEndpointCategory, envId, portalId);
-
- if (!websiteDetails) {
- showErrorDialog(
- vscode.l10n.t("There was a problem opening the workspace"),
- vscode.l10n.t("Unable to fetch website details")
- );
-
- isSuccess = false;
- return;
- }
-
- WebExtensionContext.tenantId = websiteDetails?.tenantId ?? "";
- WebExtensionContext.websiteId = websiteDetails.websiteRecordId ?? "";
- WebExtensionContext.schema = websiteDetails?.dataModel === WebsiteDataModel.Standard ? Constants.portalSchemaVersion.V1 : Constants.portalSchemaVersion.V2;
- WebExtensionContext.siteVisibility = websiteDetails?.siteVisibility ?? SiteVisibility.Private;
- WebExtensionContext.orgUrl = websiteDetails?.dataverseInstanceUrl?.replace(/\/$/, '') ?? "";
- WebExtensionContext.websiteName = websiteDetails?.name ?? "";
- WebExtensionContext.organizationId = websiteDetails?.dataverseOrganizationId ?? "";
- }
- );
+async function fetchArtemisData(orgId: string) {
+ const artemisResponse = await ArtemisService.getArtemisResponse(orgId, "");
+ if (artemisResponse === null || artemisResponse.response === null) {
+ WebExtensionContext.telemetry.sendErrorTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_ARTEMIS_RESPONSE_FAILED,
+ fetchArtemisData.name,
+ ARTEMIS_RESPONSE_FAILED
+ );
+ return;
+ }
- return isSuccess;
+ WebExtensionContext.geoName = artemisResponse.response.geoName;
+ WebExtensionContext.geoLongName = artemisResponse.response.geoLongName;
+ WebExtensionContext.serviceEndpointCategory = artemisResponse.stamp;
+ WebExtensionContext.clusterLocation = getECSOrgLocationValue(artemisResponse.response.clusterName, artemisResponse.response.clusterNumber);
}
diff --git a/src/web/client/schema/constants.ts b/src/web/client/schema/constants.ts
index 7eb0f531d..a303d394d 100644
--- a/src/web/client/schema/constants.ts
+++ b/src/web/client/schema/constants.ts
@@ -8,6 +8,7 @@ export const SCHEMA_WEBFILE_FOLDER_NAME = "web-files";
export enum schemaKey {
SINGLE_ENTITY_URL = "singleEntityURL",
MULTI_ENTITY_URL = "multiEntityURL",
+ SCHEMA_VERSION = "schema",
DATAVERSE_API_VERSION = "version",
DATA = "data",
API = "api",
diff --git a/src/web/client/services/NPSService.ts b/src/web/client/services/NPSService.ts
index e0d7991c8..77a2f3ebb 100644
--- a/src/web/client/services/NPSService.ts
+++ b/src/web/client/services/NPSService.ts
@@ -5,7 +5,7 @@
import jwt_decode from 'jwt-decode';
import { npsAuthentication } from "../../../common/services/AuthenticationProvider";
-import { httpMethod } from '../common/constants';
+import { httpMethod, queryParameters } from '../common/constants';
import { RequestInit } from 'node-fetch'
import WebExtensionContext from '../WebExtensionContext';
import { webExtensionTelemetryEventNames } from '../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents';
@@ -22,7 +22,7 @@ export class NPSService {
}
public static getNpsSurveyEndpoint(): string {
- const region = WebExtensionContext.region.toLowerCase();
+ const region = WebExtensionContext.urlParametersMap?.get(queryParameters.REGION)?.toLowerCase();
const dataBoundary = getCurrentDataBoundary();
let npsSurveyEndpoint = '';
switch (region) {
diff --git a/src/web/client/services/etagHandlerService.ts b/src/web/client/services/etagHandlerService.ts
index 43c843e83..8a3d1e6f2 100644
--- a/src/web/client/services/etagHandlerService.ts
+++ b/src/web/client/services/etagHandlerService.ts
@@ -6,7 +6,7 @@
import * as vscode from "vscode";
import { RequestInit } from "node-fetch";
import { getCommonHeadersForDataverse } from "../../../common/services/AuthenticationProvider";
-import { httpMethod, ODATA_ETAG } from "../common/constants";
+import { httpMethod, ODATA_ETAG, queryParameters } from "../common/constants";
import { IAttributePath } from "../common/interfaces";
import { PortalsFS } from "../dal/fileSystemProvider";
import { webExtensionTelemetryEventNames } from "../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
@@ -33,7 +33,9 @@ export class EtagHandlerService {
const entityEtag = getFileEntityEtag(fileFsPath);
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ queryParameters.ORG_URL
+ ) as string;
const requestUrl = getRequestURL(
dataverseOrgUrl,
@@ -147,7 +149,9 @@ export class EtagHandlerService {
const entityId = getFileEntityId(fileFsPath);
const requestSentAtTime = new Date().getTime();
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ queryParameters.ORG_URL
+ ) as string;
const requestUrl = getRequestURL(
dataverseOrgUrl,
diff --git a/src/web/client/telemetry/webExtensionTelemetry.ts b/src/web/client/telemetry/webExtensionTelemetry.ts
index e5e0dc41d..345588b4d 100644
--- a/src/web/client/telemetry/webExtensionTelemetry.ts
+++ b/src/web/client/telemetry/webExtensionTelemetry.ts
@@ -33,9 +33,15 @@ export class WebExtensionTelemetry {
eventName: webExtensionTelemetryEventNames.WEB_EXTENSION_INIT_QUERY_PARAMETERS,
properties: {
orgId: queryParamsMap.get(queryParameters.ORG_ID),
+ tenantId: queryParamsMap.get(queryParameters.TENANT_ID),
portalId: queryParamsMap.get(queryParameters.PORTAL_ID),
+ websiteId: queryParamsMap.get(queryParameters.WEBSITE_ID),
+ dataSource: queryParamsMap.get(queryParameters.DATA_SOURCE),
+ schema: queryParamsMap.get(queryParameters.SCHEMA),
referrerSessionId: queryParamsMap.get(queryParameters.REFERRER_SESSION_ID),
referrer: queryParamsMap.get(queryParameters.REFERRER),
+ siteVisibility: queryParamsMap.get(queryParameters.SITE_VISIBILITY),
+ region: queryParamsMap.get(queryParameters.REGION),
geo: queryParamsMap.get(queryParameters.GEO),
envId: getEnvironmentIdFromUrl(),
referrerSource: queryParamsMap.get(queryParameters.REFERRER_SOURCE),
diff --git a/src/web/client/test/integration/WebExtensionContext.test.ts b/src/web/client/test/integration/WebExtensionContext.test.ts
index 922940df2..5e94ef233 100644
--- a/src/web/client/test/integration/WebExtensionContext.test.ts
+++ b/src/web/client/test/integration/WebExtensionContext.test.ts
@@ -29,8 +29,10 @@ describe("WebExtensionContext", () => {
const queryParamsMap = new Map([
["_fetchQueryParameters", schemaEntityKey.FETCH_QUERY_PARAMETERS],
[schemaEntityKey.DATAVERSE_ENTITY_NAME, "DATAVERSE_ENTITY_NAME"],
+ [schemaKey.SCHEMA_VERSION, "1.1"],
[schemaKey.DATA, "schemaKey.DATA"],
- [schemaKey.DATAVERSE_API_VERSION, "1.0"]
+ [schemaKey.DATAVERSE_API_VERSION, "1.0"],
+ [Constants.queryParameters.WEBSITE_NAME, "powerPages"],
]);
const entityMap = new Map([["test", "Entity"]]);
@@ -68,7 +70,7 @@ describe("WebExtensionContext", () => {
);
//Assert
- expect(WebExtensionContext.schema).eq("portalschemav1");
+ expect(WebExtensionContext.currentSchemaVersion).eq("1.1");
expect(WebExtensionContext.defaultEntityType).eq(
entityName.toLowerCase()
);
@@ -94,7 +96,8 @@ describe("WebExtensionContext", () => {
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, "1.1"],
+ [Constants.queryParameters.ORG_URL, "PowerPages.com"],
]);
stub(authenticationProvider, "dataverseAuthentication").resolves({ accessToken: "", userId: "" });
@@ -136,7 +139,8 @@ describe("WebExtensionContext", () => {
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, "1.1"],
+ [Constants.queryParameters.ORG_URL, "PowerPages.com"],
]);
stub(authenticationProvider, "dataverseAuthentication").resolves(
@@ -314,7 +318,8 @@ describe("WebExtensionContext", () => {
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, "1.1"],
+ [Constants.queryParameters.ORG_URL, "PowerPages.com"],
]);
stub(authenticationProvider, "dataverseAuthentication").resolves({ accessToken: "", userId: "" });
@@ -354,11 +359,12 @@ describe("WebExtensionContext", () => {
"4cdf3b4d873a65135553afdf420a47dbc898ba0c1c0ece2407bbbf2bde02a68b";
const ORG_URL = "PowerPages.com";
- const SCHEMA_VERSION = "portalschemav1";
+ const SCHEMA_VERSION = "powerPage";
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, SCHEMA_VERSION],
+ [Constants.queryParameters.ORG_URL, ORG_URL],
]);
const dataverseAuthentication = stub(
@@ -433,7 +439,6 @@ describe("WebExtensionContext", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any);
- WebExtensionContext.orgUrl = ORG_URL;
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -548,7 +553,7 @@ describe("WebExtensionContext", () => {
{
headers: header,
dataverseOrgUrl: ORG_URL,
- websiteId: '36429b2e-8b29-4020-8493-bd5e277444d8'
+ websiteId: undefined
}
);
});
@@ -560,10 +565,12 @@ describe("WebExtensionContext", () => {
"4cdf3b4d873a65135553afdf420a47dbc898ba0c1c0ece2407bbbf2bde02a68b";
const ORG_URL = "PowerPages.com";
+ const SCHEMA_VERSION = "powerPage";
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, SCHEMA_VERSION],
+ [Constants.queryParameters.ORG_URL, ORG_URL],
]);
const dataverseAuthentication = stub(
@@ -619,7 +626,6 @@ describe("WebExtensionContext", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any);
- WebExtensionContext.orgUrl = ORG_URL;
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -687,10 +693,12 @@ describe("WebExtensionContext", () => {
"4cdf3b4d873a65135553afdf420a47dbc898ba0c1c0ece2407bbbf2bde02a68b";
const ORG_URL = "PowerPages.com";
+ const SCHEMA_VERSION = "powerPage";
const entityName = "webPages";
const entityId = "3355d5ec-b38d-46ca-a150-c00386b0a4be";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"]
+ [schemaKey.SCHEMA_VERSION, SCHEMA_VERSION],
+ [Constants.queryParameters.ORG_URL, ORG_URL],
]);
const dataverseAuthentication = stub(
@@ -731,7 +739,6 @@ describe("WebExtensionContext", () => {
stub(schemaHelperUtil, "getPortalLanguageIdToLcidMap").returns(
portalLanguageIdCodeMap
);
- WebExtensionContext.orgUrl = ORG_URL;
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
diff --git a/src/web/client/test/integration/errorHandler.test.ts b/src/web/client/test/integration/errorHandler.test.ts
index e23b00e97..011754369 100644
--- a/src/web/client/test/integration/errorHandler.test.ts
+++ b/src/web/client/test/integration/errorHandler.test.ts
@@ -4,15 +4,23 @@
*/
import * as vscode from "vscode";
-import Sinon, { stub, assert } from "sinon";
+import Sinon, { stub, assert, spy } from "sinon";
import { expect } from "chai";
+import WebExtensionContext from "../../../client/WebExtensionContext";
+import { schemaKey } from "../../schema/constants";
+import { webExtensionTelemetryEventNames } from "../../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
-import { queryParameters } from "../../common/constants";
+import {
+ queryParameters,
+ PORTALS_FOLDER_NAME_DEFAULT,
+} from "../../common/constants";
import {
+ removeEncodingFromParameters,
checkMandatoryParameters,
checkMandatoryPathParameters,
checkMandatoryQueryParameters,
+ isDynamicsCRMUrl,
} from "../../common/errorHandler";
import {
showErrorDialog
@@ -58,14 +66,64 @@ describe("errorHandler", () => {
);
});
+ it("removeEncodingFromParameters_whenEncodedStrginPassed_shouldDecodeSCHEMAVERSIONAndWEBSITENAME", () => {
+ //Act
+ const queryParamsMap = new Map([
+ [schemaKey.SCHEMA_VERSION, "3A%20test_file_name"],
+ [queryParameters.WEBSITE_NAME, "3A%20test_test_webSiteName"],
+ ]);
+
+ //Action
+ removeEncodingFromParameters(queryParamsMap);
+
+ //Assert
+ const websiteName = queryParamsMap.get(
+ queryParameters.WEBSITE_NAME
+ ) as string;
+
+ const schemaFileName = queryParamsMap.get(
+ schemaKey.SCHEMA_VERSION
+ ) as string;
+
+ expect(schemaFileName).eq("3A test_file_name");
+ expect(websiteName).eq("3A test_test_webSiteName");
+ });
+
+ it("removeEncodingFromParameters__whenWebsiteNameIsBlank_shouldMapPORTALSFOLDERNAMEDEFAULT", () => {
+ //Act
+ const queryParamsMap = new Map([
+ [schemaKey.SCHEMA_VERSION, "3A%20test_file_name"],
+ [queryParameters.WEBSITE_NAME, ""],
+ ]);
+ const portalFolderName = PORTALS_FOLDER_NAME_DEFAULT;
+
+ //Action
+ removeEncodingFromParameters(queryParamsMap);
+
+ //Assert
+ const websiteName = queryParamsMap.get(
+ queryParameters.WEBSITE_NAME
+ ) as string;
+
+ const schemaFileName = queryParamsMap.get(
+ schemaKey.SCHEMA_VERSION
+ ) as string;
+
+ expect(schemaFileName).eq("3A test_file_name");
+ expect(websiteName).eq(portalFolderName);
+ });
it("checkMandatoryParameters_whenAppNameIsPortalAndEntityAndEntityIdHavingValues_shouldReturnTrue", () => {
//Act
const appName = "portal";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.ENV_ID, "2e23a54a-d9c1-4e5e-bb18-86a69841ad43"],
- [queryParameters.PORTAL_ID, "c913e4ab-bdbc-4a53-beb5-f2650cc8e3c4"]
+ [queryParameters.ORG_URL, "https://org.crm4.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
]);
//Action
@@ -83,9 +141,13 @@ describe("errorHandler", () => {
const _mockShowErrorMessage = stub(vscode.window, "showErrorMessage");
const appName = "por";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.ENV_ID, "2e23a54a-d9c1-4e5e-bb18-86a69841ad43"],
- [queryParameters.PORTAL_ID, "c913e4ab-bdbc-4a53-beb5-f2650cc8e3c4"]
+ [queryParameters.ORG_URL, "https://org.crm.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
]);
//Action
const result = checkMandatoryParameters(
@@ -100,13 +162,17 @@ describe("errorHandler", () => {
assert.calledOnce(_mockShowErrorMessage);
});
- it("checkMandatoryParameters_whenOrgIdIsBlank_shouldReturnFalse", () => {
+ it("checkMandatoryParameters_whenOrgURLIsBlank_shouldReturnFalse", () => {
//Act
const appName = "portal";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, ""],
- [queryParameters.ENV_ID, "2e23a54a-d9c1-4e5e-bb18-86a69841ad43"],
- [queryParameters.PORTAL_ID, "c913e4ab-bdbc-4a53-beb5-f2650cc8e3c4"]
+ [queryParameters.ORG_URL, ""],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
]);
//Action
const result = checkMandatoryParameters(
@@ -117,13 +183,17 @@ describe("errorHandler", () => {
expect(result).false;
});
- it("checkMandatoryParameters_whenEnvIdIsBlank_shouldReturnFalse", () => {
+ it("checkMandatoryParameters_whenDATASOURCEIsBlank_shouldReturnFalse", () => {
//Act
const appName = "portal";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.ENV_ID, ""],
- [queryParameters.PORTAL_ID, "c913e4ab-bdbc-4a53-beb5-f2650cc8e3c4"]
+ [queryParameters.ORG_URL, "https://org.crm2.dynamics.com"],
+ [queryParameters.DATA_SOURCE, ""],
+ [schemaKey.SCHEMA_VERSION, "1.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
]);
//Action
@@ -136,13 +206,37 @@ describe("errorHandler", () => {
expect(result).false;
});
- it("checkMandatoryParameters_whenPortalIdIsBlank_shouldReturnFalse", () => {
+ it("checkMandatoryParameters_whenSCHEMAVERSIONIsBlank_shouldReturnFalse", () => {
//Act
const appName = "portal";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.ENV_ID, "2e23a54a-d9c1-4e5e-bb18-86a69841ad43"],
- [queryParameters.PORTAL_ID, ""]
+ [queryParameters.ORG_URL, "https://org.crm11.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, ""],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
+ ]);
+
+ //Action
+ const result = checkMandatoryParameters(
+ appName,
+ queryParamsMap
+ );
+
+ //Assert
+ expect(result).false;
+ });
+
+ it("checkMandatoryParameters_whenWEBSITEIDIsBlank_shouldReturnFalse", () => {
+ //Act
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.crm20.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [queryParameters.WEBSITE_ID, ""],
]);
//Action
@@ -182,13 +276,245 @@ describe("errorHandler", () => {
//Act
const appName = "portal";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.ENV_ID, "2e23a54a-d9c1-4e5e-bb18-86a69841ad43"],
- [queryParameters.PORTAL_ID, "c913e4ab-bdbc-4a53-beb5-f2650cc8e3c4"]
+ [queryParameters.ORG_URL, "https://org.crm11.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
]);
//Action
const result = checkMandatoryQueryParameters(appName, queryParamsMap);
//Assert
expect(result).true;
});
+
+ it("checkMandatoryQueryParameters_whenOrgUrlIsBlank_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const _mockSendErrorTelemetry = spy(
+ WebExtensionContext.telemetry,
+ "sendErrorTelemetry"
+ );
+
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, ""],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
+ ]);
+ //Action
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ const detailMessage = vscode.l10n.t("Check the URL and verify the parameters are correct");
+
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const options = { detail: detailMessage, modal: true };
+
+ assert.calledOnceWithExactly(
+ _mockShowErrorMessage,
+ errorString,
+ options
+ );
+ assert.calledOnceWithExactly(
+ _mockSendErrorTelemetry,
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
+ checkMandatoryQueryParameters.name,
+ `orgURL:, dataSource:SQL, schemaName:1.0.0.0 ,websiteId:ed9a6c19-5ab6-4f67-8c35-2423cff958c4`
+ );
+ });
+
+ it("checkMandatoryQueryParameters_whenDataSourceIsBlank_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const _mockSendErrorTelemetry = spy(
+ WebExtensionContext.telemetry,
+ "sendErrorTelemetry"
+ );
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.crm14.dynamics.com"],
+ [queryParameters.DATA_SOURCE, ""],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
+ ]);
+ //Action
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ const detailMessage = vscode.l10n.t("Check the URL and verify the parameters are correct");
+
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const options = { detail: detailMessage, modal: true };
+
+ assert.calledOnceWithExactly(
+ _mockShowErrorMessage,
+ errorString,
+ options
+ );
+ assert.calledOnceWithExactly(
+ _mockSendErrorTelemetry,
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
+ checkMandatoryQueryParameters.name,
+ `orgURL:https://org.crm14.dynamics.com, dataSource:, schemaName:1.0.0.0 ,websiteId:ed9a6c19-5ab6-4f67-8c35-2423cff958c4`
+ );
+ });
+
+ it("checkMandatoryQueryParameters_whenSchemaVersionIsBlank_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const _mockSendErrorTelemetry = spy(
+ WebExtensionContext.telemetry,
+ "sendErrorTelemetry"
+ );
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.crm19.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, ""],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
+ ]);
+ //Action
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ const detailMessage = vscode.l10n.t("Check the URL and verify the parameters are correct");
+
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const options = { detail: detailMessage, modal: true };
+
+ assert.calledOnceWithExactly(
+ _mockShowErrorMessage,
+ errorString,
+ options
+ );
+ assert.calledOnceWithExactly(
+ _mockSendErrorTelemetry,
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
+ checkMandatoryQueryParameters.name,
+ `orgURL:https://org.crm19.dynamics.com, dataSource:SQL, schemaName: ,websiteId:ed9a6c19-5ab6-4f67-8c35-2423cff958c4`
+ );
+ });
+
+ it("checkMandatoryQueryParameters_whenWebsiteIdIsBlank_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const _mockSendErrorTelemetry = spy(
+ WebExtensionContext.telemetry,
+ "sendErrorTelemetry"
+ );
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.crm4.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [queryParameters.WEBSITE_ID, ""],
+ ]);
+ //Action
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ const detailMessage = vscode.l10n.t("Check the URL and verify the parameters are correct");
+
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const options = { detail: detailMessage, modal: true };
+
+ assert.calledOnceWithExactly(
+ _mockShowErrorMessage,
+ errorString,
+ options
+ );
+ assert.calledOnceWithExactly(
+ _mockSendErrorTelemetry,
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
+ checkMandatoryQueryParameters.name,
+ `orgURL:https://org.crm4.dynamics.com, dataSource:SQL, schemaName:1.0.0.0 ,websiteId:`
+ );
+ });
+
+ it("checkMandatoryQueryParameters_whenAppNameIsNotPortal_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const appName = "por";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.crm4.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [queryParameters.WEBSITE_ID, "12345"],
+ ]);
+ //Action
+ const detailMessage = { detail: vscode.l10n.t("Unable to find that app"), modal: true };
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ assert.calledOnce(_mockShowErrorMessage);
+ assert.calledWith(
+ _mockShowErrorMessage,
+ errorString,
+ detailMessage
+ );
+ });
+
+ it("checkMandatoryQueryParameters_whenOrgUrlIsInvalid_shouldReturnFalse", () => {
+ //Act
+ const _mockShowErrorMessage = spy(vscode.window, "showErrorMessage");
+ const _mockSendErrorTelemetry = spy(
+ WebExtensionContext.telemetry,
+ "sendErrorTelemetry"
+ );
+
+ const appName = "portal";
+ const queryParamsMap = new Map([
+ [queryParameters.ORG_URL, "https://org.dynamics.com"],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [schemaKey.SCHEMA_VERSION, "1.0.0.0"],
+ [
+ queryParameters.WEBSITE_ID,
+ "ed9a6c19-5ab6-4f67-8c35-2423cff958c4",
+ ],
+ ]);
+ //Action
+ const result = checkMandatoryQueryParameters(appName, queryParamsMap);
+ //Assert
+ expect(result).false;
+ const detailMessage = vscode.l10n.t("Check the URL and verify the parameters are correct");
+
+ const errorString = vscode.l10n.t("There was a problem opening the workspace");
+ const options = { detail: detailMessage, modal: true };
+
+ assert.calledOnceWithExactly(
+ _mockShowErrorMessage,
+ errorString,
+ options
+ );
+
+
+ const sendErrorTelemetryCalls = _mockSendErrorTelemetry.getCalls();
+ assert.callCount(_mockSendErrorTelemetry, 2);
+ assert.calledWithMatch(
+ sendErrorTelemetryCalls[0],
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_INVALID_DATAVERSE_URL,
+ isDynamicsCRMUrl.name,
+ `orgURL:https://org.dynamics.com`
+ );
+ assert.calledWithMatch(
+ sendErrorTelemetryCalls[1],
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MANDATORY_QUERY_PARAMETERS_MISSING,
+ checkMandatoryQueryParameters.name,
+ `orgURL:https://org.dynamics.com, dataSource:SQL, schemaName:1.0.0.0 ,websiteId:ed9a6c19-5ab6-4f67-8c35-2423cff958c4`
+ );
+ });
});
diff --git a/src/web/client/test/integration/remoteFetchProvider.test.ts b/src/web/client/test/integration/remoteFetchProvider.test.ts
index 47ae99c02..bfa7d6e59 100644
--- a/src/web/client/test/integration/remoteFetchProvider.test.ts
+++ b/src/web/client/test/integration/remoteFetchProvider.test.ts
@@ -4,21 +4,19 @@
*/
import * as vscode from "vscode";
+import * as fetch from "node-fetch";
import sinon, { stub, assert } from "sinon";
import { fetchDataFromDataverseAndUpdateVFS } from "../../dal/remoteFetchProvider";
import { PortalsFS } from "../../dal/fileSystemProvider";
import WebExtensionContext from "../../WebExtensionContext";
import * as Constants from "../../common/constants";
import * as schemaHelperUtil from "../../utilities/schemaHelperUtil";
-import { schemaEntityKey, folderExportType } from "../../schema/constants";
+import { schemaEntityKey, schemaKey } from "../../schema/constants";
import * as urlBuilderUtil from "../../utilities/urlBuilderUtil";
import * as commonUtil from "../../utilities/commonUtil";
-import * as folderHelperUtility from "../../utilities/folderHelperUtility";
import { expect } from "chai";
import * as authenticationProvider from "../../../../common/services/AuthenticationProvider";
import { webExtensionTelemetryEventNames } from "../../../../common/OneDSLoggerTelemetry/web/client/webExtensionTelemetryEvents";
-import { queryParameters } from "../../common/constants";
-import { ECSFeaturesClient } from "../../../../common/ecs-features/ecsFeatureClient";
describe("remoteFetchProvider", () => {
afterEach(() => {
@@ -30,21 +28,13 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
- [
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
const languageIdCodeMap = new Map([["1033", "en-US"]]);
@@ -80,7 +70,7 @@ describe("remoteFetchProvider", () => {
{ accessToken: accessToken, userId: "" }
);
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -118,37 +108,16 @@ describe("remoteFetchProvider", () => {
);
const requestURL = "make.powerpgaes.com";
- stub(urlBuilderUtil, "getRequestURL").returns(requestURL);
+ const getRequestURL = stub(urlBuilderUtil, "getRequestURL").returns(requestURL);
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: requestURL }
- ]);
stub(commonUtil, "isWebfileContentLoadNeeded").returns(true);
stub(urlBuilderUtil, "getCustomRequestURL").returns(requestURL);
stub(schemaHelperUtil, "isBase64Encoded").returns(true);
stub(commonUtil, "GetFileNameWithExtension").returns("test.txt");
- stub(commonUtil, "getSanitizedFileName").returns("testname");
- stub(commonUtil, "getAttributeContent").returns("VGhpcyBpcyBhIHRlc3Qgc3RyaW5nLg==");
stub(schemaHelperUtil, "getAttributePath").returns({
source: "value",
relativePath: "ddrive",
});
- stub(schemaHelperUtil, "getEntity").returns(
- new Map([
- [schemaEntityKey.EXPORT_TYPE, folderExportType.SubFolders],
- [schemaEntityKey.FILE_FOLDER_NAME, "web-pages"],
- [schemaEntityKey.FILE_NAME_FIELD, "name"],
- [schemaEntityKey.FILE_ID_FIELD, "powerpagecomponentid"],
- [schemaEntityKey.ATTRIBUTES, "value,value2,value3"],
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [schemaEntityKey.ATTRIBUTES_EXTENSION, new Map([["value", "css"], ["value2", "js"], ["value3", "html"]]) as any],
- ])
- );
- stub(schemaHelperUtil, "encodeAsBase64").returns(false);
- stub(schemaHelperUtil, "getEntityParameters").returns([]);
- stub(urlBuilderUtil, "getMetadataInfo").returns({});
- stub(commonUtil, "convertContentToUint8Array").returns(new Uint8Array());
- stub(commonUtil, "isNullOrUndefined").returns(false);
const updateSingleFileUrisInContext = stub(
WebExtensionContext,
"updateSingleFileUrisInContext"
@@ -161,39 +130,18 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
const createDirectory = stub(portalFs, "createDirectory");
const writeFile = stub(portalFs, "writeFile");
-
- // Stub getWebpageNames to return a Set
- const webpageNamesSet = new Set();
- stub(WebExtensionContext, "getWebpageNames").returns(webpageNamesSet);
-
- // Stub ECS feature flags
- stub(ECSFeaturesClient, "getConfig").returns({
- enableDuplicateFileHandling: false,
- disallowedDuplicateFileHandlingOrgs: "",
- enableServerLogicChanges: false
- });
-
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
- WebExtensionContext.orgUrl = "PowerPages.com";
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
queryParamsMap
);
-
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
//Action
await fetchDataFromDataverseAndUpdateVFS(portalFs, { entityId: entityId, entityName: entityName });
//Assert
- assert.callCount(_mockFetch, 4); // 3 calls from authenticateAndUpdateDataverseProperties + 1 for the entity fetch
+ assert.callCount(_mockFetch, 4);
assert.calledWith(
sendAPITelemetry,
@@ -202,7 +150,7 @@ describe("remoteFetchProvider", () => {
Constants.httpMethod.GET
);
- // parse is called multiple times: once for setWebExtensionContext, once for createDirectory, 3 times for writeFile, and once for updateSingleFileUrisInContext
+ assert.calledOnce(getRequestURL);
assert.callCount(parse, 6);
assert.callCount(createDirectory, 1);
const createDirectoryCalls = createDirectory.getCalls();
@@ -261,9 +209,7 @@ describe("remoteFetchProvider", () => {
assert.callCount(writeFile, 3);
assert.calledOnce(updateSingleFileUrisInContext);
- // sendInfoTelemetry is called 3 times by authenticateAndUpdateDataverseProperties
- assert.callCount(sendInfoTelemetry, 3);
- // sendAPISuccessTelemetry is called 4 times: 3 from authenticateAndUpdateDataverseProperties + 1 from fetch
+ assert.callCount(sendInfoTelemetry, 5);
assert.callCount(sendAPISuccessTelemetry, 4);
});
@@ -274,21 +220,13 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
- [
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
const languageIdCodeMap = new Map([["1033", "en-US"]]);
@@ -324,7 +262,7 @@ describe("remoteFetchProvider", () => {
{ accessToken: accessToken, userId: "" }
);
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -362,39 +300,18 @@ describe("remoteFetchProvider", () => {
);
const requestURL = "make.powerpgaes.com";
- stub(urlBuilderUtil, "getRequestURL").returns(
+ const getRequestURL = stub(urlBuilderUtil, "getRequestURL").returns(
requestURL
);
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: requestURL }
- ]);
stub(urlBuilderUtil, "getCustomRequestURL").returns(requestURL);
stub(schemaHelperUtil, "isBase64Encoded").returns(true);
stub(commonUtil, "GetFileNameWithExtension").returns("test.txt");
- stub(commonUtil, "getSanitizedFileName").returns("testname");
- stub(commonUtil, "getAttributeContent").returns("VGhpcyBpcyBhIHRlc3Qgc3RyaW5nLg==");
stub(schemaHelperUtil, "getAttributePath").returns({
source: "value",
relativePath: "ddrive",
});
- stub(schemaHelperUtil, "getEntity").returns(
- new Map([
- [schemaEntityKey.EXPORT_TYPE, folderExportType.SubFolders],
- [schemaEntityKey.FILE_FOLDER_NAME, "web-pages"],
- [schemaEntityKey.FILE_NAME_FIELD, "name"],
- [schemaEntityKey.FILE_ID_FIELD, "powerpagecomponentid"],
- [schemaEntityKey.ATTRIBUTES, "value,value2,value3"],
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [schemaEntityKey.ATTRIBUTES_EXTENSION, new Map([["value", "css"], ["value2", "js"], ["value3", "html"]]) as any],
- ])
- );
- stub(schemaHelperUtil, "encodeAsBase64").returns(false);
- stub(schemaHelperUtil, "getEntityParameters").returns([]);
- stub(urlBuilderUtil, "getMetadataInfo").returns({});
- stub(commonUtil, "convertContentToUint8Array").returns(new Uint8Array());
- stub(commonUtil, "isNullOrUndefined").returns(false);
const fileUri: vscode.Uri = {
path: "powerplatform-vfs:/testWebSite/web-pages/testname/",
} as vscode.Uri;
@@ -404,39 +321,18 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
const createDirectory = stub(portalFs, "createDirectory");
const writeFile = stub(portalFs, "writeFile");
-
- // Stub getWebpageNames to return a Set
- const webpageNamesSet = new Set();
- stub(WebExtensionContext, "getWebpageNames").returns(webpageNamesSet);
-
- // Stub ECS feature flags
- stub(ECSFeaturesClient, "getConfig").returns({
- enableDuplicateFileHandling: false,
- disallowedDuplicateFileHandlingOrgs: "",
- enableServerLogicChanges: false
- });
-
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
- WebExtensionContext.orgUrl = "PowerPages.com";
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
queryParamsMap
);
-
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
//Action
await fetchDataFromDataverseAndUpdateVFS(portalFs);
//Assert
- assert.callCount(_mockFetch, 4); // 3 calls from authenticateAndUpdateDataverseProperties + 1 for entity fetch
+ assert.callCount(_mockFetch, 4);
assert.calledWith(
sendAPITelemetry,
@@ -445,7 +341,7 @@ describe("remoteFetchProvider", () => {
Constants.httpMethod.GET
);
- // parse is called multiple times: once for setWebExtensionContext, once for createDirectory, and 3 times for writeFile
+ assert.calledOnce(getRequestURL);
assert.callCount(parse, 5);
assert.callCount(createDirectory, 1);
const createDirectoryCalls = createDirectory.getCalls();
@@ -503,10 +399,8 @@ describe("remoteFetchProvider", () => {
expect(updateFileDetailsInContextCalls[1].args[7], "false");
assert.callCount(writeFile, 3);
- // sendInfoTelemetry is called 3 times by authenticateAndUpdateDataverseProperties + 2 times for file operations = 5 total
- assert.callCount(sendInfoTelemetry, 5);
+ assert.callCount(sendInfoTelemetry, 7);
assert.calledOnce(executeCommand);
- // sendAPISuccessTelemetry is called 4 times: 3 from authenticateAndUpdateDataverseProperties + 1 from fetch
assert.callCount(sendAPISuccessTelemetry, 4);
});
@@ -515,30 +409,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
- [
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -581,11 +460,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -620,30 +495,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
- [
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -690,11 +550,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: false,
statusText: "statusText",
json: () => {
@@ -740,30 +596,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
- [
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -806,11 +647,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -852,7 +689,7 @@ describe("remoteFetchProvider", () => {
assert.calledOnce(_mockFetch);
assert.calledTwice(sendAPITelemetry);
assert.calledOnce(sendErrorTelemetry);
- assert.calledOnce(getEntity); // getEntity is only called once in createContentFiles
+ assert.callCount(getEntity, 2);
});
it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessAndAttributesIsBlank_shouldThrowError", async () => {
@@ -860,30 +697,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
- [
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -926,11 +748,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -974,7 +792,7 @@ describe("remoteFetchProvider", () => {
assert.calledOnce(_mockFetch);
assert.calledTwice(sendAPITelemetry);
assert.calledOnce(sendErrorTelemetry);
- assert.calledOnce(getEntity); // getEntity is only called once in createContentFiles
+ assert.callCount(getEntity, 2);
});
it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessAndAttributeExtensionIsBlank_shouldThrowError", async () => {
@@ -982,30 +800,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
- [
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -1048,11 +851,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -1097,7 +896,7 @@ describe("remoteFetchProvider", () => {
assert.calledOnce(_mockFetch);
assert.calledTwice(sendAPITelemetry);
assert.calledOnce(sendErrorTelemetry);
- assert.calledOnce(getEntity); // getEntity is only called once in createContentFiles
+ assert.callCount(getEntity, 2);
});
it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessAndFileNameIsDefaultFilename_shouldThrowError", async () => {
@@ -1105,30 +904,15 @@ describe("remoteFetchProvider", () => {
const entityName = "webpages";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
- [
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
- // Set required WebExtensionContext properties
- WebExtensionContext.websiteName = "testWebSite";
- WebExtensionContext.websiteId = "36429b2e-8b29-4020-8493-bd5e277444d8";
- WebExtensionContext.organizationId = "e5dce21c-f85f-4849-b699-920c0fad5fbf";
- WebExtensionContext.environmentId = "c4dc3686-1e6b-e428-b886-16cd0b9f4918";
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
-
WebExtensionContext.setWebExtensionContext(
entityName,
entityId,
@@ -1171,11 +955,7 @@ describe("remoteFetchProvider", () => {
const portalFs = new PortalsFS();
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, "handleRequest").resolves({
+ const _mockFetch = stub(fetch, "default").resolves({
ok: true,
statusText: "statusText",
json: () => {
@@ -1220,7 +1000,7 @@ describe("remoteFetchProvider", () => {
assert.calledOnce(_mockFetch);
assert.calledTwice(sendAPITelemetry);
assert.calledOnce(sendErrorTelemetry);
- assert.calledOnce(getEntity); // getEntity is only called once in createContentFiles
+ assert.callCount(getEntity, 2);
});
it("fetchDataFromDataverseAndUpdateVFS_forWebFile_whenResponseSuccess_forDefaultFileInfo_shouldCallAllSuccessFunction", async () => {
@@ -1228,21 +1008,13 @@ describe("remoteFetchProvider", () => {
const entityName = "webfiles";
const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14";
const queryParamsMap = new Map([
- [queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
- [queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
- [
- queryParameters.REFERRER_SESSION_ID,
- "4269b44f-8085-4001-88fe-3f30f1194c6f",
- ],
- [queryParameters.REFERRER, "yes"],
- [queryParameters.GEO, "US"],
- [queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
- [queryParameters.ENTITY, "webpage"],
+ [Constants.queryParameters.ORG_URL, "powerPages.com"],
[
- queryParameters.ENTITY_ID,
- "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ Constants.queryParameters.WEBSITE_ID,
+ "a58f4e1e-5fe2-45ee-a7c1-398073b40181",
],
- [queryParameters.REFERRER_SOURCE, "test"]
+ [Constants.queryParameters.WEBSITE_NAME, "testWebSite"],
+ [schemaKey.SCHEMA_VERSION, "portalschemav2"],
]);
const languageIdCodeMap = new Map([["1033", "en-US"]]);
@@ -1278,7 +1050,7 @@ describe("remoteFetchProvider", () => {
{ accessToken: accessToken, userId: "" }
);
- const _mockFetch = stub(WebExtensionContext.concurrencyHandler, 'handleRequest').callsFake((url) => {
+ const _mockFetch = stub(fetch, 'default').callsFake((url) => {
// Customize the response based on input parameters (url, options, etc.)
if (url === 'powerPages.com/api/data/v9.2/powerpagecomponents(aa563be7-9a38-4a89-9216-47f9fc6a3f14)/filecontent') {
return Promise.resolve({
@@ -1327,20 +1099,6 @@ describe("remoteFetchProvider", () => {
stub(schemaHelperUtil, "isBase64Encoded").returns(true);
stub(commonUtil, "GetFileNameWithExtension").returns("circle-1.png");
stub(schemaHelperUtil, "getAttributePath").returns({ source: "value", relativePath: "", });
- stub(schemaHelperUtil, "getEntity").returns(
- new Map([
- [schemaEntityKey.EXPORT_TYPE, "SingleFolder"],
- [schemaEntityKey.FILE_FOLDER_NAME, "web-files"],
- [schemaEntityKey.FILE_NAME_FIELD, "name"],
- [schemaEntityKey.FILE_ID_FIELD, "powerpagecomponentid"],
- [schemaEntityKey.ATTRIBUTES, "value"],
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- [schemaEntityKey.ATTRIBUTES_EXTENSION, new Map([["value", "css"]]) as any],
- ])
- );
- stub(schemaHelperUtil, "encodeAsBase64").returns(false);
- stub(schemaHelperUtil, "getEntityParameters").returns([]);
- stub(urlBuilderUtil, "getMetadataInfo").returns({});
const updateSingleFileUrisInContext = stub(WebExtensionContext, "updateSingleFileUrisInContext");
const fileUri: vscode.Uri = { path: "powerplatform-vfs:/testWebSite/web-files/", } as vscode.Uri;
const parse = stub(vscode.Uri, "parse").returns(fileUri);
@@ -1354,18 +1112,12 @@ describe("remoteFetchProvider", () => {
);
await WebExtensionContext.authenticateAndUpdateDataverseProperties();
- stub(folderHelperUtility, "getRequestUrlForEntities").returns([
- { entityName: entityName, requestUrl: "make.powerpgaes.com" }
- ]);
-
//Action
await fetchDataFromDataverseAndUpdateVFS(portalFs, { entityId: entityId, entityName: entityName });
//Assert
- // handleRequest is called 4 times: 3 from authenticateAndUpdateDataverseProperties + 1 for the entity fetch
- assert.callCount(_mockFetch, 4);
- assert.callCount(sendAPITelemetry, 4);
- // parse is called 3 times: once for setWebExtensionContext, once for writeFile, once for updateSingleFileUrisInContext
+ assert.callCount(_mockFetch, 5);
+ assert.callCount(sendAPITelemetry, 5);
assert.callCount(parse, 3);
assert.callCount(updateFileDetailsInContext, 1);
@@ -1385,13 +1137,15 @@ describe("remoteFetchProvider", () => {
{}
);
- assert.calledOnce(convertContentToUint8Array);
+ assert.calledWith(convertContentToUint8Array,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAMAAAACh/xsAAAAGFBMVEXaQivfWkb43Nf////rlYj99PL20MrtoZUWcxnPAAAAIElEQVR4nGNgwA8YmZiZQTQLKzOIwcjGDAIM7KxgmhkABHsAUGHBzX8AAAAddEVYdFNvZnR3YXJlAEBsdW5hcGFpbnQvcG5nLWNvZGVj9UMZHgAAAABJRU5ErkJggg==',
+ true
+ );
assert.callCount(writeFile, 1);
assert.calledOnce(updateSingleFileUrisInContext);
- // sendInfoTelemetry is called 3 times by authenticateAndUpdateDataverseProperties
- assert.callCount(sendInfoTelemetry, 3);
- // sendAPISuccessTelemetry is called 3 times by authenticateAndUpdateDataverseProperties + 1 for the fetch = 4 total
- assert.callCount(sendAPISuccessTelemetry, 4);
+ assert.callCount(sendInfoTelemetry, 5);
+ assert.callCount(sendAPISuccessTelemetry, 5);
});
});
diff --git a/src/web/client/test/integration/schemaHelperUtil.test.ts b/src/web/client/test/integration/schemaHelperUtil.test.ts
index ff7b88d73..00b12948d 100644
--- a/src/web/client/test/integration/schemaHelperUtil.test.ts
+++ b/src/web/client/test/integration/schemaHelperUtil.test.ts
@@ -53,9 +53,10 @@ describe("schemaHelperUtil", () => {
it("getEntity_withPortalschemav2_shouldReturnEntitiesSchemaMap", () => {
//Act
+ const schema = "portalschemav2";
const entity = "webPages";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "orgId"],
+ [schemaKey.SCHEMA_VERSION, schema],
]);
const entityMap = new Map([["test", "Entity"]]);
@@ -75,8 +76,6 @@ describe("schemaHelperUtil", () => {
sinon
.stub(portalSchemaReader, "getEntitiesSchemaMap")
.returns(entitiesSchemaMap);
-
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
WebExtensionContext.setWebExtensionContext("", "", queryParamsMap);
//Action
const result = getEntity(entity);
@@ -86,9 +85,10 @@ describe("schemaHelperUtil", () => {
it("getEntity_whenQueryParamsMapIsNotPortalschemav1_shouldReturnEntitiesSchemaMap", () => {
//Act
+ const schema = "portalschemav1";
const entity = "webPages";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "orgId"],
+ [schemaKey.SCHEMA_VERSION, schema],
]);
const entityMap = new Map([["test", "Entity"]]);
@@ -108,8 +108,6 @@ describe("schemaHelperUtil", () => {
sinon
.stub(portalSchemaReader, "getEntitiesSchemaMap")
.returns(entitiesSchemaMap);
-
- WebExtensionContext.schema = Constants.portalSchemaVersion.V1;
WebExtensionContext.setWebExtensionContext("", "", queryParamsMap);
//Action
@@ -121,9 +119,10 @@ describe("schemaHelperUtil", () => {
it("getEntity_whenEntityDoNotMapAndschemaIsportalschemav2_shouldReturnEmptySchema", () => {
//Act
+ const schema = "portalschemav2";
const entity = "webPages1";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "orgId"],
+ [schemaKey.SCHEMA_VERSION, schema],
]);
sinon
@@ -137,8 +136,6 @@ describe("schemaHelperUtil", () => {
sinon
.stub(portalSchemaReader, "getEntitiesSchemaMap")
.returns(new Map());
-
- WebExtensionContext.schema = Constants.portalSchemaVersion.V2;
WebExtensionContext.setWebExtensionContext("", "", queryParamsMap);
//Action
const result = getEntity(entity);
@@ -149,9 +146,10 @@ describe("schemaHelperUtil", () => {
it("getEntity_whenEntityDoNotMapAndschemaIsNotPortalschemav2_shouldReturnEmptySchema", () => {
//Act
+ const schema = "portalschemav1";
const entity = "webPages";
const queryParamsMap = new Map([
- [Constants.queryParameters.ORG_ID, "orgId"],
+ [schemaKey.SCHEMA_VERSION, schema],
]);
sinon
@@ -165,8 +163,6 @@ describe("schemaHelperUtil", () => {
sinon
.stub(portalSchemaReader, "getEntitiesSchemaMap")
.returns(new Map());
-
- WebExtensionContext.schema = Constants.portalSchemaVersion.V1;
WebExtensionContext.setWebExtensionContext("", "", queryParamsMap);
//Action
const result = getEntity(entity);
diff --git a/src/web/client/test/integration/urlBuilderUtil.test.ts b/src/web/client/test/integration/urlBuilderUtil.test.ts
index 557402672..bcab23f25 100644
--- a/src/web/client/test/integration/urlBuilderUtil.test.ts
+++ b/src/web/client/test/integration/urlBuilderUtil.test.ts
@@ -289,7 +289,7 @@ describe("URLBuilder", () => {
it("getCustomRequestURL", () => {
const mock = new Map([
- [schemaEntityKey.MULTI_FILE_FETCH_QUERY_PARAMETERS, "_fetchQueryParameters"],
+ ["_fetchQueryParameters", schemaEntityKey.FETCH_QUERY_PARAMETERS],
[schemaEntityKey.DATAVERSE_ENTITY_NAME, "DATAVERSE_ENTITY_NAME"],
[schemaKey.DATA, "schemaKey.DATA"],
[schemaKey.DATAVERSE_API_VERSION, "1.0"],
diff --git a/src/web/client/test/integration/webExtensionTelemetry.test.ts b/src/web/client/test/integration/webExtensionTelemetry.test.ts
index d1b44ee78..cdf0e7f69 100644
--- a/src/web/client/test/integration/webExtensionTelemetry.test.ts
+++ b/src/web/client/test/integration/webExtensionTelemetry.test.ts
@@ -88,12 +88,21 @@ describe("webExtensionTelemetry", () => {
//Act
const queryParamsMap = new Map([
[queryParameters.ORG_ID, "e5dce21c-f85f-4849-b699-920c0fad5fbf"],
+ [queryParameters.TENANT_ID, "3fcf33c5-46c9-495e-a025-d1f2efe44667"],
[queryParameters.PORTAL_ID, "36429b2e-8b29-4020-8493-bd5e277444d8"],
+ [
+ queryParameters.WEBSITE_ID,
+ "edde7aaf-ccde-4f2a-9ab2-f9086ac5b4be",
+ ],
+ [queryParameters.DATA_SOURCE, "SQL"],
+ [queryParameters.SCHEMA, "test"],
[
queryParameters.REFERRER_SESSION_ID,
"4269b44f-8085-4001-88fe-3f30f1194c6f",
],
[queryParameters.REFERRER, "yes"],
+ [queryParameters.SITE_VISIBILITY, "false"],
+ [queryParameters.REGION, "NAM"],
[queryParameters.GEO, "US"],
[queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
[queryParameters.ENTITY, "webpage"],
@@ -106,11 +115,17 @@ describe("webExtensionTelemetry", () => {
const properties = {
orgId: queryParamsMap.get(queryParameters.ORG_ID),
+ tenantId: queryParamsMap.get(queryParameters.TENANT_ID),
portalId: queryParamsMap.get(queryParameters.PORTAL_ID),
+ websiteId: queryParamsMap.get(queryParameters.WEBSITE_ID),
+ dataSource: queryParamsMap.get(queryParameters.DATA_SOURCE),
+ schema: queryParamsMap.get(queryParameters.SCHEMA),
referrerSessionId: queryParamsMap.get(
queryParameters.REFERRER_SESSION_ID
),
referrer: queryParamsMap.get(queryParameters.REFERRER),
+ siteVisibility: queryParamsMap.get(queryParameters.SITE_VISIBILITY),
+ region: queryParamsMap.get(queryParameters.REGION),
geo: queryParamsMap.get(queryParameters.GEO),
envId: queryParamsMap.get(queryParameters.ENV_ID),
entity: queryParamsMap.get(queryParameters.ENTITY),
@@ -143,11 +158,17 @@ describe("webExtensionTelemetry", () => {
const properties = {
orgId: queryParamsMap.get(queryParameters.ORG_ID),
+ tenantId: queryParamsMap.get(queryParameters.TENANT_ID),
portalId: queryParamsMap.get(queryParameters.PORTAL_ID),
+ websiteId: queryParamsMap.get(queryParameters.WEBSITE_ID),
+ dataSource: queryParamsMap.get(queryParameters.DATA_SOURCE),
+ schema: queryParamsMap.get(queryParameters.SCHEMA),
referrerSessionId: queryParamsMap.get(
queryParameters.REFERRER_SESSION_ID
),
referrer: queryParamsMap.get(queryParameters.REFERRER),
+ siteVisibility: queryParamsMap.get(queryParameters.SITE_VISIBILITY),
+ region: queryParamsMap.get(queryParameters.REGION),
geo: queryParamsMap.get(queryParameters.GEO),
envId: queryParamsMap.get(queryParameters.ENV_ID),
referrerSource: queryParamsMap.get(queryParameters.REFERRER_SOURCE),
diff --git a/src/web/client/utilities/commonUtil.ts b/src/web/client/utilities/commonUtil.ts
index 806c9e251..f060397ab 100644
--- a/src/web/client/utilities/commonUtil.ts
+++ b/src/web/client/utilities/commonUtil.ts
@@ -9,6 +9,7 @@ import {
BASE_64,
CO_PRESENCE_FEATURE_SETTING_NAME,
DATA,
+ MULTI_FILE_FEATURE_SETTING_NAME,
STUDIO_PROD_REGION,
VERSION_CONTROL_FOR_WEB_EXTENSION_SETTING_NAME,
portalSchemaVersion,
@@ -122,6 +123,25 @@ export function isVersionControlEnabled() {
return isVersionControlEnabled as boolean;
}
+export function isMultifileEnabled() {
+ const isMultifileEnabled = vscode.workspace
+ .getConfiguration(SETTINGS_EXPERIMENTAL_STORE_NAME)
+ .get(MULTI_FILE_FEATURE_SETTING_NAME);
+
+ if (!isMultifileEnabled) {
+ WebExtensionContext.telemetry.sendInfoTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_FEATURE_FLAG_DISABLED
+ );
+ }
+ else {
+ WebExtensionContext.telemetry.sendInfoTelemetry(
+ webExtensionTelemetryEventNames.WEB_EXTENSION_MULTI_FILE_FEATURE_FLAG_ENABLED
+ );
+ }
+
+ return isMultifileEnabled as boolean;
+}
+
export function isCoPresenceEnabled() {
const isCoPresenceEnabled = vscode.workspace
.getConfiguration(SETTINGS_EXPERIMENTAL_STORE_NAME)
@@ -193,11 +213,11 @@ export function isWebfileContentLoadNeeded(fileName: string, fsPath: string): bo
}
export function isPortalVersionV1(): boolean {
- return WebExtensionContext.schema?.toLowerCase() === portalSchemaVersion.V1;
+ return WebExtensionContext.currentSchemaVersion.toLowerCase() === portalSchemaVersion.V1;
}
export function isPortalVersionV2(): boolean {
- return WebExtensionContext.schema?.toLowerCase() === portalSchemaVersion.V2;
+ return WebExtensionContext.currentSchemaVersion.toLowerCase() === portalSchemaVersion.V2;
}
export function getWorkSpaceName(websiteId: string): string {
@@ -214,18 +234,18 @@ export function getEnvironmentIdFromUrl() {
}
export function getBackToStudioURL() {
- const region = WebExtensionContext.region;
+ const region = WebExtensionContext.urlParametersMap.get(queryParameters.REGION) as string;
if (isStringUndefinedOrEmpty(getEnvironmentIdFromUrl()) ||
- isStringUndefinedOrEmpty(region) ||
- isStringUndefinedOrEmpty(WebExtensionContext.websiteId)) {
+ isStringUndefinedOrEmpty(WebExtensionContext.urlParametersMap.get(queryParameters.REGION)) ||
+ isStringUndefinedOrEmpty(WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_ID))) {
return undefined;
}
return BACK_TO_STUDIO_URL_TEMPLATE
.replace("{environmentId}", getEnvironmentIdFromUrl())
- .replace("{.region}", region.toLowerCase() === STUDIO_PROD_REGION ? "" : `.${WebExtensionContext.region}`)
- .replace("{webSiteId}", WebExtensionContext.websiteId);
+ .replace("{.region}", region.toLowerCase() === STUDIO_PROD_REGION ? "" : `.${WebExtensionContext.urlParametersMap.get(queryParameters.REGION) as string}`)
+ .replace("{webSiteId}", WebExtensionContext.urlParametersMap.get(queryParameters.WEBSITE_ID) as string);
}
export function getSupportedImageFileExtensionsForEdit() {
diff --git a/src/web/client/utilities/folderHelperUtility.ts b/src/web/client/utilities/folderHelperUtility.ts
index 27ad2776b..7b3bb30bf 100644
--- a/src/web/client/utilities/folderHelperUtility.ts
+++ b/src/web/client/utilities/folderHelperUtility.ts
@@ -6,14 +6,22 @@
import WebExtensionContext from "../WebExtensionContext";
import {
httpMethod,
+ queryParameters,
} from "../common/constants";
import { IEntityRequestUrl } from "../common/interfaces";
import { MultiFileSupportedEntityName, schemaEntityKey, schemaEntityName } from "../schema/constants";
+import { getEntity } from "./schemaHelperUtil";
import { getRequestURL } from "./urlBuilderUtil";
export function getFolderSubUris(): string[] {
const subUris: string[] = [];
+ if (!WebExtensionContext.showMultifileInVSCode) {
+ const entityDetails = getEntity(WebExtensionContext.defaultEntityType);
+ const subUri = entityDetails?.get(schemaEntityKey.FILE_FOLDER_NAME);
+ return [subUri as string];
+ }
+
for (const entry of Object.entries(MultiFileSupportedEntityName)) {
const entityDetails = WebExtensionContext.schemaEntitiesMap.get(entry[1]);
const subUri = entityDetails?.get(
@@ -31,9 +39,14 @@ export function getRequestUrlForEntities(
entityName?: string
): IEntityRequestUrl[] {
const entityRequestURLs: IEntityRequestUrl[] = [];
- const dataverseOrgUrl = WebExtensionContext.orgUrl;
+ const dataverseOrgUrl = WebExtensionContext.urlParametersMap.get(
+ queryParameters.ORG_URL
+ ) as string;
- if (entityId && entityName && entityId.length > 0 && entityName.length > 0) {
+ if (
+ !WebExtensionContext.showMultifileInVSCode ||
+ (entityId && entityName && entityId.length > 0 && entityName.length > 0)
+ ) {
entityName = entityName && entityName.length > 0
? entityName
: WebExtensionContext.defaultEntityType;
diff --git a/src/web/client/utilities/schemaHelperUtil.ts b/src/web/client/utilities/schemaHelperUtil.ts
index d4e575acd..45e42ffd1 100644
--- a/src/web/client/utilities/schemaHelperUtil.ts
+++ b/src/web/client/utilities/schemaHelperUtil.ts
@@ -15,9 +15,10 @@ import {
import { IAttributePath } from "../common/interfaces";
export function getEntityFetchQuery(entity: string, useRegularFetchQuery = false) {
- return getEntity(entity)?.get(useRegularFetchQuery
- ? schemaEntityKey.FETCH_QUERY_PARAMETERS
- : schemaEntityKey.MULTI_FILE_FETCH_QUERY_PARAMETERS
+ return getEntity(entity)?.get(
+ WebExtensionContext.showMultifileInVSCode && !useRegularFetchQuery
+ ? schemaEntityKey.MULTI_FILE_FETCH_QUERY_PARAMETERS
+ : schemaEntityKey.FETCH_QUERY_PARAMETERS
);
}
diff --git a/src/web/client/utilities/urlBuilderUtil.ts b/src/web/client/utilities/urlBuilderUtil.ts
index af25f1f83..56d7f977e 100644
--- a/src/web/client/utilities/urlBuilderUtil.ts
+++ b/src/web/client/utilities/urlBuilderUtil.ts
@@ -6,6 +6,7 @@
import {
MIMETYPE,
httpMethod,
+ queryParameters,
} from "../common/constants";
import WebExtensionContext from "../WebExtensionContext";
import {
@@ -92,7 +93,9 @@ export function getRequestURL(
)
.replace(
"{websiteId}",
- WebExtensionContext.websiteId
+ WebExtensionContext.urlParametersMap.get(
+ queryParameters.WEBSITE_ID
+ ) as string
)
.replace("{entityId}", entityId);
}
@@ -135,7 +138,9 @@ export function getCustomRequestURL(
)
.replace(
"{websiteId}",
- WebExtensionContext.websiteId
+ WebExtensionContext.urlParametersMap.get(
+ queryParameters.WEBSITE_ID
+ ) as string
);
return requestUrl;
diff --git a/src/web/client/webViews/NPSWebView.ts b/src/web/client/webViews/NPSWebView.ts
index 45b05b92d..b0c415c35 100644
--- a/src/web/client/webViews/NPSWebView.ts
+++ b/src/web/client/webViews/NPSWebView.ts
@@ -25,7 +25,9 @@ export class NPSWebView {
try {
const nonce = getNonce();
const mainJs = this.extensionResourceUrl("media", "main.js");
- const tid = WebExtensionContext.tenantId;
+ const tid = WebExtensionContext.urlParametersMap?.get(
+ queryParameters.TENANT_ID
+ );
const envId = getEnvironmentIdFromUrl();
const geo = WebExtensionContext.urlParametersMap?.get(
queryParameters.GEO