Skip to content

Commit

Permalink
feat(tests): add more Extensions unit tests (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed Jun 7, 2019
1 parent 72fa5db commit 5f6f3b0
Show file tree
Hide file tree
Showing 16 changed files with 1,878 additions and 302 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ describe('cellExternalCopyManagerExtension', () => {
} as GridOption;

beforeEach(() => {
extensionUtility = new ExtensionUtility({} as I18N, sharedService);
sharedService = new SharedService();
extensionUtility = new ExtensionUtility({} as I18N, sharedService);
extension = new CellExternalCopyManagerExtension(extensionUtility, sharedService);
});

Expand All @@ -73,11 +73,11 @@ describe('cellExternalCopyManagerExtension', () => {

it('should register the addon', () => {
const pluginSpy = jest.spyOn(SharedService.prototype.grid, 'registerPlugin');
const optionSpy = jest.spyOn(SharedService.prototype.gridOptions.excelCopyBufferOptions, 'onExtensionRegistered');
const onRegisteredSpy = jest.spyOn(SharedService.prototype.gridOptions.excelCopyBufferOptions, 'onExtensionRegistered');

const instance = extension.register();

expect(optionSpy).toHaveBeenCalledWith(instance);
expect(onRegisteredSpy).toHaveBeenCalledWith(instance);
expect(pluginSpy).toHaveBeenCalledWith(instance);
expect(mockSelectionModel).toHaveBeenCalled();
expect(mockAddon).toHaveBeenCalledWith({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { I18N } from 'aurelia-i18n';
import { EventAggregator } from 'aurelia-event-aggregator';
import { BindingSignaler } from 'aurelia-templating-resources';
import { GridOption } from '../../models/gridOption.interface';
import { ColumnPickerExtension } from '../columnPickerExtension';
import { ExtensionUtility } from '../extensionUtility';
import { SharedService } from '../../services/shared.service';
import { Column } from '../../models';

declare var Slick: any;

const gridStub = {
getOptions: jest.fn(),
registerPlugin: jest.fn(),
};

const mockAddon = jest.fn().mockImplementation(() => ({
init: jest.fn(),
destroy: jest.fn(),
onColumnsChanged: new Slick.Event(),
}));

jest.mock('slickgrid/controls/slick.columnpicker', () => mockAddon);
Slick.Controls = {
ColumnPicker: mockAddon
};

describe('columnPickerExtension', () => {
const columnsMock: Column[] = [{ id: 'field1', field: 'field1', width: 100, headerKey: 'TITLE' }, { id: 'field2', field: 'field2', width: 75 }];
let extensionUtility: ExtensionUtility;
let i18n: I18N;
let extension: ColumnPickerExtension;
let sharedService: SharedService;

const gridOptionsMock = {
enableColumnPicker: true,
enableTranslate: true,
columnPicker: {
hideForceFitButton: false,
hideSyncResizeButton: true,
onExtensionRegistered: jest.fn(),
onColumnsChanged: (e, args: { columns: Column[] }) => { }
},
} as GridOption;

beforeEach(() => {
sharedService = new SharedService();
i18n = new I18N(new EventAggregator(), new BindingSignaler());
extensionUtility = new ExtensionUtility(i18n, sharedService);
extension = new ColumnPickerExtension(extensionUtility, sharedService);
i18n.setup({
resources: {
en: {
translation: {
TITLE: 'Title', COMMANDS: 'Commands', COLUMNS: 'Columns', FORCE_FIT_COLUMNS: 'Force fit columns', SYNCHRONOUS_RESIZE: 'Synchronous resize'
}
},
fr: {
translation: {
TITLE: 'Titre', COMMANDS: 'Commandes', COLUMNS: 'Colonnes', FORCE_FIT_COLUMNS: 'Ajustement forcé des colonnes', SYNCHRONOUS_RESIZE: 'Redimension synchrone'
}
}
},
lng: '0',
fallbackLng: 'en',
debug: false
});
i18n.setLocale('fr');
});

it('should return null when either the grid object or the grid options is missing', () => {
const output = extension.register();
expect(output).toBeNull();
});

describe('registered addon', () => {
beforeEach(() => {
jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub);
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);
jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(columnsMock);
jest.spyOn(SharedService.prototype, 'columnDefinitions', 'get').mockReturnValue(columnsMock);
});

it('should register the addon', () => {
const onRegisteredSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onExtensionRegistered');
const instance = extension.register();

expect(instance).not.toBeNull();
expect(onRegisteredSpy).toHaveBeenCalledWith(instance);
expect(mockAddon).toHaveBeenCalledWith(columnsMock, gridStub, gridOptionsMock);
});

it('should call internal event handler subscribe and expect the "onColumnSpy" option to be called when addon notify is called', () => {
const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe');
const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onColumnsChanged');

const instance = extension.register();
instance.onColumnsChanged.notify(columnsMock.slice(0, 1), new Slick.EventData(), gridStub);

expect(handlerSpy).toHaveBeenCalledTimes(1);
expect(handlerSpy).toHaveBeenCalledWith(
{ notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
expect.anything()
);
expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), columnsMock.slice(0, 1));
});

it('should dispose of the addon', () => {
const instance = extension.register();
const destroySpy = jest.spyOn(instance, 'destroy');

extension.dispose();

expect(destroySpy).toHaveBeenCalled();
});
});

describe('translateColumnPicker method', () => {
it('should translate the column picker header titles', () => {
const utilitySpy = jest.spyOn(extensionUtility, 'getPickerTitleOutputString');
const translateSpy = jest.spyOn(extensionUtility, 'translateItems');

const instance = extension.register();
extension.translateColumnPicker();
const initSpy = jest.spyOn(instance, 'init');

expect(utilitySpy).toHaveBeenCalled();
expect(translateSpy).toHaveBeenCalled();
expect(initSpy).toHaveBeenCalledWith(gridStub);
expect(SharedService.prototype.gridOptions.columnPicker.columnTitle).toBe('Colonnes');
expect(SharedService.prototype.gridOptions.columnPicker.forceFitTitle).toBe('Ajustement forcé des colonnes');
expect(SharedService.prototype.gridOptions.columnPicker.syncResizeTitle).toBe('Redimension synchrone');
expect(columnsMock).toEqual([
{ id: 'field1', field: 'field1', width: 100, name: 'Titre', headerKey: 'TITLE' },
{ id: 'field2', field: 'field2', width: 75 }
]);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { I18N } from 'aurelia-i18n';
import { GridOption } from '../../models/gridOption.interface';
import { DraggableGroupingExtension } from '../draggableGroupingExtension';
import { ExtensionUtility } from '../extensionUtility';
import { SharedService } from '../../services/shared.service';
import { Grouping } from '../../models';

declare var Slick: any;

const gridStub = {
getOptions: jest.fn(),
registerPlugin: jest.fn(),
};

const mockAddon = jest.fn().mockImplementation(() => ({
init: jest.fn(),
destroy: jest.fn(),
onGroupChanged: new Slick.Event(),
}));

jest.mock('slickgrid/plugins/slick.draggablegrouping', () => mockAddon);
Slick.DraggableGrouping = mockAddon;

describe('draggableGroupingExtension', () => {
let extensionUtility: ExtensionUtility;
let sharedService: SharedService;
let extension: DraggableGroupingExtension;
const gridOptionsMock = {
enableDraggableGrouping: true,
draggableGrouping: {
deleteIconCssClass: 'class',
dropPlaceHolderText: 'test',
groupIconCssClass: 'group-class',
onExtensionRegistered: jest.fn(),
onGroupChanged: (e: Event, args: { caller?: string; groupColumns: Grouping[] }) => { },
}
} as GridOption;

beforeEach(() => {
sharedService = new SharedService();
extensionUtility = new ExtensionUtility({} as I18N, sharedService);
extension = new DraggableGroupingExtension(extensionUtility, sharedService);
});

it('should return null when either the grid object or the grid options is missing', () => {
const output = extension.register();
expect(output).toBeNull();
});

describe('registered addon', () => {
beforeEach(() => {
jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub);
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);
});

it('should register the addon', () => {
const onRegisteredSpy = jest.spyOn(SharedService.prototype.gridOptions.draggableGrouping, 'onExtensionRegistered');
const pluginSpy = jest.spyOn(SharedService.prototype.grid, 'registerPlugin');

const instance = extension.create(gridOptionsMock);
const addon = extension.register();

expect(addon).not.toBeNull();
expect(mockAddon).toHaveBeenCalledWith({
deleteIconCssClass: 'class',
dropPlaceHolderText: 'test',
groupIconCssClass: 'group-class',
onExtensionRegistered: expect.anything(),
onGroupChanged: expect.anything(),
});
expect(onRegisteredSpy).toHaveBeenCalledWith(instance);
expect(pluginSpy).toHaveBeenCalledWith(instance);
});

it('should dispose of the addon', () => {
const instance = extension.create(gridOptionsMock);
const destroySpy = jest.spyOn(instance, 'destroy');

extension.dispose();

expect(destroySpy).toHaveBeenCalled();
});

it('should provide addon options and expect them to be called in the addon constructor', () => {
const optionMock = {
deleteIconCssClass: 'different-class',
dropPlaceHolderText: 'different-test',
groupIconCssClass: 'different-group-class',
};
const addonOptions = { ...gridOptionsMock, draggableGrouping: optionMock };
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(addonOptions);

extension.create(addonOptions);
extension.register();

expect(mockAddon).toHaveBeenCalledWith(optionMock);
});

it('should call internal event handler subscribe and expect the "onGroupChanged" option to be called when addon notify is called', () => {
const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe');
const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.draggableGrouping, 'onGroupChanged');

const instance = extension.create(gridOptionsMock);
extension.register();
instance.onGroupChanged.notify({ caller: 'clear-all', groupColumns: [] }, new Slick.EventData(), gridStub);

expect(handlerSpy).toHaveBeenCalledWith(
{ notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
expect.anything()
);
expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), { caller: 'clear-all', groupColumns: [] });
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { I18N } from 'aurelia-i18n';
import { EventAggregator } from 'aurelia-event-aggregator';
import { BindingSignaler } from 'aurelia-templating-resources';
import { GridOption } from '../../models/gridOption.interface';
import { ExtensionUtility } from '../extensionUtility';
import { SharedService } from '../../services/shared.service';
import { ExtensionName } from '../../models';

declare var Slick: any;

const mockAddon = jest.fn().mockImplementation(() => ({
init: jest.fn(),
destroy: jest.fn()
}));

jest.mock('slickgrid/slick.groupitemmetadataprovider', () => mockAddon);
Slick.Data = {
GroupItemMetadataProvider: mockAddon
};

describe('extensionUtility', () => {
let i18n: I18N;
let sharedService: SharedService;
let utility: ExtensionUtility;

beforeEach(async () => {
sharedService = new SharedService();
i18n = new I18N(new EventAggregator(), new BindingSignaler());
utility = new ExtensionUtility(i18n, sharedService);
i18n.setup({
resources: { en: { translation: { TITLE: 'Title' } }, fr: { translation: { TITLE: 'Titre' } } },
lng: '0',
fallbackLng: 'en',
debug: false
});
await i18n.setLocale('fr');
});

describe('arrayRemoveItemByIndex method', () => {
it('should remove an item from the array', () => {
const input = [{ field: 'field1', name: 'Field 1' }, { field: 'field2', name: 'Field 2' }, { field: 'field3', name: 'Field 3' }];
const expected = [{ field: 'field1', name: 'Field 1' }, { field: 'field3', name: 'Field 3' }];

const output = utility.arrayRemoveItemByIndex(input, 1);
expect(output).toEqual(expected);
});
});

describe('loadExtensionDynamically method', () => {
// we can test only the GroupItemMetadataProvider which is not tested in any other extension test
it('should check that groupItemMetaProvider gets loaded', () => {
utility.loadExtensionDynamically(ExtensionName.groupItemMetaProvider);
const groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider();
expect(mockAddon).toHaveBeenCalled();
expect(groupItemMetadataProvider).not.toBeNull();
});
});

describe('getPickerTitleOutputString method', () => {
it('should translate titleKey when there is one', () => {
const gridOptionsMock = { enableTranslate: true, enableGridMenu: true, gridMenu: { hideForceFitButton: false, hideSyncResizeButton: true, columnTitleKey: 'TITLE' } } as GridOption;
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);

const output = utility.getPickerTitleOutputString('columnTitle', 'gridMenu');

expect(output).toEqual('Titre');
});

it('should return undefined when the given property is not found', () => {
const gridOptionsMock = { enableTranslate: true, enableGridMenu: true, gridMenu: { hideForceFitButton: false, hideSyncResizeButton: true } } as GridOption;
jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);

const output = utility.getPickerTitleOutputString('unknown', 'gridMenu');

expect(output).toEqual(undefined);
});
});

describe('sortItems method', () => {
it('should sort the items by their order property', () => {
const inputArray = [{ field: 'field1', order: 3 }, { field: 'field2', order: 1 }, { field: 'field3', order: 2 }];
const expectedArray = [{ field: 'field2', order: 1 }, { field: 'field3', order: 2 }, { field: 'field1', order: 3 }];

utility.sortItems(inputArray, 'order');

expect(inputArray).toEqual(expectedArray);
});

it('should sort the items by their order property when found and then return the object without the property', () => {
const inputArray = [{ field: 'field1', order: 3 }, { field: 'field3', order: 2 }, { field: 'field2' }];
const expectedArray = [{ field: 'field3', order: 2 }, { field: 'field1', order: 3 }, { field: 'field2' }];

utility.sortItems(inputArray, 'order');

expect(inputArray).toEqual(expectedArray);
});
});
});
Loading

0 comments on commit 5f6f3b0

Please sign in to comment.