mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added ERD Diagram support with basic table fields, primary key, foreign key, and DDL SQL generation. Fixes #1802
This commit is contained in:
committed by
Akshay Joshi
parent
065bda37b4
commit
0c8226ff39
382
web/regression/javascript/erd/erd_core_spec.js
Normal file
382
web/regression/javascript/erd/erd_core_spec.js
Normal file
@@ -0,0 +1,382 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore';
|
||||
import * as createEngineLib from '@projectstorm/react-diagrams';
|
||||
import TEST_TABLES_DATA from './test_tables';
|
||||
|
||||
describe('ERDCore', ()=>{
|
||||
let eleFactory = jasmine.createSpyObj('nodeFactories', {
|
||||
'registerFactory': null,
|
||||
'getFactory': jasmine.createSpyObj('getFactory', ['generateModel', 'calculateRoutingMatrix']),
|
||||
});
|
||||
let erdEngine = jasmine.createSpyObj('engine', {
|
||||
'getNodeFactories': eleFactory,
|
||||
'getLinkFactories': eleFactory,
|
||||
'getPortFactories': eleFactory,
|
||||
'getActionEventBus': jasmine.createSpyObj('actionBus', ['fireAction', 'deregisterAction', 'registerAction']),
|
||||
'setModel': null,
|
||||
'getModel': jasmine.createSpyObj('modelObj', {
|
||||
'addNode': null,
|
||||
'clearSelection': null,
|
||||
'getNodesDict': null,
|
||||
'getLinks': null,
|
||||
'serialize': ()=>({
|
||||
'data': 'serialized',
|
||||
}),
|
||||
'addLink': null,
|
||||
'getNodes': null,
|
||||
'setZoomLevel': null,
|
||||
'getZoomLevel': null,
|
||||
'fireEvent': null,
|
||||
'registerListener': null,
|
||||
}),
|
||||
'repaintCanvas': null,
|
||||
'zoomToFit': null,
|
||||
'fireEvent': null,
|
||||
});
|
||||
|
||||
beforeAll(()=>{
|
||||
spyOn(createEngineLib, 'default').and.returnValue(erdEngine);
|
||||
});
|
||||
|
||||
it('initialization', ()=>{
|
||||
spyOn(ERDCore.prototype, 'initializeEngine').and.callThrough();
|
||||
spyOn(ERDCore.prototype, 'initializeModel').and.callThrough();
|
||||
spyOn(ERDCore.prototype, 'computeTableCounter').and.callThrough();
|
||||
let erdCoreObj = new ERDCore();
|
||||
expect(erdCoreObj.initializeEngine).toHaveBeenCalled();
|
||||
expect(erdCoreObj.initializeModel).toHaveBeenCalled();
|
||||
expect(erdCoreObj.computeTableCounter).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('functions', ()=>{
|
||||
let erdCoreObj;
|
||||
|
||||
beforeAll(()=>{
|
||||
erdCoreObj = new ERDCore();
|
||||
});
|
||||
|
||||
describe('cache check', ()=>{
|
||||
it('for single value', ()=>{
|
||||
erdCoreObj.setCache('key1', 'value1');
|
||||
expect(erdCoreObj.getCache('key1')).toEqual('value1');
|
||||
});
|
||||
|
||||
it('for multiple value', ()=>{
|
||||
erdCoreObj.setCache({'key1': 'valuem1', 'key2': 'valuem2'});
|
||||
expect(erdCoreObj.getCache('key1')).toEqual('valuem1');
|
||||
expect(erdCoreObj.getCache('key2')).toEqual('valuem2');
|
||||
});
|
||||
});
|
||||
|
||||
it('registerModelEvent', ()=>{
|
||||
let fn = ()=>{};
|
||||
erdCoreObj.registerModelEvent('someEvent', fn);
|
||||
expect(erdCoreObj.getModel().registerListener).toHaveBeenCalledWith({
|
||||
'someEvent': fn,
|
||||
});
|
||||
});
|
||||
|
||||
it('getNextTableName', ()=>{
|
||||
expect(erdCoreObj.getNextTableName()).toEqual('newtable1');
|
||||
expect(erdCoreObj.getNextTableName()).toEqual('newtable2');
|
||||
});
|
||||
|
||||
it('getEngine', ()=>{
|
||||
expect(erdCoreObj.getEngine()).toBe(erdEngine);
|
||||
});
|
||||
|
||||
it('getNewNode', ()=>{
|
||||
let data = {name: 'table1'};
|
||||
erdCoreObj.getNewNode(data);
|
||||
|
||||
expect(erdEngine.getNodeFactories().getFactory().generateModel).toHaveBeenCalledWith({
|
||||
initialConfig: {
|
||||
otherInfo: {
|
||||
data:data,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('getNewLink', ()=>{
|
||||
let data = {name: 'link1'};
|
||||
erdCoreObj.getNewLink('linktype', data);
|
||||
|
||||
expect(erdEngine.getLinkFactories().getFactory).toHaveBeenCalledWith('linktype');
|
||||
expect(erdEngine.getLinkFactories().getFactory().generateModel).toHaveBeenCalledWith({
|
||||
initialConfig: {
|
||||
data: data,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('getNewPort', ()=>{
|
||||
let data = {name: 'link1'};
|
||||
let options = {opt1: 'val1'};
|
||||
erdCoreObj.getNewPort('porttype', data, options);
|
||||
|
||||
expect(erdEngine.getPortFactories().getFactory).toHaveBeenCalledWith('porttype');
|
||||
expect(erdEngine.getPortFactories().getFactory().generateModel).toHaveBeenCalledWith({
|
||||
initialConfig: {
|
||||
data:data,
|
||||
options:options,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('addNode', ()=>{
|
||||
let newNode = jasmine.createSpyObj('newNode', ['setPosition']);
|
||||
spyOn(erdCoreObj, 'getNewNode').and.returnValue(newNode);
|
||||
spyOn(erdCoreObj, 'clearSelection');
|
||||
|
||||
let data = {name: 'link1'};
|
||||
|
||||
/* Without position */
|
||||
erdCoreObj.addNode(data);
|
||||
expect(erdCoreObj.getNewNode).toHaveBeenCalledWith(data);
|
||||
expect(erdEngine.getModel().addNode).toHaveBeenCalledWith(newNode);
|
||||
expect(erdCoreObj.clearSelection).toHaveBeenCalled();
|
||||
|
||||
/* With position */
|
||||
erdCoreObj.addNode(data, [108, 108]);
|
||||
expect(erdCoreObj.getNewNode().setPosition).toHaveBeenCalledWith(108, 108);
|
||||
});
|
||||
|
||||
|
||||
it('addLink', ()=>{
|
||||
let nodesDict = {
|
||||
'id1': {
|
||||
serializeData: function(){ return {
|
||||
'name': 'table1',
|
||||
};},
|
||||
getPortName: function(attnum) {
|
||||
return `port-${attnum}`;
|
||||
},
|
||||
getPort: function() {
|
||||
return null;
|
||||
},
|
||||
addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj),
|
||||
},
|
||||
'id2': {
|
||||
serializeData: function(){ return {
|
||||
'name': 'table2',
|
||||
};},
|
||||
getPortName: function(attnum) {
|
||||
return `port-${attnum}`;
|
||||
},
|
||||
getPort: function() {
|
||||
return null;
|
||||
},
|
||||
addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj),
|
||||
},
|
||||
};
|
||||
let link = jasmine.createSpyObj('link', ['setSourcePort', 'setTargetPort']);
|
||||
spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue(nodesDict);
|
||||
spyOn(erdCoreObj, 'getNewLink').and.callFake(function() {
|
||||
return link;
|
||||
});
|
||||
spyOn(erdCoreObj, 'getNewPort').and.callFake(function(type, initData, options) {
|
||||
return {
|
||||
name: options.name,
|
||||
};
|
||||
});
|
||||
|
||||
erdCoreObj.addLink({
|
||||
'referenced_column_attnum': 1,
|
||||
'referenced_table_uid': 'id1',
|
||||
'local_column_attnum': 3,
|
||||
'local_table_uid': 'id2',
|
||||
}, 'onetomany');
|
||||
|
||||
expect(nodesDict['id1'].addPort).toHaveBeenCalledWith({name: 'port-1'});
|
||||
expect(nodesDict['id2'].addPort).toHaveBeenCalledWith({name: 'port-3'});
|
||||
expect(link.setSourcePort).toHaveBeenCalledWith({name: 'port-1'});
|
||||
expect(link.setTargetPort).toHaveBeenCalledWith({name: 'port-3'});
|
||||
|
||||
});
|
||||
|
||||
it('serialize', ()=>{
|
||||
let retVal = erdCoreObj.serialize();
|
||||
expect(retVal.hasOwnProperty('version')).toBeTruthy();
|
||||
expect(retVal.hasOwnProperty('data')).toBeTruthy();
|
||||
expect(erdEngine.getModel().serialize).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('deserialize', ()=>{
|
||||
let deserialValue = {
|
||||
'version': 123,
|
||||
'data': {
|
||||
'key': 'serialized',
|
||||
},
|
||||
};
|
||||
spyOn(erdCoreObj, 'initializeModel');
|
||||
erdCoreObj.deserialize(deserialValue);
|
||||
expect(erdCoreObj.initializeModel).toHaveBeenCalledWith(deserialValue.data);
|
||||
});
|
||||
|
||||
it('serializeData', ()=>{
|
||||
spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue({
|
||||
'id1': {
|
||||
serializeData: function(){ return {
|
||||
'name': 'table1',
|
||||
};},
|
||||
},
|
||||
'id2': {
|
||||
serializeData: function(){ return {
|
||||
'name': 'table2',
|
||||
};},
|
||||
},
|
||||
});
|
||||
spyOn(erdEngine.getModel(), 'getLinks').and.returnValue([
|
||||
{
|
||||
serializeData: function(){ return {
|
||||
'name': 'link1',
|
||||
};},
|
||||
getID: function(){ return 'lid1'; },
|
||||
},
|
||||
{
|
||||
serializeData: function(){ return {
|
||||
'name': 'link2',
|
||||
};},
|
||||
getID: function(){ return 'lid2'; },
|
||||
},
|
||||
]);
|
||||
expect(JSON.stringify(erdCoreObj.serializeData())).toEqual(JSON.stringify({
|
||||
nodes: {
|
||||
'id1': {'name': 'table1'},
|
||||
'id2': {'name': 'table2'},
|
||||
},
|
||||
links: {
|
||||
'lid1': {'name': 'link1'},
|
||||
'lid2': {'name': 'link2'},
|
||||
},
|
||||
}));
|
||||
});
|
||||
|
||||
it('deserializeData', (done)=>{
|
||||
let nodesDict = {};
|
||||
TEST_TABLES_DATA.forEach((table)=>{
|
||||
nodesDict[`id-${table.name}`] = {
|
||||
getColumns: function() {
|
||||
return table.columns;
|
||||
},
|
||||
getPortName: function(attnum) {
|
||||
return `port-${attnum}`;
|
||||
},
|
||||
getPort: function(name) {
|
||||
return {'name': name};
|
||||
},
|
||||
addPort: function() {
|
||||
|
||||
},
|
||||
};
|
||||
});
|
||||
spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue(nodesDict);
|
||||
|
||||
spyOn(erdCoreObj, 'getNewLink').and.callFake(function() {
|
||||
return {
|
||||
setSourcePort: function() {},
|
||||
setTargetPort: function() {},
|
||||
};
|
||||
});
|
||||
spyOn(erdCoreObj, 'getNewPort').and.returnValue({id: 'id'});
|
||||
spyOn(erdCoreObj, 'addNode').and.callFake(function(data) {
|
||||
return {
|
||||
getID: function() {
|
||||
return `id-${data.name}`;
|
||||
},
|
||||
};
|
||||
});
|
||||
spyOn(erdCoreObj, 'addLink');
|
||||
spyOn(erdCoreObj, 'dagreDistributeNodes');
|
||||
|
||||
erdCoreObj.deserializeData(TEST_TABLES_DATA);
|
||||
expect(erdCoreObj.addNode).toHaveBeenCalledTimes(TEST_TABLES_DATA.length);
|
||||
expect(erdCoreObj.addLink).toHaveBeenCalledTimes(1);
|
||||
|
||||
setTimeout(()=>{
|
||||
expect(erdCoreObj.dagreDistributeNodes).toHaveBeenCalled();
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('clearSelection', ()=>{
|
||||
erdCoreObj.clearSelection();
|
||||
expect(erdEngine.getModel().clearSelection).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('repaint', ()=>{
|
||||
erdCoreObj.repaint();
|
||||
expect(erdEngine.repaintCanvas).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('getNodesData', ()=>{
|
||||
spyOn(erdEngine.getModel(), 'getNodes').and.returnValue([
|
||||
{getData: function () {return {name:'node1'};}},
|
||||
{getData: function () {return {name:'node2'};}},
|
||||
]);
|
||||
expect(JSON.stringify(erdCoreObj.getNodesData())).toEqual(JSON.stringify([
|
||||
{name:'node1'}, {name:'node2'},
|
||||
]));
|
||||
});
|
||||
|
||||
it('dagreDistributeNodes', ()=>{
|
||||
spyOn(erdCoreObj.dagre_engine, 'redistribute');
|
||||
erdCoreObj.dagreDistributeNodes();
|
||||
expect(erdEngine.getLinkFactories().getFactory().calculateRoutingMatrix).toHaveBeenCalled();
|
||||
expect(erdCoreObj.dagre_engine.redistribute).toHaveBeenCalledWith(erdEngine.getModel());
|
||||
});
|
||||
|
||||
it('zoomIn', ()=>{
|
||||
spyOn(erdEngine.getModel(), 'getZoomLevel').and.returnValue(100);
|
||||
spyOn(erdCoreObj, 'repaint');
|
||||
erdCoreObj.zoomIn();
|
||||
expect(erdEngine.getModel().setZoomLevel).toHaveBeenCalledWith(125);
|
||||
expect(erdCoreObj.repaint).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('zoomOut', ()=>{
|
||||
spyOn(erdEngine.getModel(), 'getZoomLevel').and.returnValue(100);
|
||||
spyOn(erdCoreObj, 'repaint');
|
||||
erdCoreObj.zoomOut();
|
||||
expect(erdEngine.getModel().setZoomLevel).toHaveBeenCalledWith(75);
|
||||
expect(erdCoreObj.repaint).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('zoomToFit', ()=>{
|
||||
erdCoreObj.zoomToFit();
|
||||
expect(erdEngine.zoomToFit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('fireAction', ()=>{
|
||||
erdCoreObj.fireAction({key: 'xyz'});
|
||||
expect(erdEngine.getActionEventBus().fireAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('fireEvent', ()=>{
|
||||
erdCoreObj.fireEvent({key: 'xyz'}, 'someevent', false);
|
||||
expect(erdEngine.fireEvent).toHaveBeenCalledWith({key: 'xyz'}, 'someevent');
|
||||
|
||||
erdCoreObj.fireEvent({key: 'xyz'}, 'someevent', true);
|
||||
expect(erdEngine.getModel().fireEvent).toHaveBeenCalledWith({key: 'xyz'}, 'someevent');
|
||||
});
|
||||
|
||||
it('registerKeyAction', ()=>{
|
||||
erdCoreObj.registerKeyAction({key: 'xyz'});
|
||||
expect(erdEngine.getActionEventBus().registerAction).toHaveBeenCalledWith({key: 'xyz'});
|
||||
});
|
||||
|
||||
it('deregisterKeyAction', ()=>{
|
||||
let action = {key: 'xyz'};
|
||||
erdCoreObj.deregisterKeyAction(action);
|
||||
expect(erdEngine.getActionEventBus().deregisterAction).toHaveBeenCalledWith({key: 'xyz'});
|
||||
});
|
||||
});
|
||||
});
|
||||
34
web/regression/javascript/erd/erd_model_spec.js
Normal file
34
web/regression/javascript/erd/erd_model_spec.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import ERDModel from 'pgadmin.tools.erd/erd_tool/ERDModel';
|
||||
|
||||
describe('ERDModel', ()=>{
|
||||
it('getNodesDict', ()=>{
|
||||
let model = new ERDModel();
|
||||
|
||||
spyOn(model, 'getNodes').and.returnValue([
|
||||
{
|
||||
name: 'test1',
|
||||
getID: function() {
|
||||
return 'id1';
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'test2',
|
||||
getID: function() {
|
||||
return 'id2';
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(JSON.stringify(model.getNodesDict())).toBe(JSON.stringify({
|
||||
'id1': {name: 'test1'},
|
||||
'id2': {name: 'test2'},
|
||||
}));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
import {KeyboardShortcutAction} from 'pgadmin.tools.erd/erd_tool/ui_components/BodyWidget';
|
||||
|
||||
describe('KeyboardShortcutAction', ()=>{
|
||||
let keyAction = null;
|
||||
let key1 = {
|
||||
alt: true,
|
||||
control: true,
|
||||
shift: false,
|
||||
key: {
|
||||
key_code: 65,
|
||||
},
|
||||
};
|
||||
let key2 = {
|
||||
alt: false,
|
||||
control: true,
|
||||
shift: false,
|
||||
key: {
|
||||
key_code: 66,
|
||||
},
|
||||
};
|
||||
let handler1 = jasmine.createSpy('handler1');
|
||||
let handler2 = jasmine.createSpy('handler2');
|
||||
|
||||
beforeAll(()=>{
|
||||
spyOn(KeyboardShortcutAction.prototype, 'shortcutKey').and.callThrough();
|
||||
keyAction = new KeyboardShortcutAction([
|
||||
[key1, handler1],
|
||||
[key2, handler2],
|
||||
]);
|
||||
});
|
||||
|
||||
it('init', ()=>{
|
||||
expect(Object.keys(keyAction.shortcuts).length).toBe(2);
|
||||
});
|
||||
|
||||
it('shortcutKey', ()=>{
|
||||
expect(keyAction.shortcutKey(true, true, true, true, 65)).toBe('true:true:true:true:65');
|
||||
expect(keyAction.shortcutKey(true, false, true, true, 65)).toBe('true:false:true:true:65');
|
||||
expect(keyAction.shortcutKey(true, true, false, true, 65)).toBe('true:true:false:true:65');
|
||||
expect(keyAction.shortcutKey(true, true, true, false, 65)).toBe('true:true:true:false:65');
|
||||
expect(keyAction.shortcutKey(false, true, true, true, 65)).toBe('false:true:true:true:65');
|
||||
});
|
||||
|
||||
it('callHandler', ()=>{
|
||||
let keyEvent = {altKey: key1.alt, ctrlKey: key1.control, shiftKey: key1.shift, metaKey: false, keyCode:key1.key.key_code};
|
||||
keyAction.callHandler(keyEvent);
|
||||
expect(handler1).toHaveBeenCalled();
|
||||
|
||||
keyEvent = {altKey: key2.alt, ctrlKey: key2.control, shiftKey: key2.shift, metaKey: false, keyCode:key2.key.key_code};
|
||||
keyAction.callHandler(keyEvent);
|
||||
expect(handler2).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
133
web/regression/javascript/erd/onetomany_link_spec.js
Normal file
133
web/regression/javascript/erd/onetomany_link_spec.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {mount} from 'enzyme';
|
||||
import '../helper/enzyme.helper';
|
||||
import {
|
||||
RightAngleLinkModel,
|
||||
} from '@projectstorm/react-diagrams';
|
||||
|
||||
import OneToManyPortModel from 'pgadmin.tools.erd/erd_tool/ports/OneToManyPort';
|
||||
import {OneToManyLinkModel, OneToManyLinkWidget, OneToManyLinkFactory} from 'pgadmin.tools.erd/erd_tool/links/OneToManyLink';
|
||||
|
||||
|
||||
describe('ERD OneToManyLinkModel', ()=>{
|
||||
let modelObj = null;
|
||||
beforeAll(()=>{
|
||||
spyOn(RightAngleLinkModel.prototype, 'serialize').and.returnValue({'key': 'value'});
|
||||
});
|
||||
beforeEach(()=>{
|
||||
modelObj = new OneToManyLinkModel({
|
||||
data: {
|
||||
local_table_uid: 'id1',
|
||||
local_column_attnum: 0,
|
||||
referenced_table_uid: 'id2',
|
||||
referenced_column_attnum: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('init', ()=>{
|
||||
expect(modelObj.getData()).toEqual({
|
||||
local_table_uid: 'id1',
|
||||
local_column_attnum: 0,
|
||||
referenced_table_uid: 'id2',
|
||||
referenced_column_attnum: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('setData', ()=>{
|
||||
modelObj.setData({
|
||||
local_column_attnum: 2,
|
||||
referenced_column_attnum: 4,
|
||||
});
|
||||
expect(modelObj.getData()).toEqual({
|
||||
local_column_attnum: 2,
|
||||
referenced_column_attnum: 4,
|
||||
});
|
||||
});
|
||||
|
||||
it('serializeData', ()=>{
|
||||
let nodesDict = {
|
||||
'id1': {
|
||||
getData: function(){ return {
|
||||
'name': 'table1',
|
||||
'schema': 'erd1',
|
||||
'columns': [
|
||||
{'name': 'col11', attnum: 0},
|
||||
{'name': 'col12', attnum: 1},
|
||||
],
|
||||
};},
|
||||
},
|
||||
'id2': {
|
||||
getData: function(){ return {
|
||||
'name': 'table2',
|
||||
'schema': 'erd2',
|
||||
'columns': [
|
||||
{'name': 'col21', attnum: 0},
|
||||
{'name': 'col22', attnum: 1},
|
||||
],
|
||||
};},
|
||||
},
|
||||
};
|
||||
|
||||
expect(modelObj.serializeData(nodesDict)).toEqual({
|
||||
'schema': 'erd1',
|
||||
'table': 'table1',
|
||||
'remote_schema': 'erd2',
|
||||
'remote_table': 'table2',
|
||||
'columns': [{
|
||||
'local_column': 'col11',
|
||||
'referenced': 'col22',
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
||||
it('serialize', ()=>{
|
||||
let retVal = modelObj.serialize();
|
||||
expect(RightAngleLinkModel.prototype.serialize).toHaveBeenCalled();
|
||||
expect(retVal).toEqual({
|
||||
key: 'value',
|
||||
data: {
|
||||
local_table_uid: 'id1',
|
||||
local_column_attnum: 0,
|
||||
referenced_table_uid: 'id2',
|
||||
referenced_column_attnum: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ERD OneToManyLinkWidget', ()=>{
|
||||
let linkFactory = new OneToManyLinkFactory();
|
||||
let engine = {
|
||||
getFactoryForLink: ()=>linkFactory,
|
||||
};
|
||||
let link = null;
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
|
||||
link = new OneToManyLinkModel({
|
||||
color: '#000',
|
||||
data: {
|
||||
local_table_uid: 'id1',
|
||||
local_column_attnum: 0,
|
||||
referenced_table_uid: 'id2',
|
||||
referenced_column_attnum: 1,
|
||||
},
|
||||
});
|
||||
link.setSourcePort(new OneToManyPortModel({options: {}}));
|
||||
link.setTargetPort(new OneToManyPortModel({options: {}}));
|
||||
});
|
||||
|
||||
it('render', ()=>{
|
||||
let linkWidget = mount(
|
||||
<svg><OneToManyLinkWidget link={link} diagramEngine={engine} factory={linkFactory} /></svg>
|
||||
);
|
||||
|
||||
let paths = linkWidget.find('g g');
|
||||
expect(paths.at(0).find('polyline').length).toBe(1);
|
||||
expect(paths.at(paths.length-1).find('polyline').length).toBe(1);
|
||||
expect(paths.at(paths.length-1).find('circle').length).toBe(1);
|
||||
});
|
||||
});
|
||||
21
web/regression/javascript/erd/onetomany_port_spec.js
Normal file
21
web/regression/javascript/erd/onetomany_port_spec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { PortModel } from '@projectstorm/react-diagrams-core';
|
||||
import OneToManyPortModel from 'pgadmin.tools.erd/erd_tool/ports/OneToManyPort';
|
||||
import {OneToManyLinkModel} from 'pgadmin.tools.erd/erd_tool/links/OneToManyLink';
|
||||
|
||||
describe('ERD OneToManyPortModel', ()=>{
|
||||
it('removeAllLinks', ()=>{
|
||||
let link1 = jasmine.createSpyObj('link1', ['remove']);
|
||||
let link2 = jasmine.createSpyObj('link2', ['remove']);
|
||||
spyOn(PortModel.prototype, 'getLinks').and.returnValue([link1, link2]);
|
||||
|
||||
let portObj = new OneToManyPortModel({options: {}});
|
||||
portObj.removeAllLinks();
|
||||
expect(link1.remove).toHaveBeenCalled();
|
||||
expect(link2.remove).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('createLinkModel', ()=>{
|
||||
let portObj = new OneToManyPortModel({options: {}});
|
||||
expect(portObj.createLinkModel()).toBeInstanceOf(OneToManyLinkModel);
|
||||
});
|
||||
});
|
||||
305
web/regression/javascript/erd/table_node_spec.js
Normal file
305
web/regression/javascript/erd/table_node_spec.js
Normal file
@@ -0,0 +1,305 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {mount} from 'enzyme';
|
||||
import '../helper/enzyme.helper';
|
||||
import { DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
|
||||
import {TableNodeModel, TableNodeWidget} from 'pgadmin.tools.erd/erd_tool/nodes/TableNode';
|
||||
import { IconButton, DetailsToggleButton } from 'pgadmin.tools.erd/erd_tool/ui_components/ToolBar';
|
||||
|
||||
|
||||
describe('ERD TableNodeModel', ()=>{
|
||||
let modelObj = null;
|
||||
beforeAll(()=>{
|
||||
spyOn(DefaultNodeModel.prototype, 'serialize').and.returnValue({'key': 'value'});
|
||||
});
|
||||
beforeEach(()=>{
|
||||
modelObj = new TableNodeModel({
|
||||
color: '#000',
|
||||
otherInfo: {
|
||||
note: 'some note',
|
||||
data: {
|
||||
name: 'table1',
|
||||
schema: 'erd',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('init', ()=>{
|
||||
expect(modelObj.getData()).toEqual({
|
||||
columns: [],
|
||||
name: 'table1',
|
||||
schema: 'erd',
|
||||
});
|
||||
expect(modelObj.getNote()).toBe('some note');
|
||||
expect(modelObj.getColumns()).toEqual([]);
|
||||
});
|
||||
|
||||
it('getPortName', ()=>{
|
||||
expect(modelObj.getPortName(2)).toBe('coll-port-2');
|
||||
});
|
||||
|
||||
it('setNote', ()=>{
|
||||
modelObj.setNote('some note to test');
|
||||
expect(modelObj.getNote()).toBe('some note to test');
|
||||
});
|
||||
|
||||
it('addColumn', ()=>{
|
||||
modelObj.addColumn({name: 'col1', not_null:false, attnum: 0});
|
||||
expect(modelObj.getColumns()).toEqual([{name: 'col1', not_null:false, attnum: 0}]);
|
||||
});
|
||||
|
||||
it('getColumnAt', ()=>{
|
||||
modelObj.addColumn({name: 'col1', not_null:false, attnum: 0});
|
||||
modelObj.addColumn({name: 'col2', not_null:false, attnum: 1});
|
||||
expect(modelObj.getColumnAt(0)).toEqual({name: 'col1', not_null:false, attnum: 0});
|
||||
expect(modelObj.getColumnAt(1)).toEqual({name: 'col2', not_null:false, attnum: 1});
|
||||
expect(modelObj.getColumnAt(2)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('setName', ()=>{
|
||||
modelObj.setName('changedName');
|
||||
expect(modelObj.getData().name).toBe('changedName');
|
||||
});
|
||||
|
||||
it('cloneData', ()=>{
|
||||
modelObj.addColumn({name: 'col1', not_null:false, attnum: 0});
|
||||
expect(modelObj.cloneData('clonedNode')).toEqual({
|
||||
name: 'clonedNode',
|
||||
schema: 'erd',
|
||||
columns: [{name: 'col1', not_null:false, attnum: 0}],
|
||||
});
|
||||
});
|
||||
|
||||
describe('setData', ()=>{
|
||||
let existPort = jasmine.createSpyObj('port', ['removeAllLinks']);
|
||||
|
||||
beforeEach(()=>{
|
||||
modelObj._data.columns = [
|
||||
{name: 'col1', not_null:false, attnum: 0},
|
||||
{name: 'col2', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:false, attnum: 2},
|
||||
];
|
||||
|
||||
spyOn(modelObj, 'getPort').and.callFake((portName)=>{
|
||||
/* If new port added there will not be any port */
|
||||
if(portName !== 'coll-port-3') {
|
||||
return existPort;
|
||||
}
|
||||
});
|
||||
spyOn(modelObj, 'removePort');
|
||||
spyOn(modelObj, 'getPortName');
|
||||
});
|
||||
|
||||
it('add columns', ()=>{
|
||||
existPort.removeAllLinks.calls.reset();
|
||||
modelObj.setData({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col1', not_null:false, attnum: 0},
|
||||
{name: 'col2', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:false, attnum: 2},
|
||||
{name: 'col4', not_null:false, attnum: 3},
|
||||
],
|
||||
});
|
||||
expect(modelObj.getData()).toEqual({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col1', not_null:false, attnum: 0},
|
||||
{name: 'col2', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:false, attnum: 2},
|
||||
{name: 'col4', not_null:false, attnum: 3},
|
||||
],
|
||||
});
|
||||
expect(existPort.removeAllLinks).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('update columns', ()=>{
|
||||
existPort.removeAllLinks.calls.reset();
|
||||
modelObj.setData({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col1', not_null:false, attnum: 0},
|
||||
{name: 'col2updated', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:true, attnum: 2},
|
||||
],
|
||||
});
|
||||
expect(modelObj.getData()).toEqual({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col1', not_null:false, attnum: 0},
|
||||
{name: 'col2updated', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:true, attnum: 2},
|
||||
],
|
||||
});
|
||||
expect(existPort.removeAllLinks).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('remove columns', ()=>{
|
||||
existPort.removeAllLinks.calls.reset();
|
||||
modelObj.setData({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col2', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:false, attnum: 2},
|
||||
],
|
||||
});
|
||||
expect(modelObj.getData()).toEqual({
|
||||
name: 'noname',
|
||||
schema: 'erd',
|
||||
columns: [
|
||||
{name: 'col2', not_null:false, attnum: 1},
|
||||
{name: 'col3', not_null:false, attnum: 2},
|
||||
],
|
||||
});
|
||||
|
||||
expect(modelObj.getPortName).toHaveBeenCalledWith(0);
|
||||
expect(existPort.removeAllLinks).toHaveBeenCalled();
|
||||
expect(modelObj.removePort).toHaveBeenCalledWith(existPort);
|
||||
});
|
||||
});
|
||||
|
||||
it('getSchemaTableName', ()=>{
|
||||
expect(modelObj.getSchemaTableName()).toEqual(['erd', 'table1']);
|
||||
});
|
||||
|
||||
it('serializeData', ()=>{
|
||||
modelObj.addColumn({name: 'col1', not_null:false, attnum: 0});
|
||||
expect(modelObj.serializeData()).toEqual({
|
||||
name: 'table1',
|
||||
schema: 'erd',
|
||||
columns: [{name: 'col1', not_null:false, attnum: 0}],
|
||||
});
|
||||
});
|
||||
|
||||
it('serialize', ()=>{
|
||||
let retVal = modelObj.serialize();
|
||||
expect(DefaultNodeModel.prototype.serialize).toHaveBeenCalled();
|
||||
expect(retVal).toEqual({
|
||||
key: 'value',
|
||||
otherInfo: {
|
||||
data: {
|
||||
columns: [],
|
||||
name: 'table1',
|
||||
schema: 'erd',
|
||||
},
|
||||
note: 'some note',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ERD TableNodeWidget', ()=>{
|
||||
let node = null;
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
|
||||
node = new TableNodeModel({
|
||||
color: '#000',
|
||||
otherInfo: {
|
||||
note: 'some note',
|
||||
data: {
|
||||
name: 'table1',
|
||||
schema: 'erd',
|
||||
columns: [{
|
||||
attnum: 0,
|
||||
is_primary_key: true,
|
||||
name: 'id',
|
||||
cltype: 'integer',
|
||||
attlen: null,
|
||||
attprecision: null,
|
||||
}, {
|
||||
attnum: 1,
|
||||
is_primary_key: false,
|
||||
name: 'amount',
|
||||
cltype: 'number',
|
||||
attlen: 10,
|
||||
attprecision: 5,
|
||||
}, {
|
||||
attnum: 2,
|
||||
is_primary_key: false,
|
||||
name: 'desc',
|
||||
cltype: 'character varrying',
|
||||
attlen: 50,
|
||||
attprecision: null,
|
||||
}],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('render', ()=>{
|
||||
let nodeWidget = mount(<TableNodeWidget node={node}/>);
|
||||
expect(nodeWidget.getDOMNode().className).toBe('table-node ');
|
||||
expect(nodeWidget.find('.table-node .table-toolbar').length).toBe(1);
|
||||
expect(nodeWidget.find('.table-node .table-schema').text()).toBe('erd');
|
||||
expect(nodeWidget.find('.table-node .table-name').text()).toBe('table1');
|
||||
expect(nodeWidget.find('.table-node .table-cols').length).toBe(1);
|
||||
expect(nodeWidget.find(DetailsToggleButton).length).toBe(1);
|
||||
expect(nodeWidget.find(IconButton).findWhere(n => n.prop('title')=='Check note').length).toBe(1);
|
||||
});
|
||||
|
||||
it('node selected', ()=>{
|
||||
spyOn(node, 'isSelected').and.returnValue(true);
|
||||
let nodeWidget = mount(<TableNodeWidget node={node}/>);
|
||||
expect(nodeWidget.getDOMNode().className).toBe('table-node selected');
|
||||
});
|
||||
|
||||
it('remove note', ()=>{
|
||||
node.setNote('');
|
||||
let nodeWidget = mount(<TableNodeWidget node={node}/>);
|
||||
expect(nodeWidget.find(IconButton).findWhere(n => n.prop('title')=='Check note').length).toBe(0);
|
||||
});
|
||||
|
||||
describe('generateColumn', ()=>{
|
||||
let nodeWidget = null;
|
||||
|
||||
beforeEach(()=>{
|
||||
nodeWidget = mount(<TableNodeWidget node={node}/>);
|
||||
});
|
||||
|
||||
it('count', ()=>{
|
||||
expect(nodeWidget.find('.table-node .table-cols .col-row').length).toBe(3);
|
||||
});
|
||||
|
||||
it('icons', ()=>{
|
||||
let cols = nodeWidget.find('.table-node .table-cols .col-row-data');
|
||||
expect(cols.at(0).find('.wcTabIcon').hasClass('icon-primary_key')).toBeTrue();
|
||||
expect(cols.at(1).find('.wcTabIcon').hasClass('icon-column')).toBeTrue();
|
||||
expect(cols.at(2).find('.wcTabIcon').hasClass('icon-column')).toBeTrue();
|
||||
});
|
||||
|
||||
it('column names', ()=>{
|
||||
let cols = nodeWidget.find('.table-node .table-cols .col-row-data');
|
||||
expect(cols.at(0).find('.col-name').text()).toBe('id');
|
||||
expect(cols.at(1).find('.col-name').text()).toBe('amount');
|
||||
expect(cols.at(2).find('.col-name').text()).toBe('desc');
|
||||
});
|
||||
|
||||
it('data types', ()=>{
|
||||
let cols = nodeWidget.find('.table-node .table-cols .col-row-data');
|
||||
expect(cols.at(0).find('.col-datatype').text()).toBe('integer');
|
||||
expect(cols.at(1).find('.col-datatype').text()).toBe('number(10,5)');
|
||||
expect(cols.at(2).find('.col-datatype').text()).toBe('character varrying(50)');
|
||||
});
|
||||
|
||||
it('show_details', (done)=>{
|
||||
nodeWidget.setState({show_details: false});
|
||||
expect(nodeWidget.find('.table-node .table-cols .col-row-data .col-datatype').length).toBe(0);
|
||||
|
||||
nodeWidget.instance().toggleShowDetails(jasmine.createSpyObj('event', ['preventDefault']));
|
||||
/* Dummy set state to wait for toggleShowDetails -> setState to complete */
|
||||
nodeWidget.setState({}, ()=>{
|
||||
expect(nodeWidget.find('.table-node .table-cols .col-row-data .col-datatype').length).toBe(3);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
651
web/regression/javascript/erd/test_tables.js
Normal file
651
web/regression/javascript/erd/test_tables.js
Normal file
@@ -0,0 +1,651 @@
|
||||
export default [
|
||||
{
|
||||
'oid': 123456,
|
||||
'name': 'test1',
|
||||
'spcoid': 0,
|
||||
'relacl_str': null,
|
||||
'spcname': 'pg_default',
|
||||
'schema': 'schema1',
|
||||
'relowner': 'postgres',
|
||||
'relkind': 'r',
|
||||
'is_partitioned': false,
|
||||
'relhassubclass': false,
|
||||
'reltuples': '0',
|
||||
'description': null,
|
||||
'conname': null,
|
||||
'conkey': null,
|
||||
'isrepl': false,
|
||||
'triggercount': '0',
|
||||
'coll_inherits': [],
|
||||
'inherited_tables_cnt': '0',
|
||||
'relpersistence': false,
|
||||
'fillfactor': null,
|
||||
'parallel_workers': null,
|
||||
'toast_tuple_target': null,
|
||||
'autovacuum_enabled': 'x',
|
||||
'autovacuum_vacuum_threshold': null,
|
||||
'autovacuum_vacuum_scale_factor': null,
|
||||
'autovacuum_analyze_threshold': null,
|
||||
'autovacuum_analyze_scale_factor': null,
|
||||
'autovacuum_vacuum_cost_delay': null,
|
||||
'autovacuum_vacuum_cost_limit': null,
|
||||
'autovacuum_freeze_min_age': null,
|
||||
'autovacuum_freeze_max_age': null,
|
||||
'autovacuum_freeze_table_age': null,
|
||||
'toast_autovacuum_enabled': 'x',
|
||||
'toast_autovacuum_vacuum_threshold': null,
|
||||
'toast_autovacuum_vacuum_scale_factor': null,
|
||||
'toast_autovacuum_analyze_threshold': null,
|
||||
'toast_autovacuum_analyze_scale_factor': null,
|
||||
'toast_autovacuum_vacuum_cost_delay': null,
|
||||
'toast_autovacuum_vacuum_cost_limit': null,
|
||||
'toast_autovacuum_freeze_min_age': null,
|
||||
'toast_autovacuum_freeze_max_age': null,
|
||||
'toast_autovacuum_freeze_table_age': null,
|
||||
'reloptions': null,
|
||||
'toast_reloptions': null,
|
||||
'reloftype': 0,
|
||||
'typname': null,
|
||||
'typoid': null,
|
||||
'rlspolicy': false,
|
||||
'forcerlspolicy': false,
|
||||
'hastoasttable': false,
|
||||
'seclabels': null,
|
||||
'is_sys_table': false,
|
||||
'partition_scheme': '',
|
||||
'autovacuum_custom': false,
|
||||
'toast_autovacuum': false,
|
||||
'rows_cnt': 0,
|
||||
'vacuum_settings_str': '',
|
||||
'vacuum_table': [
|
||||
{
|
||||
'name': 'autovacuum_analyze_scale_factor',
|
||||
'setting': '0.1',
|
||||
'label': 'ANALYZE scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_analyze_threshold',
|
||||
'setting': '50',
|
||||
'label': 'ANALYZE base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_max_age',
|
||||
'setting': '200000000',
|
||||
'label': 'FREEZE maximum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_delay',
|
||||
'setting': '2',
|
||||
'label': 'VACUUM cost delay',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_limit',
|
||||
'setting': '-1',
|
||||
'label': 'VACUUM cost limit',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_scale_factor',
|
||||
'setting': '0.2',
|
||||
'label': 'VACUUM scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_threshold',
|
||||
'setting': '50',
|
||||
'label': 'VACUUM base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_min_age',
|
||||
'setting': '50000000',
|
||||
'label': 'FREEZE minimum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_table_age',
|
||||
'setting': '150000000',
|
||||
'label': 'FREEZE table age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
],
|
||||
'vacuum_toast': [
|
||||
{
|
||||
'name': 'autovacuum_freeze_max_age',
|
||||
'setting': '200000000',
|
||||
'label': 'FREEZE maximum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_delay',
|
||||
'setting': '2',
|
||||
'label': 'VACUUM cost delay',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_limit',
|
||||
'setting': '-1',
|
||||
'label': 'VACUUM cost limit',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_scale_factor',
|
||||
'setting': '0.2',
|
||||
'label': 'VACUUM scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_threshold',
|
||||
'setting': '50',
|
||||
'label': 'VACUUM base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_min_age',
|
||||
'setting': '50000000',
|
||||
'label': 'FREEZE minimum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_table_age',
|
||||
'setting': '150000000',
|
||||
'label': 'FREEZE table age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
],
|
||||
'columns': [{
|
||||
'name': 'id',
|
||||
'atttypid': 23,
|
||||
'attlen': null,
|
||||
'attnum': 1,
|
||||
'attndims': 0,
|
||||
'atttypmod': -1,
|
||||
'attacl': [],
|
||||
'attnotnull': true,
|
||||
'attoptions': null,
|
||||
'attstattarget': -1,
|
||||
'attstorage': 'p',
|
||||
'attidentity': '',
|
||||
'defval': null,
|
||||
'typname': 'integer',
|
||||
'displaytypname': 'integer',
|
||||
'cltype': 'integer',
|
||||
'elemoid': 23,
|
||||
'typnspname': 'pg_catalog',
|
||||
'defaultstorage': 'p',
|
||||
'description': null,
|
||||
'indkey': '1',
|
||||
'isdup': false,
|
||||
'collspcname': '',
|
||||
'is_fk': false,
|
||||
'seclabels': null,
|
||||
'is_sys_column': false,
|
||||
'colconstype': 'n',
|
||||
'genexpr': null,
|
||||
'relname': 'tab1',
|
||||
'is_view_only': false,
|
||||
'seqrelid': null,
|
||||
'seqtypid': null,
|
||||
'seqstart': null,
|
||||
'seqincrement': null,
|
||||
'seqmax': null,
|
||||
'seqmin': null,
|
||||
'seqcache': null,
|
||||
'seqcycle': null,
|
||||
'is_pk': true,
|
||||
'is_primary_key': true,
|
||||
'attprecision': null,
|
||||
'edit_types': [
|
||||
'bigint',
|
||||
'double precision',
|
||||
'information_schema.cardinal_number',
|
||||
'integer',
|
||||
'money',
|
||||
'numeric',
|
||||
'oid',
|
||||
'real',
|
||||
'regclass',
|
||||
'regconfig',
|
||||
'regdictionary',
|
||||
'regnamespace',
|
||||
'regoper',
|
||||
'regoperator',
|
||||
'regproc',
|
||||
'regprocedure',
|
||||
'regrole',
|
||||
'regtype',
|
||||
'smallint',
|
||||
],
|
||||
}],
|
||||
'primary_key': [],
|
||||
'unique_constraint': [],
|
||||
'check_constraint': [],
|
||||
'index': {},
|
||||
'rule': {},
|
||||
'trigger': {},
|
||||
'row_security_policy': {},
|
||||
},
|
||||
{
|
||||
'oid': 408229,
|
||||
'name': 'test2',
|
||||
'spcoid': 0,
|
||||
'relacl_str': null,
|
||||
'spcname': 'pg_default',
|
||||
'schema': 'erd',
|
||||
'relowner': 'postgres',
|
||||
'relkind': 'r',
|
||||
'is_partitioned': false,
|
||||
'relhassubclass': false,
|
||||
'reltuples': '0',
|
||||
'description': null,
|
||||
'conname': 'tab1_pkey',
|
||||
'conkey': [
|
||||
1,
|
||||
],
|
||||
'isrepl': false,
|
||||
'triggercount': '0',
|
||||
'coll_inherits': [],
|
||||
'inherited_tables_cnt': '0',
|
||||
'relpersistence': false,
|
||||
'fillfactor': null,
|
||||
'parallel_workers': null,
|
||||
'toast_tuple_target': null,
|
||||
'autovacuum_enabled': 'x',
|
||||
'autovacuum_vacuum_threshold': null,
|
||||
'autovacuum_vacuum_scale_factor': null,
|
||||
'autovacuum_analyze_threshold': null,
|
||||
'autovacuum_analyze_scale_factor': null,
|
||||
'autovacuum_vacuum_cost_delay': null,
|
||||
'autovacuum_vacuum_cost_limit': null,
|
||||
'autovacuum_freeze_min_age': null,
|
||||
'autovacuum_freeze_max_age': null,
|
||||
'autovacuum_freeze_table_age': null,
|
||||
'toast_autovacuum_enabled': 'x',
|
||||
'toast_autovacuum_vacuum_threshold': null,
|
||||
'toast_autovacuum_vacuum_scale_factor': null,
|
||||
'toast_autovacuum_analyze_threshold': null,
|
||||
'toast_autovacuum_analyze_scale_factor': null,
|
||||
'toast_autovacuum_vacuum_cost_delay': null,
|
||||
'toast_autovacuum_vacuum_cost_limit': null,
|
||||
'toast_autovacuum_freeze_min_age': null,
|
||||
'toast_autovacuum_freeze_max_age': null,
|
||||
'toast_autovacuum_freeze_table_age': null,
|
||||
'reloptions': null,
|
||||
'toast_reloptions': null,
|
||||
'reloftype': 0,
|
||||
'typname': null,
|
||||
'typoid': null,
|
||||
'rlspolicy': false,
|
||||
'forcerlspolicy': false,
|
||||
'hastoasttable': false,
|
||||
'seclabels': null,
|
||||
'is_sys_table': false,
|
||||
'partition_scheme': '',
|
||||
'autovacuum_custom': false,
|
||||
'toast_autovacuum': false,
|
||||
'rows_cnt': 0,
|
||||
'vacuum_settings_str': '',
|
||||
'vacuum_table': [
|
||||
{
|
||||
'name': 'autovacuum_analyze_scale_factor',
|
||||
'setting': '0.1',
|
||||
'label': 'ANALYZE scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_analyze_threshold',
|
||||
'setting': '50',
|
||||
'label': 'ANALYZE base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_max_age',
|
||||
'setting': '200000000',
|
||||
'label': 'FREEZE maximum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_delay',
|
||||
'setting': '2',
|
||||
'label': 'VACUUM cost delay',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_limit',
|
||||
'setting': '-1',
|
||||
'label': 'VACUUM cost limit',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_scale_factor',
|
||||
'setting': '0.2',
|
||||
'label': 'VACUUM scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_threshold',
|
||||
'setting': '50',
|
||||
'label': 'VACUUM base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_min_age',
|
||||
'setting': '50000000',
|
||||
'label': 'FREEZE minimum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_table_age',
|
||||
'setting': '150000000',
|
||||
'label': 'FREEZE table age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
],
|
||||
'vacuum_toast': [
|
||||
{
|
||||
'name': 'autovacuum_freeze_max_age',
|
||||
'setting': '200000000',
|
||||
'label': 'FREEZE maximum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_delay',
|
||||
'setting': '2',
|
||||
'label': 'VACUUM cost delay',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_cost_limit',
|
||||
'setting': '-1',
|
||||
'label': 'VACUUM cost limit',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_scale_factor',
|
||||
'setting': '0.2',
|
||||
'label': 'VACUUM scale factor',
|
||||
'column_type': 'number',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_vacuum_threshold',
|
||||
'setting': '50',
|
||||
'label': 'VACUUM base threshold',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_min_age',
|
||||
'setting': '50000000',
|
||||
'label': 'FREEZE minimum age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
{
|
||||
'name': 'autovacuum_freeze_table_age',
|
||||
'setting': '150000000',
|
||||
'label': 'FREEZE table age',
|
||||
'column_type': 'integer',
|
||||
},
|
||||
],
|
||||
'columns': [
|
||||
{
|
||||
'name': 'id',
|
||||
'atttypid': 23,
|
||||
'attlen': null,
|
||||
'attnum': 1,
|
||||
'attndims': 0,
|
||||
'atttypmod': -1,
|
||||
'attacl': [],
|
||||
'attnotnull': true,
|
||||
'attoptions': null,
|
||||
'attstattarget': -1,
|
||||
'attstorage': 'p',
|
||||
'attidentity': '',
|
||||
'defval': null,
|
||||
'typname': 'integer',
|
||||
'displaytypname': 'integer',
|
||||
'cltype': 'integer',
|
||||
'elemoid': 23,
|
||||
'typnspname': 'pg_catalog',
|
||||
'defaultstorage': 'p',
|
||||
'description': null,
|
||||
'indkey': '1',
|
||||
'isdup': false,
|
||||
'collspcname': '',
|
||||
'is_fk': false,
|
||||
'seclabels': null,
|
||||
'is_sys_column': false,
|
||||
'colconstype': 'n',
|
||||
'genexpr': null,
|
||||
'relname': 'tab1',
|
||||
'is_view_only': false,
|
||||
'seqrelid': null,
|
||||
'seqtypid': null,
|
||||
'seqstart': null,
|
||||
'seqincrement': null,
|
||||
'seqmax': null,
|
||||
'seqmin': null,
|
||||
'seqcache': null,
|
||||
'seqcycle': null,
|
||||
'is_pk': true,
|
||||
'is_primary_key': true,
|
||||
'attprecision': null,
|
||||
'edit_types': [
|
||||
'bigint',
|
||||
'double precision',
|
||||
'information_schema.cardinal_number',
|
||||
'integer',
|
||||
'money',
|
||||
'numeric',
|
||||
'oid',
|
||||
'real',
|
||||
'regclass',
|
||||
'regconfig',
|
||||
'regdictionary',
|
||||
'regnamespace',
|
||||
'regoper',
|
||||
'regoperator',
|
||||
'regproc',
|
||||
'regprocedure',
|
||||
'regrole',
|
||||
'regtype',
|
||||
'smallint',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'col1col1col1col1col1col1col1col1',
|
||||
'atttypid': 23,
|
||||
'attlen': null,
|
||||
'attnum': 2,
|
||||
'attndims': 0,
|
||||
'atttypmod': -1,
|
||||
'attacl': [],
|
||||
'attnotnull': true,
|
||||
'attoptions': null,
|
||||
'attstattarget': -1,
|
||||
'attstorage': 'p',
|
||||
'attidentity': '',
|
||||
'defval': null,
|
||||
'typname': 'integer',
|
||||
'displaytypname': 'integer',
|
||||
'cltype': 'integer',
|
||||
'elemoid': 23,
|
||||
'typnspname': 'pg_catalog',
|
||||
'defaultstorage': 'p',
|
||||
'description': null,
|
||||
'indkey': '1',
|
||||
'isdup': false,
|
||||
'collspcname': '',
|
||||
'is_fk': true,
|
||||
'seclabels': null,
|
||||
'is_sys_column': false,
|
||||
'colconstype': 'n',
|
||||
'genexpr': null,
|
||||
'relname': 'tab1',
|
||||
'is_view_only': false,
|
||||
'seqrelid': null,
|
||||
'seqtypid': null,
|
||||
'seqstart': null,
|
||||
'seqincrement': null,
|
||||
'seqmax': null,
|
||||
'seqmin': null,
|
||||
'seqcache': null,
|
||||
'seqcycle': null,
|
||||
'is_pk': false,
|
||||
'is_primary_key': false,
|
||||
'attprecision': null,
|
||||
'edit_types': [
|
||||
'bigint',
|
||||
'double precision',
|
||||
'information_schema.cardinal_number',
|
||||
'integer',
|
||||
'integer',
|
||||
'money',
|
||||
'numeric',
|
||||
'oid',
|
||||
'real',
|
||||
'regclass',
|
||||
'regconfig',
|
||||
'regdictionary',
|
||||
'regnamespace',
|
||||
'regoper',
|
||||
'regoperator',
|
||||
'regproc',
|
||||
'regprocedure',
|
||||
'regrole',
|
||||
'regtype',
|
||||
'smallint',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'col2',
|
||||
'atttypid': 23,
|
||||
'attlen': null,
|
||||
'attnum': 3,
|
||||
'attndims': 0,
|
||||
'atttypmod': -1,
|
||||
'attacl': [],
|
||||
'attnotnull': false,
|
||||
'attoptions': null,
|
||||
'attstattarget': -1,
|
||||
'attstorage': 'p',
|
||||
'attidentity': '',
|
||||
'defval': null,
|
||||
'typname': 'integer',
|
||||
'displaytypname': 'integer',
|
||||
'cltype': 'integer',
|
||||
'elemoid': 23,
|
||||
'typnspname': 'pg_catalog',
|
||||
'defaultstorage': 'p',
|
||||
'description': null,
|
||||
'indkey': '1',
|
||||
'isdup': false,
|
||||
'collspcname': '',
|
||||
'is_fk': false,
|
||||
'seclabels': null,
|
||||
'is_sys_column': false,
|
||||
'colconstype': 'n',
|
||||
'genexpr': null,
|
||||
'relname': 'tab1',
|
||||
'is_view_only': false,
|
||||
'seqrelid': null,
|
||||
'seqtypid': null,
|
||||
'seqstart': null,
|
||||
'seqincrement': null,
|
||||
'seqmax': null,
|
||||
'seqmin': null,
|
||||
'seqcache': null,
|
||||
'seqcycle': null,
|
||||
'is_pk': false,
|
||||
'is_primary_key': false,
|
||||
'attprecision': null,
|
||||
'edit_types': [
|
||||
'bigint',
|
||||
'double precision',
|
||||
'information_schema.cardinal_number',
|
||||
'integer',
|
||||
'integer',
|
||||
'integer',
|
||||
'money',
|
||||
'numeric',
|
||||
'oid',
|
||||
'real',
|
||||
'regclass',
|
||||
'regconfig',
|
||||
'regdictionary',
|
||||
'regnamespace',
|
||||
'regoper',
|
||||
'regoperator',
|
||||
'regproc',
|
||||
'regprocedure',
|
||||
'regrole',
|
||||
'regtype',
|
||||
'smallint',
|
||||
],
|
||||
},
|
||||
],
|
||||
'primary_key': [
|
||||
{
|
||||
'oid': 408232,
|
||||
'name': 'tab1_pkey',
|
||||
'col_count': 1,
|
||||
'spcname': 'pg_default',
|
||||
'comment': null,
|
||||
'condeferrable': false,
|
||||
'condeferred': false,
|
||||
'fillfactor': null,
|
||||
'columns': [
|
||||
{
|
||||
'column': 'id',
|
||||
},
|
||||
],
|
||||
'include': [],
|
||||
},
|
||||
],
|
||||
'unique_constraint': [],
|
||||
'foreign_key': [
|
||||
{
|
||||
'oid': 408239,
|
||||
'name': 'tab1_col1_fkey',
|
||||
'condeferrable': false,
|
||||
'condeferred': false,
|
||||
'confupdtype': 'a',
|
||||
'confdeltype': 'a',
|
||||
'confmatchtype': false,
|
||||
'conkey': [
|
||||
2,
|
||||
],
|
||||
'confkey': [
|
||||
1,
|
||||
],
|
||||
'confrelid': 408234,
|
||||
'fknsp': 'erd',
|
||||
'fktab': 'tab1',
|
||||
'refnsp': 'erd',
|
||||
'reftab': 'tab2',
|
||||
'comment': null,
|
||||
'convalidated': false,
|
||||
'columns': [
|
||||
{
|
||||
'local_column': 'col1col1col1col1col1col1col1col1',
|
||||
'references': 123456,
|
||||
'referenced': 'id',
|
||||
'references_table_name': 'schema1.test1',
|
||||
},
|
||||
],
|
||||
'remote_schema': 'schema1',
|
||||
'remote_table': 'test1',
|
||||
'coveringindex': null,
|
||||
'autoindex': true,
|
||||
'hasindex': false,
|
||||
},
|
||||
],
|
||||
'check_constraint': [],
|
||||
'index': {},
|
||||
'rule': {},
|
||||
'trigger': {},
|
||||
'row_security_policy': {},
|
||||
},
|
||||
];
|
||||
514
web/regression/javascript/erd/ui_components/body_widget_spec.js
Normal file
514
web/regression/javascript/erd/ui_components/body_widget_spec.js
Normal file
@@ -0,0 +1,514 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {mount} from 'enzyme';
|
||||
import '../../helper/enzyme.helper';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from 'axios/index';
|
||||
|
||||
import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore';
|
||||
import * as erdModule from 'pgadmin.tools.erd/erd_module';
|
||||
import erdPref from './erd_preferences';
|
||||
import BodyWidget from 'pgadmin.tools.erd/erd_tool/ui_components/BodyWidget';
|
||||
import * as ERDSqlTool from 'tools/datagrid/static/js/show_query_tool';
|
||||
|
||||
let pgAdmin = {
|
||||
Browser: {
|
||||
Events: {
|
||||
on: jasmine.createSpy('on'),
|
||||
},
|
||||
get_preferences_for_module: function() {
|
||||
return erdPref;
|
||||
},
|
||||
docker: {
|
||||
findPanels: function() {
|
||||
return [
|
||||
{
|
||||
isVisible: function() {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
onPreferencesChange: ()=>{},
|
||||
utils: {
|
||||
app_version_int: 1234,
|
||||
},
|
||||
},
|
||||
FileManager: {
|
||||
init: jasmine.createSpy(),
|
||||
show_dialog: jasmine.createSpy(),
|
||||
},
|
||||
};
|
||||
|
||||
let alertify = jasmine.createSpyObj('alertify', {
|
||||
'success': null,
|
||||
'error': null,
|
||||
'confirm': null,
|
||||
'alert': {
|
||||
'set': ()=>{},
|
||||
},
|
||||
});
|
||||
|
||||
let tableDialog = jasmine.createSpyObj('TableDialog', ['show']);
|
||||
let otmDialog = jasmine.createSpyObj('otmDialog', ['show']);
|
||||
let mtmDialog = jasmine.createSpyObj('mtmDialog', ['show']);
|
||||
|
||||
let getDialog = (dialogName)=>{
|
||||
switch(dialogName) {
|
||||
case 'entity_dialog': return tableDialog;
|
||||
case 'onetomany_dialog': return otmDialog;
|
||||
case 'manytomany_dialog': return mtmDialog;
|
||||
}
|
||||
};
|
||||
|
||||
describe('ERD BodyWidget', ()=>{
|
||||
let body = null;
|
||||
let bodyInstance = null;
|
||||
let networkMock = null;
|
||||
let serverVersion = 120000;
|
||||
let colTypes = [
|
||||
{'label': 'integer', 'value': 'integer'},
|
||||
{'label': 'character varrying', 'value': 'character varrying'},
|
||||
];
|
||||
let schemas = [
|
||||
{'oid': 111, 'name': 'erd1'},
|
||||
{'oid': 222, 'name': 'erd2'},
|
||||
];
|
||||
let params = {
|
||||
bgcolor: null,
|
||||
client_platform: 'macos',
|
||||
did: '13637',
|
||||
fgcolor: null,
|
||||
gen: true,
|
||||
is_desktop_mode: true,
|
||||
is_linux: false,
|
||||
server_type: 'pg',
|
||||
sgid: '1',
|
||||
sid: '5',
|
||||
title: 'postgres/postgres@PostgreSQL 12',
|
||||
trans_id: 110008,
|
||||
};
|
||||
|
||||
beforeAll(()=>{
|
||||
spyOn(erdModule, 'setPanelTitle');
|
||||
spyOn(ERDCore.prototype, 'repaint');
|
||||
spyOn(ERDCore.prototype, 'deserializeData');
|
||||
spyOn(ERDCore.prototype, 'addNode').and.returnValue({
|
||||
setSelected: ()=>{},
|
||||
getColumns: ()=>([{attnum: 0}, {attnum: 1}]),
|
||||
getID: ()=>'newid1',
|
||||
});
|
||||
spyOn(ERDCore.prototype, 'addLink').and.returnValue({
|
||||
setSelected: ()=>{},
|
||||
});
|
||||
spyOn(alertify, 'confirm').and.callFake((arg1, arg2, okCallback)=>{
|
||||
okCallback();
|
||||
});
|
||||
|
||||
networkMock = new MockAdapter(axios);
|
||||
networkMock.onPost('/erd/initialize/110008/1/5/13637').reply(200, {'data': {
|
||||
serverVersion: serverVersion,
|
||||
}});
|
||||
networkMock.onGet('/erd/prequisite/110008/1/5/13637').reply(200, {'data': {
|
||||
'col_types': colTypes,
|
||||
'schemas': schemas,
|
||||
}});
|
||||
networkMock.onGet('/erd/tables/110008/1/5/13637').reply(200, {'data': []});
|
||||
|
||||
networkMock.onPost('/erd/sql/110008/1/5/13637').reply(200, {'data': 'SELECT 1;'});
|
||||
|
||||
networkMock.onPost('/sqleditor/load_file/').reply(200, {'data': 'data'});
|
||||
networkMock.onPost('/sqleditor/save_file/').reply(200, {'data': 'data'});
|
||||
});
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
body = mount(<BodyWidget params={params} pgAdmin={pgAdmin} getDialog={getDialog} transformToSupported={()=>{}} alertify={alertify}/>);
|
||||
bodyInstance = body.instance();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
networkMock.restore();
|
||||
if(body) {
|
||||
body.unmount();
|
||||
}
|
||||
});
|
||||
|
||||
it('constructor', (done)=>{
|
||||
|
||||
expect(body.find('ToolBar').length).toBe(1);
|
||||
expect(body.find('ConnectionBar').length).toBe(1);
|
||||
expect(body.find('FloatingNote').length).toBe(1);
|
||||
expect(body.find('.diagram-container Loader').length).toBe(1);
|
||||
expect(body.find('.diagram-container CanvasWidget').length).toBe(1);
|
||||
|
||||
body.instance().setState({}, ()=>{
|
||||
let instance = body.instance();
|
||||
|
||||
setTimeout(()=>{
|
||||
expect(body.state()).toEqual(jasmine.objectContaining({
|
||||
server_version: serverVersion,
|
||||
preferences: erdPref,
|
||||
}));
|
||||
expect(instance.diagram.getCache('colTypes')).toEqual(colTypes);
|
||||
expect(instance.diagram.getCache('schemas')).toEqual(schemas);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('event offsetUpdated', (done)=>{
|
||||
bodyInstance.diagram.fireEvent({offsetX: 4, offsetY: 5}, 'offsetUpdated', true);
|
||||
setTimeout(()=>{
|
||||
expect(bodyInstance.canvasEle.style.backgroundPosition).toBe('4px 5px');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event zoomUpdated', (done)=>{
|
||||
spyOn(bodyInstance.diagram.getModel(), 'getOptions').and.returnValue({gridSize: 15});
|
||||
bodyInstance.diagram.fireEvent({zoom: 20}, 'zoomUpdated', true);
|
||||
setTimeout(()=>{
|
||||
expect(bodyInstance.canvasEle.style.backgroundSize).toBe('9px 9px');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event nodesSelectionChanged', (done)=>{
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([{key:'value'}]);
|
||||
bodyInstance.diagram.fireEvent({}, 'nodesSelectionChanged', true);
|
||||
setTimeout(()=>{
|
||||
expect(body.state().single_node_selected).toBe(true);
|
||||
expect(body.state().any_item_selected).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event linksSelectionChanged', (done)=>{
|
||||
spyOn(bodyInstance.diagram, 'getSelectedLinks').and.returnValue([{key:'value'}]);
|
||||
bodyInstance.diagram.fireEvent({}, 'linksSelectionChanged', true);
|
||||
setTimeout(()=>{
|
||||
expect(body.state().single_link_selected).toBe(true);
|
||||
expect(body.state().any_item_selected).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event linksUpdated', (done)=>{
|
||||
bodyInstance.diagram.fireEvent({}, 'linksUpdated', true);
|
||||
setTimeout(()=>{
|
||||
expect(body.state().dirty).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event nodesUpdated', (done)=>{
|
||||
bodyInstance.diagram.fireEvent({}, 'nodesUpdated', true);
|
||||
setTimeout(()=>{
|
||||
expect(body.state().dirty).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event showNote', (done)=>{
|
||||
let noteNode = {key: 'value', getNote: ()=>'a note'};
|
||||
spyOn(bodyInstance, 'showNote');
|
||||
bodyInstance.diagram.fireEvent({node: noteNode}, 'showNote', true);
|
||||
setTimeout(()=>{
|
||||
expect(bodyInstance.showNote).toHaveBeenCalledWith(noteNode);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('event editNode', (done)=>{
|
||||
let node = {key: 'value', getNote: ()=>'a note'};
|
||||
spyOn(bodyInstance, 'addEditNode');
|
||||
bodyInstance.diagram.fireEvent({node: node}, 'editNode', true);
|
||||
setTimeout(()=>{
|
||||
expect(bodyInstance.addEditNode).toHaveBeenCalledWith(node);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('getDialog', ()=>{
|
||||
bodyInstance.getDialog('entity_dialog')();
|
||||
expect(tableDialog.show).toHaveBeenCalled();
|
||||
|
||||
bodyInstance.getDialog('onetomany_dialog')();
|
||||
expect(otmDialog.show).toHaveBeenCalled();
|
||||
|
||||
bodyInstance.getDialog('manytomany_dialog')();
|
||||
expect(mtmDialog.show).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('addEditNode', ()=>{
|
||||
/* New */
|
||||
tableDialog.show.calls.reset();
|
||||
bodyInstance.addEditNode();
|
||||
expect(tableDialog.show).toHaveBeenCalled();
|
||||
|
||||
let saveCallback = tableDialog.show.calls.mostRecent().args[5];
|
||||
let newData = {key: 'value'};
|
||||
saveCallback(newData);
|
||||
expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith(newData);
|
||||
|
||||
/* Existing */
|
||||
tableDialog.show.calls.reset();
|
||||
let node = jasmine.createSpyObj('node',{
|
||||
getSchemaTableName: ['erd1', 'table1'],
|
||||
setData: null,
|
||||
getData: null,
|
||||
});
|
||||
bodyInstance.addEditNode(node);
|
||||
expect(tableDialog.show).toHaveBeenCalled();
|
||||
|
||||
saveCallback = tableDialog.show.calls.mostRecent().args[5];
|
||||
newData = {key: 'value'};
|
||||
saveCallback(newData);
|
||||
expect(node.setData).toHaveBeenCalledWith(newData);
|
||||
});
|
||||
|
||||
it('onEditNode', ()=>{
|
||||
let node = {key: 'value'};
|
||||
spyOn(bodyInstance, 'addEditNode');
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]);
|
||||
bodyInstance.onEditNode();
|
||||
expect(bodyInstance.addEditNode).toHaveBeenCalledWith(node);
|
||||
});
|
||||
|
||||
it('onAddNewNode', ()=>{
|
||||
spyOn(bodyInstance, 'addEditNode');
|
||||
bodyInstance.onAddNewNode();
|
||||
expect(bodyInstance.addEditNode).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('onCloneNode', ()=>{
|
||||
let node = jasmine.createSpyObj('node',{
|
||||
getSchemaTableName: ['erd1', 'table1'],
|
||||
setData: null,
|
||||
getData: null,
|
||||
cloneData: {key: 'value'},
|
||||
getPosition: {x: 30, y: 30},
|
||||
});
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]);
|
||||
spyOn(bodyInstance.diagram, 'getNextTableName').and.returnValue('newtable1');
|
||||
bodyInstance.onCloneNode();
|
||||
expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith({key: 'value'}, [50, 50]);
|
||||
});
|
||||
|
||||
it('onDeleteNode', (done)=>{
|
||||
let node = jasmine.createSpyObj('node',{
|
||||
getSchemaTableName: ['erd1', 'table1'],
|
||||
setData: null,
|
||||
getData: null,
|
||||
cloneData: {key: 'value'},
|
||||
getPosition: {x: 30, y: 30},
|
||||
remove: null,
|
||||
setSelected: null,
|
||||
});
|
||||
let link = jasmine.createSpyObj('link', {
|
||||
remove: null,
|
||||
setSelected: null,
|
||||
getTargetPort: jasmine.createSpyObj('port', ['remove']),
|
||||
getSourcePort: jasmine.createSpyObj('port', ['remove']),
|
||||
});
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]);
|
||||
spyOn(bodyInstance.diagram, 'getSelectedLinks').and.returnValue([link]);
|
||||
|
||||
bodyInstance.onDeleteNode();
|
||||
setTimeout(()=>{
|
||||
expect(node.remove).toHaveBeenCalled();
|
||||
expect(link.remove).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('onAutoDistribute', ()=>{
|
||||
spyOn(bodyInstance.diagram, 'dagreDistributeNodes');
|
||||
bodyInstance.onAutoDistribute();
|
||||
expect(bodyInstance.diagram.dagreDistributeNodes).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('onDetailsToggle', (done)=>{
|
||||
let node = jasmine.createSpyObj('node',['fireEvent']);
|
||||
spyOn(bodyInstance.diagram, 'getModel').and.returnValue({
|
||||
'getNodes': ()=>[node],
|
||||
});
|
||||
|
||||
let show_details = body.state().show_details;
|
||||
bodyInstance.onDetailsToggle();
|
||||
body.setState({}, ()=>{
|
||||
expect(body.state().show_details).toBe(!show_details);
|
||||
expect(node.fireEvent).toHaveBeenCalledWith({show_details: !show_details}, 'toggleDetails');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('onLoadDiagram', ()=>{
|
||||
bodyInstance.onLoadDiagram();
|
||||
expect(pgAdmin.FileManager.show_dialog).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('openFile', (done)=>{
|
||||
spyOn(bodyInstance.diagram, 'deserialize');
|
||||
bodyInstance.openFile('test.pgerd');
|
||||
setTimeout(()=>{
|
||||
expect(body.state()).toEqual(jasmine.objectContaining({
|
||||
current_file: 'test.pgerd',
|
||||
dirty: false,
|
||||
}));
|
||||
expect(bodyInstance.diagram.deserialize).toHaveBeenCalledWith({data: 'data'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('onSaveDiagram', (done)=>{
|
||||
body.setState({
|
||||
current_file: 'newfile.pgerd',
|
||||
});
|
||||
bodyInstance.onSaveDiagram();
|
||||
setTimeout(()=>{
|
||||
expect(body.state()).toEqual(jasmine.objectContaining({
|
||||
current_file: 'newfile.pgerd',
|
||||
dirty: false,
|
||||
}));
|
||||
done();
|
||||
});
|
||||
|
||||
bodyInstance.onSaveDiagram(true);
|
||||
expect(pgAdmin.FileManager.show_dialog).toHaveBeenCalledWith({
|
||||
'supported_types': ['pgerd'],
|
||||
'dialog_type': 'create_file',
|
||||
'dialog_title': 'Save File',
|
||||
'btn_primary': 'Save',
|
||||
});
|
||||
});
|
||||
|
||||
it('onSaveAsDiagram', ()=>{
|
||||
spyOn(bodyInstance, 'onSaveDiagram');
|
||||
bodyInstance.onSaveAsDiagram();
|
||||
expect(bodyInstance.onSaveDiagram).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('onSQLClick', (done)=>{
|
||||
spyOn(bodyInstance.diagram, 'serializeData').and.returnValue({key: 'value'});
|
||||
spyOn(ERDSqlTool, 'showERDSqlTool');
|
||||
spyOn(localStorage, 'setItem');
|
||||
bodyInstance.onSQLClick();
|
||||
|
||||
setTimeout(()=>{
|
||||
let sql = '-- This script was generated by a beta version of the ERD tool in pgAdmin 4.\n'
|
||||
+ '-- Please log an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new if you find any bugs, including reproduction steps.\n'
|
||||
+ 'BEGIN;\nSELECT 1;\nEND;';
|
||||
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith('erd'+params.trans_id, sql);
|
||||
expect(ERDSqlTool.showERDSqlTool).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('onOneToManyClick', ()=>{
|
||||
let node = jasmine.createSpyObj('node',{
|
||||
getID: 'id1',
|
||||
});
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]);
|
||||
|
||||
otmDialog.show.calls.reset();
|
||||
bodyInstance.onOneToManyClick();
|
||||
expect(otmDialog.show).toHaveBeenCalled();
|
||||
|
||||
let saveCallback = otmDialog.show.calls.mostRecent().args[4];
|
||||
let newData = {key: 'value'};
|
||||
saveCallback(newData);
|
||||
expect(bodyInstance.diagram.addLink).toHaveBeenCalledWith(newData, 'onetomany');
|
||||
});
|
||||
|
||||
it('onManyToManyClick', ()=>{
|
||||
let node = jasmine.createSpyObj('node',{
|
||||
getID: 'id1',
|
||||
});
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]);
|
||||
|
||||
mtmDialog.show.calls.reset();
|
||||
bodyInstance.onManyToManyClick();
|
||||
expect(mtmDialog.show).toHaveBeenCalled();
|
||||
|
||||
/* onSave */
|
||||
let nodesDict = {
|
||||
'id1': {
|
||||
getID: ()=>'id1',
|
||||
getData: ()=>({name: 'table1', schema: 'erd1'}),
|
||||
getColumnAt: ()=>({name: 'col1', type: 'type1', attnum: 0}),
|
||||
addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj),
|
||||
},
|
||||
'id2': {
|
||||
getID: ()=>'id2',
|
||||
getData: ()=>({name: 'table2', schema: 'erd2'}),
|
||||
getColumnAt: ()=>({name: 'col2', type: 'type2', attnum: 1}),
|
||||
addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj),
|
||||
},
|
||||
};
|
||||
spyOn(bodyInstance.diagram, 'getModel').and.returnValue({
|
||||
'getNodesDict': ()=>nodesDict,
|
||||
});
|
||||
spyOn(bodyInstance.diagram, 'addLink');
|
||||
let saveCallback = mtmDialog.show.calls.mostRecent().args[4];
|
||||
let newData = {
|
||||
left_table_uid: 'id1',
|
||||
left_table_column_attnum: 1,
|
||||
right_table_uid: 'id2',
|
||||
right_table_column_attnum: 2,
|
||||
};
|
||||
|
||||
bodyInstance.diagram.addNode.calls.reset();
|
||||
bodyInstance.diagram.addLink.calls.reset();
|
||||
saveCallback(newData);
|
||||
expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith({
|
||||
name: 'table1_table2',
|
||||
schema: 'erd1',
|
||||
columns: [
|
||||
{
|
||||
type: 'type1',
|
||||
name: 'table1_col1',
|
||||
is_primary_key: false,
|
||||
attnum: 0,
|
||||
},
|
||||
{
|
||||
type: 'type2',
|
||||
name: 'table2_col2',
|
||||
is_primary_key: false,
|
||||
attnum: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let linkData = {
|
||||
local_table_uid: 'newid1',
|
||||
local_column_attnum: 0,
|
||||
referenced_table_uid: 'id1',
|
||||
referenced_column_attnum : 1,
|
||||
};
|
||||
expect(bodyInstance.diagram.addLink.calls.argsFor(0)).toEqual([linkData, 'onetomany']);
|
||||
linkData = {
|
||||
local_table_uid: 'newid1',
|
||||
local_column_attnum: 1,
|
||||
referenced_table_uid: 'id2',
|
||||
referenced_column_attnum : 2,
|
||||
};
|
||||
expect(bodyInstance.diagram.addLink.calls.argsFor(1)).toEqual([linkData, 'onetomany']);
|
||||
});
|
||||
|
||||
it('onNoteClick', ()=>{
|
||||
let noteNode = {key: 'value', getNote: ()=>'a note'};
|
||||
spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([noteNode]);
|
||||
spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').and.returnValue(null);
|
||||
spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').and.returnValue(null);
|
||||
spyOn(bodyInstance, 'setState');
|
||||
bodyInstance.onNoteClick();
|
||||
expect(bodyInstance.setState).toHaveBeenCalledWith({
|
||||
note_node: noteNode,
|
||||
note_open: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {mount} from 'enzyme';
|
||||
import '../../helper/enzyme.helper';
|
||||
|
||||
import ConnectionBar, {STATUS} from 'pgadmin.tools.erd/erd_tool/ui_components/ConnectionBar';
|
||||
|
||||
describe('ERD ConnectionBar', ()=>{
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
it('<ConnectionBar /> comp', ()=>{
|
||||
let connBar = mount(<ConnectionBar statusId="conn-bar" status={STATUS.DISCONNECTED} title="test title"/>);
|
||||
|
||||
expect(connBar.find('.editor-title').text()).toBe('test title');
|
||||
|
||||
connBar.setProps({status: STATUS.CONNECTING});
|
||||
expect(connBar.find('.editor-title').text()).toBe('(Obtaining connection...) test title');
|
||||
|
||||
connBar.setProps({bgcolor: '#000', fgcolor: '#fff'});
|
||||
expect(connBar.find('.editor-title').prop('style').backgroundColor).toBe('#000');
|
||||
expect(connBar.find('.editor-title').prop('style').color).toBe('#fff');
|
||||
});
|
||||
});
|
||||
147
web/regression/javascript/erd/ui_components/erd_preferences.js
Normal file
147
web/regression/javascript/erd/ui_components/erd_preferences.js
Normal file
@@ -0,0 +1,147 @@
|
||||
export default {
|
||||
'erd_new_browser_tab': false,
|
||||
'open_project': {
|
||||
'alt': false,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 79,
|
||||
'char': 'o',
|
||||
},
|
||||
},
|
||||
'save_project': {
|
||||
'alt': false,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 83,
|
||||
'char': 's',
|
||||
},
|
||||
},
|
||||
'save_project_as': {
|
||||
'alt': false,
|
||||
'shift': true,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 83,
|
||||
'char': 's',
|
||||
},
|
||||
},
|
||||
'generate_sql': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 83,
|
||||
'char': 's',
|
||||
},
|
||||
},
|
||||
'download_image': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 73,
|
||||
'char': 'i',
|
||||
},
|
||||
},
|
||||
'add_table': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 65,
|
||||
'char': 'a',
|
||||
},
|
||||
},
|
||||
'edit_table': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 69,
|
||||
'char': 'e',
|
||||
},
|
||||
},
|
||||
'clone_table': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 67,
|
||||
'char': 'c',
|
||||
},
|
||||
},
|
||||
'drop_table': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 68,
|
||||
'char': 'd',
|
||||
},
|
||||
},
|
||||
'add_edit_note': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 78,
|
||||
'char': 'n',
|
||||
},
|
||||
},
|
||||
'one_to_many': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 79,
|
||||
'char': 'o',
|
||||
},
|
||||
},
|
||||
'many_to_many': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 77,
|
||||
'char': 'm',
|
||||
},
|
||||
},
|
||||
'auto_align': {
|
||||
'alt': true,
|
||||
'shift': false,
|
||||
'control': true,
|
||||
'key': {
|
||||
'key_code': 76,
|
||||
'char': 'l',
|
||||
},
|
||||
},
|
||||
'zoom_to_fit': {
|
||||
'alt': true,
|
||||
'shift': true,
|
||||
'control': false,
|
||||
'key': {
|
||||
'key_code': 70,
|
||||
'char': 'f',
|
||||
},
|
||||
},
|
||||
'zoom_in': {
|
||||
'alt': true,
|
||||
'shift': true,
|
||||
'control': false,
|
||||
'key': {
|
||||
'key_code': 187,
|
||||
'char': '+',
|
||||
},
|
||||
},
|
||||
'zoom_out': {
|
||||
'alt': true,
|
||||
'shift': true,
|
||||
'control': false,
|
||||
'key': {
|
||||
'key_code': 189,
|
||||
'char': '-',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {mount} from 'enzyme';
|
||||
import '../../helper/enzyme.helper';
|
||||
|
||||
import FloatingNote from 'pgadmin.tools.erd/erd_tool/ui_components/FloatingNote';
|
||||
|
||||
describe('ERD FloatingNote', ()=>{
|
||||
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
it('<FloatingNote /> on OK click', ()=>{
|
||||
let floatNote = null;
|
||||
let onClose = jasmine.createSpy('onClose');
|
||||
let noteNode = {
|
||||
getNote: function() {
|
||||
return 'some note';
|
||||
},
|
||||
setNote: jasmine.createSpy('setNote'),
|
||||
getSchemaTableName: function() {
|
||||
return ['schema1', 'table1'];
|
||||
},
|
||||
};
|
||||
|
||||
floatNote = mount(<FloatingNote open={false} onClose={onClose}
|
||||
reference={null} noteNode={noteNode} appendTo={document.body} rows={8}/>);
|
||||
|
||||
floatNote.find('textarea').simulate('change', {
|
||||
target: {
|
||||
value: 'the new note',
|
||||
},
|
||||
});
|
||||
floatNote.find('button[data-label="OK"]').simulate('click');
|
||||
expect(noteNode.setNote).toHaveBeenCalledWith('the new note');
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
23
web/regression/javascript/erd/ui_components/loader_spec.js
Normal file
23
web/regression/javascript/erd/ui_components/loader_spec.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import '../../helper/enzyme.helper';
|
||||
|
||||
import Loader from 'pgadmin.tools.erd/erd_tool/ui_components/Loader';
|
||||
|
||||
describe('ERD Loader', ()=>{
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
it('<Loader /> comp', ()=>{
|
||||
let loaderComp = shallow(<Loader />);
|
||||
expect(loaderComp.isEmptyRender()).toBeTrue();
|
||||
|
||||
loaderComp.setProps({message: 'test message'});
|
||||
expect(loaderComp.find('.pg-sp-text').text()).toBe('test message');
|
||||
|
||||
loaderComp.setProps({autoEllipsis: true});
|
||||
expect(loaderComp.find('.pg-sp-text').text()).toBe('test message...');
|
||||
});
|
||||
});
|
||||
76
web/regression/javascript/erd/ui_components/toolbar_spec.js
Normal file
76
web/regression/javascript/erd/ui_components/toolbar_spec.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import jasmineEnzyme from 'jasmine-enzyme';
|
||||
import React from 'react';
|
||||
import Tippy from '@tippyjs/react';
|
||||
import {mount, shallow} from 'enzyme';
|
||||
import '../../helper/enzyme.helper';
|
||||
|
||||
import ToolBar, {ButtonGroup, DetailsToggleButton, IconButton, Shortcut} from 'pgadmin.tools.erd/erd_tool/ui_components/ToolBar';
|
||||
|
||||
describe('ERD Toolbar', ()=>{
|
||||
beforeEach(()=>{
|
||||
jasmineEnzyme();
|
||||
});
|
||||
|
||||
it('<Toolbar /> comp', ()=>{
|
||||
let toolBar = mount(<ToolBar id="id1"><div className="test"></div></ToolBar>);
|
||||
expect(toolBar.getDOMNode().id).toBe('id1');
|
||||
expect(toolBar.find('.test').length).toBe(1);
|
||||
});
|
||||
|
||||
it('<ButtonGroup /> comp', ()=>{
|
||||
let btnGrp = mount(<ButtonGroup><div className="test"></div></ButtonGroup>);
|
||||
expect(btnGrp.getDOMNode().className).toBe('btn-group mr-1 ');
|
||||
expect(btnGrp.find('.test').length).toBe(1);
|
||||
btnGrp.unmount();
|
||||
|
||||
btnGrp = mount(<ButtonGroup className="someclass"></ButtonGroup>);
|
||||
expect(btnGrp.getDOMNode().className).toBe('btn-group mr-1 someclass');
|
||||
});
|
||||
|
||||
it('<DetailsToggleButton /> comp', ()=>{
|
||||
let toggle = shallow(<DetailsToggleButton showDetails={true} />);
|
||||
let btn = toggle.find(IconButton);
|
||||
expect(btn.prop('icon')).toBe('far fa-eye');
|
||||
expect(btn.prop('title')).toBe('Show fewer details');
|
||||
|
||||
toggle.setProps({showDetails: false});
|
||||
btn = toggle.find(IconButton);
|
||||
expect(btn.prop('icon')).toBe('fas fa-low-vision');
|
||||
expect(btn.prop('title')).toBe('Show more details');
|
||||
});
|
||||
|
||||
it('<IconButton /> comp', ()=>{
|
||||
let btn = mount(<IconButton />);
|
||||
|
||||
let tippy = btn.find(Tippy);
|
||||
expect(tippy.length).toBe(0);
|
||||
|
||||
btn.setProps({title: 'test title'});
|
||||
tippy = btn.find(Tippy);
|
||||
expect(tippy.length).toBe(1);
|
||||
|
||||
expect(btn.find('button').getDOMNode().className).toBe('btn btn-sm btn-primary-icon ');
|
||||
|
||||
btn.setProps({icon: 'fa fa-icon'});
|
||||
expect(btn.find('button .sql-icon-lg').getDOMNode().className).toBe('fa fa-icon sql-icon-lg');
|
||||
});
|
||||
|
||||
it('<Shortcut /> comp', ()=>{
|
||||
let key = {
|
||||
alt: true,
|
||||
control: true,
|
||||
shift: false,
|
||||
key: {
|
||||
key_code: 65,
|
||||
char: 'a',
|
||||
},
|
||||
};
|
||||
let shortcutComp = mount(<Shortcut shortcut={key}/>);
|
||||
|
||||
expect(shortcutComp.find('.shortcut-key').length).toBe(3);
|
||||
|
||||
key.alt = false;
|
||||
shortcutComp.setProps({shortcut: key});
|
||||
expect(shortcutComp.find('.shortcut-key').length).toBe(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user