From 87748592d3b2f1078dd374d313eaec73085fe76a Mon Sep 17 00:00:00 2001 From: Kyle Pollich Date: Thu, 22 Sep 2022 14:16:09 -0400 Subject: [PATCH] [Fleet] Check bundled packages when querying package info in getInfo API (#141462) * Check bundled packages when querying package info in getInfo API * Add tests for fetchInfo * Remove needless beforeEach --- .../services/epm/registry/index.test.ts | 49 ++++++++++++++++++- .../server/services/epm/registry/index.ts | 18 ++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts index ba309a15b04ee..6504b6548f078 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts @@ -7,12 +7,15 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; -import { PackageNotFoundError } from '../../../errors'; +import { PackageNotFoundError, RegistryResponseError } from '../../../errors'; + +import * as Archive from '../archive'; import { splitPkgKey, fetchFindLatestPackageOrUndefined, fetchFindLatestPackageOrThrow, + fetchInfo, getLicensePath, } from '.'; @@ -21,6 +24,11 @@ const mockLogger = mockLoggerFactory.get('mock logger'); const mockGetBundledPackageByName = jest.fn(); const mockFetchUrl = jest.fn(); + +const MockArchive = Archive as jest.Mocked; + +jest.mock('../archive'); + jest.mock('../..', () => ({ appContextService: { getLogger: () => mockLogger, @@ -150,6 +158,8 @@ describe('fetch package', () => { }); describe('getLicensePath', () => { + MockArchive.getPathParts = jest.requireActual('../archive').getPathParts; + it('returns first license path if found', () => { const path = getLicensePath([ '/package/good-1.0.0/NOTICE.txt', @@ -171,3 +181,40 @@ describe('getLicensePath', () => { expect(path).toEqual(undefined); }); }); + +describe('fetchInfo', () => { + beforeEach(() => { + jest.resetAllMocks(); + + mockFetchUrl.mockRejectedValueOnce(new RegistryResponseError('Not found', 404)); + mockGetBundledPackageByName.mockResolvedValueOnce({ + name: 'test-package', + version: '1.0.0', + buffer: Buffer.from(''), + }); + MockArchive.generatePackageInfoFromArchiveBuffer.mockResolvedValueOnce({ + paths: [], + packageInfo: { + name: 'test-package', + title: 'Test Package', + version: '1.0.0', + description: 'Test package', + owner: { github: 'elastic' }, + format_version: '1.0.0', + }, + }); + }); + + it('falls back to bundled package when one exists', async () => { + const fetchedInfo = await fetchInfo('test-package', '1.0.0'); + expect(fetchedInfo).toBeTruthy(); + }); + + it('throws when no corresponding bundled package exists', async () => { + try { + await fetchInfo('test-package', '1.0.0'); + } catch (e) { + expect(e).toBeInstanceOf(PackageNotFoundError); + } + }); +}); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index fee603f188e29..0b1c1d0bd562f 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -24,6 +24,7 @@ import type { RegistrySearchResults, GetCategoriesRequest, PackageVerificationResult, + ArchivePackage, } from '../../../types'; import { getArchiveFilelist, @@ -159,7 +160,10 @@ export async function fetchFindLatestPackageOrUndefined( } } -export async function fetchInfo(pkgName: string, pkgVersion: string): Promise { +export async function fetchInfo( + pkgName: string, + pkgVersion: string +): Promise { const registryUrl = getRegistryUrl(); try { // Trailing slash avoids 301 redirect / extra hop @@ -168,6 +172,18 @@ export async function fetchInfo(pkgName: string, pkgVersion: string): Promise