Added search object functionality. Fixes #2172

This commit is contained in:
Aditya Toshniwal
2020-04-06 17:33:07 +05:30
committed by Akshay Joshi
parent f77aa3284f
commit e1f990190e
57 changed files with 5968 additions and 494 deletions

View File

@@ -19,5 +19,7 @@ define(function () {
'datagrid.initialize_query_tool_with_did': '/initialize/query_tool/<int:sgid>/<int:sid>/<int:did>',
'restore.create_job': '/restore/job/<int:sid>',
'datagrid.panel': '/panel/<int:trans_id>',
'search_objects.types': '/search_objects/types/<int:sid>/<int:did>',
'search_objects.search': '/search_objects/search/<int:sid>/<int:did>',
};
});

View File

@@ -0,0 +1,155 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import SearchObjectsDialog from 'tools/search_objects/static/js/search_objects_dialog';
import {TreeFake} from '../tree/tree_fake';
import MockAdapter from 'axios-mock-adapter';
import axios from 'axios/index';
const context = describe;
describe('SearchObjectsDialog', () => {
let soDialog;
let pgBrowser;
let jquerySpy;
let alertifySpy;
beforeEach(() => {
pgBrowser = {
treeMenu: new TreeFake(),
Nodes: {
server: {
hasId: true,
label: 'server',
getTreeNodeHierarchy: jasmine.createSpy('server.getTreeNodeHierarchy'),
},
database: {
hasId: true,
label: 'database',
getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'),
},
schema: {
hasId: true,
label: 'schema',
getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'),
},
},
stdW: {
sm: 500,
md: 700,
lg: 900,
default: 500,
},
stdH: {
sm: 200,
md: 400,
lg: 550,
default: 550,
},
};
pgBrowser.Nodes.server.hasId = true;
pgBrowser.Nodes.database.hasId = true;
jquerySpy = jasmine.createSpy('jquerySpy');
const hierarchy = {
children: [
{
id: 'root',
children: [
{
id: 'serverTreeNode',
data: {
_id: 10,
_type: 'server',
user: {name: 'username'},
label: 'theserver',
},
children: [
{
id: 'some_database',
data: {
_type: 'database',
_id: 11,
label: 'thedatabase',
},
},
],
},
{
id: 'ppasServer',
data: {
_type: 'server',
server_type: 'ppas',
children: [
{id: 'someNodeUnderneathPPASServer'},
],
},
},
],
},
],
};
pgBrowser.treeMenu = TreeFake.build(hierarchy);
});
describe('#draw', () => {
let networkMock;
beforeEach(() => {
networkMock = new MockAdapter(axios);
alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']);
alertifySpy['search_objects'] = jasmine.createSpy('search_objects');
soDialog = new SearchObjectsDialog(
pgBrowser,
jquerySpy,
alertifySpy,
null
);
pgBrowser.get_preference = jasmine.createSpy('get_preferences');
});
afterEach(() => {
networkMock.restore();
});
context('there are no ancestors of the type database', () => {
it('does not create a dialog', () => {
pgBrowser.treeMenu.selectNode([{id: 'serverTreeNode'}]);
soDialog.draw(null, null, null);
expect(alertifySpy['search_objects']).not.toHaveBeenCalled();
});
it('display an alert with a Backup Error', () => {
soDialog.draw(null, [{id: 'serverTreeNode'}], null);
expect(alertifySpy.alert).toHaveBeenCalledWith(
'Search Objects Error',
'Please select a database or its child node from the browser.'
);
});
});
context('there is an ancestor of the type database', () => {
let soDialogResizeToSpy;
beforeEach(() => {
soDialogResizeToSpy = jasmine.createSpyObj('soDialogResizeToSpy', ['resizeTo']);
alertifySpy['search_objects'].and
.returnValue(soDialogResizeToSpy);
});
it('displays the dialog when database node selected', (done) => {
soDialog.draw(null, [{id: 'some_database'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
setTimeout(() => {
expect(alertifySpy['search_objects']).toHaveBeenCalledWith('Search Objects - thedatabase/username@theserver');
expect(soDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
done();
}, 0);
});
});
});
});

View File

@@ -0,0 +1,545 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import {TreeFake} from '../tree/tree_fake';
import SearchObjectsDialogWrapper from 'tools/search_objects/static/js/search_objects_dialog_wrapper';
import axios from 'axios/index';
import MockAdapter from 'axios-mock-adapter';
import {TreeNode} from '../../../pgadmin/static/js/tree/tree';
let context = describe;
describe('SearchObjectsDialogWrapper', () => {
let jquerySpy;
let pgBrowser;
let alertifySpy;
let dialogModelKlassSpy = null;
let backform;
let soDialogWrapper;
let noDataNode;
let serverTreeNode;
let databaseTreeNode;
let viewSchema;
let soJQueryContainerSpy;
let soNodeChildNodeSpy;
let soNode;
beforeEach(() => {
pgBrowser = {
treeMenu: new TreeFake(),
Nodes: {
server: {
hasId: true,
getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'),
},
database: {
hasId: true,
getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'),
},
'coll-sometype': {
type: 'coll-sometype',
hasId: false,
label: 'Some types coll',
},
sometype: {
type: 'sometype',
hasId: true,
},
someothertype: {
type: 'someothertype',
hasId: true,
collection_type: 'coll-sometype',
},
'coll-edbfunc': {
type: 'coll-edbfunc',
hasId: true,
label: 'Functions',
},
'coll-edbproc': {
type: 'coll-edbfunc',
hasId: true,
label: 'Procedures',
},
'coll-edbvar': {
type: 'coll-edbfunc',
hasId: true,
label: 'Variables',
},
},
keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']),
};
noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]);
serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', {
_type: 'server',
_id: 10,
label: 'some-tree-label',
}, [{id: 'level2.1'}]);
databaseTreeNode = new TreeNode('database-tree-node', {
_type: 'database',
_id: 123,
_label: 'some-database-label',
}, [{id: 'database-tree-node'}]);
pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode);
jquerySpy = jasmine.createSpy('jquerySpy');
soNode = {
__internal: {
buttons: [{}, {}, {}, {
element: {
disabled: false,
},
}],
},
elements: {
body: {
childNodes: [
{},
],
},
content: jasmine.createSpyObj('content', ['appendChild', 'attr']),
},
};
soJQueryContainerSpy = jasmine.createSpyObj('soJQueryContainer', ['get', 'attr']);
soJQueryContainerSpy.get.and.returnValue(soJQueryContainerSpy);
viewSchema = {};
backform = jasmine.createSpyObj('backform', ['generateViewSchema', 'Dialog']);
backform.generateViewSchema.and.returnValue(viewSchema);
soNodeChildNodeSpy = jasmine.createSpyObj('something', ['addClass']);
jquerySpy.and.callFake((selector) => {
if (selector === '<div class=\'search_objects_dialog\'></div>') {
return soJQueryContainerSpy;
} else if (selector === soNode.elements.body.childNodes[0]) {
return soNodeChildNodeSpy;
}
});
alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']);
});
describe('#prepare', () => {
beforeEach(() => {
soDialogWrapper = new SearchObjectsDialogWrapper(
'<div class=\'search_objects_dialog\'></div>',
'soDialogTitle',
'search_objects',
jquerySpy,
pgBrowser,
alertifySpy,
dialogModelKlassSpy,
backform
);
soDialogWrapper = Object.assign(soDialogWrapper, soNode);
spyOn(soDialogWrapper, 'prepareDialog').and.callThrough();
spyOn(soDialogWrapper, 'setTypes');
spyOn(soDialogWrapper, 'setResultCount');
});
context('no tree element is selected', () => {
it('does not prepare dialog', () => {
spyOn(soDialogWrapper, 'prepareDialog');
soDialogWrapper.prepare();
expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled();
});
});
context('selected tree node has no data', () => {
beforeEach(() => {
pgBrowser.treeMenu.selectNode(noDataNode.domNode);
});
it('does not prepare the dialog', () => {
spyOn(soDialogWrapper, 'prepareDialog');
soDialogWrapper.prepare();
expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled();
});
});
context('tree element is selected', () => {
let gridDestroySpy;
let networkMock;
beforeEach(() => {
pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode);
soDialogWrapper.grid = jasmine.createSpyObj('grid', ['destroy']);
spyOn(soDialogWrapper, 'showMessage');
gridDestroySpy = spyOn(soDialogWrapper.grid, 'destroy');
networkMock = new MockAdapter(axios);
});
afterEach(() => {
networkMock.restore();
});
it('creates dialog and displays it', () => {
soDialogWrapper.prepare();
expect(soDialogWrapper.prepareDialog).toHaveBeenCalled();
expect(soDialogWrapper.showMessage).toHaveBeenCalledWith(null);
});
it('if grid set then destroy it', () => {
soDialogWrapper.prepare();
expect(gridDestroySpy).toHaveBeenCalled();
expect(soDialogWrapper.grid).toBe(null);
});
it('set result count to 0', () => {
soDialogWrapper.prepare();
expect(soDialogWrapper.setResultCount).toHaveBeenCalledWith(0);
});
it('setTypes called before and after the ajax success', (done) => {
networkMock.onGet('/search_objects/types/10/123').reply(200, {
'data': {
'type1': 'Type Label 1',
'type2': 'Type Label 2',
},
});
soDialogWrapper.prepare();
expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([
[{ id: -1, text: 'Loading...', value: null }], false,
]);
setTimeout(()=>{
expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([
[{id: 'all', text: 'All types'},
{id: 'type1', text: 'Type Label 1'},
{id: 'type2', text: 'Type Label 2'}],
]);
done();
}, 0);
});
it('setTypes called after the ajax fail', (done) => {
networkMock.onGet('/search_objects/types/10/123').reply(500);
soDialogWrapper.prepare();
expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([
[{ id: -1, text: 'Loading...', value: null }], false,
]);
setTimeout(()=>{
expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([
[{id: -1, text: 'Failed', value: null }], false,
]);
done();
}, 0);
});
});
});
describe('showMessage', () => {
beforeEach(() => {
soDialogWrapper = new SearchObjectsDialogWrapper(
'<div class=\'search_objects_dialog\'></div>',
'soDialogTitle',
'search_objects',
jquerySpy,
pgBrowser,
alertifySpy,
dialogModelKlassSpy,
backform
);
soDialogWrapper.statusBar = document.createElement('div');
soDialogWrapper.statusBar.classList.add('d-none');
document.body.appendChild(soDialogWrapper.statusBar);
});
afterEach(() => {
document.body.removeChild(soDialogWrapper.statusBar);
});
it('when info message', ()=>{
soDialogWrapper.showMessage('locating', false);
expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false);
expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).toBe(null);
expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).not.toBe(null);
expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('locating');
});
it('when error message', ()=>{
soDialogWrapper.showMessage('some error', true);
expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false);
expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).not.toBe(null);
expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).toBe(null);
expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('some error');
});
it('when no message', ()=>{
soDialogWrapper.showMessage(null);
expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(true);
});
});
describe('function', () => {
beforeEach(() => {
soDialogWrapper = new SearchObjectsDialogWrapper(
'<div class=\'search_objects_dialog\'></div>',
'soDialogTitle',
'search_objects',
jquerySpy,
pgBrowser,
alertifySpy,
dialogModelKlassSpy,
backform
);
});
it('updateDimOfSearchResult', ()=>{
soDialogWrapper.searchResultContainer = document.createElement('div');
soDialogWrapper.searchResult = document.createElement('div');
spyOn(soDialogWrapper.searchResultContainer, 'getBoundingClientRect').and.returnValue({height:100, width: 50});
soDialogWrapper.updateDimOfSearchResult();
expect(soDialogWrapper.searchResult.style.height).toEqual('100px');
expect(soDialogWrapper.searchResult.style.width).toEqual('50px');
});
it('setLoading', ()=>{
soDialogWrapper.loader = document.createElement('div');
soDialogWrapper.loader.innerHTML = `
<div class="pg-sp-text"></div>
`;
soDialogWrapper.setLoading('loading');
expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(false);
expect(soDialogWrapper.loader.querySelector('.pg-sp-text').innerHTML).toEqual('loading');
soDialogWrapper.setLoading(null);
expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(true);
});
it('searchBtnEnabled', ()=>{
soDialogWrapper.searchBtn = document.createElement('button');
soDialogWrapper.searchBtnEnabled(true);
expect(soDialogWrapper.searchBtn.disabled).toEqual(false);
expect(soDialogWrapper.searchBtnEnabled()).toEqual(true);
soDialogWrapper.searchBtnEnabled(false);
expect(soDialogWrapper.searchBtn.disabled).toEqual(true);
expect(soDialogWrapper.searchBtnEnabled()).toEqual(false);
});
it('searchBoxVal', ()=>{
soDialogWrapper.searchBox = document.createElement('input');
soDialogWrapper.searchBoxVal('abc');
expect(soDialogWrapper.searchBox.value).toEqual('abc');
expect(soDialogWrapper.searchBoxVal()).toEqual('abc');
});
it('typesVal', ()=>{
soDialogWrapper.typesSelect = document.createElement('select');
let opt = document.createElement('option');
opt.appendChild( document.createTextNode('Some type') );
opt.value = 'sometype';
soDialogWrapper.typesSelect.appendChild(opt);
soDialogWrapper.typesVal('sometype');
expect(soDialogWrapper.typesSelect.value).toEqual('sometype');
expect(soDialogWrapper.typesVal()).toEqual('sometype');
});
it('setGridData', ()=>{
soDialogWrapper.dataview = jasmine.createSpyObj('dataview', ['setItems']);
soDialogWrapper.setGridData([{id:'somedata'}]);
expect(soDialogWrapper.dataview.setItems).toHaveBeenCalled();
});
it('setGridData', ()=>{
soDialogWrapper.searchResultCount = document.createElement('span');
soDialogWrapper.setResultCount(0);
expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('0 matches found.');
soDialogWrapper.setResultCount(1);
expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('1 match found.');
soDialogWrapper.setResultCount();
expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('Unknown matches found.');
});
it('onDialogResize', ()=>{
soDialogWrapper.grid = jasmine.createSpyObj('grid', ['autosizeColumns', 'resizeCanvas']);
spyOn(soDialogWrapper, 'updateDimOfSearchResult');
soDialogWrapper.onDialogResize();
expect(soDialogWrapper.updateDimOfSearchResult).toHaveBeenCalled();
expect(soDialogWrapper.grid.resizeCanvas).toHaveBeenCalled();
expect(soDialogWrapper.grid.autosizeColumns).toHaveBeenCalled();
});
it('onDialogShow', (done)=>{
spyOn(soDialogWrapper, 'prepareGrid').and.callFake(function() {
this.grid = jasmine.createSpyObj('grid', ['init']);
});
spyOn(soDialogWrapper, 'focusOnDialog');
spyOn(soDialogWrapper, 'updateDimOfSearchResult');
spyOn(soDialogWrapper, 'setGridData');
spyOn(soDialogWrapper, 'onDialogResize');
soDialogWrapper.onDialogShow();
setTimeout(()=>{
expect(soDialogWrapper.prepareGrid).toHaveBeenCalled();
expect(soDialogWrapper.focusOnDialog).toHaveBeenCalled();
expect(soDialogWrapper.setGridData).toHaveBeenCalledWith([]);
expect(soDialogWrapper.onDialogResize).toHaveBeenCalled();
done();
}, 750);
});
context('getCollNode', ()=>{
it('type have same coll node', ()=>{
let collNode = soDialogWrapper.getCollNode('sometype');
expect(collNode.type).toEqual('coll-sometype');
});
it('type does not same coll node', ()=>{
let collNode = soDialogWrapper.getCollNode('someothertype');
expect(collNode.type).toEqual('coll-sometype');
});
it('type does not have coll node at all', ()=>{
let collNode = soDialogWrapper.getCollNode('database');
expect(collNode).toBe(null);
});
});
it('finaliseData', ()=>{
spyOn(soDialogWrapper, 'translateSearchObjectsPath').and.returnValue(['disp/path', 'id/path']);
let data = soDialogWrapper.finaliseData({
name: 'objname',
type: 'sometype',
type_label: 'Some types coll',
path: ':some.123:/path',
show_node: true,
});
expect(data).toEqual({
id: 'id/path',
icon: 'icon-sometype',
name: 'objname',
type: 'sometype',
type_label: 'Some types coll',
path: 'disp/path',
id_path: 'id/path',
show_node: true,
});
});
context('translateSearchObjectsPath', ()=>{
let path = null, catalog_level = null;
beforeEach(()=>{
pgBrowser.Nodes = {
'server_group': {
type:'server_group',
label: 'Server group',
},
'server': {
type:'server',
label: 'Server',
},
'coll-database': {
type:'coll-database',
label: 'Databases',
},
'database': {
type:'database',
label: 'Database',
},
'coll-schema': {
type:'coll-schema',
label: 'Schemas',
},
'schema': {
type:'schema',
label: 'Schema',
},
'coll-table': {
type:'coll-table',
label: 'Tables',
},
'table': {
type:'table',
label: 'Table',
},
'sometype': {
type:'sometype',
label: 'Some type',
collection_type: 'coll-table',
},
'coll-catalog': {
type:'coll-catalog',
label: 'Catalogs',
},
'catalog': {
type:'catalog',
label: 'Catalog',
},
'coll-catalog_object': {
type:'coll-catalog_object',
label: 'Catalog Objects',
},
'catalog_object': {
type:'catalog_object',
label: 'catalog object',
},
};
soDialogWrapper.treeInfo = {
'server_group': {'id': 'server_group/1', '_id': 1},
'server': {'id': 'server/3', '_id': 3},
'database': {'id': 'database/18456', '_id': 18456},
};
});
it('regular schema', ()=>{
path = ':schema.2200:/test_db/:table.2604:/sampletab';
catalog_level = 'N';
let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
expect(retVal).toEqual([
'Schemas/test_db/Tables/sampletab',
['server_group/1','server/3','coll-database/3','database/18456','coll-schema/18456','schema/2200','coll-table/2200','table/2604'],
]);
});
context('catalog schema', ()=>{
it('with db support', ()=>{
path = ':schema.11:/PostgreSQL Catalog (pg_catalog)/:table.2604:/pg_class';
catalog_level = 'D';
let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
expect(retVal).toEqual([
'Catalogs/PostgreSQL Catalog (pg_catalog)/Tables/pg_class',
['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-table/11','table/2604'],
]);
});
it('with object support only', ()=>{
path = ':schema.11:/ANSI (information_schema)/:table.2604:/attributes';
catalog_level = 'O';
let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
expect(retVal).toEqual([
'Catalogs/ANSI (information_schema)/Catalog Objects/attributes',
['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-catalog_object/11','catalog_object/2604'],
]);
});
});
});
});
});

View File

@@ -41,6 +41,9 @@ export class TreeFake extends Tree {
this.aciTreeToOurTreeTranslator = {};
this.aciTreeApi = jasmine.createSpyObj(
'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
this.aciTreeApi.unload.and.callFake(function(domNode, config) {
config.success();
});
}
addNewNode(id, data, domNode, path) {

View File

@@ -246,39 +246,70 @@ describe('tree tests', () => {
tree.aciTreeApi = jasmine.createSpyObj(
'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
tree.aciTreeApi.unload.and.callFake((domNode, config) => {
config.success();
});
});
it('reloads the node and its children', () => {
level2.reload(tree);
expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
it('reloads the node and its children', (done) => {
level2.reload(tree)
.then(()=>{
expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
done();
})
.catch((error)=>{
fail(error);
});
});
it('does not reload the children of node', () => {
level2.reload(tree);
expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
it('does not reload the children of node', (done) => {
level2.reload(tree)
.then(()=>{
expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
done();
})
.catch((error)=>{
fail(error);
});
});
it('select the node', (done) => {
level2.reload(tree);
setTimeout(() => {
expect(tree.selected()).toEqual([{id: 'level2'}]);
done();
}, 20);
level2.reload(tree)
.then(()=>{
setTimeout(() => {
expect(tree.selected()).toEqual([{id: 'level2'}]);
done();
}, 20);
})
.catch((error)=>{
fail(error);
});
});
describe('ACITree specific', () => {
it('sets the current node as a Inode, changing the Icon back to +', () => {
level2.reload(tree);
expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]);
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'}]);
done();
})
.catch((error)=>{
fail(error);
});
});
it('deselect the node and selects it again to trigger ACI tree' +
' events', (done) => {
level2.reload(tree);
setTimeout(() => {
expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]);
done();
}, 20);
level2.reload(tree)
.then(()=>{
setTimeout(() => {
expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]);
done();
}, 20);
})
.catch((error)=>{
fail(error);
});
});
});
});
@@ -292,17 +323,32 @@ describe('tree tests', () => {
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();
});
});
it('unloads the children of the current node', () => {
level2.unload(tree);
expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
it('unloads the children of the current node', (done) => {
level2.unload(tree)
.then(()=>{
expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
done();
})
.catch((error)=>{
fail(error);
});
});
it('calls unload on the ACI Tree', () => {
level2.unload(tree);
expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['<li>level2</li>']);
it('calls unload on the ACI Tree', (done) => {
level2.unload(tree)
.then(()=>{
expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['<li>level2</li>'], jasmine.any(Object));
done();
})
.catch((error)=>{
fail(error);
});
});
});
});