ohayolibs
Version:
Ohayo is a set of essential modules for ohayojp.
720 lines (702 loc) • 28.2 kB
text/typescript
import { ACLService } from '@ohayo/acl';
import { OhayoI18NService, OhayoI18NServiceFake } from '@ohayo/theme';
import { deepGet } from '@ohayo/util';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { STColumnSource, STColumnSourceProcessOptions } from '../st-column-source';
import { STRowSource } from '../st-row.directive';
import { STWidgetRegistry } from '../st-widget';
import { ST_DEFULAT_CONFIG } from '../st.config';
import { STColumn, STColumnButtonPop, STIcon, STResizable, STWidthMode } from '../st.interfaces';
import { _STColumn } from '../st.types';
const i18nResult = 'zh';
class MockI18NServiceFake extends OhayoI18NServiceFake {
fanyi(_key: string): string {
return i18nResult;
}
}
class MockDomSanitizer {
bypassSecurityTrustHtml(text: string): string {
return text;
}
}
const widthMode: STWidthMode = {
type: 'default',
strictBehavior: 'truncate',
};
describe('st: column-source', () => {
let aclSrv: ACLService | null;
let i18nSrv: OhayoI18NService | null;
let srv: STColumnSource;
let rowSrv: STRowSource;
let stWidgetRegistry: STWidgetRegistry;
let page: PageObject;
const options: STColumnSourceProcessOptions = { widthMode, resizable: { disabled: true } };
function genModule(other: { acl?: boolean; i18n?: boolean; cog?: any }): void {
aclSrv = other.acl ? new ACLService({ merge: (_: any, def: any) => def } as any) : null;
i18nSrv = other.i18n ? new MockI18NServiceFake() : null;
rowSrv = new STRowSource();
stWidgetRegistry = new STWidgetRegistry();
srv = new STColumnSource(new MockDomSanitizer() as any, rowSrv, aclSrv!, i18nSrv!, stWidgetRegistry);
srv.setCog(other.cog || ST_DEFULAT_CONFIG);
page = new PageObject();
}
it('should be throw error when is empty columns', () => {
expect(() => {
genModule({});
srv.process(null!, { widthMode: null!, resizable: {} });
}).toThrow();
expect(() => {
genModule({});
srv.process([], options);
}).toThrow();
});
describe('[columns property]', () => {
beforeEach(() => genModule({}));
describe('[index]', () => {
it('support undefined', () => {
page.expectValue([{ title: '' }], undefined);
});
it('support null', () => {
page.expectValue([{ title: '', index: null }], undefined);
});
it('support string', () => {
page.expectValue([{ title: '', index: 'id' }], 'id');
});
it('support array', () => {
page.expectValue([{ title: '', index: ['prices', 'fix'] }], 'prices.fix');
});
it('support a.b', () => {
page.expectValue([{ title: '', index: 'prices.fix' }], 'prices.fix');
});
});
describe('[type]', () => {
describe(`with no`, () => {
it('should be working', () => {
const res = srv.process([{ title: '', type: 'no' }], options).columns;
expect(res[0].type).toBe('no');
expect(res[0].noIndex).toBe(1);
});
it('should be start zero', () => {
const res = srv.process([{ title: '', type: 'no', noIndex: 0 }], options).columns;
expect(res[0].type).toBe('no');
expect(res[0].noIndex).toBe(0);
});
it('should be custom by funciton', () => {
const res = srv.process([{ title: '', type: 'no', noIndex: () => 10 }], options).columns;
expect(res[0].type).toBe('no');
expect(typeof res[0].noIndex).toBe('function');
});
});
describe(`with checkbox`, () => {
it('should be keep an empty list', () => {
const res = srv.process([{ title: '', index: 'id', type: 'checkbox' }], options).columns;
expect(res[0].selections).not.toBeNull();
expect(res[0].selections!.length).toBe(0);
});
it('should be throw error when mulit column', () => {
expect(() => {
srv.process(
[
{ title: '1', index: 'id', type: 'checkbox' },
{ title: '2', index: 'id', type: 'checkbox' },
],
options,
);
}).toThrow();
});
it('should auto 50px width when without specified with value', () => {
page.expectValue([{ title: '', index: 'id', type: 'checkbox' }], '50px', 'width');
});
it('should auto 62px width when specifyied selections and without specified with value', () => {
page.expectValue(
[
{
title: '',
index: 'id',
type: 'checkbox',
selections: [{ text: '', select: () => true }],
},
],
'62px',
'width',
);
});
it('should be width', () => {
page.expectValue([{ title: '', index: 'id', type: 'checkbox', width: '65px' }], '65px', 'width');
});
});
describe(`with radio`, () => {
it('should be throw error when mulit column', () => {
expect(() => {
srv.process(
[
{ title: '1', index: 'id', type: 'radio' },
{ title: '2', index: 'id', type: 'radio' },
],
options,
);
}).toThrow();
});
it('should auto 50px width when without specified with value', () => {
page.expectValue([{ title: '', index: 'id', type: 'radio' }], '50px', 'width');
});
it('should be specify width', () => {
page.expectValue([{ title: '', index: 'id', type: 'radio', width: '150px' }], '150px', 'width');
});
});
describe(`with yn`, () => {
it('should be auto specified truth is [true]', () => {
const res = srv.process([{ title: '', index: 'id', type: 'yn' }], options).columns[0];
expect(res.yn).not.toBeNull();
expect(res.yn!.truth).toBe(true);
});
it('should be spcified yes value', () => {
const res = srv.process([{ title: '', index: 'id', type: 'yn', yn: { yes: 'Y' } }], options).columns[0];
expect(res.yn).not.toBeNull();
expect(res.yn!.yes).toBe('Y');
});
it('should be spcified no value', () => {
const res = srv.process([{ title: '', index: 'id', type: 'yn', yn: { no: 'N' } }], options).columns[0];
expect(res.yn).not.toBeNull();
expect(res.yn!.no).toBe('N');
});
});
describe(`with widget`, () => {
it('should be working', () => {
spyOn(stWidgetRegistry, 'has').and.returnValue(true);
const res = srv.process([{ title: '', index: 'id', type: 'widget', widget: { type: 'test' } }], options).columns[0];
expect(res.type).toBe('widget');
});
it('should be remove type when widget not specified', () => {
const res = srv.process([{ title: '', index: 'id', type: 'widget' }], options).columns[0];
expect(res.type).toBeUndefined();
});
it('should be remove type when widget is not found', () => {
spyOn(stWidgetRegistry, 'has').and.returnValue(false);
const res = srv.process([{ title: '', index: 'id', type: 'widget', widget: { type: 'test' } }], options).columns[0];
expect(res.type).toBeUndefined();
});
});
describe('invalid type', () => {
it('when not specify click value', () => {
page
.expectValue([{ title: '', type: 'link' }], '', 'type')
.expectValue([{ title: '', type: 'link', click: () => true }], 'link', 'type');
});
it('when not specify badge value', () => {
page
.expectValue([{ title: '', type: 'badge' }], '', 'type')
.expectValue([{ title: '', type: 'badge', badge: {} }], 'badge', 'type');
});
it('when not specify tag value', () => {
page.expectValue([{ title: '', type: 'tag' }], '', 'type').expectValue([{ title: '', type: 'tag', tag: {} }], 'tag', 'type');
});
});
});
describe('[width]', () => {
it('should be support number type', () => {
page.expectValue([{ title: '', index: 'id', width: 65 }], '65px', 'width');
});
it('should be support string type', () => {
page.expectValue([{ title: '', index: 'id', width: '65px' }], '65px', 'width');
});
});
describe('[className]', () => {
it('should be custom class name', () => {
page.expectValue([{ title: '', type: 'number', className: 'aa' }], 'aa', 'className');
});
it('should be auto text-right when type is number', () => {
page.expectValue([{ title: '', type: 'number' }], 'text-right', 'className');
});
it('should be auto text-right when type is currency', () => {
page.expectValue([{ title: '', type: 'currency' }], 'text-right', 'className');
});
it('should be auto text-center when type is date', () => {
page.expectValue([{ title: '', type: 'date' }], 'text-center', 'className');
});
});
describe('[iif]', () => {
it('when return true', () => {
const res = srv.process([{ title: '', iif: () => true }], options).columns;
expect(res.length).toBe(1);
});
it('when return false', () => {
const res = srv.process([{ title: '', iif: () => false }], options).columns;
expect(res.length).toBe(0);
});
});
describe('[sort]', () => {
it('should be disabled', () => {
expect(srv.process([{ title: '' }], options).columns[0]._sort!.enabled).toBe(false);
});
it('should be enabled when is true', () => {
expect(srv.process([{ title: '', sort: true }], options).columns[0]._sort!.enabled).toBe(true);
});
it('should be enabled when is string', () => {
const res = srv.process([{ title: '', sort: 'true' }], options).columns[0]._sort!;
expect(res.enabled).toBe(true);
expect(res.key).toBe('true');
});
it('should be enabled when is object', () => {
const res = srv.process([{ title: '', sort: { default: 'ascend' } }], options).columns[0]._sort!;
expect(res.enabled).toBe(true);
expect(res.default).toBe('ascend');
});
it('should be used index when key is null', () => {
const res = srv.process([{ title: '', index: 'aa', sort: { key: null } }], options).columns[0]._sort!;
expect(res.enabled).toBe(true);
expect(res.key).toBe('aa');
});
});
describe('[filter]', () => {
it('should be disabled when invalid menus', () => {
const res = srv.process([{ title: '', filter: { menus: [] } }], options).columns[0].filter;
expect(res).toBeNull();
});
it('should be used index when key is null', () => {
const res = srv.process(
[
{
title: '',
index: 'aa',
filter: { menus: [{ text: '' }], key: null },
},
],
options,
).columns[0];
expect(res.filter!.key).toBe('aa');
});
it('should be used index when key is undefined', () => {
const res = srv.process(
[
{
title: '',
index: 'aa',
filter: { menus: [{ text: '' }] },
},
],
options,
).columns[0];
expect(res.filter!.key).toBe('aa');
});
it('should be key', () => {
const res = srv.process(
[
{
title: '',
index: 'aa',
filter: { menus: [{ text: '' }], key: 'aaa' },
},
],
options,
).columns[0];
expect(res.filter!.key).toBe('aaa');
});
describe('#multiple', () => {
it('should be default to true when is null', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '' }] } }], options).columns[0].filter;
expect(res!.multiple).toBe(true);
});
it('should be specify value', () => {
const res = srv.process([{ title: '', filter: { multiple: false, menus: [{ text: '' }] } }], options).columns[0].filter;
expect(res!.multiple).toBe(false);
});
});
describe('#confirmText', () => {
it('should be i18n when is null', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '' }] } }], options).columns[0].filter;
expect(res!.confirmText).toBe(undefined);
});
it('should be specify value', () => {
const res = srv.process(
[
{
title: '',
filter: { confirmText: 'yes', menus: [{ text: '' }] },
},
],
options,
).columns[0].filter;
expect(res!.confirmText).toBe('yes');
});
});
describe('#clearText', () => {
it('should be i18n when is null', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '' }] } }], options).columns[0].filter;
expect(res!.clearText).toBe(undefined);
});
it('should be specify value', () => {
const res = srv.process(
[
{
title: '',
filter: { clearText: 'reset', menus: [{ text: '' }] },
},
],
options,
).columns[0].filter;
expect(res!.clearText).toBe('reset');
});
});
describe('#icon', () => {
it('should be default to [filter] when is null', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '' }] } }], options).columns[0].filter!.icon as STIcon;
expect(res.type).toBe('filter');
});
it('should be specify value', () => {
const res = srv.process([{ title: '', filter: { icon: 'icona', menus: [{ text: '' }] } }], options).columns[0].filter!
.icon as STIcon;
expect(res.type).toBe('icona');
});
it('should be specify STIcon value', () => {
const res = srv.process([{ title: '', filter: { icon: { type: 'aa' }, menus: [{ text: '' }] } }], options).columns[0].filter!
.icon as STIcon;
expect(res.type).toBe('aa');
});
});
describe('#default', () => {
it('when menus contain checked', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '', checked: true }] } }], options).columns[0].filter;
expect(res!.default).toBe(true);
});
it('when menus non-contain checked', () => {
const res = srv.process([{ title: '', filter: { menus: [{ text: '' }] } }], options).columns[0].filter;
expect(res!.default).toBe(false);
});
});
describe('#type', () => {
describe('with keyword', () => {
it('should be ingore specify menus values', () => {
const res = srv.process([{ title: '', filter: { type: 'keyword' } }], options).columns[0].filter;
expect(res!.menus!.length).toBe(1);
});
it('should be specify menus values', () => {
const res = srv.process([{ title: '', filter: { type: 'keyword', menus: [{ text: 'a' }] } }], options).columns[0].filter;
expect(res!.menus!.length).toBe(1);
expect(res!.menus![0].text).toBe('a');
});
});
});
});
describe('[buttons]', () => {
describe('#pop', () => {
it('should be pop is true when type of del', () => {
const newColumns = srv.process([{ title: '', buttons: [{ text: '', type: 'del' }] }], options).columns;
const pop = newColumns[0].buttons![0].pop as STColumnButtonPop;
expect(pop != null).toBe(true);
expect(pop.condition!(null!)).toBe(false);
});
it('should be pop is false when type is null or false', () => {
let newColumns = srv.process([{ title: '', buttons: [{ text: '' }] }], options).columns;
expect(newColumns[0].buttons![0].pop).toBe(false);
newColumns = srv.process([{ title: '', buttons: [{ text: '', pop: false }] }], options).columns;
expect(newColumns[0].buttons![0].pop).toBe(false);
});
it('should be pop.title default to 确认删除吗?', () => {
page.expectBtnValue([{ title: '', buttons: [{ text: '', type: 'del' }] }], '确认删除吗?', 'pop.title');
});
it('should be specify pop is string type', () => {
page.expectBtnValue([{ title: '', buttons: [{ text: '', type: 'del', pop: 'aaa' }] }], 'aaa', 'pop.title');
});
it('should be specify pop is object type', () => {
page.expectBtnValue([{ title: '', buttons: [{ text: '', type: 'del', pop: { title: 'aaa' } }] }], 'aaa', 'pop.title');
});
it('should be specify condition and return a true value', () => {
const newColumns = srv.process([{ title: '', buttons: [{ text: '', type: 'del', pop: { condition: () => true } }] }], options)
.columns;
const pop = newColumns[0].buttons![0].pop as STColumnButtonPop;
expect(pop != null).toBe(true);
expect(pop.condition!(null!)).toBe(true);
});
});
describe('#icon', () => {
it('should be string', () => {
page.expectBtnValue([{ title: '', buttons: [{ text: '', icon: 'edit', type: 'del' }] }], 'edit', 'icon.type');
});
it('should be object', () => {
page.expectBtnValue(
[
{
title: '',
buttons: [{ text: '', icon: { type: 'edit', theme: 'fill' }, type: 'del' }],
},
],
'fill',
'icon.theme',
);
});
});
describe('#iif', () => {
it('should be running', () => {
const res = srv.process([{ title: '', buttons: [{ text: '' }] }], options).columns[0].buttons![0];
expect(res.iif!(null!, null!, null!)).toBe(true);
});
it('should be support condition', () => {
const res = srv.process([{ title: '', buttons: [{ text: '', iif: () => false }] }], options).columns[0].buttons![0];
expect(res.iif!(null!, null!, null!)).toBe(false);
});
it('should be support children', () => {
const res = srv.process([{ title: '', buttons: [{ text: '', children: [{ text: '', iif: () => false }] }] }], options).columns[0]
.buttons![0].children![0];
expect(res.iif!(null!, null!, null!)).toBe(false);
});
});
describe('#children', () => {
it('should be', () => {
const res = srv.process(
[
{
title: '',
buttons: [{ text: '', children: [{ text: '', type: 'del' }] }],
},
],
options,
).columns[0].buttons![0];
expect(res.children!.length).toBe(1);
expect(res.children![0].pop != null).toBe(true);
});
it('should be support condition', () => {
const res = srv.process(
[
{
title: '',
buttons: [{ text: '', children: [{ text: '', iif: () => false }] }],
},
],
options,
).columns[0].buttons![0];
expect(res.children![0].iif!(null!, null!, null!)).toBe(false);
});
});
describe('#type', () => {
describe('with modal', () => {
it('should specify modal parameter', () => {
spyOn(console, 'warn');
const res = srv.process([{ title: '', buttons: [{ text: '', type: 'modal', modal: {} }] }], options).columns[0].buttons![0];
expect(console.warn).toHaveBeenCalled();
expect(res.type).toBe('none');
});
it('should be apply default values', () => {
const res = srv.process([{ title: '', buttons: [{ text: '', type: 'modal', modal: { component: {} } }] }], options).columns[0]
.buttons![0];
expect(res.modal!.paramsName).toBe('record');
});
});
describe('with drawer', () => {
it('should specify drawer parameter', () => {
spyOn(console, 'warn');
const res = srv.process([{ title: '', buttons: [{ text: '', type: 'drawer', drawer: {} }] }], options).columns[0].buttons![0];
expect(console.warn).toHaveBeenCalled();
expect(res.type).toBe('none');
});
it('should be apply default values', () => {
const res = srv.process([{ title: '', buttons: [{ text: '', type: 'drawer', drawer: { component: {} } }] }], options).columns[0]
.buttons![0];
expect(res.drawer!.paramsName).toBe('record');
});
});
});
});
describe('[render]', () => {
beforeEach(() => {
spyOn(rowSrv, 'getTitle');
spyOn(rowSrv, 'getRow');
});
it('should be restore render row elementref', () => {
expect(rowSrv.getRow).not.toHaveBeenCalled();
// tslint:disable-next-line:no-unused-expression
srv.process([{ title: '', render: 'a' }], options).columns[0];
expect(rowSrv.getRow).toHaveBeenCalled();
});
it('should be restore render title elementref', () => {
expect(rowSrv.getTitle).not.toHaveBeenCalled();
// tslint:disable-next-line:no-unused-expression
srv.process([{ title: '', renderTitle: 'a' }], options).columns[0];
expect(rowSrv.getTitle).toHaveBeenCalled();
});
it('#restoreAllRender', () => {
expect(rowSrv.getRow).not.toHaveBeenCalled();
expect(rowSrv.getTitle).not.toHaveBeenCalled();
srv.restoreAllRender([{ title: '', render: 'a', renderTitle: 'b' }] as _STColumn[]);
expect(rowSrv.getRow).toHaveBeenCalled();
expect(rowSrv.getTitle).toHaveBeenCalled();
});
it('should be template ref', () => {
const mockTemplateRef: NzSafeAny = {};
expect(rowSrv.getRow).not.toHaveBeenCalled();
expect(rowSrv.getTitle).not.toHaveBeenCalled();
const columns: _STColumn[] = [{ title: '', render: mockTemplateRef, renderTitle: mockTemplateRef }];
srv.restoreAllRender(columns);
expect(rowSrv.getRow).not.toHaveBeenCalled();
expect(rowSrv.getTitle).not.toHaveBeenCalled();
expect(columns[0].render).toBe(mockTemplateRef);
});
});
describe('[fixed]', () => {
it('should be fixed left column', () => {
const res = srv.process(
[
{ title: '1', index: 'id', fixed: 'left', width: '100px' },
{ title: '2', index: 'id', fixed: 'left', width: '100px' },
{ title: '3', index: 'id', fixed: 'left', width: '100px' },
],
options,
).columns;
expect(res[0]._left).toBe('0px');
expect(res[1]._left).toBe('100px');
expect(res[2]._left).toBe('200px');
});
it('should be fixed right column', () => {
const res = srv.process(
[
{ title: '1', index: 'id', fixed: 'right', width: '100px' },
{ title: '2', index: 'id', fixed: 'right', width: '100px' },
{ title: '3', index: 'id', fixed: 'right', width: '100px' },
],
options,
).columns;
expect(res[0]._right).toBe('200px');
expect(res[1]._right).toBe('100px');
expect(res[2]._right).toBe('0px');
});
});
describe('[grouping-columns]', () => {
it('should be working', () => {
const res = srv.process([{ title: '1', index: 'id', children: [{ index: 'id' }] }], options);
expect(res.headers.length).toBe(2);
});
it('should be ingored grouping columns when children when is empty', () => {
const res = srv.process([{ title: '1', index: 'id', children: [] }], options);
expect(res.headers.length).toBe(1);
});
});
describe('[resizable]', () => {
it('should be working', () => {
const res = srv.process([{ title: '1', index: 'id', resizable: { minWidth: 100 } }], options).columns[0].resizable as STResizable;
expect(res.minWidth).toBe(100);
});
});
});
describe('[acl]', () => {
beforeEach(() => {
genModule({ acl: true });
aclSrv!.set({ role: ['user'] });
});
it('in columns', () => {
page.expectCount([{ title: '', index: 'id' }], 1).expectCount([{ title: '', index: 'id', acl: 'admin' }], 0);
});
it('in selections', () => {
page
.expectCount(
[
{
title: '',
index: 'id',
selections: [{ text: '1', select: () => { } }],
},
],
1,
'selections',
)
.expectCount(
[
{
title: '',
index: 'id',
selections: [{ text: '1', select: () => { }, acl: 'admin' }],
},
],
0,
'selections',
);
});
it('in filter', () => {
expect(
srv.process(
[
{
title: '',
index: 'id',
filter: {
menus: [{ text: '1' }],
},
},
],
options,
).columns[0].filter!.menus!.length,
).toBe(1);
expect(
srv.process(
[
{
title: '',
index: 'id',
filter: {
menus: [{ text: '1', acl: 'admin' }],
},
},
],
options,
).columns[0]!.filter as any,
).toBe(null);
});
it('in buttons', () => {
page.expectCount([{ title: '', buttons: [{ text: '<p class="j-btn"></p>' }] }], 1, 'buttons').expectCount(
[
{
title: '',
buttons: [{ text: '<p class="j-btn"></p>', acl: 'admin' }],
},
],
0,
'buttons',
);
});
});
describe('[i18n]', () => {
const curLang = 'en';
beforeEach(() => {
genModule({ i18n: true });
spyOn(i18nSrv!, 'fanyi').and.callFake(() => curLang);
});
it('in title', () => {
srv.process([{ title: '', index: 'id' }], options);
expect(i18nSrv!.fanyi).not.toHaveBeenCalled();
});
it('in buttons', () => {
srv.process([{ title: '', index: 'id', buttons: [{ text: '' }] }], options);
expect(i18nSrv!.fanyi).not.toHaveBeenCalled();
srv.process([{ title: '', index: 'id', buttons: [{ text: '', i18n: 'a' }] }], options);
expect(i18nSrv!.fanyi).toHaveBeenCalled();
});
});
it('should be merge default config', () => {
genModule({ cog: { size: 'lg' } });
const res = srv.process([{ title: '', buttons: [{ text: '', type: 'modal', modal: { component: {} } }] }], options).columns;
expect(res[0].buttons![0].modal!.paramsName).toBe('record');
});
class PageObject {
expectValue(columns: STColumn[], value: any, path: string = 'indexKey'): this {
const newColumns = srv.process(columns, options).columns;
expect(newColumns.length).toBeGreaterThan(0);
expect(deepGet(newColumns[0], path)).toBe(value);
return this;
}
expectBtnValue(columns: STColumn[], value: any, path: string = 'indexKey'): this {
const newColumns = srv.process(columns, options).columns;
expect(newColumns.length).toBeGreaterThan(0);
expect(deepGet(newColumns[0].buttons![0], path)).toBe(value);
return this;
}
expectCount(columns: STColumn[], count: number = 1, type: string = ''): this {
const newColumns = srv.process(columns, options).columns;
if (type) {
expect(newColumns.length).toBe(1);
expect((newColumns[0] as { [key: string]: any })[type].length).toBe(count);
} else {
expect(newColumns.length).toBe(count);
}
return this;
}
}
});