mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-18 18:38:08 -05:00
* [VAULT-33083] support mount external engine * add "Plugin type" and "Plugin version" fields to the enable mount page * add changelog * address copilot review comments * address PR comments, code cleanup * fix test failures * Add support for external plugins registered without a plugin version * external plugin should be enabled for enterprise only, plugin version should be mandatory for external plugins * fix tests * address copilot feedback * fix failing tests, add unit test coverage * address PR comments * address PR comments * remove dead code * move no external versions alert * Only show un-versioned plugin message if there are un-versioned plugins in the catalog. * address PR comments * use ApiService instead of custom PluginPinsService; fix failing tests * revert changes to forms/mount.ts and forms/auth/method.ts Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>
613 lines
21 KiB
JavaScript
613 lines
21 KiB
JavaScript
/**
|
|
* Copyright IBM Corp. 2016, 2025
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { module, test } from 'qunit';
|
|
import {
|
|
categorizeEnginesByStatus,
|
|
enhanceEnginesWithCatalogData,
|
|
getAllVersionsForEngineType,
|
|
MOUNT_CATEGORIES,
|
|
PLUGIN_CATEGORIES,
|
|
PLUGIN_TYPES,
|
|
} from 'vault/utils/plugin-catalog-helpers';
|
|
|
|
module('Unit | Utility | plugin-catalog-helpers', function () {
|
|
module('enhanceEnginesWithCatalogData', function () {
|
|
test('it returns original engines when no catalog data provided', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, []);
|
|
assert.deepEqual(result, staticEngines, 'returns original engines when no catalog data');
|
|
});
|
|
|
|
test('it returns original engines when catalog data is null', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, null);
|
|
assert.deepEqual(result, staticEngines, 'handles null catalog data gracefully');
|
|
});
|
|
|
|
test('it enhances existing engines with catalog data', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
{
|
|
type: 'pki',
|
|
displayName: 'PKI',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
deprecation_status: 'supported',
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, catalogData);
|
|
|
|
assert.strictEqual(result.length, 2, 'maintains original engine count');
|
|
assert.strictEqual(result[0].type, 'kv', 'preserves engine type');
|
|
assert.true(result[0].builtin, 'adds builtin flag from catalog');
|
|
assert.strictEqual(result[0].version, '1.0.0', 'adds version from catalog');
|
|
assert.strictEqual(result[0].deprecationStatus, 'supported', 'adds deprecation status');
|
|
assert.true(result[0].isAvailable, 'marks as available when in catalog');
|
|
assert.ok(result[0].pluginData, 'includes plugin data');
|
|
|
|
assert.false(result[1].isAvailable, 'marks as unavailable when not in catalog');
|
|
assert.notOk(result[1].builtin, 'no builtin flag when not in catalog');
|
|
});
|
|
|
|
test('it handles database engine specially', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: MOUNT_CATEGORIES.DATABASE,
|
|
displayName: 'Database',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const databasePlugins = [
|
|
{
|
|
name: 'mysql-database-plugin',
|
|
type: PLUGIN_TYPES.DATABASE,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, [], databasePlugins);
|
|
|
|
assert.true(result[0].isAvailable, 'database engine is available when database plugins exist');
|
|
assert.true(result[0].builtin, 'uses representative database plugin data');
|
|
assert.strictEqual(result[0].version, '1.0.0', 'uses representative plugin version');
|
|
});
|
|
|
|
test('it discovers external plugins not in static metadata', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
},
|
|
{
|
|
name: 'my-custom-plugin',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '2.1.0',
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, catalogData);
|
|
|
|
assert.strictEqual(result.length, 2, 'adds external plugin');
|
|
const externalPlugin = result.find((engine) => engine.type === 'my-custom-plugin');
|
|
assert.ok(externalPlugin, 'external plugin is present');
|
|
assert.strictEqual(externalPlugin.displayName, 'My Custom Plugin', 'converts name to Title Case');
|
|
assert.strictEqual(
|
|
externalPlugin.pluginCategory,
|
|
PLUGIN_CATEGORIES.EXTERNAL,
|
|
'marks as external category'
|
|
);
|
|
assert.true(externalPlugin.isAvailable, 'external plugin is available');
|
|
assert.false(externalPlugin.builtin, 'external plugin is not builtin');
|
|
});
|
|
|
|
test('it excludes external plugins with builtin mappings from external category', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
},
|
|
{
|
|
name: 'vault-plugin-secrets-kv', // This has a builtin mapping
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '2.1.0',
|
|
},
|
|
{
|
|
name: 'truly-external-plugin', // This does not have a builtin mapping
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '1.0.0',
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, catalogData);
|
|
|
|
// Should only add the truly external plugin, not the one with builtin mapping
|
|
assert.strictEqual(result.length, 2, 'adds only truly external plugin');
|
|
|
|
const kvEngine = result.find((engine) => engine.type === 'kv');
|
|
const externalKv = result.find((engine) => engine.type === 'vault-plugin-secrets-kv');
|
|
const trulyExternal = result.find((engine) => engine.type === 'truly-external-plugin');
|
|
|
|
assert.ok(kvEngine, 'KV engine is present');
|
|
assert.notOk(externalKv, 'external KV plugin is not added as separate engine');
|
|
assert.ok(trulyExternal, 'truly external plugin is present');
|
|
assert.strictEqual(
|
|
trulyExternal.pluginCategory,
|
|
PLUGIN_CATEGORIES.EXTERNAL,
|
|
'truly external plugin is in external category'
|
|
);
|
|
});
|
|
|
|
test('it matches external plugins with existing static engine glyphs', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'aws',
|
|
displayName: 'AWS',
|
|
glyph: 'aws-color',
|
|
pluginCategory: PLUGIN_CATEGORIES.CLOUD,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const catalogData = [
|
|
{
|
|
name: 'my-custom-aws-plugin',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, catalogData);
|
|
|
|
const externalPlugin = result.find((engine) => engine.type === 'my-custom-aws-plugin');
|
|
assert.strictEqual(externalPlugin.glyph, 'aws-color', 'uses matching static engine glyph');
|
|
});
|
|
|
|
test('it handles deprecation status correctly', function (assert) {
|
|
const staticEngines = [
|
|
{
|
|
type: 'legacy-plugin',
|
|
displayName: 'Legacy Plugin',
|
|
pluginCategory: PLUGIN_CATEGORIES.GENERIC,
|
|
mountCategory: [MOUNT_CATEGORIES.SECRET],
|
|
},
|
|
];
|
|
|
|
const catalogData = [
|
|
{
|
|
name: 'legacy-plugin',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
deprecation_status: 'deprecated',
|
|
},
|
|
];
|
|
|
|
const result = enhanceEnginesWithCatalogData(staticEngines, catalogData);
|
|
|
|
assert.strictEqual(
|
|
result[0].deprecationStatus,
|
|
'deprecated',
|
|
'preserves deprecation status from catalog'
|
|
);
|
|
});
|
|
});
|
|
|
|
module('categorizeEnginesByStatus', function () {
|
|
test('it separates enabled and disabled engines', function (assert) {
|
|
const engines = [
|
|
{
|
|
type: 'kv',
|
|
displayName: 'KV',
|
|
isAvailable: true,
|
|
},
|
|
{
|
|
type: 'pki',
|
|
displayName: 'PKI',
|
|
isAvailable: false,
|
|
},
|
|
{
|
|
type: 'aws',
|
|
displayName: 'AWS',
|
|
// isAvailable not set (undefined)
|
|
},
|
|
];
|
|
|
|
const result = categorizeEnginesByStatus(engines);
|
|
|
|
assert.strictEqual(result.enabled.length, 2, 'enabled includes available and undefined');
|
|
assert.strictEqual(result.disabled.length, 1, 'disabled includes only false');
|
|
assert.strictEqual(result.enabled[0].type, 'kv', 'includes available engine in enabled');
|
|
assert.strictEqual(result.enabled[1].type, 'aws', 'includes undefined availability as enabled');
|
|
assert.strictEqual(result.disabled[0].type, 'pki', 'includes unavailable engine in disabled');
|
|
});
|
|
|
|
test('it handles empty input', function (assert) {
|
|
const result = categorizeEnginesByStatus([]);
|
|
|
|
assert.strictEqual(result.enabled.length, 0, 'enabled is empty');
|
|
assert.strictEqual(result.disabled.length, 0, 'disabled is empty');
|
|
});
|
|
|
|
test('it handles all enabled engines', function (assert) {
|
|
const engines = [
|
|
{ type: 'kv', isAvailable: true },
|
|
{ type: 'pki' }, // undefined isAvailable
|
|
];
|
|
|
|
const result = categorizeEnginesByStatus(engines);
|
|
|
|
assert.strictEqual(result.enabled.length, 2, 'all engines are enabled');
|
|
assert.strictEqual(result.disabled.length, 0, 'no engines are disabled');
|
|
});
|
|
|
|
test('it handles all disabled engines', function (assert) {
|
|
const engines = [
|
|
{ type: 'kv', isAvailable: false },
|
|
{ type: 'pki', isAvailable: false },
|
|
];
|
|
|
|
const result = categorizeEnginesByStatus(engines);
|
|
|
|
assert.strictEqual(result.enabled.length, 0, 'no engines are enabled');
|
|
assert.strictEqual(result.disabled.length, 2, 'all engines are disabled');
|
|
});
|
|
});
|
|
|
|
module('constants', function () {
|
|
test('MOUNT_CATEGORIES contains expected values', function (assert) {
|
|
assert.strictEqual(MOUNT_CATEGORIES.SECRET, 'secret', 'SECRET category is correct');
|
|
assert.strictEqual(MOUNT_CATEGORIES.AUTH, 'auth', 'AUTH category is correct');
|
|
assert.strictEqual(MOUNT_CATEGORIES.DATABASE, 'database', 'DATABASE category is correct');
|
|
});
|
|
|
|
test('PLUGIN_TYPES contains expected values', function (assert) {
|
|
assert.strictEqual(PLUGIN_TYPES.SECRET, 'secret', 'SECRET type is correct');
|
|
assert.strictEqual(PLUGIN_TYPES.AUTH, 'auth', 'AUTH type is correct');
|
|
assert.strictEqual(PLUGIN_TYPES.DATABASE, 'database', 'DATABASE type is correct');
|
|
});
|
|
|
|
test('PLUGIN_CATEGORIES contains expected values', function (assert) {
|
|
assert.strictEqual(PLUGIN_CATEGORIES.GENERIC, 'generic', 'GENERIC category is correct');
|
|
assert.strictEqual(PLUGIN_CATEGORIES.CLOUD, 'cloud', 'CLOUD category is correct');
|
|
assert.strictEqual(PLUGIN_CATEGORIES.INFRA, 'infra', 'INFRA category is correct');
|
|
assert.strictEqual(PLUGIN_CATEGORIES.EXTERNAL, 'external', 'EXTERNAL category is correct');
|
|
});
|
|
});
|
|
|
|
module('getAllVersionsForEngineType', function () {
|
|
test('it returns empty array when no catalog data provided', function (assert) {
|
|
const result = getAllVersionsForEngineType(undefined, 'kv', 'secret');
|
|
assert.deepEqual(
|
|
result,
|
|
{ versions: [], hasUnversionedPlugins: false },
|
|
'returns empty result for undefined catalog data'
|
|
);
|
|
|
|
const result2 = getAllVersionsForEngineType([], 'kv', 'secret');
|
|
assert.deepEqual(
|
|
result2,
|
|
{ versions: [], hasUnversionedPlugins: false },
|
|
'returns empty result for empty catalog data'
|
|
);
|
|
});
|
|
|
|
test('it returns versions for direct engine type matches', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '2.0.0',
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'kv', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 2, 'returns both versions');
|
|
assert.strictEqual(result.versions[0].version, '1.0.0', 'includes first version');
|
|
assert.strictEqual(result.versions[1].version, '2.0.0', 'includes second version');
|
|
assert.strictEqual(result.versions[0].pluginName, 'kv', 'includes plugin name');
|
|
assert.true(result.versions[0].isBuiltin, 'marks builtin correctly');
|
|
assert.false(result.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
});
|
|
|
|
test('it returns versions for external plugins that map to engine types', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
name: 'vault-plugin-secrets-kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '2.1.0',
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'kv', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 2, 'returns both builtin and external versions');
|
|
|
|
const builtinVersion = result.versions.find((v) => v.isBuiltin);
|
|
const externalVersion = result.versions.find((v) => !v.isBuiltin);
|
|
|
|
assert.ok(builtinVersion, 'includes builtin version');
|
|
assert.ok(externalVersion, 'includes external version');
|
|
assert.strictEqual(builtinVersion.pluginName, 'kv', 'builtin uses engine name');
|
|
assert.strictEqual(
|
|
externalVersion.pluginName,
|
|
'vault-plugin-secrets-kv',
|
|
'external uses full plugin name'
|
|
);
|
|
assert.false(result.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
});
|
|
|
|
test('it excludes external plugins that do not map to the engine type', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
name: 'vault-plugin-secrets-aws',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '1.5.0',
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'kv', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 1, 'only includes matching plugins');
|
|
assert.strictEqual(result.versions[0].pluginName, 'kv', 'includes only KV engine');
|
|
assert.false(result.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
});
|
|
|
|
test('it filters by plugin type correctly', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'gcp',
|
|
type: 'auth',
|
|
builtin: true,
|
|
version: 'v0.22.0+builtin',
|
|
},
|
|
{
|
|
name: 'gcp',
|
|
type: 'secret',
|
|
builtin: true,
|
|
version: 'v0.23.0+builtin',
|
|
},
|
|
{
|
|
name: 'vault-plugin-secrets-gcp',
|
|
type: 'secret',
|
|
builtin: false,
|
|
version: 'v0.23.0',
|
|
},
|
|
];
|
|
|
|
// Test filtering for secret plugins only
|
|
const secretResult = getAllVersionsForEngineType(catalogData, 'gcp', 'secret');
|
|
assert.strictEqual(secretResult.versions.length, 2, 'returns only secret type plugins');
|
|
assert.true(
|
|
secretResult.versions.every(
|
|
(plugin) => plugin.pluginName === 'gcp' || plugin.pluginName === 'vault-plugin-secrets-gcp'
|
|
),
|
|
'includes correct secret plugins'
|
|
);
|
|
assert.false(secretResult.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
|
|
// Test filtering for auth plugins only
|
|
const authResult = getAllVersionsForEngineType(catalogData, 'gcp', 'auth');
|
|
assert.strictEqual(authResult.versions.length, 1, 'returns only auth type plugins');
|
|
assert.strictEqual(authResult.versions[0].pluginName, 'gcp', 'includes auth plugin');
|
|
assert.false(authResult.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
});
|
|
|
|
test('it handles invalid catalog data gracefully', function (assert) {
|
|
const invalidCatalogData = [
|
|
null, // null entry
|
|
{ name: 'kv' }, // missing required fields
|
|
{ name: 'aws', version: '1.0.0' }, // missing builtin field
|
|
{
|
|
name: 'pki',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
}, // valid entry
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(invalidCatalogData, 'pki');
|
|
|
|
assert.strictEqual(result.versions.length, 1, 'filters out invalid entries');
|
|
assert.strictEqual(result.versions[0].pluginName, 'pki', 'includes only valid entry');
|
|
assert.false(result.hasUnversionedPlugins, 'no unversioned plugins detected');
|
|
});
|
|
|
|
test('it excludes unversioned plugins but detects them', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'vault-plugin-secrets-keymgmt',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '', // Empty string when plugin registered without version
|
|
sha256: '9433b2b37d30abf8f7cbf8c3e616dfc263034789681081ea4ba7918673d80086',
|
|
},
|
|
{
|
|
name: 'vault-plugin-secrets-keymgmt',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '1.5.0',
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'keymgmt', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 1, 'excludes unversioned plugin from versions');
|
|
assert.true(result.hasUnversionedPlugins, 'detects presence of unversioned plugins');
|
|
|
|
const versionedPlugin = result.versions[0];
|
|
assert.strictEqual(versionedPlugin.version, '1.5.0', 'includes only versioned plugin');
|
|
assert.false(versionedPlugin.isBuiltin, 'versioned plugin is not builtin');
|
|
assert.strictEqual(
|
|
versionedPlugin.pluginName,
|
|
'vault-plugin-secrets-keymgmt',
|
|
'correct plugin name for versioned'
|
|
);
|
|
});
|
|
|
|
test('it detects unversioned plugins for builtin engines', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '', // Unversioned external kv plugin
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'kv', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 1, 'only includes versioned plugins');
|
|
assert.true(result.hasUnversionedPlugins, 'detects unversioned plugin');
|
|
assert.strictEqual(result.versions[0].version, '1.0.0', 'includes builtin version');
|
|
assert.true(result.versions[0].isBuiltin, 'included plugin is builtin');
|
|
});
|
|
|
|
test('it handles multiple unversioned plugins for same engine type', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'vault-plugin-secrets-custom',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '', // First unversioned plugin
|
|
},
|
|
{
|
|
name: 'custom',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: false,
|
|
version: '', // Second unversioned plugin (direct match)
|
|
},
|
|
{
|
|
name: 'custom',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '2.0.0', // Versioned plugin
|
|
},
|
|
];
|
|
|
|
const result = getAllVersionsForEngineType(catalogData, 'custom', 'secret');
|
|
|
|
assert.strictEqual(result.versions.length, 1, 'excludes all unversioned plugins');
|
|
assert.true(result.hasUnversionedPlugins, 'detects multiple unversioned plugins');
|
|
assert.strictEqual(result.versions[0].version, '2.0.0', 'includes only versioned plugin');
|
|
});
|
|
|
|
test('it handles invalid engine type parameters', function (assert) {
|
|
const catalogData = [
|
|
{
|
|
name: 'kv',
|
|
type: PLUGIN_TYPES.SECRET,
|
|
builtin: true,
|
|
version: '1.0.0',
|
|
},
|
|
];
|
|
|
|
const result1 = getAllVersionsForEngineType(catalogData, null);
|
|
assert.deepEqual(
|
|
result1,
|
|
{ versions: [], hasUnversionedPlugins: false },
|
|
'returns empty result for null engine type'
|
|
);
|
|
|
|
const result2 = getAllVersionsForEngineType(catalogData, '');
|
|
assert.deepEqual(
|
|
result2,
|
|
{ versions: [], hasUnversionedPlugins: false },
|
|
'returns empty result for empty engine type'
|
|
);
|
|
|
|
const result3 = getAllVersionsForEngineType(catalogData, undefined);
|
|
assert.deepEqual(
|
|
result3,
|
|
{ versions: [], hasUnversionedPlugins: false },
|
|
'returns empty result for undefined engine type'
|
|
);
|
|
});
|
|
});
|
|
});
|