UNPKG

ohayolibs

Version:

Ohayo is a set of essential modules for ohayojp.

720 lines (702 loc) 28.2 kB
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; } } });