import React from 'react'
import type { GridPreferencesAdapter } from '../types'
import { render } from '../utils/test-utils'
import type { UseGridReturn } from './use-grid'
import { createGrid } from './use-grid'
import { usePreferencesAdapter } from './use-preferences-adapter'
type UsesPreferencesProps = {
grid: UseGridReturn
preferencesAdapter?: GridPreferencesAdapter
}
const UsesPreferences = ({
grid,
preferencesAdapter,
}: UsesPreferencesProps) => {
const initialized = usePreferencesAdapter({ grid, preferencesAdapter })
return
{initialized.toString()}
}
describe('usePreferencesAdapter', () => {
let grid: UseGridReturn
beforeEach(() => {
grid = createGrid()
jest.spyOn(
grid.selectors,
'selectColumnIdsWithoutInternal'
).mockReturnValue(['123', '234'])
})
describe('initialization', () => {
it('should render as initialized if no preferencesAdapter is provided', () => {
const { getByText } = render()
expect(getByText('true')).toBeInTheDocument()
})
it('should render as not initialized while loading preferences', () => {
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockReturnValue(
new Promise(() => {
/* never resolve */
})
),
save: jest.fn(),
}
const { getByText } = render(
)
expect(getByText('false')).toBeInTheDocument()
})
it('should render as initialized once preferences are loaded', async () => {
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({}),
save: jest.fn(),
}
const { findByText } = render(
)
expect(await findByText('true')).toBeInTheDocument()
})
})
describe('when loading data', () => {
it("should not apply changes if column ids don't match (different count)", async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [{ id: '123', width: null }],
}),
save: jest.fn(),
}
const { findByText } = render(
)
await findByText('true')
expect(dispatch).not.toHaveBeenCalled()
})
it("should not apply changes if column ids don't match (different ids)", async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: null },
{ id: '345', width: null },
],
}),
save: jest.fn(),
}
const { findByText } = render(
)
await findByText('true')
expect(dispatch).not.toHaveBeenCalled()
})
it('should apply changes if column ids match', async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
}),
save: jest.fn(),
}
const { findByText } = render(
)
await findByText('true')
expect(dispatch).toHaveBeenCalledWith({
type: 'applyPreferences',
payload: {
preferences: {
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
},
multiSelection: false,
},
})
})
it('should apply changes if column ids match (multi-select)', async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
jest.spyOn(grid.selectors, 'selectSelectionMode').mockReturnValue(
'multi'
)
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
}),
save: jest.fn(),
}
const { findByText } = render(
)
await findByText('true')
expect(dispatch).toHaveBeenCalledWith({
type: 'applyPreferences',
payload: {
preferences: {
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
},
multiSelection: true,
},
})
})
it('should load changes if adapter changes', async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
const adapterOne: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
}),
save: jest.fn(),
}
const adapterTwo: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: 123 },
{ id: '234', width: 245 },
],
}),
save: jest.fn(),
}
const { findByText, rerender } = render(
)
await findByText('true')
rerender(
)
await findByText('true')
expect(dispatch).toHaveBeenCalledWith({
type: 'applyPreferences',
payload: {
preferences: {
columns: [
{ id: '123', width: 123 },
{ id: '234', width: 245 },
],
},
multiSelection: false,
},
})
})
it('should not attempt to apply changes if component is unmounted', async () => {
const dispatch = jest.spyOn(grid, 'dispatch')
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({
columns: [
{ id: '123', width: null },
{ id: '234', width: 245 },
],
}),
save: jest.fn(),
}
const { unmount } = render(
)
unmount()
/* Give load promise time to resolve */
await Promise.resolve()
expect(dispatch).not.toHaveBeenCalled()
})
})
describe('when a change happens', () => {
it('should call save with the column state', async () => {
jest.spyOn(
grid.selectors,
'selectColumnPreferences'
).mockReturnValue([{ id: '123', width: 25 }])
const adapter: GridPreferencesAdapter = {
load: jest.fn().mockResolvedValue({}),
save: jest.fn(),
}
const { findByText } = render(
)
await findByText('true')
grid.events.emit('onColumnStateChange')
expect(adapter.save).toHaveBeenCalledWith({
columns: [{ id: '123', width: 25 }],
})
})
})
})