Skip to content

Commit df9cb8c

Browse files
close function can take switching parameter
with default value of true
1 parent 6f87b73 commit df9cb8c

File tree

2 files changed

+134
-11
lines changed

2 files changed

+134
-11
lines changed

src/utils/api/api.factory.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ const _apiProps = {
4646
getCopyData: function () { return this.helper.getCopyState(this.stateRef); },
4747
isSelected: function (id = missingParamEr('isSelected')) { return this.stateRef.selectedTabID == id; },
4848
isOpen: function (id = missingParamEr('isOpen')) { return this.stateRef.openTabIDs.indexOf(id) >= 0; },
49-
_getOnChangePromise: function () {
49+
_getFlushEffectsPromise: function () {
5050
return new (Promise)(resolve => { this.one('_onFlushEffects', function () { resolve.apply(this, arguments); }); });
5151
},
5252
select: function (id = missingParamEr('select')) {
5353
if (id)
5454
id = id + '';//make sure id is string
55-
const result = this._getOnChangePromise();
55+
const result = this._getFlushEffectsPromise();
5656
this._select(id);
5757
return result;
5858
},
@@ -86,20 +86,20 @@ const _apiProps = {
8686
},
8787
open: function (tabObj = missingParamEr('open')) {
8888
const newTabObj = this._addTab(tabObj, { defaultPanelComponent: this.getOption('defaultPanelComponent') });
89-
const result = this._getOnChangePromise();
89+
const result = this._getFlushEffectsPromise();
9090
this._open(newTabObj.id);
9191
return result;
9292
},
9393
__close: function (id) {
94-
const result = this._getOnChangePromise();
94+
const result = this._getFlushEffectsPromise();
9595
this._close(id);
9696
this._removeTab(id);
9797
return result;
9898
},
99-
close: function (id = missingParamEr('close')) {
99+
close: function (id = missingParamEr('close'), switching = true) {
100100
if (id)
101101
id = id + '';//make sure id is string
102-
if (this.isSelected(id)) {
102+
if (switching && this.isOpen(id) && this.isSelected(id)) {
103103
const _openTabsId = [...this.stateRef.openTabIDs];
104104
_openTabsId.splice(_openTabsId.indexOf(id), 1);
105105
this.select(this._findTabIdForSwitching());
@@ -109,7 +109,7 @@ const _apiProps = {
109109
return this.__close(id);
110110
},
111111
refresh: function () {
112-
const result = this._getOnChangePromise();
112+
const result = this._getFlushEffectsPromise();
113113
this._refresh();
114114
return result;
115115
}
@@ -148,7 +148,7 @@ Helper.setNoneEnumProps(_apiProps, {
148148
const el = e.target, parentEl = el.parentElement, { closeClass, tabClass } = this.optionsManager.setting;
149149
if (el.className.includes(closeClass) && parentEl && parentEl.lastChild && (parentEl.lastChild == el)
150150
&& parentEl.className.includes(tabClass)) {
151-
(this.getOption('beforeClose').call(this.userProxy, e, id) !== false) && this.close(id);
151+
(this.getOption('beforeClose').call(this.userProxy, e, id) !== false) && this.close(id, true);
152152
}
153153
else {
154154
(this.getOption('beforeSelect').call(this.userProxy, e, id) !== false) && this.select(id);

src/utils/api/api.factory.test.js

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,135 @@ describe('Api.prototype.open : ', () => {
4444
const obj = new (apiConstructor)(getDeps, { options: {} });
4545
Object.assign(obj, {
4646
_addTab: jest.fn(() => ({ id: '2' })),
47-
_getOnChangePromise: jest.fn(() => Promise),
47+
_getFlushEffectsPromise: jest.fn(() => Promise),
4848
_open: jest.fn(() => { })
4949
});
5050
obj.open({ id: '2' });
5151
expect(obj._addTab.mock.calls.length === 1).toBe(true);
52-
expect(obj._addTab).toHaveBeenCalledBefore(obj._getOnChangePromise);
53-
expect(obj._getOnChangePromise).toHaveBeenCalledBefore(obj._open);
52+
expect(obj._addTab).toHaveBeenCalledBefore(obj._getFlushEffectsPromise);
53+
expect(obj._getFlushEffectsPromise).toHaveBeenCalledBefore(obj._open);
54+
});
55+
});
56+
describe('Api.prototype.close : ', () => {
57+
test('it throws an error if is called with undefined id parameter', () => {
58+
const obj = new (apiConstructor)(getDeps, { options: {} });
59+
expect.assertions(2);
60+
try {
61+
obj.close();
62+
} catch (er) {
63+
expect(1 === 1).toBe(true);
64+
}
65+
try {
66+
obj.close(undefined);
67+
} catch (er) {
68+
expect(1 === 1).toBe(true);
69+
}
70+
});
71+
test('it should call select function internally if switch parameter was true and tab was already opended and selected', () => {
72+
const obj = new (apiConstructor)(getDeps, { options: {} });
73+
expect.assertions(3);
74+
Object.assign(obj, {
75+
__close: jest.fn(() => { return Promise.resolve({ currentData: {}, instance: {} }) }),
76+
select: jest.fn(() => Promise),
77+
isOpen: jest.fn(() => true),
78+
stateRef: { openTabIDs: ['1', '2'], selectedTabID: '2' },
79+
_findTabIdForSwitching: jest.fn(() => '1'),
80+
isSelected: jest.fn(() => true)
81+
});
82+
return obj.close('2', true).then(result => {
83+
expect(result.hasOwnProperty('currentData') && result.hasOwnProperty('instance')).toBe(true);
84+
expect(obj.__close.mock.calls.length === 1).toBe(true);
85+
expect(obj.select).toHaveBeenCalledBefore(obj.__close);
86+
});
87+
});
88+
test('switch parameter default value is true', () => {
89+
const obj = new (apiConstructor)(getDeps, { options: {} });
90+
expect.assertions(3);
91+
Object.assign(obj, {
92+
__close: jest.fn(() => { return Promise.resolve({ currentData: {}, instance: {} }) }),
93+
select: jest.fn(() => Promise),
94+
isOpen: jest.fn(() => true),
95+
stateRef: { openTabIDs: ['1', '2'], selectedTabID: '2' },
96+
_findTabIdForSwitching: jest.fn(() => '1'),
97+
isSelected: jest.fn(() => true)
98+
});
99+
return obj.close('2').then(result => {
100+
expect(result.hasOwnProperty('currentData') && result.hasOwnProperty('instance')).toBe(true);
101+
expect(obj.__close.mock.calls.length === 1).toBe(true);
102+
expect(obj.select).toHaveBeenCalledBefore(obj.__close);
103+
});
104+
});
105+
test('it should not call select function internally if switch parameter was false', () => {
106+
const obj = new (apiConstructor)(getDeps, { options: {} });
107+
expect.assertions(3);
108+
Object.assign(obj, {
109+
__close: jest.fn(() => { return Promise.resolve({ currentData: {}, instance: {} }) }),
110+
select: jest.fn(() => Promise),
111+
isOpen: jest.fn(() => true),
112+
stateRef: { openTabIDs: ['1', '2'], selectedTabID: '2' },
113+
_findTabIdForSwitching: jest.fn(() => '1'),
114+
isSelected: jest.fn(() => true)
115+
});
116+
return obj.close('2', false).then(result => {
117+
expect(result.hasOwnProperty('currentData') && result.hasOwnProperty('instance')).toBe(true);
118+
expect(obj.__close.mock.calls.length === 1).toBe(true);
119+
expect(obj.select.mock.calls.length === 0).toBe(true);
120+
});
121+
});
122+
test('it should not call select function internally if tab was not opened', () => {
123+
const obj = new (apiConstructor)(getDeps, { options: {} });
124+
expect.assertions(3);
125+
Object.assign(obj, {
126+
__close: jest.fn(() => { return Promise.resolve({ currentData: {}, instance: {} }) }),
127+
select: jest.fn(() => Promise),
128+
isOpen: jest.fn(() => false),
129+
stateRef: { openTabIDs: ['1', '2'], selectedTabID: '2' },
130+
_findTabIdForSwitching: jest.fn(() => '1'),
131+
isSelected: jest.fn(() => true)
132+
});
133+
return obj.close('2', true).then(result => {
134+
expect(result.hasOwnProperty('currentData') && result.hasOwnProperty('instance')).toBe(true);
135+
expect(obj.__close.mock.calls.length === 1).toBe(true);
136+
expect(obj.select.mock.calls.length === 0).toBe(true);
137+
});
138+
});
139+
test('it should not call select function internally if tab was not selected', () => {
140+
const obj = new (apiConstructor)(getDeps, { options: {} });
141+
expect.assertions(3);
142+
Object.assign(obj, {
143+
__close: jest.fn(() => { return Promise.resolve({ currentData: {}, instance: {} }) }),
144+
select: jest.fn(() => Promise),
145+
isOpen: jest.fn(() => true),
146+
stateRef: { openTabIDs: ['1', '2'], selectedTabID: '2' },
147+
_findTabIdForSwitching: jest.fn(() => '1'),
148+
isSelected: jest.fn(() => false)
149+
});
150+
return obj.close('2', true).then(result => {
151+
expect(result.hasOwnProperty('currentData') && result.hasOwnProperty('instance')).toBe(true);
152+
expect(obj.__close.mock.calls.length === 1).toBe(true);
153+
expect(obj.select.mock.calls.length === 0).toBe(true);
154+
});
155+
});
156+
test('eventHandlerFactory method calls close function with switching=true if beforeClose callback returned true', () => {
157+
const obj = new (apiConstructor)(getDeps, { options: {} });
158+
const id = '1';
159+
const e = {
160+
target: {
161+
className: 'rc-dyn-tabs-close'
162+
}
163+
};
164+
const parentElement = {
165+
className: 'rc-dyn-tabs-tab',
166+
lastChild: e.target
167+
};
168+
e.target.parentElement = parentElement;
169+
Object.assign(obj, {
170+
close: jest.fn(() => Promise),
171+
beforeClose: jest.fn(() => true),
172+
});
173+
obj.eventHandlerFactory({ id, e });
174+
expect(obj.close.mock.calls.length === 1).toBe(true);
175+
expect(obj.close.mock.calls[0][0] === id).toBe(true);
176+
expect(obj.close.mock.calls[0][1] === true).toBe(true);
54177
});
55178
});

0 commit comments

Comments
 (0)