From c55119041bacdf95c6bdf95193ebf8ddb8bd71e7 Mon Sep 17 00:00:00 2001 From: Alex Alikiotis Date: Tue, 6 Jul 2021 12:22:55 +0300 Subject: [PATCH] Adding another batch of unit tests (#34) * adding tests for the maintenance plugin * adding tests for the license plugin * adding tests for the licenseTree plugin * adding tests for the support plugin --- test/plugins/license.test.js | 107 +++++++++++++++++++ test/plugins/licenseTree.test.js | 172 +++++++++++++++++++++++++++++++ test/plugins/maintenance.test.js | 66 ++++++++++++ test/plugins/support.test.js | 86 ++++++++++++++++ 4 files changed, 431 insertions(+) create mode 100644 test/plugins/license.test.js create mode 100644 test/plugins/licenseTree.test.js create mode 100644 test/plugins/maintenance.test.js create mode 100644 test/plugins/support.test.js diff --git a/test/plugins/license.test.js b/test/plugins/license.test.js new file mode 100644 index 0000000..affff5c --- /dev/null +++ b/test/plugins/license.test.js @@ -0,0 +1,107 @@ +/* eslint-env jest */ + +const { success, warning, failure } = require('../../src/lib/format'); +const licensePlugin = require('../../src/plugins/license'); + +jest.mock('../../src/lib/format', () => ({ + ...jest.requireActual('../../src/lib/format'), + failure: jest.fn(), + success: jest.fn(), + warning: jest.fn() +})); + +afterEach(() => { + jest.clearAllMocks(); +}); + +it('should return null when license is globally accepted', async () => { + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'MIT' + }, + config: { + licenses: { + allow: ['MIT', 'Apache-2.0'], + rules: {} + } + } + }; + + const result = await licensePlugin(testEnv.pkg, testEnv.config); + + expect(result).toBe(null); + expect(success).toHaveBeenCalled(); +}); + +it('should return null when the license is locally accepted', async () => { + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'Apache-2.0' + }, + config: { + licenses: { + allow: ['MIT'], + rules: { + test: { + allow: ['Apache-2.0'] + } + } + } + } + }; + + const result = await licensePlugin(testEnv.pkg, testEnv.config); + + expect(result).toBe(null); + expect(success).toHaveBeenCalled(); +}); + +it('should return a warning when the license is locally overridden', async () => { + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'Apache-2.0' + }, + config: { + licenses: { + allow: ['MIT'], + rules: { + test: { + override: ['Apache-2.0'] + } + } + } + } + }; + + const result = await licensePlugin(testEnv.pkg, testEnv.config); + + expect(result.type).toBe('warning'); + expect(warning).toHaveBeenCalled(); +}); + +it('should return an error when the license is not accepted', async () => { + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'Apache-2.0' + }, + config: { + licenses: { + allow: ['MIT'], + rules: {} + } + } + }; + + const result = await licensePlugin(testEnv.pkg, testEnv.config); + + expect(result.type).toBe('error'); + expect(failure).toHaveBeenCalled(); +}); diff --git a/test/plugins/licenseTree.test.js b/test/plugins/licenseTree.test.js new file mode 100644 index 0000000..842e30d --- /dev/null +++ b/test/plugins/licenseTree.test.js @@ -0,0 +1,172 @@ +/* eslint-env jest */ + +const licenseChecker = require('license-checker'); +const licenseTreePlugin = require('../../src/plugins/licenseTree'); +const { success, warning, failure } = require('../../src/lib/format'); + +jest.mock('license-checker'); + +jest.mock('../../src/lib/format', () => ({ + ...jest.requireActual('../../src/lib/format'), + failure: jest.fn(), + success: jest.fn(), + warning: jest.fn() +})); + +afterEach(() => { + jest.clearAllMocks(); +}); + +it('should return an empty list when the dep-tree has acceptable licenses', async () => { + // mock licenseChecker's functionality + licenseChecker.init.mockImplementation((_, cb) => { + const packages = { + dummy: { + licenses: 'MIT', + repository: 'https://github.com/dummy/dummy' + }, + dummy2: { + licenses: 'MIT', + repository: 'https://github.com/dummy2/dummy2' + } + }; + cb(null, packages); + }); + + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test' + }, + config: { + licenses: { + allow: ['MIT', 'Apache-2.0'], + rules: {} + } + } + }; + + const result = await licenseTreePlugin(testEnv.pkg, testEnv.config); + + expect(result).toEqual([]); + expect(success).toBeCalledTimes(2); +}); + +it('should return a list of errors when deps have non-acceptable licenses', async () => { + // mock licenseChecker's functionality + licenseChecker.init.mockImplementation((_, cb) => { + const packages = { + dummy: { + licenses: 'BSD', + repository: 'https://github.com/dummy/dummy' + }, + dummy2: { + licenses: 'BSD', + repository: 'https://github.com/dummy2/dummy2' + } + }; + cb(null, packages); + }); + + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test' + }, + config: { + licenses: { + allow: ['MIT', 'Apache-2.0'], + rules: {} + } + } + }; + + const result = await licenseTreePlugin(testEnv.pkg, testEnv.config); + + expect(result.length).toBe(2); + expect(result[0].type).toBe('error'); + expect(result[1].type).toBe('error'); + expect(failure).toHaveBeenCalledTimes(2); +}); + +it('should return an empty list when deps have "local" acceptable licenses', async () => { + // mock licenseChecker's functionality + licenseChecker.init.mockImplementation((_, cb) => { + const packages = { + dummy: { + licenses: 'BSD', + repository: 'https://github.com/dummy/dummy' + }, + dummy2: { + licenses: 'BSD', + repository: 'https://github.com/dummy2/dummy2' + } + }; + cb(null, packages); + }); + + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'Apache-2.0' + }, + config: { + licenses: { + allow: ['MIT', 'Apache-2.0'], + rules: { + test: { + allow: ['BSD'] + } + } + } + } + }; + + const result = await licenseTreePlugin(testEnv.pkg, testEnv.config); + + expect(result).toEqual([]); + expect(success).toBeCalledTimes(2); +}); + +it('should return a list of warnings when deps have "non-decidable" licenses', async () => { + // mock licenseChecker's functionality + licenseChecker.init.mockImplementation((_, cb) => { + const packages = { + dummy: { + licenses: 'BSD', + repository: 'https://github.com/dummy/dummy' + }, + dummy2: { + licenses: 'BSD', + repository: 'https://github.com/dummy2/dummy2' + } + }; + cb(null, packages); + }); + + // create a sample env with some dummy data + const testEnv = { + pkg: { + name: 'test', + license: 'Apache-2.0' + }, + config: { + licenses: { + allow: ['MIT', 'Apache-2.0'], + rules: { + test: { + override: ['BSD'] + } + } + } + } + }; + + const result = await licenseTreePlugin(testEnv.pkg, testEnv.config); + + expect(result.length).toBe(2); + expect(result[0].type).toBe('warning'); + expect(result[1].type).toBe('warning'); + expect(warning).toHaveBeenCalledTimes(2); +}); diff --git a/test/plugins/maintenance.test.js b/test/plugins/maintenance.test.js new file mode 100644 index 0000000..5d2cad3 --- /dev/null +++ b/test/plugins/maintenance.test.js @@ -0,0 +1,66 @@ +/* eslint-env jest */ + +const network = require('../../src/lib/fetch'); +const { success, warning } = require('../../src/lib/format'); +const maintenancePlugin = require('../../src/plugins/maintenance'); + +jest.mock('../../src/lib/fetch'); +jest.mock('../../src/lib/format', () => ({ + ...jest.requireActual('../../src/lib/format'), + failure: jest.fn(), + success: jest.fn(), + warning: jest.fn() +})); + +afterEach(() => { + jest.clearAllMocks(); +}); + +it('should return null when module has a recent release', async () => { + network.fetchGithub.mockImplementation(() => { + return [{ published_at: new Date() }]; + }); + + const pkg = { + repository: { + url: 'git+https://github.com/test/test.git' + } + }; + + const result = await maintenancePlugin(pkg, null, {}); + + expect(result).toBe(null); + expect(success).toHaveBeenCalled(); +}); + +it('should return a warning when release is more than six months old', async () => { + network.fetchGithub.mockImplementation(() => { + return [{ published_at: new Date(new Date() - 123456789123) }]; + }); + + const pkg = { + repository: { + url: 'git+https://github.com/test/test.git' + } + }; + + const result = await maintenancePlugin(pkg, null, {}); + expect(result.type).toBe('warning'); + expect(warning).toHaveBeenCalled(); +}); + +it('should return a warning when a module has no releases', async () => { + network.fetchGithub.mockImplementation(() => { + return []; + }); + + const pkg = { + repository: { + url: 'git+https://github.com/test/test.git' + } + }; + + const result = await maintenancePlugin(pkg, null, {}); + expect(result.type).toBe('warning'); + expect(warning).toHaveBeenCalled(); +}); diff --git a/test/plugins/support.test.js b/test/plugins/support.test.js new file mode 100644 index 0000000..28142e5 --- /dev/null +++ b/test/plugins/support.test.js @@ -0,0 +1,86 @@ +/* eslint-env jest */ + +const pkgSupport = require('@pkgjs/support'); +const nv = require('@pkgjs/nv'); + +const supportPlugin = require('../../src/plugins/support'); +const { success, warning } = require('../../src/lib/format'); + +jest.mock('@pkgjs/support'); +jest.mock('@pkgjs/nv'); +jest.mock('../../src/lib/format', () => ({ + ...jest.requireActual('../../src/lib/format'), + failure: jest.fn(), + success: jest.fn(), + warning: jest.fn() +})); + +afterEach(() => { + jest.clearAllMocks(); +}); + +it('should return null if the package supports LTS through @pkgjs/support', async () => { + // mocking the @pkgjs/support dependency + pkgSupport.getSupportData.mockImplementation(() => { + return { + contents: Buffer.from('{"versions":[{"target":{"node":"lts"}}]}') + }; + }); + + const pkg = { name: 'test' }; + + const result = await supportPlugin(pkg); + + expect(result).toBe(null); + expect(success).toHaveBeenCalled(); +}); + +it('should return null if the package supports LTS through engines field', async () => { + // mocking the @pkgjs/support dependency + pkgSupport.getSupportData.mockImplementation(() => { + return { + contents: 'unknown' + }; + }); + + const pkg = { + name: 'test', + engines: { + node: '>= 0.10.0' + } + }; + + nv.mockImplementation(() => { + return Promise.resolve([{ version: '14.2.20' }, { version: '16.3.19' }]); + }); + + const result = await supportPlugin(pkg); + + expect(result).toBe(null); + expect(success).toHaveBeenCalled(); +}); + +it("should return a warning if the package doesn't have support for LTS", async () => { + // mocking the @pkgjs/support dependency + pkgSupport.getSupportData.mockImplementation(() => { + return { + contents: 'unknown' + }; + }); + + const pkg = { + name: 'test', + engines: { + node: '>= 0.10.3 < 14' + } + }; + + nv.mockImplementation(() => { + return Promise.resolve([{ version: '14.2.20' }, { version: '16.3.19' }]); + }); + + const result = await supportPlugin(pkg); + + expect(result.type).toBe('warning'); + expect(warning).toHaveBeenCalled(); +});