mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 07:42:45 +08:00
Plugins: Introduce LoadingStrategy
for frontend loading logic (#92392)
* do it all * feat(plugins): move loadingStrategy to ds pluginMeta and add to plugin settings endpoint * support child plugins and update tests * use relative path for nested plugins * feat(plugins): support nested plugins in the plugin loader cache by extracting pluginId from path * feat(grafana-data): add plugin loading strategy to plugin meta and export * feat(plugins): pass down loadingStrategy to fe plugin loader * refactor(plugins): make PluginLoadingStrategy an enum * feat(plugins): add the loading strategy to the fe plugin loader cache * feat(plugins): load fe plugin js assets as script tags based on be loadingStrategy * add more tests * feat(plugins): add loading strategy to plugin preloader * feat(plugins): make loadingStrategy a maybe and provide fetch fallback * test(alerting): update config.apps mocks to include loadingStrategy * fix format --------- Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
This commit is contained in:
@ -1,4 +1,12 @@
|
||||
import { registerPluginInCache, invalidatePluginInCache, resolveWithCache, getPluginFromCache } from './cache';
|
||||
import { PluginLoadingStrategy } from '@grafana/data';
|
||||
|
||||
import {
|
||||
registerPluginInCache,
|
||||
invalidatePluginInCache,
|
||||
resolveWithCache,
|
||||
getPluginFromCache,
|
||||
extractCacheKeyFromPath,
|
||||
} from './cache';
|
||||
|
||||
jest.mock('./constants', () => ({
|
||||
CACHE_INITIALISED_AT: 123456,
|
||||
@ -7,28 +15,28 @@ jest.mock('./constants', () => ({
|
||||
describe('Cache Functions', () => {
|
||||
describe('registerPluginInCache', () => {
|
||||
it('should register a plugin in the cache', () => {
|
||||
const plugin = { pluginId: 'plugin1', version: '1.0.0', isAngular: false };
|
||||
registerPluginInCache(plugin);
|
||||
const plugin = { version: '1.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache({ path: 'public/plugins/plugin1/module.js', ...plugin });
|
||||
expect(getPluginFromCache('plugin1')).toEqual(plugin);
|
||||
});
|
||||
|
||||
it('should not register a plugin if it already exists in the cache', () => {
|
||||
const pluginId = 'plugin2';
|
||||
const plugin = { pluginId, version: '2.0.0' };
|
||||
const path = 'public/plugins/plugin2/module.js';
|
||||
const plugin = { path, version: '2.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
const plugin2 = { pluginId, version: '2.5.0' };
|
||||
const plugin2 = { path, version: '2.5.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin2);
|
||||
expect(getPluginFromCache(pluginId)?.version).toBe('2.0.0');
|
||||
expect(getPluginFromCache(path)?.version).toBe('2.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('invalidatePluginInCache', () => {
|
||||
it('should invalidate a plugin in the cache', () => {
|
||||
const pluginId = 'plugin3';
|
||||
const plugin = { pluginId, version: '3.0.0' };
|
||||
const path = 'public/plugins/plugin2/module.js';
|
||||
const plugin = { path, version: '3.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
invalidatePluginInCache(pluginId);
|
||||
expect(getPluginFromCache(pluginId)).toBeUndefined();
|
||||
invalidatePluginInCache('plugin2');
|
||||
expect(getPluginFromCache('plugin2')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not throw an error if the plugin does not exist in the cache', () => {
|
||||
@ -43,17 +51,43 @@ describe('Cache Functions', () => {
|
||||
});
|
||||
|
||||
it('should resolve URL with plugin version as cache bust parameter if available', () => {
|
||||
const plugin = { pluginId: 'plugin5', version: '5.0.0' };
|
||||
registerPluginInCache(plugin);
|
||||
const url = 'http://localhost:3000/public/plugins/plugin5/module.js';
|
||||
const plugin = { path: url, version: '5.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache(plugin);
|
||||
expect(resolveWithCache(url)).toContain('_cache=5.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractCacheKeyFromPath', () => {
|
||||
it('should extract plugin ID from a path', () => {
|
||||
expect(extractCacheKeyFromPath('public/plugins/plugin6/module.js')).toBe('plugin6');
|
||||
});
|
||||
|
||||
it('should extract plugin ID from a path', () => {
|
||||
expect(extractCacheKeyFromPath('public/plugins/plugin6/datasource/module.js')).toBe('plugin6');
|
||||
});
|
||||
|
||||
it('should extract plugin ID from a url', () => {
|
||||
expect(extractCacheKeyFromPath('https://my-url.com/plugin6/1.0.0/public/plugins/plugin6/module.js')).toBe(
|
||||
'plugin6'
|
||||
);
|
||||
});
|
||||
|
||||
it('should extract plugin ID from a nested plugin url', () => {
|
||||
expect(
|
||||
extractCacheKeyFromPath('https://my-url.com/plugin6/1.0.0/public/plugins/plugin6/datasource/module.js')
|
||||
).toBe('plugin6');
|
||||
});
|
||||
|
||||
it('should return null if the path does not match the pattern', () => {
|
||||
expect(extractCacheKeyFromPath('public/plugins/plugin7')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPluginFromCache', () => {
|
||||
it('should return plugin from cache if exists', () => {
|
||||
const plugin = { pluginId: 'plugin6', version: '6.0.0' };
|
||||
registerPluginInCache(plugin);
|
||||
const plugin = { version: '6.0.0', loadingStrategy: PluginLoadingStrategy.script };
|
||||
registerPluginInCache({ path: 'public/plugins/plugin6/module.js', ...plugin });
|
||||
expect(getPluginFromCache('plugin6')).toEqual(plugin);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user