From 2a049cfbf2f4f4951efd6f5a353e288db8a21093 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Wed, 8 Nov 2023 12:32:59 -0800 Subject: [PATCH] Handle NotFound when mapping pypi coordinates --- lib/pypiCoordinatesMapper.js | 13 ++++++++++-- test/lib/pypiCoordinatesMapper.js | 35 +++++++++++++++++++------------ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/pypiCoordinatesMapper.js b/lib/pypiCoordinatesMapper.js index 40555e874..8481d5dad 100644 --- a/lib/pypiCoordinatesMapper.js +++ b/lib/pypiCoordinatesMapper.js @@ -23,8 +23,17 @@ class PypiCoordinatesMapper { async _resolve(coordinates) { const url = `${this.baseUrl}/pypi/${coordinates.name}/json` - const answer = await requestPromise({ url, method: 'GET', json: true }) - return answer?.info?.name && { name: answer.info.name } + try { + const answer = await this._handleRequest(url) + return answer?.info?.name && { name: answer.info.name } + } catch (error) { + if (error.statusCode === 404) return null + throw error + } + } + + _handleRequest(url) { + return requestPromise({ url, method: 'GET', json: true }) } } diff --git a/test/lib/pypiCoordinatesMapper.js b/test/lib/pypiCoordinatesMapper.js index c7bd22435..fba22bfcb 100644 --- a/test/lib/pypiCoordinatesMapper.js +++ b/test/lib/pypiCoordinatesMapper.js @@ -10,38 +10,47 @@ function mockPypiCoordinates(name) { return EntityCoordinates.fromString(`pypi/pypi/-/${name}/1.1.0a4`) } +function mockPypiAnswer(name) { + return { info: { name } } +} + describe('PypiCoordinatesMapper', () => { + let coordinatesMapper + beforeEach(() => { + coordinatesMapper = new PypiCoordinatesMapper() + }) - it('name containing "_" mapped to "-"', async () => { - const coordinatesMapper = new PypiCoordinatesMapper() - sinon.stub(coordinatesMapper, '_resolve').resolves({ name: '0-core-client' }) + it('should map name containing "_" mapped to "-"', async () => { + sinon.stub(coordinatesMapper, '_handleRequest').resolves(mockPypiAnswer('0-core-client')) const mapped = await coordinatesMapper.map(mockPypiCoordinates('0_core_client')) expect(mapped.name).to.be.eq('0-core-client') }) - it('name containing "." mapped to "-"', async () => { - const coordinatesMapper = new PypiCoordinatesMapper() - sinon.stub(coordinatesMapper, '_resolve').resolves({ name: '0-core-client' }) + it('should map name containing "." mapped to "-"', async () => { + sinon.stub(coordinatesMapper, '_handleRequest').resolves(mockPypiAnswer('0-core-client')) const mapped = await coordinatesMapper.map(mockPypiCoordinates('0.core_client')) expect(mapped.name).to.be.eq('0-core-client') }) - it('name containing "-" mapped to "_"', async () => { - const coordinatesMapper = new PypiCoordinatesMapper() - sinon.stub(coordinatesMapper, '_resolve').resolves({ name: 'backports.ssl_match_hostname' }) + it('should map name containing "-" mapped to "_"', async () => { + sinon.stub(coordinatesMapper, '_handleRequest').resolves(mockPypiAnswer('backports.ssl_match_hostname')) const mapped = await coordinatesMapper.map(mockPypiCoordinates('Backports.ssl-match-hostname')) expect(mapped.name).to.be.eq('backports.ssl_match_hostname') }) - it('name not resolved', async () => { - const coordinatesMapper = new PypiCoordinatesMapper() + it('should return null when pypi api returns 404', async () => { + sinon.stub(coordinatesMapper, '_handleRequest').throws({ statusCode: 404 }) + const mapped = await coordinatesMapper.map(mockPypiCoordinates('blivet-gui')) + expect(mapped).to.be.null + }) + + it('should handle name not resolved', async () => { sinon.stub(coordinatesMapper, '_resolve').resolves(undefined) const mapped = await coordinatesMapper.map(mockPypiCoordinates('0_core_client')) expect(mapped).to.be.undefined }) - it('no mapping necessary', async () => { - const coordinatesMapper = new PypiCoordinatesMapper() + it('should handle no mapping necessary', async () => { sinon.stub(coordinatesMapper, '_resolve').rejects('Should not be called') const mapped = await coordinatesMapper.map(mockPypiCoordinates('backports')) expect(mapped).to.be.null