@shko.online/componentframework-mock
Version:
Mocking library to help with testing PowerApps Component Framework Components
272 lines (270 loc) • 11.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WebApiMock = void 0;
var _sinon = require("sinon");
var _dataverseOdata = require("@shko.online/dataverse-odata");
var _PropertyTypes = require("./PropertyTypes");
var _DelayedPromise = require("../utils/DelayedPromise");
/*
Copyright (c) 2022 Betim Beja and Shko Online LLC
Licensed under the MIT license.
*/
class WebApiMock {
constructor(db, formatting) {
this._Delay = 200;
this._ConvertRowToOData = void 0;
this.createRecord = void 0;
this.deleteRecord = void 0;
this.updateRecord = void 0;
this.retrieveMultipleRecords = void 0;
this.retrieveRecord = void 0;
this._ConvertRowToOData = (0, _sinon.stub)();
this._ConvertRowToOData.callsFake((row, entityMetadata) => {
const oldRow = row;
if (entityMetadata.Attributes) {
entityMetadata.Attributes.forEach(attribute => {
const key = attribute.LogicalName;
if (/* attribute.AttributeType === AttributeType.Uniqueidentifier ||*/
attribute.AttributeType === _PropertyTypes.AttributeType.Boolean) {
if (row[key] === undefined || row[key] === null) {
delete row[key];
}
} else if (attribute.AttributeType === _PropertyTypes.AttributeType.Lookup) {
const key = `_${attribute.LogicalName}_value`;
const lookupValue = oldRow[key];
if (key in row) {
row[key] = lookupValue?.id ?? null;
if (lookupValue?.id) {
row[`${key}@Microsoft.Dynamics.CRM.lookuplogicalname`] = lookupValue.entityType;
if (lookupValue.name != null) {
row[`${key}@OData.Community.Display.V1.FormattedValue`] = lookupValue.name;
}
if (oldRow[`${attribute.LogicalName}navigation`]) {
row[`${key}@Microsoft.Dynamics.CRM.associatednavigationproperty`] = oldRow[`${attribute.LogicalName}navigation`];
}
}
}
delete row[`${attribute.LogicalName}type`];
delete row[`${attribute.LogicalName}navigation`];
} else if (attribute.AttributeType === _PropertyTypes.AttributeType.DateTime) {
const dateValue = row[key];
if (dateValue) {
const YYYY = dateValue.getFullYear();
let MM = '0' + (dateValue.getMonth() + 1);
MM = MM.substring(MM.length - 2);
let DD = '0' + dateValue.getDate();
DD = DD.substring(DD.length - 2);
let HH = '0' + dateValue.getUTCHours();
HH = HH.substring(HH.length - 2);
let mm = '0' + dateValue.getMinutes();
mm = mm.substring(mm.length - 2);
let ss = '0' + dateValue.getSeconds();
ss = ss.substring(ss.length - 2);
row[key] = `${YYYY}-${MM}-${DD}T${HH}:${mm}:${ss}Z`;
row[`${key}@OData.Community.Display.V1.FormattedValue`] = `${dateValue.getUTCMonth() + 1}/${dateValue.getUTCDate()}/${dateValue.getUTCFullYear()} ${(dateValue.getUTCHours() - 1) % 12 + 1}:${dateValue.getUTCMinutes()} ${dateValue.getUTCHours() > 12 || dateValue.getUTCHours() == 12 && dateValue.getMinutes() > 0 ? 'PM' : 'AM'}`;
} else {
delete row[key];
}
} else if (attribute.AttributeType === _PropertyTypes.AttributeType.Integer || attribute.AttributeType === _PropertyTypes.AttributeType.BigInt) {
if (row[key] !== null && row[key] !== undefined) {
row[key + '@OData.Community.Display.V1.FormattedValue'] = formatting.formatInteger(row[key]);
}
}
if (!!attribute.AttributeOf) {
const original = entityMetadata.Attributes?.find(att => att.LogicalName == attribute.AttributeOf);
if (original?.AttributeType !== _PropertyTypes.AttributeType.Lookup && oldRow[original?.LogicalName ?? ''] !== undefined && oldRow[original?.LogicalName ?? ''] !== null && oldRow[key] !== null && oldRow[key] !== undefined && original?.LogicalName in row) {
row[original?.LogicalName + '@OData.Community.Display.V1.FormattedValue'] = oldRow[key];
}
delete row[key];
}
});
}
Object.getOwnPropertyNames(row).forEach(key => {
if (row[key] === undefined) {
row[key] = null;
}
});
});
this.createRecord = (0, _sinon.stub)();
this.createRecord.callsFake((entityType, data) => {
const metadata = db.getTableMetadata(entityType);
if (!metadata) {
return _DelayedPromise.DelayedPromise.rejectAfterDelay({
message: `Entity ${entityType} does not exist.`
}, this._Delay);
}
return _DelayedPromise.DelayedPromise.resolveAfterDelay({
id: db.AddRow(entityType, data, metadata) || '',
name: data[metadata.PrimaryNameAttribute || 'name'],
entityType: entityType
}, this._Delay);
});
this.deleteRecord = (0, _sinon.stub)();
this.deleteRecord.callsFake((entityType, id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = db.GetRow(entityType, id);
if (!result.entityMetadata) {
return reject({
message: `Entity ${entityType} does not exist.`
});
}
if (!result.row) {
return reject({
message: `Could not find record with id: '${id}' for entity: '${entityType}'.`
});
}
db.RemoveRow(entityType, id);
resolve({
id,
name: result.row?.[result.entityMetadata.PrimaryNameAttribute || 'name'],
entityType
});
}, this._Delay);
});
});
this.updateRecord = (0, _sinon.stub)();
this.updateRecord.callsFake((entityType, id, data) => {
const attributeHandler = attribute => {
if (attribute.AttributeOf || attribute.AttributeType === _PropertyTypes.AttributeType.Virtual) {
return;
}
const key = attribute.AttributeType === _PropertyTypes.AttributeType.Lookup ? `_${attribute.LogicalName}_value` : attribute.LogicalName;
if (key in data) {
db.UpdateValue(data[key], entityType, key, id);
}
};
const metadata = db.getTableMetadata(entityType);
if (!metadata) {
return _DelayedPromise.DelayedPromise.rejectAfterDelay(`Entity ${entityType} does not exist.`, this._Delay);
}
metadata.Attributes?.forEach(attributeHandler);
const result = db.GetRow(entityType, id);
return _DelayedPromise.DelayedPromise.resolveAfterDelay({
id,
name: result.row?.[metadata.PrimaryNameAttribute || 'name'],
entityType
}, this._Delay);
});
this.retrieveMultipleRecords = (0, _sinon.stub)();
this.retrieveMultipleRecords.callsFake((entityType, options, maxPageSize) => {
return new Promise((resolve, reject) => {
const parsed = options ? (0, _dataverseOdata.parseOData)(options) : {};
if (parsed.error) {
reject(parsed.error);
}
const entityMetadata = db.getTableMetadata(entityType);
if (!entityMetadata) {
reject(`Table ${entityType} does not exist`);
return;
}
if (parsed.userQuery) {
const userQuery = db.GetRow('userquery', parsed.userQuery);
if (!userQuery.row) {
reject({
code: '0x80040217',
message: `Entity 'userquery' With Id = ${parsed.userQuery} Does Not Exist`
});
return;
}
if (userQuery.row['returnedtypecode'] !== entityMetadata.LogicalName) {
reject({
code: '0x80060888',
message: 'No Query View exists with the Given Query Id on the Entity Set.'
});
return;
}
const parsedUserQuery = (0, _dataverseOdata.parseOData)('?fetchXml=' + encodeURIComponent(userQuery.row['fetchxml']));
if (!parsedUserQuery.fetchXml) {
throw new Error(`User Query with id ${parsed.userQuery} contains wrong data`);
}
const entities = db.SelectUsingFetchXml(parsedUserQuery.fetchXml);
resolve({
entities,
nextLink: 'next'
});
return;
}
if (parsed.savedQuery) {
const savedQuery = db.GetRow('savedquery', parsed.savedQuery);
if (!savedQuery.row) {
reject({
code: '0x80040217',
message: `Entity 'savedquery' With Id = ${parsed.savedQuery} Does Not Exist`
});
return;
}
if (savedQuery.row['returnedtypecode'] !== entityMetadata.LogicalName) {
reject({
code: '0x80060888',
message: 'No Query View exists with the Given Query Id on the Entity Set.'
});
return;
}
const parsedSavedQuery = (0, _dataverseOdata.parseOData)('?fetchXml=' + encodeURIComponent(savedQuery.row['fetchxml']));
if (!parsedSavedQuery.fetchXml) {
throw new Error(`Saved Query with id ${parsed.savedQuery} contains wrong data`);
}
const entities = db.SelectUsingFetchXml(parsedSavedQuery.fetchXml);
resolve({
entities,
nextLink: 'next'
});
return;
}
if (parsed.fetchXml) {
const entities = db.SelectUsingFetchXml(parsed.fetchXml);
resolve({
entities,
nextLink: 'next'
});
return;
}
const entities = db.SelectUsingOData(entityMetadata, parsed);
entities.forEach(row => {
this._ConvertRowToOData(row, entityMetadata);
});
resolve({
entities,
nextLink: 'string'
});
});
});
this.retrieveRecord = (0, _sinon.stub)();
this.retrieveRecord.callsFake((entityType, id, options) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = db.GetRowForAPI(entityType, id);
if (!result.entityMetadata) {
return reject({
message: `Entity ${entityType} does not exist.`
});
}
if (!result.row) {
return reject({
message: `Could not find record with id: '${id}' for entity: '${entityType}'.`
});
}
if (options) {
var parsed = (0, _dataverseOdata.parseOData)(options);
if (parsed.$select) {
const oldRow = result.row;
result.row = {};
parsed.$select.forEach(attribute => {
result.row[attribute] = oldRow[attribute];
});
if (result.entityMetadata.PrimaryIdAttribute !== undefined && !parsed.$select.includes(result.entityMetadata.PrimaryIdAttribute)) {
result.row[result.entityMetadata.PrimaryIdAttribute] = oldRow[result.entityMetadata.PrimaryIdAttribute];
}
}
}
this._ConvertRowToOData(result.row, result.entityMetadata);
resolve(result.row);
}, this._Delay);
});
});
}
}
exports.WebApiMock = WebApiMock;