Skip to content

Commit

Permalink
tests: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kulmann committed Feb 19, 2024
1 parent 2285f73 commit f2ddc18
Show file tree
Hide file tree
Showing 10 changed files with 500 additions and 70 deletions.
156 changes: 156 additions & 0 deletions packages/web-pkg/tests/unit/components/CustomComponentTarget.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import CustomComponentTarget from '../../../src/components/CustomComponentTarget.vue'
import {
defaultComponentMocks,
defaultPlugins,
mount,
useExtensionPreferencesStoreMock,
useExtensionRegistryMock
} from 'web-test-helpers'
import {
CustomComponentExtension,
Extension,
ExtensionPoint,
ExtensionPreferenceItem,
useExtensionPreferencesStore,
useExtensionRegistry
} from '../../../src'
import { mock } from 'vitest-mock-extended'
import { h } from 'vue'

vi.mock('../../../src/composables', async (importOriginal) => ({
...(await importOriginal<any>()),
useExtensionRegistry: vi.fn(),
useExtensionPreferencesStore: vi.fn()
}))

const selectors = {
target: '[data-testid="custom-component-target"]'
}

describe('CustomComponentTarget', () => {
const mockExtensionPointSingle = mock<ExtensionPoint>({
id: 'dummy-extension-point-single',
type: 'customComponent',
multiple: false
})
const mockExtensionPointMulti = mock<ExtensionPoint>({
id: 'dummy-extension-point-multi',
type: 'customComponent',
multiple: true
})

describe('no extensions match the extension point', () => {
it.each([mockExtensionPointSingle, mockExtensionPointMulti])(
'renders nothing',
(extensionPoint) => {
const { wrapper } = getWrapper({
extensionPoint,
extensions: []
})
expect(wrapper.find(selectors.target).exists()).toBeFalsy()
}
)
})

describe('exactly 1 extension matches the extension point', () => {
it.each([mockExtensionPointSingle, mockExtensionPointMulti])(
'renders 1 component',
(extensionPoint) => {
const extensionId = 'custom-1'
const { wrapper } = getWrapper({
extensionPoint,
extensions: [createExtensionMock(extensionId, extensionPoint.id)]
})
expect(wrapper.find(selectors.target).exists()).toBeTruthy()
}
)
})

describe('multiple extensions match the extension point', () => {
describe('extension point allows only 1 extension', () => {
it('renders 1 component, respecting the user preference', () => {
const extensionMocks = ['custom-1', 'custom-2'].map((id) =>
createExtensionMock(id, mockExtensionPointSingle.id)
)
const { wrapper } = getWrapper({
extensionPoint: mockExtensionPointSingle,
extensions: extensionMocks,
preference: mock<ExtensionPreferenceItem>({
extensionPointId: mockExtensionPointSingle.id,
selectedExtensionIds: [extensionMocks[1].id]
})
})
expect(wrapper.findAll(selectors.target).length).toBe(1)
})
})

describe('multiple extensions match the extension point', () => {
it('renders n components', () => {
const extensionMocks = ['custom-1', 'custom-2'].map((id) =>
createExtensionMock(id, mockExtensionPointMulti.id)
)
const { wrapper } = getWrapper({
extensionPoint: mockExtensionPointMulti,
extensions: extensionMocks
})
expect(wrapper.findAll(selectors.target).length).toBe(extensionMocks.length)
})
})
})
})

function getWrapper({
extensionPoint,
extensions,
preference
}: {
extensionPoint: ExtensionPoint
extensions: Extension[]
preference?: ExtensionPreferenceItem
}) {
vi.mocked(useExtensionRegistry).mockImplementation(() =>
useExtensionRegistryMock({
requestExtensions<ExtensionType>(type: string) {
return extensions as ExtensionType[]
}
})
)
vi.mocked(useExtensionPreferencesStore).mockImplementation(() =>
useExtensionPreferencesStoreMock({
getExtensionPreference() {
return preference
}
})
)

const mocks = defaultComponentMocks()

return {
mocks,
wrapper: mount(CustomComponentTarget, {
props: {
extensionPoint
},
global: {
plugins: [...defaultPlugins()],
mocks,
provide: mocks,
stubs: { OcCheckbox: true }
}
})
}
}

function createExtensionMock(id: string, extensionPointId: string) {
return mock<CustomComponentExtension>({
id,
type: 'customComponent',
extensionPointIds: [extensionPointId],
content: () => [
h('p', {
innerHTML: `hello from ${id}`,
'data-testid': 'custom-component-target'
})
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Extension, ExtensionPoint, useExtensionPreferencesStore } from '../../../../../src'
import { getComposableWrapper } from 'web-test-helpers'
import { createPinia, setActivePinia } from 'pinia'
import { mock } from 'vitest-mock-extended'

describe('useExtensionPreferencesStore', () => {
beforeEach(() => {
setActivePinia(createPinia())
})
afterEach(() => {
localStorage.clear()
})

it('has no preferences initially', () => {
getWrapper({
setup: (instance) => {
expect(Object.keys(instance.extensionPreferences).length).toBe(0)
}
})
})

describe('set and get selected extensions', () => {
it('can set and get selected extensions', () => {
getWrapper({
setup: (instance) => {
const extensionPointId = 'extension-point-id'
const extensionId = 'extension-id'
instance.setSelectedExtensionIds(extensionPointId, [extensionId])
const extensionPreference = instance.getExtensionPreference(extensionPointId, [
'fallback'
])
expect(extensionPreference.selectedExtensionIds).toEqual([extensionId])
}
})
})
it('keeps preferences unique by extension point id', () => {
getWrapper({
setup: (instance) => {
const extensionPointId = 'extension-point-id'
instance.setSelectedExtensionIds(extensionPointId, ['foo-1'])
instance.setSelectedExtensionIds(extensionPointId, ['foo-2'])
instance.setSelectedExtensionIds(extensionPointId, ['foo-3'])
const extensionPreference = instance.getExtensionPreference(extensionPointId, [
'fallback'
])
expect(extensionPreference.selectedExtensionIds).toEqual(['foo-3'])
}
})
})
it('uses the provided fallback value for unknown extension points', () => {
getWrapper({
setup: (instance) => {
const extensionPointId = 'extension-point-id'
const fallbackId = 'fallback'
const extensionPreference = instance.getExtensionPreference(extensionPointId, [
fallbackId
])
expect(extensionPreference.selectedExtensionIds).toEqual([fallbackId])
}
})
})
})

describe('extractDefaultExtensionIds', () => {
describe('extension points with multiple=true', () => {
it('returns all provided extension ids', () => {
getWrapper({
setup: (instance) => {
const extensionPoint = mock<ExtensionPoint>({
id: 'extension-point-id',
multiple: true
})
const extensionIds = ['foo-1', 'foo-2']
const extensionMocks = extensionIds.map((id) => mock<Extension>({ id }))
expect(instance.extractDefaultExtensionIds(extensionPoint, extensionMocks)).toEqual(
extensionIds
)
}
})
})
})
describe('extension points with multiple=false', () => {
it('returns the default extension id from the extension point', () => {
getWrapper({
setup: (instance) => {
const extensionPoint = mock<ExtensionPoint>({
id: 'extension-point-id',
multiple: false,
defaultExtensionId: 'foo-1'
})
expect(instance.extractDefaultExtensionIds(extensionPoint, [])).toEqual(['foo-1'])
}
})
})
it('returns an empty array if the extension point has no default extension id', () => {
getWrapper({
setup: (instance) => {
const extensionPoint = mock<ExtensionPoint>({
id: 'extension-point-id',
multiple: false,
defaultExtensionId: undefined
})
expect(instance.extractDefaultExtensionIds(extensionPoint, [])).toEqual([])
}
})
})
})
})
})

function getWrapper({
setup
}: {
setup: (instance: ReturnType<typeof useExtensionPreferencesStore>) => void
}) {
return {
wrapper: getComposableWrapper(
() => {
const instance = useExtensionPreferencesStore()
setup(instance)
},
{ pluginOptions: { pinia: false } }
)
}
}
Loading

0 comments on commit f2ddc18

Please sign in to comment.