diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js index 536dc9472..9ceeb6b76 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.js @@ -7,14 +7,20 @@ // ////////////////////////////////////////////////////////////// +import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../../../../../static/js/node_ajax'; +import FunctionSchema from './function.ui'; +import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui'; +import { getNodeVariableSchema } from '../../../../../static/js/variable.ui'; +import _ from 'lodash'; + /* Create and Register Function Collection and Node. */ define('pgadmin.node.function', [ - 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone', + 'sources/gettext', 'sources/url_for', 'jquery', 'backbone', 'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node', 'pgadmin.browser.collection', 'pgadmin.browser.server.privilege', ], function( - gettext, url_for, $, _, Backbone, pgAdmin, pgBrowser, Backform, schemaChild, + gettext, url_for, $, Backbone, pgAdmin, pgBrowser, Backform, schemaChild, schemaChildTreeNode ) { @@ -30,69 +36,6 @@ define('pgadmin.node.function', [ canDropCascade: schemaChildTreeNode.isTreeItemOfChildOfSchema, }); } - - // Argument Model - var ArgumentModel = pgBrowser.Node.Model.extend({ - idAttribute: 'argid', - defaults: { - argid: undefined, - argtype: undefined, - argmode: undefined, - argname: undefined, - argdefval: undefined, - }, - schema: [{ - id: 'argid', visible: false, type: 'text', - mode: ['properties', 'edit','create'], - },{ - id: 'argtype', label: gettext('Data type'), cell: - 'node-ajax-options', cellHeaderClasses: 'width_percent_30', - control: 'node-ajax-options', type: 'text', url: 'get_types', - editable: 'isEditable', first_empty: true, - },{ - id: 'argmode', label: gettext('Mode'), type: 'options', - control: 'node-ajax-options', cellHeaderClasses:'width_percent_20', - cell: 'node-ajax-options', select2: { - allowClear: false, - }, - options:[ - {'label': 'IN', 'value': 'IN'}, - {'label': 'OUT', 'value': 'OUT'}, - {'label': 'INOUT', 'value': 'INOUT'}, - {'label': 'VARIADIC', 'value': 'VARIADIC'}, - ], editable: 'isEditable', - },{ - id: 'argname', label: gettext('Argument name'), type: 'text', - cell: 'string', editable: 'isInCatalog', cellHeaderClasses:'width_percent_30', - },{ - id: 'argdefval', label: gettext('Default'), type: 'text', - cell: 'string', editable: 'isInCatalog', cellHeaderClasses:'width_percent_20', - }, - ], - toJSON: Backbone.Model.prototype.toJSON, - isEditable: function(m) { - var node_info = this.get('node_info'); - if(node_info && 'catalog' in node_info) { - return false; - } - return _.isUndefined(m.isNew) ? true : m.isNew(); - }, - isInCatalog: function(m){ - var node_info = this.get('node_info'); - if(node_info && 'catalog' in node_info) { - return false; - } - // Below will disable default value cell if argument mode is 'INOUT' or 'OUT' as - // user cannot set default value for out parameters. - if(!_.isUndefined(m.get('argmode')) && !_.isUndefined(this.get('name')) && - this.get('name') == 'argdefval' && - (m.get('argmode') == 'INOUT' || m.get('argmode') == 'OUT')) { - return false; - } - return true; - }, - }); - if (!pgBrowser.Nodes['function']) { pgBrowser.Nodes['function'] = schemaChild.SchemaChildNode.extend({ @@ -138,6 +81,36 @@ define('pgadmin.node.function', [ ]); }, + getSchema: function(treeNodeInfo, itemNodeData) { + return new FunctionSchema( + (privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges), + ()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false), + { + role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData), + schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, { + cacheLevel: 'database' + } + ), + getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData), + getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData), + getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, { + cacheNode: 'function' + }), + + }, + { + node_info: treeNodeInfo, + }, + { + type: pgBrowser.Nodes['function'].type, + }, + { + funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name, + pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null, + lanname: 'sql', + } + ); + }, model: pgBrowser.Node.Model.extend({ idAttribute: 'oid', initialize: function(attrs, args) { @@ -153,40 +126,6 @@ define('pgadmin.node.function', [ } pgBrowser.Node.Model.prototype.initialize.apply(this, arguments); }, - defaults: { - name: undefined, - oid: undefined, - xmin: undefined, - funcowner: undefined, - pronamespace: undefined, - description: undefined, - pronargs: undefined, /* Argument Count */ - proargs: undefined, /* Arguments */ - proargtypenames: undefined, /* Argument Signature */ - prorettypename: undefined, /* Return Type */ - lanname: 'sql', /* Language Name in which function is being written */ - provolatile: undefined, /* Volatility */ - proretset: undefined, /* Return Set */ - proisstrict: undefined, - prosecdef: undefined, /* Security of definer */ - proiswindow: undefined, /* Window Function ? */ - proparallel: undefined, /* Parallel mode */ - procost: undefined, /* Estimated execution Cost */ - prorows: 0, /* Estimated number of rows */ - proleakproof: undefined, - prosupportfunc: undefined, /* Support function */ - arguments: [], - prosrc: undefined, - prosrc_c: undefined, - probin: '$libdir/', - options: [], - variables: [], - proacl: undefined, - seclabels: [], - acl: [], - sysfunc: undefined, - sysproc: undefined, - }, schema: [{ id: 'name', label: gettext('Name'), cell: 'string', type: 'text', mode: ['properties', 'create', 'edit'], @@ -202,270 +141,8 @@ define('pgadmin.node.function', [ id: 'pronamespace', label: gettext('Schema'), cell: 'string', control: 'node-list-by-id', type: 'text', cache_level: 'database', node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit'], - },{ - id: 'sysfunc', label: gettext('System function?'), - cell:'boolean', type: 'switch', - mode: ['properties'], visible: 'isVisible', - },{ - id: 'sysproc', label: gettext('System procedure?'), - cell:'boolean', type: 'switch', - mode: ['properties'], visible: 'isVisible', - },{ - id: 'description', label: gettext('Comment'), cell: 'string', - type: 'multiline', disabled: 'isDisabled', - },{ - id: 'pronargs', label: gettext('Argument count'), cell: 'string', - type: 'text', group: gettext('Definition'), mode: ['properties'], - },{ - id: 'proargs', label: gettext('Arguments'), cell: 'string', - type: 'text', group: gettext('Definition'), mode: ['properties'], - },{ - id: 'proargtypenames', label: gettext('Signature arguments'), cell: - 'string', type: 'text', group: gettext('Definition'), mode: ['properties'], - },{ - id: 'prorettypename', label: gettext('Return type'), cell: 'string', - control: 'node-ajax-options', type: 'text', group: gettext('Definition'), - url: 'get_types', readonly: 'isReadonly', first_empty: true, - mode: ['create'], visible: 'isVisible', - },{ - id: 'prorettypename', label: gettext('Return type'), cell: 'string', - type: 'text', group: gettext('Definition'), - mode: ['properties', 'edit'], readonly: 'isReadonly', visible: 'isVisible', - }, { - id: 'lanname', label: gettext('Language'), cell: 'string', - control: 'node-ajax-options', type: 'text', group: gettext('Definition'), - url: 'get_languages', disabled: 'isDisabled', - },{ - id: 'prosrc', label: gettext('Code'), cell: 'string', - type: 'text', mode: ['properties', 'create', 'edit'], - group: gettext('Code'), deps: ['lanname'], - tabPanelCodeClass: 'sql-code-control', - control: Backform.SqlCodeControl, - extraClasses:['custom_height_css_class'], - visible: function(m) { - if (m.get('lanname') == 'c') { - return false; - } - return true; - }, disabled: 'isDisabled', - },{ - id: 'probin', label: gettext('Object file'), cell: 'string', - type: 'text', group: gettext('Definition'), deps: ['lanname'], visible: - function(m) { - if (m.get('lanname') == 'c') { return true; } - return false; - }, disabled: 'isDisabled', - },{ - id: 'prosrc_c', label: gettext('Link symbol'), cell: 'string', - type: 'text', group: gettext('Definition'), deps: ['lanname'], visible: - function(m) { - if (m.get('lanname') == 'c') { return true; } - return false; - }, disabled: 'isDisabled', - },{ - id: 'provolatile', label: gettext('Volatility'), cell: 'string', - control: 'node-ajax-options', type: 'text', group: gettext('Options'), - deps: ['lanname'], - options:[ - {'label': 'VOLATILE', 'value': 'v'}, - {'label': 'STABLE', 'value': 's'}, - {'label': 'IMMUTABLE', 'value': 'i'}, - ], disabled: 'isDisabled', select2: {allowClear: false}, - },{ - id: 'proretset', label: gettext('Returns a set?'), type: 'switch', - disabled: 'isDisabled', group: gettext('Options'), - visible: 'isVisible', - },{ - id: 'proisstrict', label: gettext('Strict?'), type: 'switch', - group: gettext('Options'), disabled: 'isDisabled', - deps: ['lanname'], - },{ - id: 'prosecdef', label: gettext('Security of definer?'), - group: gettext('Options'), type: 'switch', - disabled: 'isDisabled', - },{ - id: 'proiswindow', label: gettext('Window?'), - group: gettext('Options'), cell:'boolean', type: 'switch', - disabled: 'isDisabled', visible: 'isVisible', - },{ - id: 'proparallel', label: gettext('Parallel'), cell: 'string', - control: 'node-ajax-options', type: 'text', group: gettext('Options'), - deps: ['lanname'], - options:[ - {'label': 'UNSAFE', 'value': 'u'}, - {'label': 'RESTRICTED', 'value': 'r'}, - {'label': 'SAFE', 'value': 's'}, - ], disabled: 'isDisabled', min_version: 90600, - select2: {allowClear: false}, - },{ - id: 'procost', label: gettext('Estimated cost'), group: gettext('Options'), - cell:'string', type: 'text', readonly: 'isReadonly', deps: ['lanname'], disabled: 'isDisabled', - },{ - id: 'prorows', label: gettext('Estimated rows'), type: 'text', - deps: ['proretset'], visible: 'isVisible', readonly: 'isReadonly', - group: gettext('Options'),disabled: 'isDisabled', - },{ - id: 'proleakproof', label: gettext('Leak proof?'), - group: gettext('Options'), cell:'boolean', type: 'switch', min_version: 90200, - disabled: 'isDisabled', deps: ['lanname'], - },{ - id: 'prosupportfunc', label: gettext('Support function'), - type: 'text', disabled: 'isDisabled', - group: gettext('Options'), visible: 'isVisible', - control: 'node-ajax-options', url: 'get_support_functions', - cache_node: 'function', min_version: 120000, - },{ - id: 'proacl', label: gettext('Privileges'), type: 'text', - mode: ['properties'], group: gettext('Security'), - },{ - id: 'arguments', label: gettext('Arguments'), cell: 'string', - group: gettext('Definition'), type: 'collection', canAdd: function(m){ - return m.isNew(); - }, - canDelete: true, model: ArgumentModel, mode: ['create', 'edit'], - columns: ['argtype', 'argmode', 'argname', 'argdefval'], - disabled: 'isDisabled', canDeleteRow: function(m) { - return m.isNew(); - }, - },{ - id: 'variables', label: '', type: 'collection', - group: gettext('Parameters'), control: 'variable-collection', - model: pgBrowser.Node.VariableModel, - mode: ['edit', 'create'], canAdd: 'canVarAdd', canEdit: false, - canDelete: true, disabled: 'isDisabled', - }, pgBrowser.SecurityGroupSchema, { - id: 'acl', label: gettext('Privileges'), editable: false, - model: pgBrowser.Node.PrivilegeRoleModel.extend({ - privileges: ['X'], - }), uniqueCol : ['grantee', 'grantor'], type: 'collection', - group: 'security', mode: ['edit', 'create'], canAdd: true, - canDelete: true, control: 'unique-col-collection', - disabled: 'isDisabled', - },{ - id: 'seclabels', label: gettext('Security labels'), canAdd: true, - model: pgBrowser.SecLabelModel, type: 'collection', - min_version: 90100, group: 'security', mode: ['edit', 'create'], - canEdit: false, canDelete: true, uniqueCol : ['provider'], - disabled: 'isDisabled', control: 'unique-col-collection', - visible: function() { - return this.node && this.node.type != 'procedure'; - }, }, ], - validate: function() - { - var err = {}, - errmsg, - seclabels = this.get('seclabels'); - - if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') { - err['name'] = gettext('Name cannot be empty.'); - errmsg = err['name']; - } - - if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') { - err['funcowner'] = gettext('Owner cannot be empty.'); - errmsg = errmsg || err['funcowner']; - } - - if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') { - err['pronamespace'] = gettext('Schema cannot be empty.'); - errmsg = errmsg || err['pronamespace']; - } - - if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') { - err['prorettypename'] = gettext('Return type cannot be empty.'); - errmsg = errmsg || err['prorettypename']; - } - - if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') { - err['lanname'] = gettext('Language cannot be empty.'); - errmsg = errmsg || err['lanname']; - } - - if (String(this.get('lanname')) == 'c') { - if (_.isUndefined(this.get('probin')) || String(this.get('probin')) - .replace(/^\s+|\s+$/g, '') == '') { - err['probin'] = gettext('Object File cannot be empty.'); - errmsg = errmsg || err['probin']; - } - - if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') { - err['prosrc_c'] = gettext('Link Symbol cannot be empty.'); - errmsg = errmsg || err['prosrc_c']; - } - } - else { - if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') { - err['prosrc'] = gettext('Code cannot be empty.'); - errmsg = errmsg || err['prosrc']; - } - } - - if (seclabels) { - var secLabelsErr; - for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) { - secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]); - if (secLabelsErr) { - err['seclabels'] = secLabelsErr; - errmsg = errmsg || secLabelsErr; - } - } - } - - this.errorModel.clear().set(err); - - if (_.size(err)) { - this.trigger('on-status', {msg: errmsg}); - return errmsg; - } - - return null; - }, - isVisible: function() { - if (this.name == 'sysproc') { return false; } - return true; - }, - isDisabled: function(m) { - //Disable the returns a set and window in edit mode. - if((this.name == 'proretset' || this.name == 'proiswindow') && !m.isNew()){ - return true; - } - if(this.node_info && 'catalog' in this.node_info) { - return true; - } - if(this.name === 'prosupportfunc'){ - var item = pgAdmin.Browser.tree.selected(); - if(pgAdmin.Browser.Nodes['function'].getTreeNodeHierarchy(item).server.user.is_superuser) - return false; - return true; - } else { - return false; - } - }, - isReadonly: function(m) { - switch(this.name){ - case 'proargs': - case 'proargtypenames': - case 'proretset': - case 'proiswindow': - case 'prorettypename': - return !m.isNew(); - case 'prorows': - if(m.get('proretset') == true) { - return false; - } - return true; - default: - return false; - } - }, - canVarAdd: function() { - if(this.node_info && 'catalog' in this.node_info) { - return false; - } - return true; - }, }), }); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js new file mode 100644 index 000000000..ac29accb9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js @@ -0,0 +1,470 @@ +///////////////////////////////////////////////////////////// +// +// 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 SecLabelSchema from '../../../../../static/js/sec_label.ui'; +import { isEmptyString } from 'sources/validators'; +import _ from 'lodash'; + +export class DefaultArgumentSchema extends BaseUISchema { + constructor(node_info, getTypes) { + super(); + this.node_info = node_info; + this.getTypes = getTypes; + this.type_options = {}; + } + setTypeOptions(options) { + options.forEach((option)=>{ + this.type_options[option.value] = { + ...option, + }; + }); + } + + get baseFields() { + return[{ + id: 'argid', visible: false, type: 'text', + mode: ['properties', 'edit','create'], + },{ + id: 'argtype', label: gettext('Data type'), + options: this.getTypes, + type: 'text', + cell: ()=>({ + cell: 'select', options: this.getTypes, + optionsLoaded: (options)=>{this.setTypeOptions(options);}, + controlProps: { + allowClear: false, + } + }), + editable: this.isEditable, first_empty: true, + },{ + id: 'argmode', label: gettext('Mode'), + type: 'text', + cell: ()=>({ + cell: 'select', + options:[ + {'label': 'IN', 'value': 'IN'}, + {'label': 'OUT', 'value': 'OUT'}, + {'label': 'INOUT', 'value': 'INOUT'}, + {'label': 'VARIADIC', 'value': 'VARIADIC'}, + ], + optionsLoaded: (options)=>{this.setTypeOptions(options);}, + controlProps: { + allowClear: false, + } + }), + editable: this.isEditable, + },{ + id: 'argname', label: gettext('Argument name'), type: 'text', + editable: this.isInCatalog, cell: ()=>({cell: 'text'}) + },{ + id: 'argdefval', label: gettext('Default'), type: 'text', + cell: ()=>({cell: 'text'}), editable: this.isInCatalog, + }]; + } + + isEditable() { + var node_info = this.node_info; + if(node_info && 'catalog' in node_info) { + return false; + } + return _.isUndefined(this.isNew) ? true : this.isNew(); + } + isInCatalog(state){ + var node_info = this.node_info; + if(node_info && 'catalog' in node_info) { + return false; + } + // Below will disable default value cell if argument mode is 'INOUT' or 'OUT' as + // user cannot set default value for out parameters. + if(!_.isUndefined(state.argmode) && !_.isUndefined(state.name) && + state.name == 'argdefval' && + (state.argmode == 'INOUT' || state.argmode == 'OUT')) { + return false; + } + return true; + } +} + +export default class FunctionSchema extends BaseUISchema { + constructor(getPrivilegeRoleSchema, getNodeVariableSchema, fieldOptions={}, node_info, type, initValues) { + super({ + name: undefined, + oid: undefined, + xmin: undefined, + funcowner: undefined, + pronamespace: undefined, + description: undefined, + pronargs: undefined, /* Argument Count */ + proargs: undefined, /* Arguments */ + proargtypenames: undefined, /* Argument Signature */ + prorettypename: undefined, /* Return Type */ + lanname: undefined, /* Language Name in which function is being written */ + provolatile: undefined, /* Volatility */ + proretset: undefined, /* Return Set */ + proisstrict: undefined, + prosecdef: undefined, /* Security of definer */ + proiswindow: undefined, /* Window Function ? */ + proparallel: undefined, /* Parallel mode */ + procost: undefined, /* Estimated execution Cost */ + prorows: 0, /* Estimated number of rows */ + proleakproof: undefined, + prosupportfunc: undefined, /* Support function */ + arguments: [], + prosrc: undefined, + prosrc_c: undefined, + probin: '$libdir/', + options: [], + variables: [], + proacl: undefined, + seclabels: [], + acl: [], + sysfunc: undefined, + sysproc: undefined, + ...initValues + }); + + this.getPrivilegeRoleSchema = getPrivilegeRoleSchema; + this.getNodeVariableSchema = getNodeVariableSchema; + this.node_info = node_info; + this.type = type.type; + this.fieldOptions = { + role: [], + schema: [], + getTypes: [], + ...fieldOptions, + }; + } + + get idAttribute() { + return 'oid'; + } + + isVisible(state) { + if(!(this.type === 'procedure')){ + if (state.sysproc) { return false; } + return true; + }else{ + if (state.sysfunc) { + return false; + } else if (state.sysproc) { + return true; + } + + return false; + } + } + isDisabled() { + if (this.node_info && 'catalog' in this.node_info) { + return true; + } + } + isGreaterThan95(state){ + if ( + this.node_info['node_info'].server.version < 90500 || + this.node_info['node_info']['server'].server_type != 'ppas' || + state.lanname != 'edbspl' + ) { + state.provolatile = null; + state.proisstrict = false; + state.procost = null; + state.proleakproof = false; + return true; + } else { + return false; + } + } + + isGreaterThan96(state){ + if ( + this.node_info['node_info'].server.version < 90600 || + this.node_info['node_info']['server'].server_type != 'ppas' || + state.lanname != 'edbspl' + ) { + state.proparallel = null; + return true; + } else { + return false; + } + } + + isProcedure(state) { + + if (this.node_info && 'catalog' in this.node_info) { + return true; + } + + if (state.prorows) { + var server = this.node_info['node_info']['server']; + return !(server.version >= 90500 && state.proretset == true); + } + } + + isReadonly() { + return !this.isNew(); + } + + canVarAdd(){ + if(this.node_info && 'catalog' in this.node_info) { + return false; + } + return true; + } + + get baseFields() { + let obj = this; + return [{ + id: 'name', label: gettext('Name'), cell: 'string', + type: 'text', mode: ['properties', 'create', 'edit'], + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + noEmpty: true, + },{ + id: 'oid', label: gettext('OID'), cell: 'string', + type: 'text' , mode: ['properties'], + },{ + id: 'funcowner', label: gettext('Owner'), cell: 'string', + options: this.fieldOptions.role, type: 'select', + disabled: (!(this.type === 'procedure')) ? obj.isDisabled : obj.isGreaterThan95, + noEmpty: true, + },{ + id: 'pronamespace', label: gettext('Schema'), cell: 'string', + type: 'select', disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + mode: ['create', 'edit'], + controlProps: { + allowClear: false, + first_empty: false, + }, + options: obj.fieldOptions.schema, noEmpty: true, + },{ + id: 'sysfunc', label: gettext('System function?'), + cell:'boolean', type: 'switch', + mode: ['properties'], visible: obj.isVisible, + },{ + id: 'sysproc', label: gettext('System procedure?'), + cell:'boolean', type: 'switch', + mode: ['properties'], visible: obj.isVisible, + },{ + id: 'description', label: gettext('Comment'), cell: 'string', + type: 'multiline', disabled: obj.isDisabled, + },{ + id: 'pronargs', label: gettext('Argument count'), cell: 'string', + type: 'text', group: gettext('Definition'), mode: ['properties'], + },{ + id: 'proargs', label: gettext('Arguments'), cell: 'string', + type: 'text', group: gettext('Definition'), mode: ['properties'], + },{ + id: 'proargtypenames', label: gettext('Signature arguments'), cell: + 'string', type: 'text', group: gettext('Definition'), mode: ['properties'], + },{ + id: 'prorettypename', label: gettext('Return type'), cell: 'string', + type: 'select', group: gettext('Definition'), + options: this.fieldOptions.getTypes, + readonly: obj.isReadonly, first_empty: true, + mode: ['create'], visible: obj.isVisible, + },{ + id: 'prorettypename', label: gettext('Return type'), cell: 'string', + type: 'text', group: gettext('Definition'), + mode: ['properties', 'edit'], readonly: obj.isReadonly, visible: obj.isVisible, + },{ + id: 'lanname', label: gettext('Language'), cell: 'string', + options: this.fieldOptions.getLanguage, type: 'select', group: gettext('Definition'), + disabled: function() { + if (this.node_info && 'catalog' in this.node_info) { + return true; + } + + return this.node_info['node_info'].server.version < 110000; + } + }, + { + id: 'probin', label: gettext('Object file'), cell: 'string', + type: 'text', group: gettext('Definition'), deps: ['lanname'], visible: + function(state) { + if (state.lanname == 'c') { return true; } + return false; + }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + },{ + id: 'prosrc_c', label: gettext('Link symbol'), cell: 'string', + type: 'text', group: gettext('Definition'), deps: ['lanname'], visible: + function(state) { + if (state.lanname == 'c') { return true; } + return false; + }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + }, + { + id: 'arguments', label: gettext('Arguments'), cell: 'string', + group: gettext('Definition'), type: 'collection', canAdd: function(){ + return obj.isNew(); + }, + canDelete: true, mode: ['create', 'edit'], + columns: ['argtype', 'argmode', 'argname', 'argdefval'], + schema : new DefaultArgumentSchema(this.node_info, this.fieldOptions.getTypes), + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + canDeleteRow: function() { + return obj.isNew(); + }, + },{ + id: 'prosrc', label: gettext('Code'), cell: 'text', + type: 'sql', mode: ['properties', 'create', 'edit'], + group: gettext('Code'), deps: ['lanname'], + isFullTab: true, + visible: function(state) { + if (state.lanname === 'c') { + return false; + } + return true; + }, disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + },{ + id: 'provolatile', label: gettext('Volatility'), cell: 'text', + type: 'select', group: gettext('Options'), + deps: ['lanname'], + options:[ + {'label': 'VOLATILE', 'value': 'v'}, + {'label': 'STABLE', 'value': 's'}, + {'label': 'IMMUTABLE', 'value': 'i'}, + ], disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + controlProps: {allowClear: false}, + },{ + id: 'proretset', label: gettext('Returns a set?'), type: 'switch', + disabled: ()=>{return !obj.isNew();}, group: gettext('Options'), + visible: obj.isVisible, readonly: obj.isReadonly, + },{ + id: 'proisstrict', label: gettext('Strict?'), type: 'switch', + group: gettext('Options'), disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95, + deps: ['lanname'], + },{ + id: 'prosecdef', label: gettext('Security of definer?'), + group: gettext('Options'), type: 'switch', + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: ()=>{ + return obj.node_info['node_info'].server.version < 90500; + }, + },{ + id: 'proiswindow', label: gettext('Window?'), + group: gettext('Options'), cell:'boolean', type: 'switch', + disabled: ()=>{return !obj.isNew();}, visible: obj.isVisible, readonly: obj.isReadonly, + },{ + id: 'proparallel', label: gettext('Parallel'), cell: 'string', + type: 'select', group: gettext('Options'), + deps: ['lanname'], + options:[ + {'label': 'UNSAFE', 'value': 'u'}, + {'label': 'RESTRICTED', 'value': 'r'}, + {'label': 'SAFE', 'value': 's'}, + ], + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan96, + min_version: 90600, + controlProps: {allowClear: false}, + },{ + id: 'procost', label: gettext('Estimated cost'), group: gettext('Options'), + cell:'string', type: 'text', deps: ['lanname'], + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95, + },{ + id: 'prorows', label: gettext('Estimated rows'), type: 'text', + deps: ['proretset'], visible: obj.isVisible, + readonly: (state) => { + let isReadonly = true; + if(state.proretset == true) { + isReadonly = false; + } + return isReadonly; + }, + group: gettext('Options'), + },{ + id: 'proleakproof', label: gettext('Leak proof?'), + group: gettext('Options'), cell:'boolean', type: 'switch', min_version: 90200, + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isGreaterThan95, + deps: ['lanname'], + },{ + id: 'prosupportfunc', label: gettext('Support function'), + type: 'select', + disabled: ()=>{ + if (obj.node_info && 'catalog' in obj.node_info) { + return true; + } + + if (obj.node_info['node_info'].server.user.is_superuser) + return false; + return true; + }, + group: gettext('Options'), visible: obj.isVisible, + options: this.fieldOptions.getSupportFunctions, min_version: 120000, + },{ + id: 'proacl', label: gettext('Privileges'), type: 'text', + mode: ['properties'], group: gettext('Security'), + }, + { + id: 'variables', label: '', type: 'collection', + group: gettext('Parameters'), + schema: this.getNodeVariableSchema(), + mode: ['edit', 'create'], canAdd: obj.canVarAdd, canEdit: false, + canDelete: true, + }, + { + id: 'acl', label: gettext('Privileges'), editable: false, + schema: this.getPrivilegeRoleSchema(['X']), + uniqueCol : ['grantee', 'grantor'], type: 'collection', + group: 'Security', mode: ['edit', 'create'], canAdd: true, + canDelete: true, + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + },{ + id: 'seclabels', label: gettext('Security labels'), canAdd: true, + schema: new SecLabelSchema(), type: 'collection', + min_version: 90100, group: 'Security', mode: ['edit', 'create'], + canEdit: false, canDelete: true, uniqueCol : ['provider'], + disabled: (!(this.type === 'procedure')) ? obj.isDisabled: obj.isProcedure, + visible: function() { + return this.node_info && !(this.type === 'procedure'); + }, + }, + ]; + } + validate(state, setError) { + let errmsg = null; + if (!(this.type === 'procedure') &&(isEmptyString(state.prorettypename))) { + errmsg = gettext('Return type cannot be empty.'); + setError('prorettypename', errmsg); + return true; + } else { + errmsg = null; + setError('prorettypename', errmsg); + } + + if ((String(state.lanname) == 'c')) { + if (isEmptyString(state.probin)){ + errmsg = gettext('Object File cannot be empty.'); + setError('probin', errmsg); + return true; + }else { + errmsg = null; + setError('probin', errmsg); + } + + if (isEmptyString(state.prosrc_c)) { + errmsg = gettext('Link Symbol cannot be empty.'); + setError('prosrc_c', errmsg); + return true; + }else { + errmsg = null; + setError('prosrc_c', errmsg); + } + + }else { + /* code validation*/ + if (isEmptyString(state.prosrc)) { + errmsg = gettext('Code cannot be empty.'); + setError('prosrc', errmsg); + return true; + } else { + errmsg = null; + setError('prosrc', errmsg); + } + } + } +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js index 850e5386b..ad9d9a46f 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js @@ -7,14 +7,20 @@ // ////////////////////////////////////////////////////////////// +import { getNodeAjaxOptions, getNodeListByName, getNodeListById} from '../../../../../../../static/js/node_ajax'; +import FunctionSchema from './function.ui'; +import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.ui'; +import { getNodeVariableSchema } from '../../../../../static/js/variable.ui'; +import _ from 'lodash'; + /* Create and Register Procedure Collection and Node. */ define('pgadmin.node.procedure', [ - 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', + 'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.node.function', 'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node', 'pgadmin.browser.collection', 'pgadmin.browser.server.privilege', -], function(gettext, url_for, $, _, pgAdmin, pgBrowser, alertify, Function, +], function(gettext, url_for, $, pgAdmin, pgBrowser, alertify, Function, schemaChild, schemaChildTreeNode) { if (!pgBrowser.Nodes['coll-procedure']) { @@ -89,6 +95,37 @@ define('pgadmin.node.procedure', [ ) ); }, + getSchema: function(treeNodeInfo, itemNodeData) { + return new FunctionSchema( + (privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges), + ()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false), + { + role: ()=>getNodeListByName('role', treeNodeInfo, itemNodeData), + schema: ()=>getNodeListById(pgBrowser.Nodes['schema'], treeNodeInfo, itemNodeData, { + cacheLevel: 'database' + } + ), + getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData), + getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData), + getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, { + cacheNode: 'function' + }), + + }, + { + node_info: treeNodeInfo, + }, + { + type: pgBrowser.Nodes['procedure'].type, + }, + { + funcowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name, + pronamespace: treeNodeInfo.schema ? treeNodeInfo.schema._id : null, + lanname: 'edbspl', + } + ); + }, + model: Function.model.extend({ defaults: _.extend({}, Function.model.prototype.defaults, diff --git a/web/regression/javascript/schema_ui_files/cast.ui.spec.js b/web/regression/javascript/schema_ui_files/cast.ui.spec.js index 516d9ca4d..7b94fe5f3 100644 --- a/web/regression/javascript/schema_ui_files/cast.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/cast.ui.spec.js @@ -70,7 +70,7 @@ describe('CastSchema', ()=>{ schema={schemaObj} getInitData={getInitData} viewHelperProps={{ - mode: 'create', + mode: 'edit', }} onSave={()=>{}} onClose={()=>{}} @@ -99,12 +99,14 @@ describe('CastSchema', ()=>{ it('srctyp depChange', ()=>{ let depChange = _.find(schemaObj.fields, (f)=>f.id=='srctyp').depChange; - depChange({srctyp: 'abc', trgtyp: 'abc'}); + let status = depChange({srctyp: 'abc', trgtyp: 'abc'}); + expect(status).toEqual('abc->abc'); }); it('trgtyp depChange', ()=>{ let depChange = _.find(schemaObj.fields, (f)=>f.id=='trgtyp').depChange; - depChange({srctyp: 'abc', trgtyp: 'abc'}); + let status = depChange({srctyp: 'abc', trgtyp: 'abc'}); + expect(status).toEqual('abc->abc'); }); it('validate', ()=>{ diff --git a/web/regression/javascript/schema_ui_files/functions.ui.spec.js b/web/regression/javascript/schema_ui_files/functions.ui.spec.js new file mode 100644 index 000000000..e9f78663e --- /dev/null +++ b/web/regression/javascript/schema_ui_files/functions.ui.spec.js @@ -0,0 +1,610 @@ +///////////////////////////////////////////////////////////// +// +// 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 FunctionSchema from '../../../pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui'; + +class MockSchema extends BaseUISchema { + get baseFields() { + return []; + } +} + +describe('FunctionSchema', ()=>{ + let mount; + //Procedure schema + let procedureSchemaObj = new FunctionSchema( + ()=>new MockSchema(), + ()=>new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + connected: true, + user: {id: 10, name: 'postgres', is_superuser: true, can_create_role: true, can_create_db: true}, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + } }, + }, + { + type: 'procedure', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + + let schemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + connected: true, + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'function', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + 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({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + }); + + it('create', ()=>{ + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + }); + + it('edit', ()=>{ + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + }); + + it('properties', ()=>{ + mount({}} + onEdit={()=>{}} + />); + }); + + it('proiswindow visible', ()=>{ + + + let editSchemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + catalog: {}, + connected: true, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'function', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + let initData = ()=>Promise.resolve({ + sysfunc: true, + type: 'function', + }); + + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + + }); + + it('proiswindow visible', ()=>{ + + + let editSchemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + catalog: {}, + connected: true, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'function', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + let initData = ()=>Promise.resolve({ + sysproc: true, + type: 'function', + }); + + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + + }); + + it('proiswindow visible', ()=>{ + + + let editSchemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + connected: true, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'procedure', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + let initData = ()=>Promise.resolve({ + sysfunc: true, + type: 'procedure', + }); + + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + }); + + it('proiswindow visible', ()=>{ + + + let editSchemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + connected: true, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'procedure', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + let initData = ()=>Promise.resolve({ + sysproc: true, + type: 'procedure', + }); + + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + }); + + it('pronamespace disabled', ()=>{ + + + let editSchemaObj = new FunctionSchema( + () => new MockSchema(), + () => new MockSchema(), + { + role: [], + schema: [], + getLanguage: [], + getTypes: [], + getSupportFunctions: [], + }, + { + node_info: { + catalog: {}, + connected: true, + user_id: 1, + user_name: 'postgres', + version: 130005, + server: { + host: '127.0.0.1', + port: 5432, + server_type: 'postgres', + user: { + id: 10, + name: 'postgres', + is_superuser: true, + can_create_role: true, + can_create_db: true, + }, + }, + }, + }, + { + type: 'procedure', + }, + { + funcowner: 'postgres', + pronamespace: 'public', + } + ); + + let initData = ()=>Promise.resolve({ + sysfunc: true, + type: 'procedure', + }); + + mount({}} + onClose={()=>{}} + onHelp={()=>{}} + onEdit={()=>{}} + onDataChange={()=>{}} + confirmOnCloseReset={false} + hasSQL={false} + disableSqlHelp={false} + />); + + }); + + it('probin visible', ()=>{ + let editable = _.find(schemaObj.fields, (f)=>f.id=='probin').visible; + let status = editable({lanname: 'c'}); + expect(status).toBe(true); + }); + + it('prosrc_c visible', ()=>{ + let visibleData = _.find(schemaObj.fields, (f)=>f.id=='prosrc_c').visible; + let status = visibleData({lanname: 'c'}); + expect(status).toBe(true); + }); + + it('prosrc visible', ()=>{ + let visibleData = _.find(schemaObj.fields, (f)=>f.id=='prosrc').visible; + let status = visibleData({lanname: 'c'}); + expect(status).toBe(false); + }); + + it('prorows readonly', ()=>{ + let readOnly = _.find(schemaObj.fields, (f)=>f.id=='prorows').readonly; + let status = readOnly({proretset: true}); + expect(status).toBe(false); + }); + + it('prorettypename validate', () => { + let state = {lanname: 'c', prorettypename: null}; + let setError = jasmine.createSpy('setError'); + + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('prorettypename', 'Return type cannot be empty.'); + }); + + it('probin validate', () => { + let state = { lanname: 'c', prorettypename: 'char' }; + let setError = jasmine.createSpy('setError'); + + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('probin', 'Object File cannot be empty.'); + }); + + it('probin validate', () => { + let state = { lanname: 'c', probin: 'test1', prorettypename: 'char'}; + let setError = jasmine.createSpy('setError'); + + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('probin', null); + }); + + it('prosrc_c validate', () => { + let state = { lanname: 'c', probin : '$libdir/', prorettypename: 'char'}; + let setError = jasmine.createSpy('setError'); + + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('prosrc_c', 'Link Symbol cannot be empty.'); + }); + + it('prosrc_c validate', () => { + let state = { lanname: 'c', probin : '$libdir/', prosrc_c: 'test1', prorettypename: 'char'}; + let setError = jasmine.createSpy('setError'); + + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('prosrc_c', null); + }); + + it('validate', ()=>{ + let state = {prorettypename: 'char'}; + let setError = jasmine.createSpy('setError'); + state.prosrc = null; + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('prosrc', 'Code cannot be empty.'); + + state.prosrc = 'SELECT 1'; + schemaObj.validate(state, setError); + expect(setError).toHaveBeenCalledWith('prosrc', null); + }); + +}); + diff --git a/web/regression/javascript/schema_ui_files/language.ui.spec.js b/web/regression/javascript/schema_ui_files/language.ui.spec.js index 8ad431097..026ea7f72 100644 --- a/web/regression/javascript/schema_ui_files/language.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/language.ui.spec.js @@ -85,7 +85,7 @@ describe('LanguageSchema', ()=>{ schema={schemaObj} getInitData={getInitData} viewHelperProps={{ - mode: 'create', + mode: 'edit', }} onSave={()=>{}} onClose={()=>{}} diff --git a/web/regression/javascript/schema_ui_files/publication.ui.spec.js b/web/regression/javascript/schema_ui_files/publication.ui.spec.js index 2471268a6..2bb31cf36 100644 --- a/web/regression/javascript/schema_ui_files/publication.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/publication.ui.spec.js @@ -109,12 +109,14 @@ describe('PublicationSchema', ()=>{ it('pubtable disabled', ()=>{ let disabled = _.find(schemaObj.fields, (f)=>f.id=='pubtable').disabled; - disabled({all_table: true}); + let status = disabled({all_table: true}); + expect(status).toBe(true); }); it('only_table readonly', ()=>{ let readonly = _.find(schemaObj.fields, (f)=>f.id=='only_table').readonly; - readonly({all_table: true}); + let status = readonly({all_table: true}); + expect(status).toBe(true); }); }); diff --git a/web/regression/javascript/schema_ui_files/subscription.ui.spec.js b/web/regression/javascript/schema_ui_files/subscription.ui.spec.js index d84d130a7..5d04b5b4c 100644 --- a/web/regression/javascript/schema_ui_files/subscription.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/subscription.ui.spec.js @@ -81,7 +81,7 @@ describe('SubscriptionSchema', ()=>{ schema={schemaObj} getInitData={getInitData} viewHelperProps={{ - mode: 'create', + mode: 'edit', }} onSave={()=>{}} onClose={()=>{}} @@ -110,12 +110,14 @@ describe('SubscriptionSchema', ()=>{ it('copy_data_after_refresh readonly', ()=>{ let isReadonly = _.find(schemaObj.fields, (f)=>f.id=='copy_data_after_refresh').readonly; - isReadonly({host: '127.0.0.1', port : 5432}); + let status = isReadonly({host: '127.0.0.1', port : 5432}); + expect(status).toBe(true); }); it('copy_data_after_refresh readonly', ()=>{ let isReadonly = _.find(schemaObj.fields, (f)=>f.id=='copy_data_after_refresh').readonly; - isReadonly({refresh_pub : true}); + let status = isReadonly({refresh_pub : true}); + expect(status).toBe(false); }); it('validate', ()=>{ @@ -159,9 +161,5 @@ describe('SubscriptionSchema', ()=>{ state.tunnel_identity_file = '/file/path/xyz.pem'; expect(schemaObj.validate(state, setError)).toBeFalse(); }); - - - - });