451 lines
19 KiB
TypeScript
451 lines
19 KiB
TypeScript
/*
|
|
* QQQ - Low-code Application Framework for Engineers.
|
|
* Copyright (C) 2021-2026. Kingsrook, LLC
|
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
|
* contact@kingsrook.com
|
|
* https://github.com/Kingsrook/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
import {QHelpContent} from "../../../src/model/metaData/QHelpContent";
|
|
import {QMenu} from "../../../src/model/metaData/QMenu";
|
|
import {QMenuItem} from "../../../src/model/metaData/QMenuItem";
|
|
import {QTableMetaData} from "../../../src/model/metaData/QTableMetaData";
|
|
import {QVirtualFieldMetaData} from "../../../src/model/metaData/QVirtualFieldMetaData";
|
|
|
|
describe("QTableMetaData tests", () =>
|
|
{
|
|
it("it should read field supplementalFieldMetaData", () =>
|
|
{
|
|
const table = new QTableMetaData({
|
|
"name": "myTable",
|
|
"label": "My Table",
|
|
"primaryKeyField": "id",
|
|
"fields": {
|
|
"warehouseId": {
|
|
"name": "warehouseId",
|
|
"label": "Warehouse",
|
|
"type": "INTEGER",
|
|
"displayFormat": "%s",
|
|
"supplementalFieldMetaData": {
|
|
"materialDashboard": {
|
|
"formAdjusterIdentifier": "process:myProcess;field:warehouseId",
|
|
"type": "materialDashboard"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
expect(table.fields?.get("warehouseId")?.supplementalFieldMetaData.get("materialDashboard")).toEqual(
|
|
expect.objectContaining({
|
|
formAdjusterIdentifier: "process:myProcess;field:warehouseId",
|
|
type: "materialDashboard"
|
|
})
|
|
);
|
|
});
|
|
|
|
it("it should read field supplementalMetaData", () =>
|
|
{
|
|
const table = new QTableMetaData({
|
|
"name": "myTable",
|
|
"label": "My Table",
|
|
"primaryKeyField": "id",
|
|
"fields": {
|
|
"warehouseId": {
|
|
"name": "warehouseId",
|
|
"label": "Warehouse",
|
|
"type": "INTEGER",
|
|
"displayFormat": "%s",
|
|
"supplementalMetaData": {
|
|
"materialDashboard": {
|
|
"formAdjusterIdentifier": "process:myProcess;field:warehouseId",
|
|
"type": "materialDashboard"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
expect(table.fields?.get("warehouseId")?.supplementalFieldMetaData.get("materialDashboard")).toEqual(
|
|
expect.objectContaining({
|
|
formAdjusterIdentifier: "process:myProcess;field:warehouseId",
|
|
type: "materialDashboard"
|
|
})
|
|
);
|
|
});
|
|
|
|
it("it should clone", () =>
|
|
{
|
|
/////////////////////////////////////
|
|
// build a table with lots of data //
|
|
/////////////////////////////////////
|
|
const table = new QTableMetaData(
|
|
{
|
|
"name": "myTable",
|
|
"label": "My Table",
|
|
"isHidden": false,
|
|
"primaryKeyField": "id",
|
|
"icon": {"name": "link"},
|
|
"fields": {
|
|
"id": {
|
|
"name": "id",
|
|
"label": "Id",
|
|
"type": "INTEGER",
|
|
"isRequired": false,
|
|
"isEditable": true,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"displayFormat": "%s"
|
|
},
|
|
"name": {
|
|
"name": "name",
|
|
"label": "Name",
|
|
"type": "STRING",
|
|
"isRequired": false,
|
|
"isEditable": true,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"displayFormat": "%s",
|
|
"maxLength": 100
|
|
},
|
|
"clientId": {
|
|
"name": "clientId",
|
|
"label": "Client",
|
|
"type": "INTEGER",
|
|
"isRequired": false,
|
|
"isEditable": true,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"possibleValueSourceName": "client",
|
|
"displayFormat": "%s",
|
|
"adornments": [
|
|
{
|
|
"type": "LINK",
|
|
"values": {
|
|
"toRecordFromTable": "client"
|
|
}
|
|
}
|
|
],
|
|
"possibleValueSourceFilter": {
|
|
"criteria": [
|
|
{
|
|
"fieldName": "isActive",
|
|
"operator": "EQUALS",
|
|
"values": [
|
|
true
|
|
]
|
|
}
|
|
],
|
|
"booleanOperator": "AND",
|
|
"subFilters": [
|
|
{
|
|
"criteria": [
|
|
{
|
|
"fieldName": "clientId",
|
|
"operator": "EQUALS",
|
|
"values": [
|
|
"${input.clientId}"
|
|
]
|
|
},
|
|
{
|
|
"fieldName": "clientId",
|
|
"operator": "IS_BLANK"
|
|
}
|
|
],
|
|
"booleanOperator": "OR"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"apiKey": {
|
|
"name": "apiKey",
|
|
"label": "API Key",
|
|
"type": "PASSWORD",
|
|
"isRequired": false,
|
|
"isEditable": true,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"displayFormat": "%s",
|
|
"helpContents": [
|
|
{
|
|
"content": "Field Help",
|
|
"format": "MARKDOWN",
|
|
"roles": ["READ_SCREENS"],
|
|
"contentAsHtml": "Field Help"
|
|
}
|
|
],
|
|
"supplementalMetaData": {
|
|
"materialDashboard": {
|
|
"formAdjusterIdentifier": "table:connection;field:externalSystemId",
|
|
"onChangeFormAdjuster": {
|
|
"name": "com.coldtrack.live.tables.setup.customizers.ConnectionTableMetaDataAdjuster",
|
|
"codeType": "JAVA"
|
|
},
|
|
"type": "materialDashboard"
|
|
}
|
|
},
|
|
"adornments": [
|
|
{
|
|
"type": "LINK",
|
|
"values": {"toRecordFromTable": "foreignTable"}
|
|
}
|
|
]
|
|
},
|
|
"type": {
|
|
"name": "type",
|
|
"label": "Type",
|
|
"type": "BOOLEAN",
|
|
"isRequired": false,
|
|
"isEditable": true,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"displayFormat": "%s",
|
|
"possibleValueSourceName": "type",
|
|
"supplementalMetaData": {
|
|
"materialDashboard": {
|
|
"formAdjusterIdentifier": "table:myTable;field:type",
|
|
"onChangeFormAdjuster": {
|
|
"name": "com.qqq.MyTableFormAdjuster",
|
|
"codeType": "JAVA"
|
|
},
|
|
"type": "materialDashboard"
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"virtualFields": {
|
|
"nameLength": {
|
|
"name": "nameLength",
|
|
"label": "Name Length",
|
|
"type": "INTEGER",
|
|
"isRequired": false,
|
|
"isEditable": false,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"isQueryCriteria": true,
|
|
"isQuerySelectable": false
|
|
},
|
|
"createDateWeekday": {
|
|
"name": "createDateWeekday",
|
|
"label": "Create Date Weekday",
|
|
"type": "DATE",
|
|
"isRequired": false,
|
|
"isEditable": false,
|
|
"isHeavy": false,
|
|
"isHidden": false,
|
|
"gridColumns": -1,
|
|
"isQueryCriteria": false,
|
|
"isQuerySelectable": true
|
|
},
|
|
},
|
|
"sections": [
|
|
{
|
|
"name": "identity",
|
|
"label": "Identity",
|
|
"tier": "T1",
|
|
"fieldNames": ["id", "name"],
|
|
"icon": {"name": "badge"},
|
|
"isHidden": false,
|
|
"alternatives": {
|
|
"RECORD_VIEW": {
|
|
"name": "identityView",
|
|
"label": "Identity",
|
|
"fieldNames": ["id", "specialName"]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "authentication",
|
|
"label": "Authentication",
|
|
"tier": "T2",
|
|
"fieldNames": ["apiKey",],
|
|
"icon": {"name": "edit_attributes"},
|
|
"isHidden": false
|
|
},
|
|
],
|
|
"exposedJoins": [
|
|
{
|
|
"label": "Parcel",
|
|
"isMany": false,
|
|
"joinTable": {
|
|
"name": "parcel",
|
|
"label": "Parcel",
|
|
"primaryKeyField": "id",
|
|
"fields": {
|
|
"id": {"name": "id", "label": "Id", "type": "INTEGER", "isEditable": false, "isHidden": false},
|
|
"trackingNumber": {"name": "trackingNumber", "label": "Tracking Number", "type": "STRING", "isEditable": true, "isHidden": false},
|
|
"status": {"name": "status", "label": "Status", "type": "STRING", "isEditable": true, "isHidden": false}
|
|
},
|
|
"sections": [],
|
|
"capabilities": []
|
|
},
|
|
"joinPath": [
|
|
{"name": "orderShipmentJoinParcel", "leftTable": "orderShipment", "rightTable": "parcel", "type": "ONE_TO_ONE", "joinOns": []}
|
|
]
|
|
}
|
|
],
|
|
"supplementalTableMetaData": {
|
|
"materialDashboard": {
|
|
"onLoadFormAdjuster": {
|
|
"name": "com.qqq.MyTableFormAdjuster",
|
|
"codeType": "JAVA"
|
|
},
|
|
"type": "materialDashboard"
|
|
}
|
|
},
|
|
"capabilities": [
|
|
"TABLE_COUNT",
|
|
"TABLE_GET",
|
|
"TABLE_QUERY",
|
|
"QUERY_STATS",
|
|
"TABLE_INSERT",
|
|
"TABLE_UPDATE",
|
|
"TABLE_DELETE",
|
|
"TABLE_EXPORT"
|
|
],
|
|
"readPermission": true,
|
|
"insertPermission": true,
|
|
"editPermission": true,
|
|
"deletePermission": true,
|
|
"usesVariants": false,
|
|
"iconName": "link",
|
|
"helpContents": {
|
|
"key": [
|
|
{
|
|
"content": "Table Help",
|
|
"format": "MARKDOWN",
|
|
"roles": ["WRITE_SCREENS"],
|
|
"contentAsHtml": "Table Help"
|
|
}
|
|
]
|
|
},
|
|
"menus": [
|
|
{
|
|
label: "My Menu",
|
|
icon: {name: "hotdog"},
|
|
slot: "VIEW_SCREEN_ADDITIONAL",
|
|
items: [
|
|
{label: "Cars", icon: {name: "car"}, itemType: "RUN_PROCESS", values: {processName: "runCarsProcess"}},
|
|
{label: "Apples", icon: {name: "download"}, itemType: "DOWNLOAD_FILE", values: {fieldName: "appleFileUrl"}},
|
|
]
|
|
}
|
|
]
|
|
});
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// clone it - make a few assertions about data being the same //
|
|
////////////////////////////////////////////////////////////////
|
|
const cloneTable = table.clone();
|
|
expect(cloneTable.name).toEqual(table.name);
|
|
|
|
expect(cloneTable.virtualFields?.size).toEqual(2);
|
|
expect(cloneTable.virtualFields?.get("nameLength") instanceof QVirtualFieldMetaData).toBeTruthy();
|
|
|
|
expect(cloneTable.sections?.length).toEqual(2);
|
|
expect(cloneTable.sections?.length).toEqual(table.sections?.length);
|
|
expect(cloneTable.sections?.[0].name).toEqual(table.sections?.[0].name);
|
|
expect(cloneTable.sections?.[0].iconName).toEqual(table.sections?.[0].iconName);
|
|
expect(cloneTable.sections?.[0].alternatives?.size).toEqual(1);
|
|
|
|
expect(cloneTable.capabilities.size).toEqual(table.capabilities.size);
|
|
|
|
expect(cloneTable.helpContent?.size).toEqual(table.helpContent?.size);
|
|
expect(cloneTable.helpContent?.get("key")?.[0].roles.size).not.toEqual(0);
|
|
expect(cloneTable.helpContent?.get("key")?.[0].roles.size).toEqual(table.helpContent?.get("key")?.[0].roles.size);
|
|
|
|
expect(cloneTable.supplementalTableMetaData.size).not.toEqual(0);
|
|
expect(cloneTable.supplementalTableMetaData.size).toEqual(table.supplementalTableMetaData.size);
|
|
|
|
const apiKeyField = table.fields?.get("apiKey");
|
|
const cloneApiKeyField = cloneTable.fields?.get("apiKey");
|
|
expect(cloneApiKeyField?.supplementalFieldMetaData.size).not.toEqual(0);
|
|
expect(cloneApiKeyField?.supplementalFieldMetaData.size).toEqual(apiKeyField?.supplementalFieldMetaData.size);
|
|
expect(cloneApiKeyField?.adornments?.length).not.toEqual(0);
|
|
expect(cloneApiKeyField?.adornments?.length).toEqual(apiKeyField?.adornments?.length);
|
|
expect(cloneApiKeyField?.adornments?.[0].values?.size).not.toEqual(0);
|
|
expect(cloneApiKeyField?.adornments?.[0].values?.size).toEqual(apiKeyField?.adornments?.[0].values?.size);
|
|
|
|
expect(cloneTable.menus?.length).toEqual(1);
|
|
expect(cloneTable.menus?.[0].items?.length).toEqual(2);
|
|
|
|
expect(cloneTable.exposedJoins?.length).toEqual(1);
|
|
expect(cloneTable.exposedJoins?.[0].joinTable.name).toEqual("parcel");
|
|
expect(cloneTable.exposedJoins?.[0].joinTable.fields?.size).toEqual(3);
|
|
expect(cloneTable.exposedJoins?.[0].joinTable.fields?.get("trackingNumber")?.name).toEqual("trackingNumber");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// turns out toEqual will do a deep equality test, so, we could have just done this all along //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
expect(cloneTable).toEqual(table);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// change some things in the clone - assert that they are then not equal to the original //
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
cloneTable.name = "changed";
|
|
expect(cloneTable.name).not.toEqual(table.name);
|
|
|
|
cloneTable.virtualFields?.set("new", new QVirtualFieldMetaData({}));
|
|
expect(cloneTable.virtualFields?.size).toEqual(3);
|
|
expect(table.virtualFields?.size).toEqual(2);
|
|
|
|
cloneTable.virtualFields!.get("nameLength")!.gridColumns = 6;
|
|
cloneTable.virtualFields!.get("nameLength")!.isQuerySelectable = !cloneTable.virtualFields!.get("nameLength")!.isQuerySelectable;
|
|
cloneTable.virtualFields!.get("nameLength")!.isQueryCriteria = !cloneTable.virtualFields!.get("nameLength")!.isQueryCriteria;
|
|
expect(cloneTable.virtualFields?.get("nameLength")?.gridColumns).not.toEqual(table.virtualFields?.get("nameLength")?.gridColumns);
|
|
expect(cloneTable.virtualFields?.get("nameLength")?.isQuerySelectable).not.toEqual(table.virtualFields?.get("nameLength")?.isQuerySelectable);
|
|
expect(cloneTable.virtualFields?.get("nameLength")?.isQueryCriteria).not.toEqual(table.virtualFields?.get("nameLength")?.isQueryCriteria);
|
|
|
|
cloneTable.sections![0]!.name = "changed";
|
|
cloneTable.sections![0]!.isHidden = true;
|
|
|
|
expect(cloneTable.sections?.[0].name).not.toEqual(table.sections?.[0].name);
|
|
expect(cloneTable.sections?.[0].isHidden).not.toEqual(table.sections?.[0].isHidden);
|
|
|
|
cloneTable.capabilities.delete("TABLE_COUNT");
|
|
expect(cloneTable.capabilities.size).not.toEqual(table.capabilities.size);
|
|
|
|
cloneTable.helpContent?.set("key2", []);
|
|
expect(cloneTable.helpContent?.size).not.toEqual(table.helpContent?.size);
|
|
|
|
cloneTable.helpContent?.get("key")?.push(new QHelpContent({}));
|
|
expect(cloneTable.helpContent?.get("key")?.length).not.toEqual(table.helpContent?.get("key")?.length);
|
|
|
|
cloneTable.helpContent?.get("key")?.[0].roles.add("READ_SCREENS");
|
|
expect(cloneTable.helpContent?.get("key")?.[0].roles.size).not.toEqual(table.helpContent?.get("key")?.[0].roles.size);
|
|
|
|
cloneTable.sections?.[0]?.fieldNames?.push("foobar");
|
|
expect(cloneTable.sections?.[0]?.fieldNames?.length).not.toEqual(table.sections?.[0]?.fieldNames?.length);
|
|
|
|
cloneTable.sections?.[0]?.alternatives?.get("RECORD_VIEW")?.fieldNames?.push("another");
|
|
expect(table.sections?.[0]?.alternatives?.get("RECORD_VIEW")?.fieldNames?.length).toEqual(2);
|
|
expect(cloneTable.sections?.[0]?.alternatives?.get("RECORD_VIEW")?.fieldNames?.length).toEqual(3);
|
|
|
|
cloneTable.menus?.[0]?.icon && (cloneTable.menus[0].icon.name = "hamburger");
|
|
cloneTable.menus?.[0]?.items && (cloneTable.menus[0].items.push(new QMenuItem({itemType: "DIVIDER"})));
|
|
cloneTable.menus && (cloneTable.menus.push(new QMenu({})));
|
|
expect(cloneTable.menus?.[0]?.icon?.name).not.toEqual(table.menus?.[0]?.icon?.name);
|
|
expect(cloneTable.menus?.[0]?.items?.length).not.toEqual(table.menus?.[0]?.items?.length);
|
|
expect(cloneTable.menus?.length).not.toEqual(table.menus?.length);
|
|
});
|
|
|
|
});
|