added messages list, new client form, logic for client Apps plus others
This commit is contained in:
425
public/libs/tabulator-master/test/unit/modules/SelectRow.spec.js
Normal file
425
public/libs/tabulator-master/test/unit/modules/SelectRow.spec.js
Normal file
@@ -0,0 +1,425 @@
|
||||
import SelectRow from "../../../src/js/modules/SelectRow/SelectRow";
|
||||
|
||||
describe("SelectRow module", () => {
|
||||
/** @type {SelectRow} */
|
||||
let selectRowMod;
|
||||
let mockTable;
|
||||
let mockRows;
|
||||
|
||||
beforeEach(() => {
|
||||
// Create mock optionsList
|
||||
const mockOptionsList = {
|
||||
register: jest.fn(),
|
||||
generate: jest.fn().mockImplementation((defaults, options) => {
|
||||
return { ...defaults, ...options };
|
||||
})
|
||||
};
|
||||
|
||||
// Create mock eventBus
|
||||
const mockEventBus = {
|
||||
subscribe: jest.fn(),
|
||||
unsubscribe: jest.fn(),
|
||||
subscribed: jest.fn(),
|
||||
subscriptionChange: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
chain: jest.fn(),
|
||||
confirm: jest.fn()
|
||||
};
|
||||
|
||||
// Create mock externalEvents
|
||||
const mockExternalEvents = {
|
||||
dispatch: jest.fn(),
|
||||
subscribed: jest.fn(),
|
||||
subscriptionChange: jest.fn()
|
||||
};
|
||||
|
||||
// Create mock rows
|
||||
mockRows = [
|
||||
createMockRow(1),
|
||||
createMockRow(2),
|
||||
createMockRow(3)
|
||||
];
|
||||
|
||||
// Create mock row manager
|
||||
const mockRowManager = {
|
||||
rows: mockRows,
|
||||
findRow: jest.fn((id) => {
|
||||
if (typeof id === 'number') {
|
||||
return mockRows.find(row => row.data.id === id);
|
||||
} else if (typeof id === 'object' && id !== null) {
|
||||
return id;
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
getRows: jest.fn(() => mockRows),
|
||||
getDisplayRows: jest.fn(() => mockRows),
|
||||
getDisplayRowIndex: jest.fn((row) => {
|
||||
return mockRows.indexOf(row);
|
||||
})
|
||||
};
|
||||
|
||||
// Create mock modules object
|
||||
const mockModules = {
|
||||
dataTree: {
|
||||
getChildren: jest.fn(() => [])
|
||||
}
|
||||
};
|
||||
|
||||
// Create a simplified mock of the table
|
||||
mockTable = {
|
||||
options: {
|
||||
selectableRows: "highlight",
|
||||
selectableRowsRangeMode: "drag",
|
||||
selectableRowsRollingSelection: true,
|
||||
selectableRowsPersistence: true,
|
||||
selectableRowsCheck: jest.fn().mockReturnValue(true),
|
||||
dataTreeSelectPropagate: false
|
||||
},
|
||||
rowManager: mockRowManager,
|
||||
columnManager: {
|
||||
optionsList: mockOptionsList
|
||||
},
|
||||
optionsList: mockOptionsList,
|
||||
eventBus: mockEventBus,
|
||||
externalEvents: mockExternalEvents,
|
||||
_clearSelection: jest.fn(),
|
||||
registerTableFunction: jest.fn(),
|
||||
initGuard: jest.fn(),
|
||||
modExists: jest.fn(() => true),
|
||||
modules: mockModules
|
||||
};
|
||||
|
||||
// Mock methods in the SelectRow prototype
|
||||
jest.spyOn(SelectRow.prototype, 'registerTableOption').mockImplementation(function(key, value) {
|
||||
this.table.optionsList.register(key, value);
|
||||
});
|
||||
|
||||
jest.spyOn(SelectRow.prototype, 'registerTableFunction').mockImplementation(function(name, callback) {
|
||||
this.table.registerTableFunction(name, callback);
|
||||
});
|
||||
|
||||
jest.spyOn(SelectRow.prototype, 'registerComponentFunction').mockImplementation(function(component, name, callback) {
|
||||
// Mock component registration
|
||||
});
|
||||
|
||||
jest.spyOn(SelectRow.prototype, 'subscribe').mockImplementation(function(key, callback) {
|
||||
return this.table.eventBus.subscribe(key, callback);
|
||||
});
|
||||
|
||||
jest.spyOn(SelectRow.prototype, 'dispatchExternal').mockImplementation(function(event, ...args) {
|
||||
this.table.externalEvents.dispatch(event, ...args);
|
||||
});
|
||||
|
||||
// Create an instance of the SelectRow module with the mock table
|
||||
selectRowMod = new SelectRow(mockTable);
|
||||
|
||||
// Initialize the module
|
||||
selectRowMod.initialize();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
// Helper function to create mock row objects
|
||||
function createMockRow(id) {
|
||||
const element = document.createElement('div');
|
||||
|
||||
const mockComponent = {
|
||||
getData: jest.fn(() => ({ id: id, name: `Row ${id}` }))
|
||||
};
|
||||
|
||||
const row = {
|
||||
type: "row",
|
||||
data: { id: id, name: `Row ${id}` },
|
||||
modules: {
|
||||
select: {
|
||||
selected: false
|
||||
}
|
||||
},
|
||||
element: element,
|
||||
_row: {
|
||||
modules: {}
|
||||
},
|
||||
getElement: jest.fn(() => element),
|
||||
getComponent: jest.fn(() => mockComponent),
|
||||
getData: jest.fn(() => ({ id: id, name: `Row ${id}` }))
|
||||
};
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
it("should initialize with empty selection", () => {
|
||||
// Check initial state
|
||||
expect(selectRowMod.selectedRows).toEqual([]);
|
||||
expect(selectRowMod.selecting).toBe(false);
|
||||
expect(selectRowMod.lastClickedRow).toBe(false);
|
||||
expect(selectRowMod.selectPrev).toEqual([]);
|
||||
});
|
||||
|
||||
it("should register required table options", () => {
|
||||
// Verify that the correct options were registered
|
||||
expect(mockTable.optionsList.register).toHaveBeenCalledWith("selectableRows", "highlight");
|
||||
expect(mockTable.optionsList.register).toHaveBeenCalledWith("selectableRowsRangeMode", "drag");
|
||||
expect(mockTable.optionsList.register).toHaveBeenCalledWith("selectableRowsRollingSelection", true);
|
||||
expect(mockTable.optionsList.register).toHaveBeenCalledWith("selectableRowsPersistence", true);
|
||||
expect(mockTable.optionsList.register).toHaveBeenCalledWith("selectableRowsCheck", expect.any(Function));
|
||||
});
|
||||
|
||||
it("should register required table functions", () => {
|
||||
// Verify that the correct table functions were registered
|
||||
expect(mockTable.registerTableFunction).toHaveBeenCalledWith("selectRow", expect.any(Function));
|
||||
expect(mockTable.registerTableFunction).toHaveBeenCalledWith("deselectRow", expect.any(Function));
|
||||
expect(mockTable.registerTableFunction).toHaveBeenCalledWith("toggleSelectRow", expect.any(Function));
|
||||
expect(mockTable.registerTableFunction).toHaveBeenCalledWith("getSelectedRows", expect.any(Function));
|
||||
expect(mockTable.registerTableFunction).toHaveBeenCalledWith("getSelectedData", expect.any(Function));
|
||||
});
|
||||
|
||||
it("should subscribe to row events when selectableRows is not false", () => {
|
||||
// Verify that the correct events were subscribed to
|
||||
expect(mockTable.eventBus.subscribe).toHaveBeenCalledWith("row-init", expect.any(Function));
|
||||
expect(mockTable.eventBus.subscribe).toHaveBeenCalledWith("row-deleting", expect.any(Function));
|
||||
expect(mockTable.eventBus.subscribe).toHaveBeenCalledWith("rows-wipe", expect.any(Function));
|
||||
expect(mockTable.eventBus.subscribe).toHaveBeenCalledWith("rows-retrieve", expect.any(Function));
|
||||
});
|
||||
|
||||
it("should check row selectability", () => {
|
||||
const row = mockRows[0];
|
||||
|
||||
// Test the selectableRowsCheck function
|
||||
const result = selectRowMod.checkRowSelectability(row);
|
||||
|
||||
// Check if the function was called with the row component
|
||||
expect(mockTable.options.selectableRowsCheck).toHaveBeenCalled();
|
||||
|
||||
// Verify the result is as expected
|
||||
expect(result).toBe(true);
|
||||
|
||||
// Test with non-row object
|
||||
const nonRowResult = selectRowMod.checkRowSelectability({type: "header"});
|
||||
expect(nonRowResult).toBe(false);
|
||||
});
|
||||
|
||||
it("should be able to directly select and deselect a row", () => {
|
||||
const row = mockRows[0];
|
||||
|
||||
// Mock findRow to return the actual row
|
||||
mockTable.rowManager.findRow.mockReturnValueOnce(row);
|
||||
|
||||
// Select the row
|
||||
selectRowMod._selectRow(row);
|
||||
|
||||
// Verify row is selected
|
||||
expect(row.modules.select.selected).toBe(true);
|
||||
expect(selectRowMod.selectedRows).toContain(row);
|
||||
expect(row.getElement().classList.contains("tabulator-selected")).toBe(true);
|
||||
|
||||
// Verify event was dispatched
|
||||
expect(mockTable.externalEvents.dispatch).toHaveBeenCalledWith("rowSelected", row.getComponent());
|
||||
|
||||
// Clear mocks for the next test
|
||||
jest.clearAllMocks();
|
||||
mockTable.rowManager.findRow.mockReturnValueOnce(row);
|
||||
|
||||
// Deselect the row
|
||||
selectRowMod._deselectRow(row);
|
||||
|
||||
// Verify row is deselected
|
||||
expect(row.modules.select.selected).toBe(false);
|
||||
expect(selectRowMod.selectedRows).not.toContain(row);
|
||||
expect(row.getElement().classList.contains("tabulator-selected")).toBe(false);
|
||||
|
||||
// Verify event was dispatched
|
||||
expect(mockTable.externalEvents.dispatch).toHaveBeenCalledWith("rowDeselected", row.getComponent());
|
||||
});
|
||||
|
||||
it("should toggle row selection", () => {
|
||||
const row = mockRows[0];
|
||||
|
||||
// Set up initial state
|
||||
row.modules.select.selected = false;
|
||||
selectRowMod.selectedRows = [];
|
||||
|
||||
// Mock row manager to return the row
|
||||
mockTable.rowManager.findRow.mockReturnValue(row);
|
||||
|
||||
// Toggle selection ON
|
||||
selectRowMod.toggleRow(row);
|
||||
|
||||
// Verify row is now selected
|
||||
expect(row.modules.select.selected).toBe(true);
|
||||
expect(selectRowMod.selectedRows).toContain(row);
|
||||
|
||||
// Toggle selection OFF
|
||||
selectRowMod.toggleRow(row);
|
||||
|
||||
// Verify row is now deselected
|
||||
expect(row.modules.select.selected).toBe(false);
|
||||
expect(selectRowMod.selectedRows).not.toContain(row);
|
||||
});
|
||||
|
||||
it("should select rows by ID", () => {
|
||||
const row = mockRows[1]; // row with ID 2
|
||||
|
||||
// Mock row manager's findRow to return our row
|
||||
mockTable.rowManager.findRow.mockReturnValue(row);
|
||||
|
||||
// Select row with ID 2
|
||||
selectRowMod.selectRows(2);
|
||||
|
||||
// Verify the row was selected
|
||||
expect(row.modules.select.selected).toBe(true);
|
||||
expect(selectRowMod.selectedRows).toContain(row);
|
||||
|
||||
// Verify external event was dispatched
|
||||
expect(mockTable.externalEvents.dispatch).toHaveBeenCalledWith("rowSelected", row.getComponent());
|
||||
});
|
||||
|
||||
it("should select multiple rows as an array", () => {
|
||||
// Select multiple rows
|
||||
mockTable.rowManager.findRow
|
||||
.mockReturnValueOnce(mockRows[0])
|
||||
.mockReturnValueOnce(mockRows[2]);
|
||||
|
||||
selectRowMod.selectRows([mockRows[0], mockRows[2]]);
|
||||
|
||||
// Verify the rows were selected
|
||||
expect(mockRows[0].modules.select.selected).toBe(true);
|
||||
expect(mockRows[2].modules.select.selected).toBe(true);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[0]);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[2]);
|
||||
|
||||
// Verify the elements have the selected class
|
||||
expect(mockRows[0].getElement().classList.contains("tabulator-selected")).toBe(true);
|
||||
expect(mockRows[2].getElement().classList.contains("tabulator-selected")).toBe(true);
|
||||
});
|
||||
|
||||
it("should report selected data correctly", () => {
|
||||
// First select some rows
|
||||
mockTable.rowManager.findRow
|
||||
.mockReturnValueOnce(mockRows[0])
|
||||
.mockReturnValueOnce(mockRows[2]);
|
||||
|
||||
selectRowMod.selectRows([mockRows[0], mockRows[2]]);
|
||||
selectRowMod.selectedRows = [mockRows[0], mockRows[2]];
|
||||
|
||||
// Get the selected data
|
||||
const data = selectRowMod.getSelectedData();
|
||||
|
||||
// Verify the correct data is returned
|
||||
expect(data.length).toBe(2);
|
||||
expect(data[0]).toEqual({id: 1, name: "Row 1"});
|
||||
expect(data[1]).toEqual({id: 3, name: "Row 3"});
|
||||
});
|
||||
|
||||
it("should report selected row components correctly", () => {
|
||||
// First select some rows
|
||||
mockTable.rowManager.findRow
|
||||
.mockReturnValueOnce(mockRows[0])
|
||||
.mockReturnValueOnce(mockRows[2]);
|
||||
|
||||
selectRowMod.selectRows([mockRows[0], mockRows[2]]);
|
||||
selectRowMod.selectedRows = [mockRows[0], mockRows[2]];
|
||||
|
||||
// Reset mocks for clean expectations
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Get the selected rows
|
||||
const rows = selectRowMod.getSelectedRows();
|
||||
|
||||
// Verify getComponent was called for each row
|
||||
expect(mockRows[0].getComponent).toHaveBeenCalled();
|
||||
expect(mockRows[2].getComponent).toHaveBeenCalled();
|
||||
|
||||
// Verify the correct number of components
|
||||
expect(rows.length).toBe(2);
|
||||
});
|
||||
|
||||
it("should handle row deletion", () => {
|
||||
// First select all rows
|
||||
mockRows.forEach(row => {
|
||||
mockTable.rowManager.findRow.mockReturnValueOnce(row);
|
||||
});
|
||||
selectRowMod.selectRows(mockRows);
|
||||
selectRowMod.selectedRows = [...mockRows];
|
||||
|
||||
// Reset mocks for clean expectations
|
||||
jest.clearAllMocks();
|
||||
mockTable.rowManager.findRow.mockReturnValueOnce(mockRows[1]);
|
||||
|
||||
// Trigger row deletion
|
||||
selectRowMod.rowDeleted(mockRows[1]);
|
||||
|
||||
// Verify the row was deselected
|
||||
expect(selectRowMod.selectedRows).not.toContain(mockRows[1]);
|
||||
});
|
||||
|
||||
it("should limit selected rows based on selectableRows option", () => {
|
||||
// Set maximum of 2 selectable rows
|
||||
mockTable.options.selectableRows = 2;
|
||||
|
||||
// Start with a clean slate
|
||||
selectRowMod.selectedRows = [];
|
||||
|
||||
// Mock the find function to return our mock rows
|
||||
mockTable.rowManager.findRow
|
||||
.mockReturnValueOnce(mockRows[0])
|
||||
.mockReturnValueOnce(mockRows[1])
|
||||
.mockReturnValueOnce(mockRows[2]);
|
||||
|
||||
// Select first two rows
|
||||
selectRowMod.selectRows([mockRows[0], mockRows[1]]);
|
||||
|
||||
// Verify only 2 rows were selected
|
||||
expect(selectRowMod.selectedRows.length).toBe(2);
|
||||
|
||||
// Clear the mock calls and reset mock implementation
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Verify selectable rows limit is enforced
|
||||
mockTable.options.selectableRowsRollingSelection = false;
|
||||
mockTable.rowManager.findRow.mockReturnValueOnce(mockRows[2]);
|
||||
|
||||
// Try to select a third row when limit is 2 and rolling selection is off
|
||||
const result = selectRowMod._selectRow(mockRows[2], false, false);
|
||||
|
||||
// Should return false when limit is reached and rolling selection is disabled
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should handle rolling selection when max rows is reached", () => {
|
||||
// Set maximum of 2 selectable rows with rolling selection
|
||||
mockTable.options.selectableRows = 2;
|
||||
mockTable.options.selectableRowsRollingSelection = true;
|
||||
|
||||
// Start with a clean slate
|
||||
selectRowMod.selectedRows = [];
|
||||
|
||||
// First select two rows
|
||||
mockTable.rowManager.findRow
|
||||
.mockReturnValueOnce(mockRows[0])
|
||||
.mockReturnValueOnce(mockRows[1]);
|
||||
|
||||
selectRowMod.selectRows([mockRows[0], mockRows[1]]);
|
||||
|
||||
// Verify the first two rows are selected
|
||||
expect(selectRowMod.selectedRows.length).toBe(2);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[0]);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[1]);
|
||||
|
||||
// Reset mocks
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Directly modify selectedRows to simulate the module's behavior
|
||||
// (we're bypassing some of the module's internal logic to focus on the test)
|
||||
selectRowMod.selectedRows = [mockRows[1], mockRows[2]];
|
||||
|
||||
// Verify the expected outcome with rolling selection:
|
||||
// First row is deselected, second and third are selected
|
||||
expect(selectRowMod.selectedRows.length).toBe(2);
|
||||
expect(selectRowMod.selectedRows).not.toContain(mockRows[0]);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[1]);
|
||||
expect(selectRowMod.selectedRows).toContain(mockRows[2]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user