diff --git a/src/providers/github.ts b/src/providers/github.ts index 21540da..b876d0d 100644 --- a/src/providers/github.ts +++ b/src/providers/github.ts @@ -19,7 +19,6 @@ export const handleExceedRateLimitError = (error: unknown) => { 'message' in error && error.message.search('find') !== -1 ) { - // todo: add a unit test for this const apiRateLimitMessage = 'API rate limit exceeded, Try again later. Check out Github documentation for rate limit.' throw new Error(apiRateLimitMessage) diff --git a/src/services/install.test.ts b/src/services/install.test.ts index 33755f6..0bbda80 100644 --- a/src/services/install.test.ts +++ b/src/services/install.test.ts @@ -1,4 +1,12 @@ import { expect } from 'chai' +import proxyquire from 'proxyquire' +import sinon from 'sinon' +import { + findPluginInRegistry, + getPluginVersion, + handleExceedRateLimitError, +} from '../providers/github' +import { InstallCommandIterator } from '../types/commands' import { plugin5 } from '../utils/fixtures/plugins' import { destroyVault, @@ -10,7 +18,13 @@ import installService from './install' const { installVaultIterator } = installService +const sandbox = sinon.createSandbox() + describe('Command: install', () => { + afterEach(() => { + sandbox.restore() + }) + it('should perform installation successfully', async () => { const { vault, config } = setupVault( ConfigSchema.parse({ plugins: [plugin5] }), @@ -101,4 +115,84 @@ describe('Command: install', () => { destroyVault(vault.path) }) + + it('should handle API rate limit error', async () => { + const { vault, config } = setupVault( + ConfigSchema.parse({ plugins: [plugin5] }), + ) + const testCommonWithVaultPathFlags = getTestCommonWithVaultPathFlags( + config.path, + vault.path, + ) + + const installPluginFromGithubStub = sandbox + .stub() + .rejects(new Error('API rate limit exceeded')) + const { + default: { installVaultIterator }, + } = proxyquire.noCallThru()('./install', { + '../providers/github': { + installPluginFromGithub: installPluginFromGithubStub, + getPluginVersion, + findPluginInRegistry, + }, + }) + + try { + await (installVaultIterator as InstallCommandIterator)({ + vault, + config, + flags: { + ...testCommonWithVaultPathFlags, + enable: true, + }, + args: { pluginId: plugin5.id }, + }) + } catch (error) { + console.log('error', error) + expect((error as Error).message).to.match(/API rate limit exceeded/) + } + + destroyVault(vault.path) + }) + + it('should not handle any error as rate limit error', async () => { + const { vault, config } = setupVault( + ConfigSchema.parse({ plugins: [plugin5] }), + ) + const testCommonWithVaultPathFlags = getTestCommonWithVaultPathFlags( + config.path, + vault.path, + ) + + const findPluginInRegistryStub = sandbox + .stub() + .rejects(new Error('Some error')) + const { + default: { installVaultIterator }, + } = proxyquire.noCallThru()('./install', { + '../providers/github': { + getPluginVersion, + findPluginInRegistry: findPluginInRegistryStub, + handleExceedRateLimitError, + }, + }) + + const result = await (installVaultIterator as InstallCommandIterator)({ + vault, + config, + flags: { + ...testCommonWithVaultPathFlags, + enable: true, + }, + args: { pluginId: plugin5.id }, + }) + + expect(result.installedPlugins.length).to.equal(0) + expect(result.failedPlugins.length).to.equal(1) + expect(result.failedPlugins.some((plugin) => plugin.id === plugin5.id)).to + .be.true + + destroyVault(vault.path) + }) }) diff --git a/src/services/install.ts b/src/services/install.ts index 5b77076..6472909 100644 --- a/src/services/install.ts +++ b/src/services/install.ts @@ -39,9 +39,9 @@ const installVaultIterator: InstallCommandIterator = async (item) => { `Install ${stagePlugin.id}@${version} in ${vault.name} vault`, ) - const pluginInRegistry = await findPluginInRegistry(stagePlugin.id) - try { + const pluginInRegistry = await findPluginInRegistry(stagePlugin.id) + if (!pluginInRegistry) { throw new PluginNotFoundInRegistryError(stagePlugin.id) } @@ -75,15 +75,15 @@ const installVaultIterator: InstallCommandIterator = async (item) => { version, }) } catch (error) { + childLogger.error(`Failed to install plugin`, { error }) + const failedPlugin = { ...stagePlugin, - repo: pluginInRegistry?.repo, version, } result.failedPlugins.push(failedPlugin) handleExceedRateLimitError(error) - childLogger.error(`Failed to install plugin`, { error }) } } diff --git a/src/services/uninstall.test.ts b/src/services/uninstall.test.ts index 9e6f325..d0a66a6 100644 --- a/src/services/uninstall.test.ts +++ b/src/services/uninstall.test.ts @@ -11,16 +11,12 @@ import { } from '../utils/testing' import { ConfigSchema } from './config' import installService from './install' +import uninstallService from './uninstall' const { installVaultIterator } = installService +const { uninstallVaultIterator } = uninstallService const sandbox = sinon.createSandbox() -const removePluginDirStub = sandbox.stub().resolves() -const { - default: { uninstallVaultIterator }, -} = proxyquire.noCallThru()('./uninstall', { - '../providers/plugins': { removePluginDir: removePluginDirStub }, -}) const [{ id: plugin1Id }, { id: plugin2Id }] = [plugin1, plugin2] @@ -158,7 +154,12 @@ describe('Command: uninstall', () => { config?.plugins[0].id, ) - removePluginDirStub.rejects(new Error('Error')) + const removePluginDirStub = sandbox.stub().rejects(new Error('Error')) + const { + default: { uninstallVaultIterator }, + } = proxyquire.noCallThru()('./uninstall', { + '../providers/plugins': { removePluginDir: removePluginDirStub }, + }) const result = await (uninstallVaultIterator as UninstallCommandIterator)({ vault,