mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-07-31 08:38:30 -05:00
Port browser tree to React. Fixes #6129
This commit is contained in:
committed by
Akshay Joshi
parent
d983225683
commit
483e2ca8d0
@@ -1,363 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import {
|
||||
getTreeNodeHierarchyFromElement,
|
||||
getTreeNodeHierarchyFromIdentifier,
|
||||
} from '../../../pgadmin/static/js/tree/pgadmin_tree_node';
|
||||
import {TreeNode} from '../../../pgadmin/static/js/tree/tree';
|
||||
import {TreeFake} from './tree_fake';
|
||||
|
||||
const context = describe;
|
||||
|
||||
describe('tree#node#getTreeNodeHierarchy', () => {
|
||||
let browser;
|
||||
let newTree;
|
||||
beforeEach(() => {
|
||||
newTree = new TreeFake();
|
||||
browser = {
|
||||
Nodes: {
|
||||
'special one': {hasId: true},
|
||||
'child special': {hasId: true},
|
||||
'other type': {hasId: true},
|
||||
'table': {hasId: true},
|
||||
'partition': {hasId: true},
|
||||
'no id': {hasId: false},
|
||||
},
|
||||
};
|
||||
browser.treeMenu = newTree;
|
||||
});
|
||||
|
||||
context('getTreeNodeHierarchy is called with aciTreeNode object', () => {
|
||||
describe('When the current node is root element', () => {
|
||||
beforeEach(() => {
|
||||
newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a object with the element type passed data and priority == 0', () => {
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'root'}]);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': 0,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node is not of a known type', () => {
|
||||
beforeEach(() => {
|
||||
newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'do not exist',
|
||||
}, []);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)('root');
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node type has no id', () => {
|
||||
beforeEach(() => {
|
||||
newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'no id',
|
||||
}, []);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)('root');
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node is at the second level', () => {
|
||||
beforeEach(() => {
|
||||
const root = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
});
|
||||
const firstChild = new TreeNode('first child', {
|
||||
'some key': 'some other value',
|
||||
'_type': 'child special',
|
||||
}, ['root']);
|
||||
newTree.addChild(root, firstChild);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'first child'}]);
|
||||
expect(result).toEqual({
|
||||
'child special': {
|
||||
'some key': 'some other value',
|
||||
'_type': 'child special',
|
||||
'priority': 0,
|
||||
},
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('When tree as "special type"', () => {
|
||||
context('When "special type" have "other type"', () => {
|
||||
context('When "other type" have "special type"', () => {
|
||||
describe('When retrieving lead node', () => {
|
||||
it('does not override previous node type data', () => {
|
||||
const rootNode = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
}, []);
|
||||
|
||||
const level1 = new TreeNode('level 1', {
|
||||
'some key': 'some value',
|
||||
'_type': 'other type',
|
||||
});
|
||||
newTree.addChild(rootNode, level1);
|
||||
|
||||
newTree.addChild(level1, new TreeNode('level 2', {
|
||||
'some key': 'expected value',
|
||||
'_type': 'special one',
|
||||
'some other key': 'some other value',
|
||||
}));
|
||||
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'level 2'}]);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'expected value',
|
||||
'_type': 'special one',
|
||||
'some other key': 'some other value',
|
||||
'priority': 0,
|
||||
},
|
||||
'other type': {
|
||||
'some key': 'some value',
|
||||
'_type': 'other type',
|
||||
'priority': -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('When tree has table', () => {
|
||||
context('when table has partition', () => {
|
||||
it('returns table with partition parameters', () => {
|
||||
const root = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
}, []);
|
||||
const level1 = new TreeNode('level 1', {
|
||||
'some key': 'some value',
|
||||
'_type': 'table',
|
||||
});
|
||||
newTree.addChild(root, level1);
|
||||
newTree.addChild(level1, new TreeNode('level 2', {
|
||||
'some key': 'expected value',
|
||||
'_type': 'partition',
|
||||
'some other key': 'some other value',
|
||||
}));
|
||||
|
||||
const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id:'level 2'}]);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': -2,
|
||||
},
|
||||
'table': {
|
||||
'some key': 'some value',
|
||||
'_type': 'table',
|
||||
'priority': -1,
|
||||
},
|
||||
'partition': {
|
||||
'some key': 'expected value',
|
||||
'some other key': 'some other value',
|
||||
'_type': 'partition',
|
||||
'priority': 0,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('getTreeNodeHierarchy is called with TreeNode object', () => {
|
||||
let treeNode;
|
||||
describe('When the current node is root element', () => {
|
||||
beforeEach(() => {
|
||||
treeNode = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
}, []);
|
||||
});
|
||||
|
||||
it('returns a object with the element type passed data and priority == 0', () => {
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': 0,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node is not of a known type', () => {
|
||||
beforeEach(() => {
|
||||
treeNode = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'do not exist',
|
||||
}, []);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node type has no id', () => {
|
||||
beforeEach(() => {
|
||||
treeNode = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'no id',
|
||||
}, []);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the current node is at the second level', () => {
|
||||
beforeEach(() => {
|
||||
const root = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
}, []);
|
||||
treeNode = new TreeNode('first child', {
|
||||
'some key': 'some other value',
|
||||
'_type': 'child special',
|
||||
});
|
||||
newTree.addChild(root, treeNode);
|
||||
});
|
||||
|
||||
it('returns a empty object', () => {
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({
|
||||
'child special': {
|
||||
'some key': 'some other value',
|
||||
'_type': 'child special',
|
||||
'priority': 0,
|
||||
},
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('When tree as "special type"', () => {
|
||||
context('When "special type" have "other type"', () => {
|
||||
context('When "other type" have "special type"', () => {
|
||||
describe('When retrieving lead node', () => {
|
||||
it('does not override previous node type data', () => {
|
||||
const root = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
}, []);
|
||||
const level1 = new TreeNode('level 1', {
|
||||
'some key': 'some value',
|
||||
'_type': 'other type',
|
||||
});
|
||||
newTree.addChild(root, level1);
|
||||
treeNode = new TreeNode('level 2', {
|
||||
'some key': 'expected value',
|
||||
'_type': 'special one',
|
||||
'some other key': 'some other value',
|
||||
});
|
||||
newTree.addChild(level1, treeNode);
|
||||
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'expected value',
|
||||
'_type': 'special one',
|
||||
'some other key': 'some other value',
|
||||
'priority': 0,
|
||||
},
|
||||
'other type': {
|
||||
'some key': 'some value',
|
||||
'_type': 'other type',
|
||||
'priority': -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('When tree has table', () => {
|
||||
context('when table has partition', () => {
|
||||
it('returns table with partition parameters', () => {
|
||||
const root = newTree.addNewNode('root', {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
});
|
||||
const level1 = newTree.addNewNode('level 1', {
|
||||
'some key': 'some value',
|
||||
'_type': 'table',
|
||||
});
|
||||
newTree.addChild(root, level1);
|
||||
treeNode = new TreeNode('level 2', {
|
||||
'some key': 'expected value',
|
||||
'_type': 'partition',
|
||||
'some other key': 'some other value',
|
||||
});
|
||||
newTree.addChild(level1, treeNode);
|
||||
|
||||
const result = getTreeNodeHierarchyFromElement(browser, treeNode);
|
||||
expect(result).toEqual({
|
||||
'special one': {
|
||||
'some key': 'some value',
|
||||
'_type': 'special one',
|
||||
'priority': -2,
|
||||
},
|
||||
'table': {
|
||||
'some key': 'some value',
|
||||
'_type': 'table',
|
||||
'priority': -1,
|
||||
},
|
||||
'partition': {
|
||||
'some key': 'expected value',
|
||||
'some other key': 'some other value',
|
||||
'_type': 'partition',
|
||||
'priority': 0,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -107,7 +107,10 @@ describe('#browserTreeState', () => {
|
||||
};},
|
||||
},
|
||||
};
|
||||
pgBrowser.tree = jasmine.createSpyObj('tree', ['itemData', 'pathId', 'hasParent', 'isOpen', 'isClosed', 'selected']);
|
||||
pgBrowser.tree = jasmine.createSpyObj('tree', ['itemData', 'pathId', 'hasParent', 'isOpen', 'isClosed', 'selected', 'parent']);
|
||||
pgBrowser.tree.getTreeNodeHierarchy = function (item) {
|
||||
return pgBrowser.Nodes[item._type].getTreeNodeHierarchy();
|
||||
};
|
||||
});
|
||||
|
||||
describe('When node is opened tree state is getting updated', () => {
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import {Tree} from '../../../pgadmin/static/js/tree/tree';
|
||||
import {ManageTreeNodes, TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes';
|
||||
|
||||
export class TreeFake extends Tree {
|
||||
static build(structure) {
|
||||
let tree = new TreeFake();
|
||||
static build(structure, pgBrowser) {
|
||||
let tree = new TreeFake(pgBrowser);
|
||||
let rootNode = tree.rootNode;
|
||||
|
||||
if (structure.children !== undefined) {
|
||||
@@ -27,7 +28,10 @@ export class TreeFake extends Tree {
|
||||
let id = newNode.id;
|
||||
let data = newNode.data ? newNode.data : {};
|
||||
let domNode = newNode.domNode ? newNode.domNode : [{id: id}];
|
||||
tree.addNewNode(id, data, domNode, tree.translateTreeNodeIdFromACITree([parent]));
|
||||
|
||||
let parentPath = tree.translateTreeNodeIdFromReactTree([parent]);
|
||||
|
||||
tree.addNewNode(id, data, domNode, parentPath);
|
||||
|
||||
if (newNode.children !== undefined) {
|
||||
newNode.children.forEach((child) => {
|
||||
@@ -36,50 +40,96 @@ export class TreeFake extends Tree {
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.aciTreeToOurTreeTranslator = {};
|
||||
this.aciTreeApi = jasmine.createSpyObj(
|
||||
'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
|
||||
this.aciTreeApi.unload.and.callFake(function(domNode, config) {
|
||||
constructor(pgBrowser) {
|
||||
let manageTree = new ManageTreeNodes();
|
||||
let tree = jasmine.createSpyObj(
|
||||
'tree', ['unload', 'onTreeEvents',
|
||||
'getActiveFile', 'setActiveFile',
|
||||
'deSelectActiveFile', 'closeDirectory']);
|
||||
tree.unload.and.callFake(function(domNode, config) {
|
||||
config.success();
|
||||
});
|
||||
|
||||
super(tree, manageTree, pgBrowser);
|
||||
this.aciTreeToOurTreeTranslator = {};
|
||||
|
||||
}
|
||||
|
||||
addNewNode(id, data, domNode, path) {
|
||||
this.aciTreeToOurTreeTranslator[id] = [id];
|
||||
this.aciTreeToOurTreeTranslator[id] = id;
|
||||
if (path !== null && path !== undefined) {
|
||||
this.aciTreeToOurTreeTranslator[id] = path.concat(id);
|
||||
if (typeof(path) === 'object') path = path.join('/');
|
||||
this.aciTreeToOurTreeTranslator[id] = path != '' ? path + '/' + id : id;
|
||||
if (path.indexOf('/browser/') != 0) path = path != '' ? '/browser/' + path : undefined;
|
||||
}
|
||||
return super.addNewNode(id, data, domNode, path);
|
||||
}
|
||||
|
||||
addChild(parent, child) {
|
||||
child.setParent(parent);
|
||||
this.aciTreeToOurTreeTranslator[child.id] = this.aciTreeToOurTreeTranslator[parent.id].concat(child.id);
|
||||
this.aciTreeToOurTreeTranslator[child.id] = this.aciTreeToOurTreeTranslator[parent.id] + '/' + child.id;
|
||||
parent.children.push(child);
|
||||
}
|
||||
|
||||
hasParent(aciTreeNode) {
|
||||
return this.translateTreeNodeIdFromACITree(aciTreeNode).length > 1;
|
||||
let parents = this.translateTreeNodeIdFromReactTree(aciTreeNode).split('/');
|
||||
return parents.length > 1;
|
||||
}
|
||||
|
||||
parent(aciTreeNode) {
|
||||
if (this.hasParent(aciTreeNode)) {
|
||||
let path = this.translateTreeNodeIdFromACITree(aciTreeNode);
|
||||
return [{id: this.findNode(path).parent().id}];
|
||||
let path = this.translateTreeNodeIdFromReactTree(aciTreeNode);
|
||||
return [{id: this.findNode('/browser/' + path).parent().id}];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
translateTreeNodeIdFromACITree(aciTreeNode) {
|
||||
translateTreeNodeIdFromReactTree(aciTreeNode) {
|
||||
if (aciTreeNode === undefined || aciTreeNode[0] === undefined) {
|
||||
return null;
|
||||
}
|
||||
return this.aciTreeToOurTreeTranslator[aciTreeNode[0].id];
|
||||
}
|
||||
|
||||
findNodeByDomElement(domElement) {
|
||||
const path = this.translateTreeNodeIdFromReactTree(domElement);
|
||||
|
||||
if(!path || !path[0]) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.findNode('/browser/' + path);
|
||||
|
||||
}
|
||||
|
||||
getTreeNodeHierarchy(identifier) {
|
||||
let idx = 0;
|
||||
let node_cnt = 0;
|
||||
let result = {};
|
||||
let item = TreeNode.prototype.isPrototypeOf(identifier) ? identifier :
|
||||
(identifier.path ? this.findNode(identifier.path) : this.findNodeByDomElement(identifier));
|
||||
|
||||
if (item == undefined || item == null) return null;
|
||||
|
||||
do {
|
||||
const currentNodeData = item.getData();
|
||||
if (currentNodeData._type in this.Nodes && this.Nodes[currentNodeData._type].hasId) {
|
||||
const nodeType = mapType(currentNodeData._type, node_cnt);
|
||||
if (result[nodeType] === undefined) {
|
||||
result[nodeType] = _.extend({}, currentNodeData, {
|
||||
'priority': idx,
|
||||
});
|
||||
idx -= 1;
|
||||
}
|
||||
}
|
||||
node_cnt += 1;
|
||||
item = item.hasParent() ? item.parent() : null;
|
||||
} while (item);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
itemData(aciTreeNode) {
|
||||
let node = this.findNodeByDomElement(aciTreeNode);
|
||||
if (node === undefined || node === null) {
|
||||
@@ -96,3 +146,7 @@ export class TreeFake extends Tree {
|
||||
this.selectedNode = selectedNode;
|
||||
}
|
||||
}
|
||||
|
||||
function mapType(type, idx) {
|
||||
return (type === 'partition' && idx > 0) ? 'table' : type;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
// pgAdmin 4 PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// Copyright (C) 2013 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import {Tree, TreeNode} from '../../../pgadmin/static/js/tree/tree';
|
||||
import {Tree} from '../../../pgadmin/static/js/tree/tree';
|
||||
import {TreeNode, ManageTreeNodes} from '../../../pgadmin/static/js/tree/tree_nodes';
|
||||
import {TreeFake} from './tree_fake';
|
||||
|
||||
const context = describe;
|
||||
@@ -15,28 +16,34 @@ const context = describe;
|
||||
const treeTests = (treeClass, setDefaultCallBack) => {
|
||||
let tree;
|
||||
beforeEach(() => {
|
||||
tree = new treeClass();
|
||||
let manageTree = new ManageTreeNodes();
|
||||
let reactTree = jasmine.createSpyObj(
|
||||
'tree', ['onTreeEvents', 'getActiveFile']);
|
||||
tree = new treeClass(reactTree, manageTree);
|
||||
});
|
||||
|
||||
describe('#addNewNode', () => {
|
||||
beforeEach(() => {
|
||||
tree.rootNode = new TreeNode(undefined, {});
|
||||
});
|
||||
describe('when add a new root element', () => {
|
||||
context('using [] as the parent', () => {
|
||||
context('using undefined as the parent', () => {
|
||||
beforeEach(() => {
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, []);
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, undefined);
|
||||
});
|
||||
|
||||
it('can be retrieved', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.data).toEqual({data: 'interesting'});
|
||||
});
|
||||
|
||||
it('return false for #hasParent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.hasParent()).toEqual(false);
|
||||
});
|
||||
|
||||
it('return null for #parent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.parent()).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -47,38 +54,17 @@ const treeTests = (treeClass, setDefaultCallBack) => {
|
||||
});
|
||||
|
||||
it('can be retrieved', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.data).toEqual({data: 'interesting'});
|
||||
});
|
||||
|
||||
it('return false for #hasParent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.hasParent()).toEqual(false);
|
||||
});
|
||||
|
||||
it('return null for #parent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
expect(node.parent()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
context('using undefined as the parent', () => {
|
||||
beforeEach(() => {
|
||||
tree.addNewNode('some new node', {data: 'interesting'});
|
||||
});
|
||||
|
||||
it('can be retrieved', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
expect(node.data).toEqual({data: 'interesting'});
|
||||
});
|
||||
|
||||
it('return false for #hasParent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
expect(node.hasParent()).toEqual(false);
|
||||
});
|
||||
|
||||
it('return null for #parent()', () => {
|
||||
const node = tree.findNode(['some new node']);
|
||||
const node = tree.findNode('/browser/some new node');
|
||||
expect(node.parent()).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -87,101 +73,46 @@ const treeTests = (treeClass, setDefaultCallBack) => {
|
||||
describe('when add a new element as a child', () => {
|
||||
let parentNode;
|
||||
beforeEach(() => {
|
||||
parentNode = tree.addNewNode('parent node', {data: 'parent data'}, undefined, []);
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, ['parent' +
|
||||
' node']);
|
||||
parentNode = tree.addNewNode('parent node', {data: 'parent data'}, undefined, undefined);
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, '/browser/parent node');
|
||||
});
|
||||
|
||||
it('can be retrieved', () => {
|
||||
const node = tree.findNode(['parent node', 'some new node']);
|
||||
const node = tree.findNode('/browser/parent node/some new node');
|
||||
expect(node.data).toEqual({data: 'interesting'});
|
||||
});
|
||||
|
||||
it('return true for #hasParent()', () => {
|
||||
const node = tree.findNode(['parent node', 'some new node']);
|
||||
const node = tree.findNode('/browser/parent node/some new node');
|
||||
expect(node.hasParent()).toEqual(true);
|
||||
});
|
||||
|
||||
it('return "parent node" object for #parent()', () => {
|
||||
const node = tree.findNode(['parent node', 'some new node']);
|
||||
const node = tree.findNode('/browser/parent node/some new node');
|
||||
expect(node.parent()).toEqual(parentNode);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when add an element that already exists under a parent', () => {
|
||||
beforeEach(() => {
|
||||
tree.addNewNode('parent node', {data: 'parent data'}, undefined, []);
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, ['parent' +
|
||||
' node']);
|
||||
tree.addNewNode('parent node', {data: 'parent data'}, undefined, undefined);
|
||||
tree.addNewNode('some new node', {data: 'interesting'}, undefined, '/browser/parent node');
|
||||
});
|
||||
|
||||
it('does not add a new child', () => {
|
||||
tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, ['parent' +
|
||||
' node']);
|
||||
const parentNode = tree.findNode(['parent node']);
|
||||
tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, '/browser/parent node');
|
||||
const parentNode = tree.findNode('/browser/parent node');
|
||||
expect(parentNode.children.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('updates the existing node data', () => {
|
||||
tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, ['parent' +
|
||||
' node']);
|
||||
const node = tree.findNode(['parent node', 'some new node']);
|
||||
tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, '/browser/parent node');
|
||||
const node = tree.findNode('/browser/parent node/some new node');
|
||||
expect(node.data).toEqual({data: 'interesting 1'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#translateTreeNodeIdFromACITree', () => {
|
||||
let aciTreeApi;
|
||||
beforeEach(() => {
|
||||
aciTreeApi = jasmine.createSpyObj('ACITreeApi', [
|
||||
'hasParent',
|
||||
'parent',
|
||||
'getId',
|
||||
]);
|
||||
|
||||
aciTreeApi.getId.and.callFake((node) => {
|
||||
return node[0].id;
|
||||
});
|
||||
tree.aciTreeApi = aciTreeApi;
|
||||
});
|
||||
|
||||
describe('When tree as a single level', () => {
|
||||
beforeEach(() => {
|
||||
aciTreeApi.hasParent.and.returnValue(false);
|
||||
});
|
||||
|
||||
it('returns an array with the ID of the first level', () => {
|
||||
let node = [{
|
||||
id: 'some id',
|
||||
}];
|
||||
tree.addNewNode('some id', {}, undefined, []);
|
||||
|
||||
expect(tree.translateTreeNodeIdFromACITree(node)).toEqual(['some id']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When tree as a 2 levels', () => {
|
||||
describe('When we try to retrieve the node in the second level', () => {
|
||||
it('returns an array with the ID of the first level and second level', () => {
|
||||
aciTreeApi.hasParent.and.returnValues(true, false);
|
||||
aciTreeApi.parent.and.returnValue([{
|
||||
id: 'parent id',
|
||||
}]);
|
||||
let node = [{
|
||||
id: 'some id',
|
||||
}];
|
||||
|
||||
tree.addNewNode('parent id', {}, undefined, []);
|
||||
tree.addNewNode('some id', {}, undefined, ['parent id']);
|
||||
|
||||
expect(tree.translateTreeNodeIdFromACITree(node))
|
||||
.toEqual(['parent id', 'some id']);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#selected', () => {
|
||||
context('a node in the tree is selected', () => {
|
||||
it('returns that node object', () => {
|
||||
@@ -195,16 +126,17 @@ const treeTests = (treeClass, setDefaultCallBack) => {
|
||||
describe('#findNodeByTreeElement', () => {
|
||||
context('retrieve data from node not found', () => {
|
||||
it('return undefined', () => {
|
||||
let aciTreeApi = jasmine.createSpyObj('ACITreeApi', [
|
||||
let reactTree = jasmine.createSpyObj('tree', [
|
||||
'hasParent',
|
||||
'parent',
|
||||
'getId',
|
||||
'onTreeEvents',
|
||||
]);
|
||||
|
||||
aciTreeApi.getId.and.callFake((node) => {
|
||||
reactTree.getId.and.callFake((node) => {
|
||||
return node[0].id;
|
||||
});
|
||||
tree.aciTreeApi = aciTreeApi;
|
||||
tree.tree = reactTree;
|
||||
expect(tree.findNodeByDomElement(['<li>something</li>'])).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -240,14 +172,18 @@ describe('tree tests', () => {
|
||||
let level2;
|
||||
beforeEach(() => {
|
||||
tree = new TreeFake();
|
||||
tree.addNewNode('level1', {data: 'interesting'}, [{id: 'level1'}], []);
|
||||
tree.addNewNode('level1', {data: 'interesting'}, [{id: 'level1'}], undefined);
|
||||
level2 = tree.addNewNode('level2', {data: 'data'}, [{id: 'level2'}], ['level1']);
|
||||
tree.addNewNode('level3', {data: 'more data'}, [{id: 'level3'}], ['level1', 'level2']);
|
||||
|
||||
tree.aciTreeApi = jasmine.createSpyObj(
|
||||
'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
|
||||
tree.aciTreeApi.unload.and.callFake((domNode, config) => {
|
||||
config.success();
|
||||
tree.tree = jasmine.createSpyObj(
|
||||
'tree', ['unload', 'onTreeEvents',
|
||||
'setActiveFile', 'closeDirectory', 'getActiveFile',
|
||||
'deSelectActiveFile']);
|
||||
tree.tree.unload.and.callFake(function() {
|
||||
return new Promise((resolve)=>{
|
||||
resolve('Success!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -286,11 +222,11 @@ describe('tree tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ACITree specific', () => {
|
||||
describe('ReactTree specific', () => {
|
||||
it('sets the current node as a Inode, changing the Icon back to +', (done) => {
|
||||
level2.reload(tree)
|
||||
.then(()=>{
|
||||
expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]);
|
||||
expect(tree.tree.closeDirectory).toHaveBeenCalledWith([{id: 'level2'}]);
|
||||
done();
|
||||
})
|
||||
.catch((error)=>{
|
||||
@@ -298,12 +234,12 @@ describe('tree tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('deselect the node and selects it again to trigger ACI tree' +
|
||||
' events', (done) => {
|
||||
it('deselect the node and selects it again to trigger React tree' +
|
||||
' events', (done) => {
|
||||
level2.reload(tree)
|
||||
.then(()=>{
|
||||
setTimeout(() => {
|
||||
expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]);
|
||||
expect(tree.tree.deSelectActiveFile).toHaveBeenCalledWith([{id: 'level2'}]);
|
||||
done();
|
||||
}, 20);
|
||||
})
|
||||
@@ -319,12 +255,14 @@ describe('tree tests', () => {
|
||||
let level2;
|
||||
beforeEach(() => {
|
||||
tree = new TreeFake();
|
||||
tree.addNewNode('level1', {data: 'interesting'}, ['<li>level1</li>'], []);
|
||||
tree.addNewNode('level1', {data: 'interesting'}, ['<li>level1</li>'], undefined);
|
||||
level2 = tree.addNewNode('level2', {data: 'data'}, ['<li>level2</li>'], ['level1']);
|
||||
tree.addNewNode('level3', {data: 'more data'}, ['<li>level3</li>'], ['level1', 'level2']);
|
||||
tree.aciTreeApi = jasmine.createSpyObj('ACITreeApi', ['unload']);
|
||||
tree.aciTreeApi.unload.and.callFake((domNode, config) => {
|
||||
config.success();
|
||||
tree.addNewNode('level3', {data: 'more data'}, ['<li>level3</li>'], ['level1','level2']);
|
||||
tree.tree = jasmine.createSpyObj('tree', ['unload']);
|
||||
tree.tree.unload.and.callFake(() => {
|
||||
return new Promise((resolve)=>{
|
||||
resolve('Success!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -340,10 +278,10 @@ describe('tree tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('calls unload on the ACI Tree', (done) => {
|
||||
it('calls unload on the React Tree', (done) => {
|
||||
level2.unload(tree)
|
||||
.then(()=>{
|
||||
expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['<li>level2</li>'], jasmine.any(Object));
|
||||
expect(tree.tree.unload).toHaveBeenCalledWith(['<li>level2</li>']);
|
||||
done();
|
||||
})
|
||||
.catch((error)=>{
|
||||
@@ -355,11 +293,11 @@ describe('tree tests', () => {
|
||||
|
||||
describe('Tree', () => {
|
||||
function realTreeSelectNode(tree, selectedNode) {
|
||||
let aciTreeApi = jasmine.createSpyObj('ACITreeApi', [
|
||||
'selected',
|
||||
let reactTree = jasmine.createSpyObj('tree', [
|
||||
'getActiveFile',
|
||||
]);
|
||||
tree.aciTreeApi = aciTreeApi;
|
||||
aciTreeApi.selected.and.returnValue(selectedNode);
|
||||
tree.tree = reactTree;
|
||||
reactTree.getActiveFile.and.returnValue(selectedNode);
|
||||
}
|
||||
|
||||
treeTests(Tree, realTreeSelectNode);
|
||||
@@ -377,8 +315,8 @@ describe('tree tests', () => {
|
||||
let tree;
|
||||
beforeEach(() => {
|
||||
tree = new TreeFake();
|
||||
tree.addNewNode('level1', {data: 'interesting'}, undefined, []);
|
||||
tree.addNewNode('level2', {data: 'interesting'}, undefined, ['level1']);
|
||||
tree.addNewNode('level1', {data: 'interesting'}, undefined, undefined);
|
||||
tree.addNewNode('level2', {data: 'interesting'}, undefined, '/browser/level1');
|
||||
});
|
||||
|
||||
context('node is at the first level', () => {
|
||||
@@ -399,7 +337,7 @@ describe('tree tests', () => {
|
||||
let tree;
|
||||
beforeEach(() => {
|
||||
tree = new TreeFake();
|
||||
tree.addNewNode('level1', {data: 'interesting'}, undefined, []);
|
||||
tree.addNewNode('level1', {data: 'interesting'}, undefined, undefined);
|
||||
tree.addNewNode('level2', {data: 'interesting'}, undefined, ['level1']);
|
||||
});
|
||||
|
||||
@@ -416,30 +354,6 @@ describe('tree tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#itemData', () => {
|
||||
let tree;
|
||||
beforeEach(() => {
|
||||
tree = new TreeFake();
|
||||
tree.addNewNode('level1', {data: 'interesting'}, undefined, []);
|
||||
tree.addNewNode('level2', {data: 'expected data'}, undefined, ['level1']);
|
||||
});
|
||||
|
||||
context('retrieve data from the node', () => {
|
||||
it('return the node data', () => {
|
||||
expect(tree.itemData([{id: 'level2'}])).toEqual({
|
||||
data: 'expected' +
|
||||
' data',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('retrieve data from node not found', () => {
|
||||
it('return undefined', () => {
|
||||
expect(tree.itemData([{id: 'bamm'}])).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#addChild', () => {
|
||||
let root, child;
|
||||
beforeEach(() => {
|
||||
@@ -459,7 +373,7 @@ describe('tree tests', () => {
|
||||
});
|
||||
|
||||
it('changes the path of the child', () => {
|
||||
expect(child.path).toEqual('root.node.1');
|
||||
expect(child.path).toEqual('/browser/root/node.1');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user