Port Triggers node to react. Fixes #6672

This commit is contained in:
Nikhil Mohite 2021-08-16 19:48:08 +05:30 committed by Akshay Joshi
parent bb5e2b98e9
commit 351cb3e6ca
9 changed files with 908 additions and 9 deletions

View File

@ -1480,8 +1480,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
parallel_dict = {'u': 'UNSAFE', 's': 'SAFE', 'r': 'RESTRICTED'} parallel_dict = {'u': 'UNSAFE', 's': 'SAFE', 'r': 'RESTRICTED'}
# Get Schema Name from its OID. # Get Schema Name from its OID.
if self.node_type != 'trigger_function': self._get_schema_name_from_oid(data)
self._get_schema_name_from_oid(data)
if fnid is not None: if fnid is not None:
# Edit Mode # Edit Mode

View File

@ -7,7 +7,7 @@
// //
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
import TriggerFunctionSchema from './trigger_function.ui'; import TriggerFunctionSchema from './trigger_function.ui';
import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../static/js/node_ajax'; import { getNodeListByName, getNodeListById, getNodeAjaxOptions } from '../../../../../../../static/js/node_ajax';
import { getNodeVariableSchema } from '../../../../../static/js/variable.ui'; import { getNodeVariableSchema } from '../../../../../static/js/variable.ui';
import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui'; import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui';
@ -91,7 +91,9 @@ define('pgadmin.node.trigger_function', [
()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false), ()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
{ {
role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData), role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData),
schema: ()=>getNodeListByName('schema', treeNodeInfo, itemNodeData, {cacheLevel: 'database'}), schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, {
cacheLevel: 'database'
}),
language: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData, {noCache: true}, (res) => { language: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData, {noCache: true}, (res) => {
return _.reject(res, function(o) { return _.reject(res, function(o) {
return o.label == 'sql' || o.label == 'edbspl'; return o.label == 'sql' || o.label == 'edbspl';
@ -101,7 +103,7 @@ define('pgadmin.node.trigger_function', [
}, },
{ {
funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name, funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema.label : '' pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null
} }
); );
}, },

View File

@ -6,6 +6,8 @@
// This software is released under the PostgreSQL Licence // This software is released under the PostgreSQL Licence
// //
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
import { getNodeListByName, getNodeAjaxOptions } from '../../../../../../../../static/js/node_ajax';
import TriggerSchema from './trigger.ui';
define('pgadmin.node.trigger', [ define('pgadmin.node.trigger', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
@ -173,6 +175,19 @@ define('pgadmin.node.trigger', [
}, },
canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema, canDrop: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema, canDropCascade: SchemaChildTreeNode.isTreeItemOfChildOfSchema,
getSchema: function(treeNodeInfo, itemNodeData) {
return new TriggerSchema(
{
triggerFunction: ()=>getNodeAjaxOptions('get_triggerfunctions', this, treeNodeInfo, itemNodeData, {cacheLevel: 'trigger_function'}, (data) => {
return _.reject(data, function(option) {
return option.label == '';
});
}),
columns: ()=> getNodeListByName('column', treeNodeInfo, itemNodeData, { cacheLevel: 'column'}),
nodeInfo: treeNodeInfo
},
);
},
model: pgAdmin.Browser.Node.Model.extend({ model: pgAdmin.Browser.Node.Model.extend({
idAttribute: 'oid', idAttribute: 'oid',
defaults: { defaults: {

View File

@ -0,0 +1,492 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import gettext from 'sources/gettext';
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
import { isEmptyString } from 'sources/validators';
export class EventSchema extends BaseUISchema {
constructor(fieldOptions={}, initValues) {
super({
evnt_update: false,
evnt_insert: false,
evnt_delete: false,
evnt_truncate: false,
is_row_trigger: false,
is_constraint_trigger: false,
...initValues,
});
this.fieldOptions = {
nodeInfo: null,
...fieldOptions,
};
this.nodeInfo = this.fieldOptions.nodeInfo;
}
get idAttribute() {
return 'oid';
}
inSchemaWithModelCheck(state) {
// Check if we are under schema node & in 'create' mode
if(this.nodeInfo && 'schema' in this.nodeInfo) {
// We will disable control if it's in 'edit' mode
return !this.isNew(state);
}
return true;
}
get baseFields() {
let obj = this;
return [{
id: 'evnt_insert', label: gettext('INSERT'),
type: 'switch', mode: ['create','edit', 'properties'],
group: gettext('Events'),
disabled: (state) => {
var evn_insert = state.evnt_insert;
if (!_.isUndefined(evn_insert) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
return false;
return obj.inSchemaWithModelCheck(state);
},
},{
id: 'evnt_update', label: gettext('UPDATE'),
type: 'switch', mode: ['create','edit', 'properties'],
group: gettext('Events'),
disabled: (state) => {
var evn_update = state.evnt_update;
if (!_.isUndefined(evn_update) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
return false;
return obj.inSchemaWithModelCheck(state);
},
},{
id: 'evnt_delete', label: gettext('DELETE'),
type: 'switch', mode: ['create','edit', 'properties'],
group: gettext('Events'),
disabled: (state) => {
var evn_delete = state.evnt_delete;
if (!_.isUndefined(evn_delete) && obj.nodeInfo && obj.nodeInfo.server.server_type == 'ppas' && obj.isNew(state))
return false;
return obj.inSchemaWithModelCheck(state);
},
},{
id: 'evnt_truncate', label: gettext('TRUNCATE'),
type: 'switch', group: gettext('Events'), deps: ['is_row_trigger', 'is_constraint_trigger'],
disabled: (state) => {
var is_constraint_trigger = state.is_constraint_trigger,
is_row_trigger = state.is_row_trigger,
server_type = obj.nodeInfo ? obj.nodeInfo.server.server_type: null;
if (is_row_trigger == true){
state.evnt_truncate = false;
return true;
}
if (server_type === 'ppas' && !_.isUndefined(is_constraint_trigger) &&
!_.isUndefined(is_row_trigger) &&
is_constraint_trigger === false && obj.isNew(state))
return false;
return obj.inSchemaWithModelCheck(state);
},
}];
}
validate(state, setError) {
if (isEmptyString(state.service)) {
let errmsg = null;
/* events validation*/
if (state.tfunction && !state.evnt_truncate && !state.evnt_delete && !state.evnt_update && !state.evnt_insert) {
errmsg = gettext('Specify at least one event.');
//setError('evnt_truncate', errmsg);
//setError('evnt_delete', errmsg);
//setError('evnt_update', errmsg);
setError('evnt_insert', errmsg);
//setError('evnt_update', errmsg);
return true;
} else {
errmsg = null;
//setError('evnt_truncate', errmsg);
//setError('evnt_delete', errmsg);
//setError('evnt_update', errmsg);
setError('evnt_insert', errmsg);
}
}
}
}
export default class TriggerSchema extends BaseUISchema {
constructor(fieldOptions={}, initValues) {
super({
name: undefined,
is_row_trigger: true,
fires: 'BEFORE',
...initValues
});
this.fieldOptions = {
triggerFunction: [],
//columns: [],
...fieldOptions,
};
this.nodeInfo = this.fieldOptions.nodeInfo;
}
get idAttribute() {
return 'oid';
}
inSchema() {
// Check if under schema node & in 'create' mode
if('catalog' in this.nodeInfo) {
return true;
}
return false;
}
inSchemaWithModelCheck(state) {
// Check if we are under schema node & in 'create' mode
if('schema' in this.nodeInfo) {
// We will disable control if it's in 'edit' mode
return !this.isNew(state);
}
return true;
}
disableTransition(state) {
if (!this.isNew())
return true;
var flag = false,
evnt = null,
name = state.name,
evnt_count = 0;
// Disable transition tables for view trigger and PG version < 100000
if(_.indexOf(Object.keys(this.nodeInfo), 'table') == -1 ||
this.nodeInfo.server.version < 100000) return true;
if (name == 'tgoldtable') evnt = 'evnt_delete';
else if (name == 'tgnewtable') evnt = 'evnt_insert';
if(state.evnt_insert) evnt_count++;
if(state.evnt_update) evnt_count++;
if(state.evnt_delete) evnt_count++;
// Disable transition tables if
// - It is a constraint trigger
// - Fires other than AFTER
// - More than one events enabled
// - Update event with the column list
// Disable Old transition table if both UPDATE and DELETE events are disabled
// Disable New transition table if both UPDATE and INSERT events are disabled
if(!state.is_constraint_trigger && state.fires == 'AFTER' &&
(state.evnt_update || state[evnt]) && evnt_count == 1) {
flag = (state.evnt_update && (_.size(state.columns) >= 1 && state.columns[0] != ''));
}
if(flag && state.name) {
state.name = null;
}
return flag;
}
get baseFields() {
let obj = this;
return [{
id: 'name', label: gettext('Name'), cell: 'text',
type: 'text', disabled: obj.inSchema, noEmpty: true
},{
id: 'oid', label: gettext('OID'), cell: 'text',
type: 'int', mode: ['properties'],
},{
id: 'is_enable_trigger', label: gettext('Trigger enabled?'),
mode: ['edit', 'properties'], group: gettext('Definition'),
type: 'select',
disabled: () => {
if('catalog' in obj.nodeInfo || 'view' in obj.nodeInfo) {
return true;
}
return false;
},
options: [
{label: gettext('Enable'), value: 'O'},
{label: gettext('Enable Replica'), value: 'R'},
{label: gettext('Enable Always'), value: 'A'},
{label: gettext('Disable'), value: 'D'},
],
controlProps: { allowClear: false },
},{
id: 'is_row_trigger', label: gettext('Row trigger?'),
type: 'switch', group: gettext('Definition'),
mode: ['create','edit', 'properties'],
deps: ['is_constraint_trigger'],
disabled: (state) => {
// Disabled if table is a partitioned table.
if (!obj.isNew())
return true;
if (obj.nodeInfo.table.is_partitioned && obj.nodeInfo.server.version < 110000)
{
state.is_row_trigger = false;
return true;
}
// If constraint trigger is set to True then row trigger will
// automatically set to True and becomes disable
var is_constraint_trigger = state.is_constraint_trigger;
if(!obj.inSchemaWithModelCheck(state)) {
if(!_.isUndefined(is_constraint_trigger) &&
is_constraint_trigger === true) {
// change it's model value
state.is_row_trigger = true;
return true;
} else {
return false;
}
} else {
// Check if it is row trigger then enabled it.
var is_row_trigger = state.is_row_trigger;
if (!_.isUndefined(is_row_trigger) && obj.nodeInfo.server.server_type == 'ppas') {
return false;
}
// Disable it
return true;
}
},
},{
id: 'is_constraint_trigger', label: gettext('Constraint trigger?'),
type: 'switch',
mode: ['create','edit', 'properties'],
group: gettext('Definition'),
deps: ['tfunction'],
disabled: (state) => {
// Disabled if table is a partitioned table.
var tfunction = state.tfunction;
if (( _.has(obj.nodeInfo, 'table') && _.has(obj.nodeInfo.table, 'is_partitioned') &&
obj.nodeInfo.table.is_partitioned) || ( _.has(obj.nodeInfo, 'view')) ||
(obj.nodeInfo.server.server_type === 'ppas' && !_.isUndefined(tfunction) &&
tfunction === 'Inline EDB-SPL')) {
state.is_constraint_trigger = false;
return true;
}
return obj.inSchemaWithModelCheck(state);
},
},{
id: 'tgdeferrable', label: gettext('Deferrable?'),
type: 'switch', group: gettext('Definition'),
mode: ['create','edit', 'properties'],
deps: ['is_constraint_trigger'],
disabled: (state) => {
// If constraint trigger is set to True then only enable it
var is_constraint_trigger = state.is_constraint_trigger;
if(!obj.inSchemaWithModelCheck(state)) {
if(!_.isUndefined(is_constraint_trigger) &&
is_constraint_trigger === true) {
return false;
} else {
// If value is already set then reset it to false
if(state.tgdeferrable) {
state.tgdeferrable = false;
}
return true;
}
} else {
// Disable it
return true;
}
},
},{
id: 'tginitdeferred', label: gettext('Deferred?'),
type: 'switch', group: gettext('Definition'),
mode: ['create','edit', 'properties'],
deps: ['tgdeferrable', 'is_constraint_trigger'],
disabled: (state) => {
// If Deferrable is set to True then only enable it
var tgdeferrable = state.tgdeferrable;
if(!obj.inSchemaWithModelCheck(state)) {
if(!_.isUndefined(tgdeferrable) && tgdeferrable) {
return false;
} else {
// If value is already set then reset it to false
if(obj.tginitdeferred) {
state.tginitdeferred = false;
}
// If constraint trigger is set then do not disable
return state.is_constraint_trigger ? false : true;
}
} else {
// Disable it
return true;
}
},
},{
id: 'tfunction', label: gettext('Trigger function'),
type: 'select', disabled: obj.inSchemaWithModelCheck,
mode: ['create','edit', 'properties'], group: gettext('Definition'),
control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema',
options: obj.fieldOptions.triggerFunction,
cache_node: 'trigger_function',
},{
id: 'tgargs', label: gettext('Arguments'), cell: 'text',
group: gettext('Definition'),
type: 'text',mode: ['create','edit', 'properties'], deps: ['tfunction'],
disabled: (state) => {
// We will disable it when EDB PPAS and trigger function is
// set to Inline EDB-SPL
var tfunction = state.tfunction,
server_type = obj.nodeInfo.server.server_type;
if(!obj.inSchemaWithModelCheck(state)) {
if(server_type === 'ppas' &&
!_.isUndefined(tfunction) &&
tfunction === 'Inline EDB-SPL') {
// Disable and clear its value
state.tgargs = undefined;
return true;
} else {
return false;
}
} else {
// Disable it
return true;
}
},
},{
id: 'fires', label: gettext('Fires'), deps: ['is_constraint_trigger'],
mode: ['create','edit', 'properties'], group: gettext('Events'),
options: () => {
var table_options = [
{label: 'BEFORE', value: 'BEFORE'},
{label: 'AFTER', value: 'AFTER'}],
view_options = [
{label: 'BEFORE', value: 'BEFORE'},
{label: 'AFTER', value: 'AFTER'},
{label: 'INSTEAD OF', value: 'INSTEAD OF'}];
// If we are under table then show table specific options
if(_.indexOf(Object.keys(obj.nodeInfo), 'table') != -1) {
return table_options;
} else {
return view_options;
}
},
type: 'select', controlProps: { allowClear: false },
disabled: (state) => {
if (!obj.isNew())
return true;
// If contraint trigger is set to True then only enable it
var is_constraint_trigger = obj.is_constraint_trigger;
if(!obj.inSchemaWithModelCheck(state)) {
if(!_.isUndefined(is_constraint_trigger) &&
is_constraint_trigger === true) {
state.fires = 'AFTER';
return true;
} else {
return false;
}
} else {
// Check if it is row trigger then enabled it.
var fires_ = state.fires;
if (!_.isUndefined(fires_) && obj.nodeInfo.server.server_type == 'ppas') {
return false;
}
// Disable it
return true;
}
},
},{
type: 'nested-fieldset', mode: ['create','edit', 'properties'],
label: gettext('Events'), group: gettext('Events'),
schema: new EventSchema({nodeInfo: obj.nodeInfo}),
},{
id: 'whenclause', label: gettext('When'),
type: 'sql',
readonly: obj.inSchemaWithModelCheck,
mode: ['create', 'edit', 'properties'], visible: true,
group: gettext('Events'),
},{
id: 'columns', label: gettext('Columns'),
type: 'select', controlProps: { multiple: true },
deps: ['evnt_update'], group: gettext('Events'),
options: obj.fieldOptions.columns,
disabled: (state) => {
if(obj.nodeInfo && 'catalog' in obj.nodeInfo) {
return true;
}
//Disable in edit mode
if (!obj.isNew()) {
return true;
}
// Enable column only if update event is set true
var isUpdate = state.evnt_update;
if(!_.isUndefined(isUpdate) && isUpdate) {
return false;
}
return true;
},
},{
id: 'tgoldtable', label: gettext('Old table'),
type: 'text', group: gettext('Transition'),
cell: 'text', mode: ['create', 'edit', 'properties'],
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
disabled: obj.disableTransition,
},{
id: 'tgnewtable', label: gettext('New table'),
type: 'text', group: gettext('Transition'),
cell: 'string', mode: ['create', 'edit', 'properties'],
deps: ['fires', 'is_constraint_trigger', 'evnt_insert', 'evnt_update', 'evnt_delete', 'columns'],
disabled: obj.disableTransition,
},{
id: 'prosrc', label: gettext('Code'), group: gettext('Code'),
type: 'sql', mode: ['create', 'edit'], deps: ['tfunction'],
isFullTab: true,
visible: true,
readonly: (state) => {
// We will enable it only when EDB PPAS and trigger function is
// set to Inline EDB-SPL
var tfunction = state.tfunction,
server_type = obj.nodeInfo.server.server_type;
return (server_type !== 'ppas' ||
_.isUndefined(tfunction) ||
tfunction !== 'Inline EDB-SPL');
},
},{
id: 'is_sys_trigger', label: gettext('System trigger?'), cell: 'text',
type: 'switch', disabled: obj.inSchemaWithModelCheck, mode: ['properties'],
},{
id: 'description', label: gettext('Comment'), cell: 'string',
type: 'multiline', mode: ['properties', 'create', 'edit'],
disabled: obj.inSchema,
}];
}
validate(state, setError) {
let errmsg = null;
if (isEmptyString(state.service)) {
/* trigger function validation*/
if (isEmptyString(state.tfunction)) {
errmsg = gettext('Trigger function cannot be empty.');
setError('tfunction', errmsg);
return true;
} else {
errmsg = null;
setError('tfunction', errmsg);
}
}
}
}

View File

@ -405,6 +405,7 @@ export default class PgaJobScheduleSchema extends BaseUISchema {
} }
]; ];
} }
validate(state, setError) { validate(state, setError) {
if (isEmptyString(state.jscstart)) { if (isEmptyString(state.jscstart)) {
setError('jscstart', gettext('Please enter the start time.')); setError('jscstart', gettext('Please enter the start time.'));

View File

@ -63,6 +63,7 @@ function SQLTab({active, getSQLValue}) {
readOnly: true, readOnly: true,
}} }}
isAsync={true} isAsync={true}
readonly={true}
/>; />;
} }

View File

@ -13,7 +13,7 @@ import {useOnScreen} from 'sources/custom_hooks';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
/* React wrapper for CodeMirror */ /* React wrapper for CodeMirror */
export default function CodeMirror({name, value, options, events, ...props}) { export default function CodeMirror({currObj, name, value, options, events, ...props}) {
const taRef = useRef(); const taRef = useRef();
const cmObj = useRef(); const cmObj = useRef();
const cmWrapper = useRef(); const cmWrapper = useRef();
@ -24,6 +24,8 @@ export default function CodeMirror({name, value, options, events, ...props}) {
cmObj.current = new OrigCodeMirror.fromTextArea( cmObj.current = new OrigCodeMirror.fromTextArea(
taRef.current, options); taRef.current, options);
currObj && currObj(cmObj.current);
if(cmObj.current) { if(cmObj.current) {
try { try {
cmWrapper.current = cmObj.current.getWrapperElement(); cmWrapper.current = cmObj.current.getWrapperElement();
@ -65,6 +67,7 @@ export default function CodeMirror({name, value, options, events, ...props}) {
} }
CodeMirror.propTypes = { CodeMirror.propTypes = {
currObj: PropTypes.func,
name: PropTypes.string, name: PropTypes.string,
value: PropTypes.string, value: PropTypes.string,
options: PropTypes.object, options: PropTypes.object,

View File

@ -137,11 +137,19 @@ FormInput.propTypes = {
testcid: PropTypes.any, testcid: PropTypes.any,
}; };
export function InputSQL({value, options, onChange, ...props}) { export function InputSQL({value, options, onChange, readonly, ...props}) {
const classes = useStyles(); const classes = useStyles();
const cmObj = useRef();
useEffect(()=>{
if(cmObj.current) {
cmObj.current.setOption('readOnly', readonly);
}
}, [readonly]);
return ( return (
<CodeMirror <CodeMirror
currObj={(obj)=>cmObj.current=obj}
value={value||''} value={value||''}
options={{ options={{
lineNumbers: true, lineNumbers: true,
@ -161,8 +169,8 @@ export function InputSQL({value, options, onChange, ...props}) {
InputSQL.propTypes = { InputSQL.propTypes = {
value: PropTypes.string, value: PropTypes.string,
options: PropTypes.object, options: PropTypes.object,
onChange: PropTypes.func onChange: PropTypes.func,
readonly: PropTypes.bool
}; };
export function FormInputSQL({hasError, required, label, className, helpMessage, testcid, value, controlProps, noLabel, ...props}) { export function FormInputSQL({hasError, required, label, className, helpMessage, testcid, value, controlProps, noLabel, ...props}) {

View File

@ -0,0 +1,378 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import jasmineEnzyme from 'jasmine-enzyme';
import React from 'react';
import '../helper/enzyme.helper';
import { createMount } from '@material-ui/core/test-utils';
import pgAdmin from 'sources/pgadmin';
import {messages} from '../fake_messages';
import SchemaView from '../../../pgadmin/static/js/SchemaView';
//import BaseUISchema from 'sources/SchemaView/base_schema.ui';
import TriggerSchema, { EventSchema } from '../../../pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.ui';
describe('TriggerSchema', ()=>{
let mount;
let schemaObj = new TriggerSchema(
{
triggerFunction: [],
columns: [],
nodeInfo: {
schema: {},
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
table: {is_partitioned: false}
}
}
);
let getInitData = ()=>Promise.resolve({});
/* Use createMount so that material ui components gets the required context */
/* https://material-ui.com/guides/testing/#api */
beforeAll(()=>{
mount = createMount();
});
afterAll(() => {
mount.cleanUp();
});
beforeEach(()=>{
jasmineEnzyme();
/* messages used by validators */
pgAdmin.Browser = pgAdmin.Browser || {};
pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
});
it('create', ()=>{
mount(<SchemaView
formType='dialog'
schema={schemaObj}
viewHelperProps={{
mode: 'create',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('edit', ()=>{
mount(<SchemaView
formType='dialog'
schema={schemaObj}
getInitData={getInitData}
viewHelperProps={{
mode: 'edit',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('properties', ()=>{
mount(<SchemaView
formType='tab'
schema={schemaObj}
getInitData={getInitData}
viewHelperProps={{
mode: 'properties',
}}
onHelp={()=>{}}
onEdit={()=>{}}
/>);
});
it('validate', ()=>{
let state = {};
let setError = jasmine.createSpy('setError');
state.tfunction = null;
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('tfunction', 'Trigger function cannot be empty.');
state.tfunction = 'public';
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('tfunction', null);
});
it('catalog create', ()=>{
let catalogSchemaObj = new TriggerSchema(
{
triggerFunction: [],
columns: [],
nodeInfo: {
catalog: {},
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
table: {is_partitioned: false}
}
}
);
mount(<SchemaView
formType='dialog'
schema={catalogSchemaObj}
viewHelperProps={{
mode: 'create',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('catalog properties', ()=>{
let catalogPropertiesSchemaObj = new TriggerSchema(
{
triggerFunction: [],
columns: [],
nodeInfo: {
catalog: {},
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
table: {is_partitioned: false}
}
}
);
mount(<SchemaView
formType='tab'
schema={catalogPropertiesSchemaObj}
getInitData={getInitData}
viewHelperProps={{
mode: 'properties',
}}
onHelp={()=>{}}
onEdit={()=>{}}
/>);
});
it('edit disableTransition', ()=>{
let editSchemaObj = new TriggerSchema(
{
triggerFunction: [],
columns: [],
nodeInfo: {
catalog: {},
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 100000},
table: {is_partitioned: false}
}
}
);
let initData = ()=>Promise.resolve({
tgoldtable: 'tgoldtable',
evnt_insert: true,
evnt_update: true,
evnt_delete: true,
is_constraint_trigger: true,
name: 'tgoldtable',
fires: 'AFTER'
});
mount(<SchemaView
formType='dialog'
schema={editSchemaObj}
getInitData={initData}
viewHelperProps={{
mode: 'edit',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('edit disableTransition tgnewtable', ()=>{
let editSchemaObj = new TriggerSchema(
{
triggerFunction: [],
columns: [],
nodeInfo: {
catalog: {},
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 100000},
table: {is_partitioned: false}
}
}
);
let initData = ()=>Promise.resolve({
tgoldtable: 'tgnewtable',
evnt_insert: true,
evnt_update: true,
evnt_delete: true,
is_constraint_trigger: false,
name: 'tgnewtable',
fires: 'AFTER'
});
mount(<SchemaView
formType='dialog'
schema={editSchemaObj}
getInitData={initData}
viewHelperProps={{
mode: 'edit',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
});
describe('TriggerEventsSchema', ()=>{
let mount;
let schemaObj = new EventSchema(
{
nodeInfo: {
server: {user: {name:'postgres', id:0}, server_type: 'pg', version: 90400},
table: {is_partitioned: false}
}
}
);
let getInitData = ()=>Promise.resolve({});
/* Use createMount so that material ui components gets the required context */
/* https://material-ui.com/guides/testing/#api */
beforeAll(()=>{
mount = createMount();
});
afterAll(() => {
mount.cleanUp();
});
beforeEach(()=>{
jasmineEnzyme();
/* messages used by validators */
pgAdmin.Browser = pgAdmin.Browser || {};
pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages;
pgAdmin.Browser.utils = pgAdmin.Browser.utils || {};
});
it('create', ()=>{
mount(<SchemaView
formType='dialog'
schema={schemaObj}
viewHelperProps={{
mode: 'create',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('properties', ()=>{
mount(<SchemaView
formType='tab'
schema={schemaObj}
getInitData={getInitData}
viewHelperProps={{
mode: 'properties',
}}
onHelp={()=>{}}
onEdit={()=>{}}
/>);
});
it('edit', ()=>{
mount(<SchemaView
formType='dialog'
schema={schemaObj}
getInitData={getInitData}
viewHelperProps={{
mode: 'edit',
}}
onSave={()=>{}}
onClose={()=>{}}
onHelp={()=>{}}
onEdit={()=>{}}
onDataChange={()=>{}}
confirmOnCloseReset={false}
hasSQL={false}
disableSqlHelp={false}
/>);
});
it('validate', ()=>{
let state = {};
let setError = jasmine.createSpy('setError');
state.tfunction = 'public';
state.evnt_truncate = false;
state.evnt_delete = false;
state.evnt_update = false;
state.evnt_insert = false;
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('evnt_insert', 'Specify at least one event.');
state.tfunction = 'public';
state.evnt_insert = true;
schemaObj.validate(state, setError);
expect(setError).toHaveBeenCalledWith('evnt_insert', null);
});
//spyOn(schemaObj, 'isNew).and.returnValue(true);
/*it('evnt_insert disabled', ()=>{
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_insert').disabled;
disabled({evnt_insert : true});
});
it('evnt_update disabled', ()=>{
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_update').disabled;
disabled({evnt_update : true});
});
it('evnt_delete disabled', ()=>{
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_delete').disabled;
disabled({evnt_delete : true});
});
it('evnt_truncate disabled', ()=>{
getInitData = ()=>Promise.resolve({is_constraint_trigger: true});
let disabled = _.find(schemaObj.fields, (f)=>f.id=='evnt_truncate').disabled;
disabled({evnt_truncate : true});
});*/
});