2024-04-24 02:33:16 -05:00
import { act } from '@testing-library/react' ;
import { renderHook } from '@testing-library/react-hooks' ;
import { PluginExtensionTypes } from '@grafana/data' ;
import { ReactivePluginExtensionsRegistry } from './reactivePluginExtensionRegistry' ;
2024-06-07 11:05:00 -05:00
import { createUsePluginExtensions } from './usePluginExtensions' ;
2024-04-24 02:33:16 -05:00
describe ( 'usePluginExtensions()' , ( ) = > {
let reactiveRegistry : ReactivePluginExtensionsRegistry ;
beforeEach ( ( ) = > {
reactiveRegistry = new ReactivePluginExtensionsRegistry ( ) ;
} ) ;
it ( 'should return an empty array if there are no extensions registered for the extension point' , ( ) = > {
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
const { result } = renderHook ( ( ) = >
usePluginExtensions ( {
extensionPointId : 'foo/bar' ,
} )
) ;
expect ( result . current . extensions ) . toEqual ( [ ] ) ;
} ) ;
it ( 'should return the plugin extensions from the registry' , ( ) = > {
const extensionPointId = 'plugins/foo/bar' ;
const pluginId = 'my-app-plugin' ;
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '1' ,
description : '1' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '2' ,
description : '2' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
const { result } = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId } ) ) ;
expect ( result . current . extensions . length ) . toBe ( 2 ) ;
expect ( result . current . extensions [ 0 ] . title ) . toBe ( '1' ) ;
expect ( result . current . extensions [ 1 ] . title ) . toBe ( '2' ) ;
} ) ;
it ( 'should dynamically update the extensions registered for a certain extension point' , ( ) = > {
const extensionPointId = 'plugins/foo/bar' ;
const pluginId = 'my-app-plugin' ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
let { result , rerender } = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId } ) ) ;
// No extensions yet
expect ( result . current . extensions . length ) . toBe ( 0 ) ;
// Add extensions to the registry
act ( ( ) = > {
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '1' ,
description : '1' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '2' ,
description : '2' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
} ) ;
// Check if the hook returns the new extensions
rerender ( ) ;
expect ( result . current . extensions . length ) . toBe ( 2 ) ;
expect ( result . current . extensions [ 0 ] . title ) . toBe ( '1' ) ;
expect ( result . current . extensions [ 1 ] . title ) . toBe ( '2' ) ;
} ) ;
it ( 'should only render the hook once' , ( ) = > {
const spy = jest . spyOn ( reactiveRegistry , 'asObservable' ) ;
const extensionPointId = 'plugins/foo/bar' ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
renderHook ( ( ) = > usePluginExtensions ( { extensionPointId } ) ) ;
expect ( spy ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
it ( 'should return the same extensions object if the context object is the same' , ( ) = > {
const extensionPointId = 'plugins/foo/bar' ;
const pluginId = 'my-app-plugin' ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
// Add extensions to the registry
act ( ( ) = > {
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '1' ,
description : '1' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '2' ,
description : '2' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
} ) ;
// Check if it returns the same extensions object in case nothing changes
const context = { } ;
const firstResults = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId , context } ) ) ;
const secondResults = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId , context } ) ) ;
expect ( firstResults . result . current . extensions === secondResults . result . current . extensions ) . toBe ( true ) ;
} ) ;
it ( 'should return a new extensions object if the context object is different' , ( ) = > {
const extensionPointId = 'plugins/foo/bar' ;
const pluginId = 'my-app-plugin' ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
// Add extensions to the registry
act ( ( ) = > {
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '1' ,
description : '1' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '2' ,
description : '2' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
} ) ;
// Check if it returns a different extensions object in case the context object changes
const firstResults = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId , context : { } } ) ) ;
const secondResults = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId , context : { } } ) ) ;
expect ( firstResults . result . current . extensions === secondResults . result . current . extensions ) . toBe ( false ) ;
} ) ;
it ( 'should return a new extensions object if the registry changes but the context object is the same' , ( ) = > {
const extensionPointId = 'plugins/foo/bar' ;
const pluginId = 'my-app-plugin' ;
const context = { } ;
2024-06-07 11:05:00 -05:00
const usePluginExtensions = createUsePluginExtensions ( reactiveRegistry ) ;
2024-04-24 02:33:16 -05:00
// Add the first extension
act ( ( ) = > {
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
title : '1' ,
description : '1' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
} ) ;
const { result , rerender } = renderHook ( ( ) = > usePluginExtensions ( { extensionPointId , context } ) ) ;
const firstExtensions = result . current . extensions ;
// Add the second extension
act ( ( ) = > {
reactiveRegistry . register ( {
pluginId ,
extensionConfigs : [
{
type : PluginExtensionTypes . link ,
extensionPointId ,
// extensionPointId: 'plugins/foo/bar/zed', // A different extension point (to be sure that it's also returning a new object when the actual extension point doesn't change)
title : '2' ,
description : '2' ,
path : ` /a/ ${ pluginId } /2 ` ,
} ,
] ,
} ) ;
} ) ;
rerender ( ) ;
const secondExtensions = result . current . extensions ;
expect ( firstExtensions === secondExtensions ) . toBe ( false ) ;
} ) ;
} ) ;