From 4448d3f25b1d8406abaf3c87db0921066cb831c5 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Mon, 22 Aug 2022 23:56:34 +0200 Subject: [PATCH 01/23] happy path is done: packagist depenency version is returned for dependencyVendor and dependencyRepo --- services/packagist/packagist-base.js | 8 +- .../packagist-dependency-version.service.js | 193 ++++++++++++++++++ 2 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 services/packagist/packagist-dependency-version.service.js diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 298105e40997f..2fb6d093df451 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -6,9 +6,7 @@ const packageSchema = Joi.array().items( Joi.object({ version: Joi.string().required(), require: Joi.alternatives( - Joi.object({ - php: Joi.string(), - }).required(), + Joi.object().pattern(Joi.string(), Joi.string()).required(), Joi.string().valid('__unset') ), }) @@ -23,7 +21,7 @@ class BasePackagistService extends BaseJsonService { /** * Default fetch method. * - * This method utilize composer metadata API which + * This method utilizes composer metadata API which * "... is the preferred way to access the data as it is always up to date, * and dumped to static files so it is very efficient on our end." (comment from official documentation). * For more information please refer to https://packagist.org/apidoc#get-package-data. @@ -47,7 +45,7 @@ class BasePackagistService extends BaseJsonService { /** * Fetch dev releases method. * - * This method utilize composer metadata API which + * This method utilizes composer metadata API which * "... is the preferred way to access the data as it is always up to date, * and dumped to static files so it is very efficient on our end." (comment from official documentation). * For more information please refer to https://packagist.org/apidoc#get-package-data. diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js new file mode 100644 index 0000000000000..fadacd887686e --- /dev/null +++ b/services/packagist/packagist-dependency-version.service.js @@ -0,0 +1,193 @@ +import Joi from 'joi' +import { optionalUrl } from '../validators.js' +import { NotFound } from '../index.js' +import { + allVersionsSchema, + BasePackagistService, + customServerDocumentationFragment, +} from './packagist-base.js' + +const queryParamSchema = Joi.object({ + dependencyVendor: Joi.string(), + dependencyRepo: Joi.string(), + server: optionalUrl, +}).required() + +export default class PackagistDependencyVersion extends BasePackagistService { + static category = 'platform-support' + + static route = { + base: 'packagist/dependency-v', + pattern: ':user/:repo/:version?', + queryParamSchema, + } + + static examples = [ + { + title: 'Packagist Dependency Version Support', + pattern: ':user/:repo', + namedParams: { + user: 'symfony', + repo: 'symfony', + }, + queryParams: { + dependencyVendor: 'twig', + dependencyRepo: 'twig', + }, + staticPreview: this.render({ dependencyVersion: '2.13|^3.0.4' }), + }, + { + title: 'Packagist Dependency Version Support (specify version)', + pattern: ':user/:repo/:version', + namedParams: { + user: 'symfony', + repo: 'symfony', + version: 'v2.8.0', + }, + queryParams: { + dependencyVendor: 'twig', + dependencyRepo: 'twig', + }, + staticPreview: this.render({ dependencyVersion: '1.12' }), + }, + { + title: 'Packagist Dependency Version Support (custom server)', + pattern: ':user/:repo', + namedParams: { + user: 'symfony', + repo: 'symfony', + }, + queryParams: { + dependencyVendor: 'twig', + dependencyRepo: 'twig', + server: 'https://packagist.org', + }, + staticPreview: this.render({ dependencyVersion: '2.13|^3.0.4' }), + documentation: customServerDocumentationFragment, + }, + ] + + static defaultBadgeData = { + label: 'dependency version', + color: 'blue', + } + + static render({ dependencyVersion }) { + return { + message: dependencyVersion, + } + } + + findVersionIndex(json, version) { + return json.findIndex(v => v.version === version) + } + + async findSpecifiedVersion(json, user, repo, version, server) { + let release + + if ((release = json[this.findVersionIndex(json, version)])) { + return release + } else { + try { + const allData = await this.fetchDev({ + user, + repo, + schema: allVersionsSchema, + server, + }) + + const versions = BasePackagistService.expandPackageVersions( + allData, + this.getPackageName(user, repo) + ) + + return versions[this.findVersionIndex(versions, version)] + } catch (e) { + return release + } + } + } + + async getDependencyVersion({ + json, + user, + repo, + version = '', + server, + dependencyVendor, + dependencyRepo, + }) { + let packageVersion + const versions = BasePackagistService.expandPackageVersions( + json, + this.getPackageName(user, repo) + ) + + if (version === '') { + packageVersion = this.findLatestRelease(versions) + } else { + try { + packageVersion = await this.findSpecifiedVersion( + versions, + user, + repo, + version, + server + ) + } catch (e) { + packageVersion = null + } + } + + if (!packageVersion) { + throw new NotFound({ prettyMessage: 'invalid version' }) + } + + if (!packageVersion.require || !packageVersion.require.php) { + throw new NotFound({ prettyMessage: 'version requirement not found' }) + } + + let dependencyIdentifier + + const depVendLowercase = dependencyVendor?.toLowerCase() + const depRepoLowercase = dependencyRepo?.toLowerCase() + + if (dependencyRepo || dependencyVendor) { + if (!!dependencyRepo & !dependencyVendor) { + dependencyIdentifier = depRepoLowercase + } else if (!dependencyRepo & !!dependencyVendor) { + dependencyIdentifier = depVendLowercase + } else { + dependencyIdentifier = `${depVendLowercase}/${depRepoLowercase}` + } + } else { + throw new NotFound({ prettyMessage: 'version requirement not found' }) + } + + return { dependencyVersion: packageVersion.require[dependencyIdentifier] } + } + + async handle( + { user, repo, version = '' }, + { dependencyVendor, dependencyRepo, server } + ) { + const allData = await this.fetch({ + user, + repo, + schema: allVersionsSchema, + server, + }) + + const { dependencyVersion } = await this.getDependencyVersion({ + json: allData, + user, + repo, + version, + server, + dependencyVendor, + dependencyRepo, + }) + + return this.constructor.render({ dependencyVersion }) + } +} From 2b9703332d14cf0e0f668ea206aecf2049cae018 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Thu, 25 Aug 2022 23:20:45 +0200 Subject: [PATCH 02/23] changes in error handling in packagist dependency version service --- .../packagist/packagist-dependency-version.service.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index fadacd887686e..2d5d1ffefde2b 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -143,7 +143,7 @@ export default class PackagistDependencyVersion extends BasePackagistService { throw new NotFound({ prettyMessage: 'invalid version' }) } - if (!packageVersion.require || !packageVersion.require.php) { + if (!packageVersion.require) { throw new NotFound({ prettyMessage: 'version requirement not found' }) } @@ -161,6 +161,12 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyIdentifier = `${depVendLowercase}/${depRepoLowercase}` } } else { + throw new NotFound({ + prettyMessage: 'dependency vendor or repo not specified', + }) + } + + if (!packageVersion.require[dependencyIdentifier]) { throw new NotFound({ prettyMessage: 'version requirement not found' }) } From 77717e4559d86d2861e7b705e9571e1eeae41493 Mon Sep 17 00:00:00 2001 From: PaulaBarszcz Date: Fri, 26 Aug 2022 19:33:48 +0200 Subject: [PATCH 03/23] Move to packagist-base common parts of packagist-php and packagist-dep-ver --- services/packagist/packagist-base.js | 31 ++++++++++++++++++- .../packagist-dependency-version.service.js | 30 ------------------ .../packagist-php-version.service.js | 30 ------------------ 3 files changed, 30 insertions(+), 61 deletions(-) diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 2fb6d093df451..5cc6bbfc0aa22 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -163,8 +163,37 @@ class BasePackagistService extends BaseJsonService { } return versions.filter(version => version.version === release)[0] } -} + findVersionIndex(json, version) { + return json.findIndex(v => v.version === version) + } + + async findSpecifiedVersion(json, user, repo, version, server) { + let release + + if ((release = json[this.findVersionIndex(json, version)])) { + return release + } else { + try { + const allData = await this.fetchDev({ + user, + repo, + schema: allVersionsSchema, + server, + }) + + const versions = this.expandPackageVersions( + allData, + this.getPackageName(user, repo) + ) + + return versions[this.findVersionIndex(versions, version)] + } catch (e) { + return release + } + } + } +} const customServerDocumentationFragment = `

Note that only network-accessible packagist.org and other self-hosted Packagist instances are supported. diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 2d5d1ffefde2b..8d846d39f2826 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -78,36 +78,6 @@ export default class PackagistDependencyVersion extends BasePackagistService { } } - findVersionIndex(json, version) { - return json.findIndex(v => v.version === version) - } - - async findSpecifiedVersion(json, user, repo, version, server) { - let release - - if ((release = json[this.findVersionIndex(json, version)])) { - return release - } else { - try { - const allData = await this.fetchDev({ - user, - repo, - schema: allVersionsSchema, - server, - }) - - const versions = BasePackagistService.expandPackageVersions( - allData, - this.getPackageName(user, repo) - ) - - return versions[this.findVersionIndex(versions, version)] - } catch (e) { - return release - } - } - } - async getDependencyVersion({ json, user, diff --git a/services/packagist/packagist-php-version.service.js b/services/packagist/packagist-php-version.service.js index 11ef271899ed6..1fcbc06ddf359 100644 --- a/services/packagist/packagist-php-version.service.js +++ b/services/packagist/packagist-php-version.service.js @@ -66,36 +66,6 @@ export default class PackagistPhpVersion extends BasePackagistService { } } - findVersionIndex(json, version) { - return json.findIndex(v => v.version === version) - } - - async findSpecifiedVersion(json, user, repo, version, server) { - let release - - if ((release = json[this.findVersionIndex(json, version)])) { - return release - } else { - try { - const allData = await this.fetchDev({ - user, - repo, - schema: allVersionsSchema, - server, - }) - - const versions = BasePackagistService.expandPackageVersions( - allData, - this.getPackageName(user, repo) - ) - - return versions[this.findVersionIndex(versions, version)] - } catch (e) { - return release - } - } - } - async getPhpVersion({ json, user, repo, version = '', server }) { let packageVersion const versions = BasePackagistService.expandPackageVersions( From 623b78710384ae3b8cabb00ce404dda8e477354f Mon Sep 17 00:00:00 2001 From: PaulaBarszcz Date: Thu, 1 Sep 2022 15:56:19 +0200 Subject: [PATCH 04/23] the label now shows the name of the dependency --- .../packagist-dependency-version.service.js | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 8d846d39f2826..17617e07ddfaf 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -34,7 +34,10 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyVendor: 'twig', dependencyRepo: 'twig', }, - staticPreview: this.render({ dependencyVersion: '2.13|^3.0.4' }), + staticPreview: this.render({ + dependencyNameForLabel: 'twig/twig', + dependencyVersion: '2.13|^3.0.4', + }), }, { title: 'Packagist Dependency Version Support (specify version)', @@ -48,7 +51,10 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyVendor: 'twig', dependencyRepo: 'twig', }, - staticPreview: this.render({ dependencyVersion: '1.12' }), + staticPreview: this.render({ + dependencyNameForLabel: 'twig/twig', + dependencyVersion: '1.12', + }), }, { title: 'Packagist Dependency Version Support (custom server)', @@ -62,7 +68,10 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyRepo: 'twig', server: 'https://packagist.org', }, - staticPreview: this.render({ dependencyVersion: '2.13|^3.0.4' }), + staticPreview: this.render({ + dependencyNameForLabel: 'twig/twig', + dependencyVersion: '2.13|^3.0.4', + }), documentation: customServerDocumentationFragment, }, ] @@ -72,12 +81,23 @@ export default class PackagistDependencyVersion extends BasePackagistService { color: 'blue', } - static render({ dependencyVersion }) { + static render({ dependencyNameForLabel, dependencyVersion }) { return { + label: dependencyNameForLabel, message: dependencyVersion, } } + determineDependencyNameForLabel({ dependencyVendor, dependencyRepo }) { + if (dependencyVendor && dependencyRepo) { + return `${dependencyVendor}/${dependencyRepo}` + } else if (dependencyVendor && !dependencyRepo) { + return dependencyVendor + } else if (!dependencyVendor && dependencyRepo) { + return dependencyRepo + } + } + async getDependencyVersion({ json, user, @@ -164,6 +184,14 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyRepo, }) - return this.constructor.render({ dependencyVersion }) + const dependencyNameForLabel = this.determineDependencyNameForLabel({ + dependencyVendor, + dependencyRepo, + }) + + return this.constructor.render({ + dependencyNameForLabel, + dependencyVersion, + }) } } From 6de21c3bd3e94a8435de734e94a8f2df23eef24b Mon Sep 17 00:00:00 2001 From: PaulaBarszcz Date: Thu, 1 Sep 2022 17:28:21 +0200 Subject: [PATCH 05/23] add comments,slightly modify if statement --- services/packagist/packagist-base.js | 2 ++ services/packagist/packagist-dependency-version.service.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 5cc6bbfc0aa22..431e59bec042b 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -164,10 +164,12 @@ class BasePackagistService extends BaseJsonService { return versions.filter(version => version.version === release)[0] } + // moved from packagist-php-version.service.js so that it can be reused in packagist-dependency-version.service.js findVersionIndex(json, version) { return json.findIndex(v => v.version === version) } + // moved from packagist-php-version.service.js so that it can be reused in packagist-dependency-version.service.js async findSpecifiedVersion(json, user, repo, version, server) { let release diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 17617e07ddfaf..c725d5977a3fc 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -143,9 +143,9 @@ export default class PackagistDependencyVersion extends BasePackagistService { const depRepoLowercase = dependencyRepo?.toLowerCase() if (dependencyRepo || dependencyVendor) { - if (!!dependencyRepo & !dependencyVendor) { + if (dependencyRepo & !dependencyVendor) { dependencyIdentifier = depRepoLowercase - } else if (!dependencyRepo & !!dependencyVendor) { + } else if (!dependencyRepo & dependencyVendor) { dependencyIdentifier = depVendLowercase } else { dependencyIdentifier = `${depVendLowercase}/${depRepoLowercase}` From 905667c36b7db26245fed3b6e262770e728ee96b Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 16:17:41 +0200 Subject: [PATCH 06/23] fix unit tests in services/packagist/packagist-php-version.spec.js --- services/packagist/packagist-php-version.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/packagist/packagist-php-version.spec.js b/services/packagist/packagist-php-version.spec.js index 9fc1bc150060c..4a4a170b43ba0 100644 --- a/services/packagist/packagist-php-version.spec.js +++ b/services/packagist/packagist-php-version.spec.js @@ -1,5 +1,8 @@ -import { expect } from 'chai' +import chai from 'chai' +import chaiAsPromised from 'chai-as-promised' import PackagistPhpVersion from './packagist-php-version.service.js' +const { expect } = chai +chai.use(chaiAsPromised) describe('PackagistPhpVersion', function () { const json = { From 6fe762eeb74ab1fc684b409915035a026e3bc111 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 17:11:35 +0200 Subject: [PATCH 07/23] add unit tests for services/packagist/packagist-dependency-version.js --- .../packagist-dependency-version.spec.js | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 services/packagist/packagist-dependency-version.spec.js diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js new file mode 100644 index 0000000000000..2b0491d798cf0 --- /dev/null +++ b/services/packagist/packagist-dependency-version.spec.js @@ -0,0 +1,116 @@ +import chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import PackagistDependencyVersion from './packagist-dependency-version.service.js' +const { expect } = chai +chai.use(chaiAsPromised) + +// majority of tests below are copied from packagist-php-version.spec, since PackagistDependencyVersion should work very similarly to PackagistDependencyVersion (just with the option to specify the second dependency, instead of the hardoded 'php') +describe('PackagistDependencyVersion', function () { + const fullPackagistJson = { + packages: { + 'frodo/the-one-package': [ + { + version: '3.0.0', + require: { php: '^7.4 || 8', 'twig/twig': '~1.28|~2.0' }, + }, + { + version: '2.0.0', + require: { php: '^7.2', 'twig/twig': '~1.20|~1.30' }, + }, + { + version: '1.0.0', + require: { php: '^5.6 || ^7', 'twig/twig': '~1.10|~1.0' }, + }, + ], + }, + } + + it('should throw NotFound when package version is missing', async function () { + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + version: '4.0.0', + }) + ).to.be.rejectedWith('invalid version') + }) + + it('should throw NotFound when dependency version not found on package when using default release', async function () { + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + }) + ).to.be.rejectedWith('dependency vendor or repo not specified') + }) + + it('should throw NotFound when dependency version not found on package when using specified release', async function () { + const fullPackagistJson = { + packages: { + 'frodo/the-one-package': [ + { + version: '3.0.0', + require: { php: '^7.4 || 8' }, + }, + { + version: '2.0.0', + require: { php: '^7.2' }, + }, + { + version: '1.0.0', + require: '__unset', + }, + ], + }, + } + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + version: '1.0.0', + }) + ).to.be.rejectedWith('version requirement not found') + }) + + it('should throw NotFound if neither dependencyVendor nor dependencyRepo was specified', async function () { + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + }) + ).to.be.rejectedWith('dependency vendor or repo not specified') + }) + + it('should return dependency version for the default release', async function () { + expect( + await PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + dependencyVendor: 'twig', + dependencyRepo: 'twig', + }) + ) + .to.have.property('dependencyVersion') + .that.equals('~1.28|~2.0') + }) + + it('should return dependency version for the specified release', async function () { + expect( + await PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + version: '2.0.0', + dependencyVendor: 'twig', + dependencyRepo: 'twig', + }) + ) + .to.have.property('dependencyVersion') + .that.equals('~1.20|~1.30') + }) +}) From 55f50ce2cfff4243faf3dfcb086c43694e19ae85 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 18:24:52 +0200 Subject: [PATCH 08/23] service tests for packagist-dependency-version.service.js are in progress --- .../packagist-dependency-version.tester.js | 49 +++++++++++++++++++ services/test-validators.js | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 services/packagist/packagist-dependency-version.tester.js diff --git a/services/packagist/packagist-dependency-version.tester.js b/services/packagist/packagist-dependency-version.tester.js new file mode 100644 index 0000000000000..817ceadb19199 --- /dev/null +++ b/services/packagist/packagist-dependency-version.tester.js @@ -0,0 +1,49 @@ +import { isComposerVersion } from '../test-validators.js' +import { createServiceTester } from '../tester.js' +export const t = await createServiceTester() + +t.create('gets the package version of symfony') + .get('/symfony/symfony.json?dependencyVendor=twig&dependencyRepo=twig') + .expectBadge({ label: 'twig/twig', message: isComposerVersion }) + +t.create('gets the package version of symfony 5.2.3') + .get('/symfony/symfony/v5.2.3.json?dependencyVendor=twig&dependencyRepo=twig') + .expectBadge({ label: 'twig/twig', message: isComposerVersion }) + +t.create('package with no requirements') + .get('/bpampuch/pdfmake.json?dependencyVendor=twig&dependencyRepo=twig') + .expectBadge({ + label: 'dependency version', + message: 'version requirement not found', + }) + +t.create('package with no twig/twig version requirement') + .get( + '/raulfraile/ladybug-theme-modern.json?dependencyVendor=twig&dependencyRepo=twig' + ) + .expectBadge({ + label: 'dependency version', + message: 'version requirement not found', + }) + +t.create('invalid package name') + .get('/frodo/is-not-a-package.json?dependencyVendor=twig&dependencyRepo=twig') + .expectBadge({ label: 'dependency version', message: 'not found' }) + +t.create('invalid version') + .get( + '/symfony/symfony/invalid.json?dependencyVendor=twig&dependencyRepo=twig' + ) + .expectBadge({ label: 'dependency version', message: 'invalid version' }) + +t.create('custom server') + .get( + '/symfony/symfony.json?server=https%3A%2F%2Fpackagist.org&dependencyVendor=twig&dependencyRepo=twig' + ) + .expectBadge({ label: 'twig/twig', message: isComposerVersion }) + +t.create('invalid custom server') + .get( + '/symfony/symfony.json?server=https%3A%2F%2Fpackagist.com&dependencyVendor=twig&dependencyRepo=twig' + ) + .expectBadge({ label: 'dependency version', message: 'not found' }) diff --git a/services/test-validators.js b/services/test-validators.js index ad1c131204f0a..a547bc7f9146a 100644 --- a/services/test-validators.js +++ b/services/test-validators.js @@ -43,7 +43,7 @@ const isVPlusDottedVersionNClausesWithOptionalSuffixAndEpoch = withRegex( // https://getcomposer.org/doc/04-schema.md#package-links // https://getcomposer.org/doc/04-schema.md#minimum-stability const isComposerVersion = withRegex( - /^\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?((\s*\|\|)?\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?)*\s*$/ + /^\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?((\s*\|*)?\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?)*\s*$/ ) // Regex for validate php-version.versionReduction() From 623b4423474c0dee4cbdef62cecc51d0cf6bc431 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 18:55:49 +0200 Subject: [PATCH 09/23] Add additional service tests for packagist-dependency-version.tester.js --- .../packagist-dependency-version.service.js | 4 +- .../packagist-dependency-version.tester.js | 61 ++++++++++++++++++- services/test-validators.js | 2 +- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index c725d5977a3fc..17617e07ddfaf 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -143,9 +143,9 @@ export default class PackagistDependencyVersion extends BasePackagistService { const depRepoLowercase = dependencyRepo?.toLowerCase() if (dependencyRepo || dependencyVendor) { - if (dependencyRepo & !dependencyVendor) { + if (!!dependencyRepo & !dependencyVendor) { dependencyIdentifier = depRepoLowercase - } else if (!dependencyRepo & dependencyVendor) { + } else if (!dependencyRepo & !!dependencyVendor) { dependencyIdentifier = depVendLowercase } else { dependencyIdentifier = `${depVendLowercase}/${depRepoLowercase}` diff --git a/services/packagist/packagist-dependency-version.tester.js b/services/packagist/packagist-dependency-version.tester.js index 817ceadb19199..0923e2dd16195 100644 --- a/services/packagist/packagist-dependency-version.tester.js +++ b/services/packagist/packagist-dependency-version.tester.js @@ -2,14 +2,71 @@ import { isComposerVersion } from '../test-validators.js' import { createServiceTester } from '../tester.js' export const t = await createServiceTester() -t.create('gets the package version of symfony') +t.create('gets the package version of symfony 5.2.3 - without query params') + .get('/symfony/symfony/v5.2.3.json') + .expectBadge({ + label: 'dependency version', + message: 'dependency vendor or repo not specified', + }) + +t.create( + 'gets the package version of symfony - with correct dependencyVendor and dependencyRepo' +) .get('/symfony/symfony.json?dependencyVendor=twig&dependencyRepo=twig') .expectBadge({ label: 'twig/twig', message: isComposerVersion }) -t.create('gets the package version of symfony 5.2.3') +t.create( + 'gets the package version of symfony 5.2.3 - with correct dependencyVendor and dependencyRepo' +) .get('/symfony/symfony/v5.2.3.json?dependencyVendor=twig&dependencyRepo=twig') .expectBadge({ label: 'twig/twig', message: isComposerVersion }) +t.create( + 'gets the package version of symfony 5.2.3 - with incorrect dependencyVendor' +) + .get( + '/symfony/symfony/v5.2.3.json?dependencyVendor=twiiiiiiiiiig&dependencyRepo=twig' + ) + .expectBadge({ + label: 'dependency version', + message: 'version requirement not found', + }) + +t.create( + 'gets the package version of symfony 5.2.3 - name of the dependencyVendor contains hyphen' +) + .get('/symfony/symfony/v5.2.3.json?dependencyVendor=ext-xml') + .expectBadge({ label: 'ext-xml', message: isComposerVersion }) + +t.create( + 'gets the package version of symfony 5.2.3 - incorrectly with missing dependencyVendor (twig/twig needs both dependencyVendor and dependencyRepo)' +) + .get('/symfony/symfony/v5.2.3.json?dependencyRepo=twig') + .expectBadge({ + label: 'dependency version', + message: 'version requirement not found', + }) + +t.create( + 'gets the package version of symfony 5.2.3 - correctly with missing dependencyVendor (php needs only dependencyVendor or dependencyRepo)' +) + .get('/symfony/symfony/v5.2.3.json?dependencyRepo=php') + .expectBadge({ label: 'php', message: isComposerVersion }) + +t.create( + 'gets the package version of symfony 5.2.3 - correctly when the dependencyVendor is the same as the name of the package' +) + .get( + '/symfony/symfony/v5.2.3.json?dependencyVendor=symfony&dependencyRepo=contracts' + ) + .expectBadge({ label: 'symfony/contracts', message: isComposerVersion }) + +t.create( + 'gets the package version of symfony 5.2.3 - correctly with missing dependencyRepo (php needs only dependencyVendor or dependencyRepo)' +) + .get('/symfony/symfony/v5.2.3.json?dependencyVendor=php') + .expectBadge({ label: 'php', message: isComposerVersion }) + t.create('package with no requirements') .get('/bpampuch/pdfmake.json?dependencyVendor=twig&dependencyRepo=twig') .expectBadge({ diff --git a/services/test-validators.js b/services/test-validators.js index a547bc7f9146a..148f471ba254c 100644 --- a/services/test-validators.js +++ b/services/test-validators.js @@ -43,7 +43,7 @@ const isVPlusDottedVersionNClausesWithOptionalSuffixAndEpoch = withRegex( // https://getcomposer.org/doc/04-schema.md#package-links // https://getcomposer.org/doc/04-schema.md#minimum-stability const isComposerVersion = withRegex( - /^\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?((\s*\|*)?\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?)*\s*$/ + /^\*|(\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?((\s*\|*)?\s*(>=|>|<|<=|!=|\^|~)?\d+(\.(\*|(\d+(\.(\d+|\*))?)))?)*\s*)$/ ) // Regex for validate php-version.versionReduction() From fd96f9ee3cba3f1a471ec5e54797b68eb32a7223 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 19:07:30 +0200 Subject: [PATCH 10/23] remove toLowerCase() --- .../packagist/packagist-dependency-version.service.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 17617e07ddfaf..434c6180defc4 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -139,16 +139,13 @@ export default class PackagistDependencyVersion extends BasePackagistService { let dependencyIdentifier - const depVendLowercase = dependencyVendor?.toLowerCase() - const depRepoLowercase = dependencyRepo?.toLowerCase() - if (dependencyRepo || dependencyVendor) { if (!!dependencyRepo & !dependencyVendor) { - dependencyIdentifier = depRepoLowercase + dependencyIdentifier = dependencyRepo } else if (!dependencyRepo & !!dependencyVendor) { - dependencyIdentifier = depVendLowercase + dependencyIdentifier = dependencyVendor } else { - dependencyIdentifier = `${depVendLowercase}/${depRepoLowercase}` + dependencyIdentifier = `${dependencyVendor}/${dependencyRepo}` } } else { throw new NotFound({ From de9aee1e771eaace8c1717ff361ed56512dac964 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Fri, 2 Sep 2022 19:13:34 +0200 Subject: [PATCH 11/23] resolve from lgtm: 1 for Wrong use of 'this' for static method --- services/packagist/packagist-base.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 431e59bec042b..81b4c48cd64bf 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -184,7 +184,7 @@ class BasePackagistService extends BaseJsonService { server, }) - const versions = this.expandPackageVersions( + const versions = BasePackagistService.expandPackageVersions( allData, this.getPackageName(user, repo) ) From 9b0e9cc836db20612362026de73d30f5c2d97f6b Mon Sep 17 00:00:00 2001 From: PaulaBarszcz Date: Sat, 3 Sep 2022 15:34:18 +0200 Subject: [PATCH 12/23] DRY determining the name of the dependency (depVen/depRepo) --- .../packagist/packagist-dependency-version.service.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 434c6180defc4..d5215bb896c5c 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -140,13 +140,10 @@ export default class PackagistDependencyVersion extends BasePackagistService { let dependencyIdentifier if (dependencyRepo || dependencyVendor) { - if (!!dependencyRepo & !dependencyVendor) { - dependencyIdentifier = dependencyRepo - } else if (!dependencyRepo & !!dependencyVendor) { - dependencyIdentifier = dependencyVendor - } else { - dependencyIdentifier = `${dependencyVendor}/${dependencyRepo}` - } + dependencyIdentifier = this.determineDependencyNameForLabel({ + dependencyVendor, + dependencyRepo, + }) } else { throw new NotFound({ prettyMessage: 'dependency vendor or repo not specified', From c1a77868436e9efeee9f2f44e92b5fcbb7b95341 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Wed, 7 Sep 2022 21:59:53 +0200 Subject: [PATCH 13/23] url change in strategy is in progress --- services/packagist/packagist-base.js | 32 ----- .../packagist-dependency-version.service.js | 72 ++++++++--- .../packagist-dependency-version.spec.js | 1 - .../packagist-php-version.service.js | 118 ++---------------- .../packagist/packagist-php-version.spec.js | 118 ------------------ .../packagist/packagist-php-version.tester.js | 22 ++++ 6 files changed, 85 insertions(+), 278 deletions(-) delete mode 100644 services/packagist/packagist-php-version.spec.js diff --git a/services/packagist/packagist-base.js b/services/packagist/packagist-base.js index 81b4c48cd64bf..2e50a0c010896 100644 --- a/services/packagist/packagist-base.js +++ b/services/packagist/packagist-base.js @@ -163,38 +163,6 @@ class BasePackagistService extends BaseJsonService { } return versions.filter(version => version.version === release)[0] } - - // moved from packagist-php-version.service.js so that it can be reused in packagist-dependency-version.service.js - findVersionIndex(json, version) { - return json.findIndex(v => v.version === version) - } - - // moved from packagist-php-version.service.js so that it can be reused in packagist-dependency-version.service.js - async findSpecifiedVersion(json, user, repo, version, server) { - let release - - if ((release = json[this.findVersionIndex(json, version)])) { - return release - } else { - try { - const allData = await this.fetchDev({ - user, - repo, - schema: allVersionsSchema, - server, - }) - - const versions = BasePackagistService.expandPackageVersions( - allData, - this.getPackageName(user, repo) - ) - - return versions[this.findVersionIndex(versions, version)] - } catch (e) { - return release - } - } - } } const customServerDocumentationFragment = `

diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index d5215bb896c5c..fe32b609a108c 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -8,9 +8,8 @@ import { } from './packagist-base.js' const queryParamSchema = Joi.object({ - dependencyVendor: Joi.string(), - dependencyRepo: Joi.string(), server: optionalUrl, + version: Joi.string(), }).required() export default class PackagistDependencyVersion extends BasePackagistService { @@ -18,62 +17,69 @@ export default class PackagistDependencyVersion extends BasePackagistService { static route = { base: 'packagist/dependency-v', - pattern: ':user/:repo/:version?', + pattern: ':user/:repo/:dependency+', queryParamSchema, } static examples = [ { title: 'Packagist Dependency Version Support', - pattern: ':user/:repo', + pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', - }, - queryParams: { - dependencyVendor: 'twig', - dependencyRepo: 'twig', + dependency: 'twig/twig', }, staticPreview: this.render({ - dependencyNameForLabel: 'twig/twig', dependencyVersion: '2.13|^3.0.4', }), }, { title: 'Packagist Dependency Version Support (specify version)', - pattern: ':user/:repo/:version', + pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', - version: 'v2.8.0', + dependency: 'twig/twig', }, queryParams: { - dependencyVendor: 'twig', - dependencyRepo: 'twig', + version: 'v2.8.0', }, staticPreview: this.render({ - dependencyNameForLabel: 'twig/twig', dependencyVersion: '1.12', }), }, { title: 'Packagist Dependency Version Support (custom server)', - pattern: ':user/:repo', + pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', + dependency: 'twig/twig', }, queryParams: { - dependencyVendor: 'twig', - dependencyRepo: 'twig', server: 'https://packagist.org', }, staticPreview: this.render({ - dependencyNameForLabel: 'twig/twig', dependencyVersion: '2.13|^3.0.4', }), documentation: customServerDocumentationFragment, }, + { + title: 'Packagist PHP Version Support (custom server)', + pattern: ':user/:repo/:dependency+', + namedParams: { + user: 'symfony', + repo: 'symfony', + dependency: 'php', + }, + queryParams: { + server: 'https://packagist.org', + version: 'v2.8.0', + }, + staticPreview: this.render({ dependencyVersion: '^7.1.3' }), + documentation: customServerDocumentationFragment, + }, ] static defaultBadgeData = { @@ -188,4 +194,34 @@ export default class PackagistDependencyVersion extends BasePackagistService { dependencyVersion, }) } + + findVersionIndex(json, version) { + return json.findIndex(v => v.version === version) + } + + async findSpecifiedVersion(json, user, repo, version, server) { + let release + + if ((release = json[this.findVersionIndex(json, version)])) { + return release + } else { + try { + const allData = await this.fetchDev({ + user, + repo, + schema: allVersionsSchema, + server, + }) + + const versions = BasePackagistService.expandPackageVersions( + allData, + this.getPackageName(user, repo) + ) + + return versions[this.findVersionIndex(versions, version)] + } catch (e) { + return release + } + } + } } diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 2b0491d798cf0..bf1c9237141e5 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -4,7 +4,6 @@ import PackagistDependencyVersion from './packagist-dependency-version.service.j const { expect } = chai chai.use(chaiAsPromised) -// majority of tests below are copied from packagist-php-version.spec, since PackagistDependencyVersion should work very similarly to PackagistDependencyVersion (just with the option to specify the second dependency, instead of the hardoded 'php') describe('PackagistDependencyVersion', function () { const fullPackagistJson = { packages: { diff --git a/services/packagist/packagist-php-version.service.js b/services/packagist/packagist-php-version.service.js index 1fcbc06ddf359..862ce0e0d86f4 100644 --- a/services/packagist/packagist-php-version.service.js +++ b/services/packagist/packagist-php-version.service.js @@ -1,119 +1,19 @@ import Joi from 'joi' +import { redirector } from '../index.js' import { optionalUrl } from '../validators.js' -import { NotFound } from '../index.js' -import { - allVersionsSchema, - BasePackagistService, - customServerDocumentationFragment, -} from './packagist-base.js' const queryParamSchema = Joi.object({ server: optionalUrl, }).required() -export default class PackagistPhpVersion extends BasePackagistService { - static category = 'platform-support' - - static route = { +export default redirector({ + category: 'platform-support', + route: { base: 'packagist/php-v', pattern: ':user/:repo/:version?', queryParamSchema, - } - - static examples = [ - { - title: 'Packagist PHP Version Support', - pattern: ':user/:repo', - namedParams: { - user: 'symfony', - repo: 'symfony', - }, - staticPreview: this.render({ php: '^7.1.3' }), - }, - { - title: 'Packagist PHP Version Support (specify version)', - pattern: ':user/:repo/:version', - namedParams: { - user: 'symfony', - repo: 'symfony', - version: 'v2.8.0', - }, - staticPreview: this.render({ php: '>=5.3.9' }), - }, - { - title: 'Packagist PHP Version Support (custom server)', - pattern: ':user/:repo', - namedParams: { - user: 'symfony', - repo: 'symfony', - }, - queryParams: { - server: 'https://packagist.org', - }, - staticPreview: this.render({ php: '^7.1.3' }), - documentation: customServerDocumentationFragment, - }, - ] - - static defaultBadgeData = { - label: 'php', - color: 'blue', - } - - static render({ php }) { - return { - message: php, - } - } - - async getPhpVersion({ json, user, repo, version = '', server }) { - let packageVersion - const versions = BasePackagistService.expandPackageVersions( - json, - this.getPackageName(user, repo) - ) - - if (version === '') { - packageVersion = this.findLatestRelease(versions) - } else { - try { - packageVersion = await this.findSpecifiedVersion( - versions, - user, - repo, - version, - server - ) - } catch (e) { - packageVersion = null - } - } - - if (!packageVersion) { - throw new NotFound({ prettyMessage: 'invalid version' }) - } - - if (!packageVersion.require || !packageVersion.require.php) { - throw new NotFound({ prettyMessage: 'version requirement not found' }) - } - - return { phpVersion: packageVersion.require.php } - } - - async handle({ user, repo, version = '' }, { server }) { - const allData = await this.fetch({ - user, - repo, - schema: allVersionsSchema, - server, - }) - const { phpVersion } = await this.getPhpVersion({ - json: allData, - user, - repo, - version, - server, - }) - return this.constructor.render({ php: phpVersion }) - } -} + }, + transformPath: ({ user, repo, version }) => + `/packagist/dependency-v/${user}/${repo}${version ? `/${version}` : ''}`, + dateAdded: new Date('2022-09-07'), +}) diff --git a/services/packagist/packagist-php-version.spec.js b/services/packagist/packagist-php-version.spec.js deleted file mode 100644 index 4a4a170b43ba0..0000000000000 --- a/services/packagist/packagist-php-version.spec.js +++ /dev/null @@ -1,118 +0,0 @@ -import chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import PackagistPhpVersion from './packagist-php-version.service.js' -const { expect } = chai -chai.use(chaiAsPromised) - -describe('PackagistPhpVersion', function () { - const json = { - packages: { - 'frodo/the-one-package': [ - { - version: '3.0.0', - require: { php: '^7.4 || 8' }, - }, - { - version: '2.0.0', - require: { php: '^7.2' }, - }, - { - version: '1.0.0', - require: { php: '^5.6 || ^7' }, - }, - ], - }, - } - - it('should throw NotFound when package version is missing', async function () { - await expect( - PackagistPhpVersion.prototype.getPhpVersion({ - json, - user: 'frodo', - repo: 'the-one-package', - version: '4.0.0', - }) - ).to.be.rejectedWith('invalid version') - }) - - it('should throw NotFound when PHP version not found on package when using default release', async function () { - const specJson = { - packages: { - 'frodo/the-one-package': [ - { - version: '3.0.0', - }, - { - version: '2.0.0', - require: { php: '^7.2' }, - }, - { - version: '1.0.0', - require: { php: '^5.6 || ^7' }, - }, - ], - }, - } - await expect( - PackagistPhpVersion.prototype.getPhpVersion({ - json: specJson, - user: 'frodo', - repo: 'the-one-package', - }) - ).to.be.rejectedWith('version requirement not found') - }) - - it('should throw NotFound when PHP version not found on package when using specified release', async function () { - const specJson = { - packages: { - 'frodo/the-one-package': [ - { - version: '3.0.0', - require: { php: '^7.4 || 8' }, - }, - { - version: '2.0.0', - require: { php: '^7.2' }, - }, - { - version: '1.0.0', - require: '__unset', - }, - ], - }, - } - await expect( - PackagistPhpVersion.prototype.getPhpVersion({ - json: specJson, - user: 'frodo', - repo: 'the-one-package', - version: '1.0.0', - }) - ).to.be.rejectedWith('version requirement not found') - }) - - it('should return PHP version for the default release', async function () { - expect( - await PackagistPhpVersion.prototype.getPhpVersion({ - json, - user: 'frodo', - repo: 'the-one-package', - }) - ) - .to.have.property('phpVersion') - .that.equals('^7.4 || 8') - }) - - it('should return PHP version for the specified release', async function () { - expect( - await PackagistPhpVersion.prototype.getPhpVersion({ - json, - user: 'frodo', - repo: 'the-one-package', - version: '2.0.0', - }) - ) - .to.have.property('phpVersion') - .that.equals('^7.2') - }) -}) diff --git a/services/packagist/packagist-php-version.tester.js b/services/packagist/packagist-php-version.tester.js index d552985228ad9..6c5b4a8356af6 100644 --- a/services/packagist/packagist-php-version.tester.js +++ b/services/packagist/packagist-php-version.tester.js @@ -2,6 +2,28 @@ import { isComposerVersion } from '../test-validators.js' import { createServiceTester } from '../tester.js' export const t = await createServiceTester() +t.create( + 'redirect getting required php version for the dependency from packagist (valid, package version not specified in request)' +) + .get('/symfony/symfony.json') + .expectRedirect( + '/pypi/frameworkversions/django/djangorestframework/3.7.3.json' + ) + +t.create( + 'redirect supported django versions (valid, no package version specified)' +) + .get('/djangorestframework.json') + .expectRedirect('/pypi/frameworkversions/django/djangorestframework.json') + +t.create('redirect supported django versions (no versions specified)') + .get('/django/1.11.json') + .expectRedirect('/pypi/frameworkversions/django/django/1.11.json') + +t.create('redirect supported django versions (invalid)') + .get('/not-a-package.json') + .expectRedirect('/pypi/frameworkversions/django/not-a-package.json') + t.create('gets the package version of symfony') .get('/symfony/symfony.json') .expectBadge({ label: 'php', message: isComposerVersion }) From b3c8014a2c95080b45e108f94f51d0048e16ab43 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Wed, 7 Sep 2022 23:40:53 +0200 Subject: [PATCH 14/23] basic examples of packagist/dependency-v work with new url; packagist/php-v redirects to the new url --- .../packagist-dependency-version.service.js | 67 ++++++------------- .../packagist-dependency-version.spec.js | 8 +-- .../packagist-php-version.service.js | 5 +- 3 files changed, 28 insertions(+), 52 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index fe32b609a108c..19163cd4fb0ad 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -24,19 +24,18 @@ export default class PackagistDependencyVersion extends BasePackagistService { static examples = [ { title: 'Packagist Dependency Version Support', - pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', dependency: 'twig/twig', }, staticPreview: this.render({ + dependency: 'twig/twig', dependencyVersion: '2.13|^3.0.4', }), }, { title: 'Packagist Dependency Version Support (specify version)', - pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', @@ -46,12 +45,12 @@ export default class PackagistDependencyVersion extends BasePackagistService { version: 'v2.8.0', }, staticPreview: this.render({ + dependency: 'twig/twig', dependencyVersion: '1.12', }), }, { title: 'Packagist Dependency Version Support (custom server)', - pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', @@ -61,13 +60,13 @@ export default class PackagistDependencyVersion extends BasePackagistService { server: 'https://packagist.org', }, staticPreview: this.render({ + dependency: 'twig/twig', dependencyVersion: '2.13|^3.0.4', }), documentation: customServerDocumentationFragment, }, { title: 'Packagist PHP Version Support (custom server)', - pattern: ':user/:repo/:dependency+', namedParams: { user: 'symfony', repo: 'symfony', @@ -77,7 +76,10 @@ export default class PackagistDependencyVersion extends BasePackagistService { server: 'https://packagist.org', version: 'v2.8.0', }, - staticPreview: this.render({ dependencyVersion: '^7.1.3' }), + staticPreview: this.render({ + dependency: 'php', + dependencyVersion: '^7.1.3', + }), documentation: customServerDocumentationFragment, }, ] @@ -87,31 +89,20 @@ export default class PackagistDependencyVersion extends BasePackagistService { color: 'blue', } - static render({ dependencyNameForLabel, dependencyVersion }) { + static render({ dependency, dependencyVersion }) { return { - label: dependencyNameForLabel, + label: dependency, message: dependencyVersion, } } - determineDependencyNameForLabel({ dependencyVendor, dependencyRepo }) { - if (dependencyVendor && dependencyRepo) { - return `${dependencyVendor}/${dependencyRepo}` - } else if (dependencyVendor && !dependencyRepo) { - return dependencyVendor - } else if (!dependencyVendor && dependencyRepo) { - return dependencyRepo - } - } - async getDependencyVersion({ json, user, repo, + dependency, version = '', server, - dependencyVendor, - dependencyRepo, }) { let packageVersion const versions = BasePackagistService.expandPackageVersions( @@ -135,6 +126,12 @@ export default class PackagistDependencyVersion extends BasePackagistService { } } + if (!dependency) { + throw new NotFound({ + prettyMessage: 'dependency vendor or repo not specified', + }) + } + if (!packageVersion) { throw new NotFound({ prettyMessage: 'invalid version' }) } @@ -143,30 +140,14 @@ export default class PackagistDependencyVersion extends BasePackagistService { throw new NotFound({ prettyMessage: 'version requirement not found' }) } - let dependencyIdentifier - - if (dependencyRepo || dependencyVendor) { - dependencyIdentifier = this.determineDependencyNameForLabel({ - dependencyVendor, - dependencyRepo, - }) - } else { - throw new NotFound({ - prettyMessage: 'dependency vendor or repo not specified', - }) - } - - if (!packageVersion.require[dependencyIdentifier]) { + if (!packageVersion.require[dependency]) { throw new NotFound({ prettyMessage: 'version requirement not found' }) } - return { dependencyVersion: packageVersion.require[dependencyIdentifier] } + return { dependencyVersion: packageVersion.require[dependency] } } - async handle( - { user, repo, version = '' }, - { dependencyVendor, dependencyRepo, server } - ) { + async handle({ user, repo, dependency }, { server, version = '' }) { const allData = await this.fetch({ user, repo, @@ -178,19 +159,13 @@ export default class PackagistDependencyVersion extends BasePackagistService { json: allData, user, repo, + dependency, version, server, - dependencyVendor, - dependencyRepo, - }) - - const dependencyNameForLabel = this.determineDependencyNameForLabel({ - dependencyVendor, - dependencyRepo, }) return this.constructor.render({ - dependencyNameForLabel, + dependency, dependencyVersion, }) } diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index bf1c9237141e5..01046d5bc312a 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -74,7 +74,7 @@ describe('PackagistDependencyVersion', function () { ).to.be.rejectedWith('version requirement not found') }) - it('should throw NotFound if neither dependencyVendor nor dependencyRepo was specified', async function () { + it('should throw NotFound if dependency was not specified', async function () { await expect( PackagistDependencyVersion.prototype.getDependencyVersion({ json: fullPackagistJson, @@ -90,8 +90,7 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - dependencyVendor: 'twig', - dependencyRepo: 'twig', + dependency: 'twig/twig', }) ) .to.have.property('dependencyVersion') @@ -105,8 +104,7 @@ describe('PackagistDependencyVersion', function () { user: 'frodo', repo: 'the-one-package', version: '2.0.0', - dependencyVendor: 'twig', - dependencyRepo: 'twig', + dependency: 'twig/twig', }) ) .to.have.property('dependencyVersion') diff --git a/services/packagist/packagist-php-version.service.js b/services/packagist/packagist-php-version.service.js index 862ce0e0d86f4..c743a59fc0c3b 100644 --- a/services/packagist/packagist-php-version.service.js +++ b/services/packagist/packagist-php-version.service.js @@ -14,6 +14,9 @@ export default redirector({ queryParamSchema, }, transformPath: ({ user, repo, version }) => - `/packagist/dependency-v/${user}/${repo}${version ? `/${version}` : ''}`, + `/packagist/dependency-v/${user}/${repo}/php${ + version ? `/${version}` : '' + }`, + transformQueryParams: ({ version, server }) => ({ version, server }), dateAdded: new Date('2022-09-07'), }) From 46bc9b089dd9bbfe81150f1c64ab4e263b0ba7b8 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Thu, 8 Sep 2022 22:23:44 +0200 Subject: [PATCH 15/23] service tests should be green --- .../packagist-dependency-version.tester.js | 88 ++++++++----------- .../packagist-php-version.service.js | 7 +- .../packagist/packagist-php-version.tester.js | 57 +++--------- 3 files changed, 50 insertions(+), 102 deletions(-) diff --git a/services/packagist/packagist-dependency-version.tester.js b/services/packagist/packagist-dependency-version.tester.js index 0923e2dd16195..e861551576042 100644 --- a/services/packagist/packagist-dependency-version.tester.js +++ b/services/packagist/packagist-dependency-version.tester.js @@ -6,101 +6,83 @@ t.create('gets the package version of symfony 5.2.3 - without query params') .get('/symfony/symfony/v5.2.3.json') .expectBadge({ label: 'dependency version', - message: 'dependency vendor or repo not specified', + message: 'version requirement not found', }) +t.create('gets the package version of symfony - with correct dependency') + .get('/symfony/symfony/twig/twig.json') + .expectBadge({ label: 'twig/twig', message: isComposerVersion }) + t.create( - 'gets the package version of symfony - with correct dependencyVendor and dependencyRepo' + 'gets the package version of symfony - with correct dependency and specified version' ) - .get('/symfony/symfony.json?dependencyVendor=twig&dependencyRepo=twig') + .get('/symfony/symfony/twig/twig.json?version=v3.2.8') .expectBadge({ label: 'twig/twig', message: isComposerVersion }) t.create( - 'gets the package version of symfony 5.2.3 - with correct dependencyVendor and dependencyRepo' + 'gets the package version of symfony - with correct dependency, correct version and correct custom server' ) - .get('/symfony/symfony/v5.2.3.json?dependencyVendor=twig&dependencyRepo=twig') + .get( + '/symfony/symfony/twig/twig.json?version=v3.2.8&server=https://packagist.org' + ) .expectBadge({ label: 'twig/twig', message: isComposerVersion }) t.create( - 'gets the package version of symfony 5.2.3 - with incorrect dependencyVendor' + 'gets the package version of symfony - with correct dependency and specified version and incorrect custom server' ) .get( - '/symfony/symfony/v5.2.3.json?dependencyVendor=twiiiiiiiiiig&dependencyRepo=twig' + '/symfony/symfony/twig/twig.json?version=v3.2.8&server=https://packagisttttttt.org' ) + .expectBadge({ + label: 'dependency version', + message: 'inaccessible', + }) + +t.create('gets the package version of symfony - with incorrect dependency name') + .get('/symfony/symfony/twig/twiiiiiiig.json?version=v3.2.8') .expectBadge({ label: 'dependency version', message: 'version requirement not found', }) -t.create( - 'gets the package version of symfony 5.2.3 - name of the dependencyVendor contains hyphen' -) - .get('/symfony/symfony/v5.2.3.json?dependencyVendor=ext-xml') - .expectBadge({ label: 'ext-xml', message: isComposerVersion }) +t.create('gets the package version of symfony - with incorrect version') + .get('/symfony/symfony/twig/twig.json?version=v3.2.80000') + .expectBadge({ + label: 'dependency version', + message: 'invalid version', + }) t.create( - 'gets the package version of symfony 5.2.3 - incorrectly with missing dependencyVendor (twig/twig needs both dependencyVendor and dependencyRepo)' + `gets the package version of symfony 5.2.3 - incorrectly with missing part of dependency's name` ) - .get('/symfony/symfony/v5.2.3.json?dependencyRepo=twig') + .get('/symfony/symfony/twig.json') .expectBadge({ label: 'dependency version', message: 'version requirement not found', }) t.create( - 'gets the package version of symfony 5.2.3 - correctly with missing dependencyVendor (php needs only dependencyVendor or dependencyRepo)' + 'gets the package version of symfony 5.2.3 - name of the dependency contains hyphen' ) - .get('/symfony/symfony/v5.2.3.json?dependencyRepo=php') - .expectBadge({ label: 'php', message: isComposerVersion }) + .get('/symfony/symfony/ext-xml.json?version=v5.2.3') + .expectBadge({ label: 'ext-xml', message: isComposerVersion }) t.create( - 'gets the package version of symfony 5.2.3 - correctly when the dependencyVendor is the same as the name of the package' + 'gets the package version of symfony 5.2.3 - correctly when the dependency is the same as the name of the package' ) - .get( - '/symfony/symfony/v5.2.3.json?dependencyVendor=symfony&dependencyRepo=contracts' - ) + .get('/symfony/symfony/symfony/contracts.json') .expectBadge({ label: 'symfony/contracts', message: isComposerVersion }) -t.create( - 'gets the package version of symfony 5.2.3 - correctly with missing dependencyRepo (php needs only dependencyVendor or dependencyRepo)' -) - .get('/symfony/symfony/v5.2.3.json?dependencyVendor=php') - .expectBadge({ label: 'php', message: isComposerVersion }) - t.create('package with no requirements') - .get('/bpampuch/pdfmake.json?dependencyVendor=twig&dependencyRepo=twig') + .get('/bpampuch/pdfmake/twig/twig.json') .expectBadge({ label: 'dependency version', message: 'version requirement not found', }) t.create('package with no twig/twig version requirement') - .get( - '/raulfraile/ladybug-theme-modern.json?dependencyVendor=twig&dependencyRepo=twig' - ) + .get('/raulfraile/ladybug-theme-modern/twig/twig.json') .expectBadge({ label: 'dependency version', message: 'version requirement not found', }) - -t.create('invalid package name') - .get('/frodo/is-not-a-package.json?dependencyVendor=twig&dependencyRepo=twig') - .expectBadge({ label: 'dependency version', message: 'not found' }) - -t.create('invalid version') - .get( - '/symfony/symfony/invalid.json?dependencyVendor=twig&dependencyRepo=twig' - ) - .expectBadge({ label: 'dependency version', message: 'invalid version' }) - -t.create('custom server') - .get( - '/symfony/symfony.json?server=https%3A%2F%2Fpackagist.org&dependencyVendor=twig&dependencyRepo=twig' - ) - .expectBadge({ label: 'twig/twig', message: isComposerVersion }) - -t.create('invalid custom server') - .get( - '/symfony/symfony.json?server=https%3A%2F%2Fpackagist.com&dependencyVendor=twig&dependencyRepo=twig' - ) - .expectBadge({ label: 'dependency version', message: 'not found' }) diff --git a/services/packagist/packagist-php-version.service.js b/services/packagist/packagist-php-version.service.js index c743a59fc0c3b..177d94bc94f17 100644 --- a/services/packagist/packagist-php-version.service.js +++ b/services/packagist/packagist-php-version.service.js @@ -13,10 +13,9 @@ export default redirector({ pattern: ':user/:repo/:version?', queryParamSchema, }, - transformPath: ({ user, repo, version }) => - `/packagist/dependency-v/${user}/${repo}/php${ - version ? `/${version}` : '' - }`, + transformPath: ({ user, repo }) => + `/packagist/dependency-v/${user}/${repo}/php`, transformQueryParams: ({ version, server }) => ({ version, server }), + overrideTransformedQueryParams: true, dateAdded: new Date('2022-09-07'), }) diff --git a/services/packagist/packagist-php-version.tester.js b/services/packagist/packagist-php-version.tester.js index 6c5b4a8356af6..24d4c73e9f671 100644 --- a/services/packagist/packagist-php-version.tester.js +++ b/services/packagist/packagist-php-version.tester.js @@ -1,4 +1,3 @@ -import { isComposerVersion } from '../test-validators.js' import { createServiceTester } from '../tester.js' export const t = await createServiceTester() @@ -6,52 +5,20 @@ t.create( 'redirect getting required php version for the dependency from packagist (valid, package version not specified in request)' ) .get('/symfony/symfony.json') + .expectRedirect('/packagist/dependency-v/symfony/symfony/php.json?') + +t.create( + 'redirect getting required php version for the dependency from packagist (valid, package version specified in request)' +) + .get('/symfony/symfony/v3.2.8.json') .expectRedirect( - '/pypi/frameworkversions/django/djangorestframework/3.7.3.json' + '/packagist/dependency-v/symfony/symfony/php.json?version=v3.2.8' ) t.create( - 'redirect supported django versions (valid, no package version specified)' + 'redirect getting required php version for the dependency from packagist (valid, package version and server specified in request)' ) - .get('/djangorestframework.json') - .expectRedirect('/pypi/frameworkversions/django/djangorestframework.json') - -t.create('redirect supported django versions (no versions specified)') - .get('/django/1.11.json') - .expectRedirect('/pypi/frameworkversions/django/django/1.11.json') - -t.create('redirect supported django versions (invalid)') - .get('/not-a-package.json') - .expectRedirect('/pypi/frameworkversions/django/not-a-package.json') - -t.create('gets the package version of symfony') - .get('/symfony/symfony.json') - .expectBadge({ label: 'php', message: isComposerVersion }) - -t.create('gets the package version of symfony 5.2.3') - .get('/symfony/symfony/v5.2.3.json') - .expectBadge({ label: 'php', message: isComposerVersion }) - -t.create('package with no requirements') - .get('/bpampuch/pdfmake.json') - .expectBadge({ label: 'php', message: 'version requirement not found' }) - -t.create('package with no php version requirement') - .get('/raulfraile/ladybug-theme-modern.json') - .expectBadge({ label: 'php', message: 'version requirement not found' }) - -t.create('invalid package name') - .get('/frodo/is-not-a-package.json') - .expectBadge({ label: 'php', message: 'not found' }) - -t.create('invalid version') - .get('/symfony/symfony/invalid.json') - .expectBadge({ label: 'php', message: 'invalid version' }) - -t.create('custom server') - .get('/symfony/symfony.json?server=https%3A%2F%2Fpackagist.org') - .expectBadge({ label: 'php', message: isComposerVersion }) - -t.create('invalid custom server') - .get('/symfony/symfony.json?server=https%3A%2F%2Fpackagist.com') - .expectBadge({ label: 'php', message: 'not found' }) + .get('/symfony/symfony/v3.2.8.json?server=https://packagist.org') + .expectRedirect( + '/packagist/dependency-v/symfony/symfony/php.json?server=https%3A%2F%2Fpackagist.org&version=v3.2.8' + ) From ed15ffb749b8b5dee933f65c1506aa3ec5a777ae Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Thu, 8 Sep 2022 22:40:23 +0200 Subject: [PATCH 16/23] unit tests for packagist should be fixed --- .../packagist-dependency-version.spec.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 01046d5bc312a..1c5b3a54ca0c9 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -9,15 +9,15 @@ describe('PackagistDependencyVersion', function () { packages: { 'frodo/the-one-package': [ { - version: '3.0.0', + version: 'v3.0.0', require: { php: '^7.4 || 8', 'twig/twig': '~1.28|~2.0' }, }, { - version: '2.0.0', + version: 'v2.0.0', require: { php: '^7.2', 'twig/twig': '~1.20|~1.30' }, }, { - version: '1.0.0', + version: 'v1.0.0', require: { php: '^5.6 || ^7', 'twig/twig': '~1.10|~1.0' }, }, ], @@ -30,12 +30,12 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - version: '4.0.0', + version: 'v4.0.0', }) - ).to.be.rejectedWith('invalid version') + ).to.be.rejectedWith('dependency vendor or repo not specified') }) - it('should throw NotFound when dependency version not found on package when using default release', async function () { + it('should throw NotFound when dependency not specified (when using default release)', async function () { await expect( PackagistDependencyVersion.prototype.getDependencyVersion({ json: fullPackagistJson, @@ -45,20 +45,20 @@ describe('PackagistDependencyVersion', function () { ).to.be.rejectedWith('dependency vendor or repo not specified') }) - it('should throw NotFound when dependency version not found on package when using specified release', async function () { + it('should throw NotFound when dependency not specified (when using specified release)', async function () { const fullPackagistJson = { packages: { 'frodo/the-one-package': [ { - version: '3.0.0', + version: 'v3.0.0', require: { php: '^7.4 || 8' }, }, { - version: '2.0.0', + version: 'v2.0.0', require: { php: '^7.2' }, }, { - version: '1.0.0', + version: 'v1.0.0', require: '__unset', }, ], @@ -69,9 +69,9 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - version: '1.0.0', + version: 'v1.0.0', }) - ).to.be.rejectedWith('version requirement not found') + ).to.be.rejectedWith('dependency vendor or repo not specified') }) it('should throw NotFound if dependency was not specified', async function () { @@ -103,7 +103,7 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - version: '2.0.0', + version: 'v2.0.0', dependency: 'twig/twig', }) ) From a0a99ad8265387847130f7d9f4a7049adfb291df Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Thu, 8 Sep 2022 23:21:20 +0200 Subject: [PATCH 17/23] add toLowerCase() --- services/packagist/packagist-dependency-version.service.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 19163cd4fb0ad..4dc738ace697c 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -140,11 +140,13 @@ export default class PackagistDependencyVersion extends BasePackagistService { throw new NotFound({ prettyMessage: 'version requirement not found' }) } - if (!packageVersion.require[dependency]) { + const depLowerCase = dependency.toLowerCase() + + if (!packageVersion.require[depLowerCase]) { throw new NotFound({ prettyMessage: 'version requirement not found' }) } - return { dependencyVersion: packageVersion.require[dependency] } + return { dependencyVersion: packageVersion.require[depLowerCase] } } async handle({ user, repo, dependency }, { server, version = '' }) { From af35f8480359b67d04f6c27a0f4c5ccc6efd6a40 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Mon, 12 Sep 2022 22:44:53 +0200 Subject: [PATCH 18/23] part of suggestions from the PR is implemented --- .../packagist-dependency-version.service.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/services/packagist/packagist-dependency-version.service.js b/services/packagist/packagist-dependency-version.service.js index 4dc738ace697c..832f9c46a985b 100644 --- a/services/packagist/packagist-dependency-version.service.js +++ b/services/packagist/packagist-dependency-version.service.js @@ -23,7 +23,7 @@ export default class PackagistDependencyVersion extends BasePackagistService { static examples = [ { - title: 'Packagist Dependency Version Support', + title: 'Packagist Dependency Version', namedParams: { user: 'symfony', repo: 'symfony', @@ -35,7 +35,7 @@ export default class PackagistDependencyVersion extends BasePackagistService { }), }, { - title: 'Packagist Dependency Version Support (specify version)', + title: 'Packagist Dependency Version (specify version)', namedParams: { user: 'symfony', repo: 'symfony', @@ -50,7 +50,7 @@ export default class PackagistDependencyVersion extends BasePackagistService { }), }, { - title: 'Packagist Dependency Version Support (custom server)', + title: 'Packagist Dependency Version (custom server)', namedParams: { user: 'symfony', repo: 'symfony', @@ -66,21 +66,16 @@ export default class PackagistDependencyVersion extends BasePackagistService { documentation: customServerDocumentationFragment, }, { - title: 'Packagist PHP Version Support (custom server)', + title: 'Packagist PHP Version', namedParams: { user: 'symfony', repo: 'symfony', dependency: 'php', }, - queryParams: { - server: 'https://packagist.org', - version: 'v2.8.0', - }, staticPreview: this.render({ dependency: 'php', dependencyVersion: '^7.1.3', }), - documentation: customServerDocumentationFragment, }, ] @@ -126,12 +121,6 @@ export default class PackagistDependencyVersion extends BasePackagistService { } } - if (!dependency) { - throw new NotFound({ - prettyMessage: 'dependency vendor or repo not specified', - }) - } - if (!packageVersion) { throw new NotFound({ prettyMessage: 'invalid version' }) } @@ -140,6 +129,13 @@ export default class PackagistDependencyVersion extends BasePackagistService { throw new NotFound({ prettyMessage: 'version requirement not found' }) } + // All dependencies' names in the 'require' section from the response should be lowercase, + // so that we can compare lowercase name of the dependency given via url by the user. + Object.keys(packageVersion.require).forEach(dependency => { + packageVersion.require[dependency.toLowerCase()] = + packageVersion.require[dependency] + }) + const depLowerCase = dependency.toLowerCase() if (!packageVersion.require[depLowerCase]) { From e356b1b03dffdfc1f2514f62af7ded6ec10b7269 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Mon, 12 Sep 2022 23:02:23 +0200 Subject: [PATCH 19/23] updated tests for packagist dependency version --- .../packagist-dependency-version.tester.js | 67 ++++++------------- 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/services/packagist/packagist-dependency-version.tester.js b/services/packagist/packagist-dependency-version.tester.js index e861551576042..3509ae484b5fa 100644 --- a/services/packagist/packagist-dependency-version.tester.js +++ b/services/packagist/packagist-dependency-version.tester.js @@ -2,77 +2,50 @@ import { isComposerVersion } from '../test-validators.js' import { createServiceTester } from '../tester.js' export const t = await createServiceTester() -t.create('gets the package version of symfony 5.2.3 - without query params') - .get('/symfony/symfony/v5.2.3.json') +t.create('gets the package version') + .get('/symfony/symfony/twig/twig.json') + .expectBadge({ label: 'twig/twig', message: isComposerVersion }) + +t.create('incorrect dependency name') + .get('/symfony/symfony/twig/twiiiiiiig.json') .expectBadge({ label: 'dependency version', message: 'version requirement not found', }) -t.create('gets the package version of symfony - with correct dependency') - .get('/symfony/symfony/twig/twig.json') - .expectBadge({ label: 'twig/twig', message: isComposerVersion }) +t.create('missing vendor of dependency') + .get('/symfony/symfony/twig.json') + .expectBadge({ + label: 'dependency version', + message: 'version requirement not found', + }) -t.create( - 'gets the package version of symfony - with correct dependency and specified version' -) +t.create('gets the package version + specified symfony version') .get('/symfony/symfony/twig/twig.json?version=v3.2.8') .expectBadge({ label: 'twig/twig', message: isComposerVersion }) -t.create( - 'gets the package version of symfony - with correct dependency, correct version and correct custom server' -) - .get( - '/symfony/symfony/twig/twig.json?version=v3.2.8&server=https://packagist.org' - ) +t.create('gets the package version + valid custom server') + .get('/symfony/symfony/twig/twig.json?server=https://packagist.org') .expectBadge({ label: 'twig/twig', message: isComposerVersion }) -t.create( - 'gets the package version of symfony - with correct dependency and specified version and incorrect custom server' -) - .get( - '/symfony/symfony/twig/twig.json?version=v3.2.8&server=https://packagisttttttt.org' - ) +t.create('invalid custom server') + .get('/symfony/symfony/twig/twig.json?server=https://packagisttttttt.org') .expectBadge({ label: 'dependency version', message: 'inaccessible', }) -t.create('gets the package version of symfony - with incorrect dependency name') - .get('/symfony/symfony/twig/twiiiiiiig.json?version=v3.2.8') - .expectBadge({ - label: 'dependency version', - message: 'version requirement not found', - }) - -t.create('gets the package version of symfony - with incorrect version') +t.create('incorrect symfony version') .get('/symfony/symfony/twig/twig.json?version=v3.2.80000') .expectBadge({ label: 'dependency version', message: 'invalid version', }) -t.create( - `gets the package version of symfony 5.2.3 - incorrectly with missing part of dependency's name` -) - .get('/symfony/symfony/twig.json') - .expectBadge({ - label: 'dependency version', - message: 'version requirement not found', - }) - -t.create( - 'gets the package version of symfony 5.2.3 - name of the dependency contains hyphen' -) - .get('/symfony/symfony/ext-xml.json?version=v5.2.3') +t.create('gets the package version - dependency does not need the vendor') + .get('/symfony/symfony/ext-xml.json') .expectBadge({ label: 'ext-xml', message: isComposerVersion }) -t.create( - 'gets the package version of symfony 5.2.3 - correctly when the dependency is the same as the name of the package' -) - .get('/symfony/symfony/symfony/contracts.json') - .expectBadge({ label: 'symfony/contracts', message: isComposerVersion }) - t.create('package with no requirements') .get('/bpampuch/pdfmake/twig/twig.json') .expectBadge({ From 407135924666d549c95afc8676f1c599287e5330 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Mon, 12 Sep 2022 23:26:24 +0200 Subject: [PATCH 20/23] fix packagist dependency version spec --- .../packagist-dependency-version.spec.js | 51 +------------------ 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 1c5b3a54ca0c9..90925d82ded7d 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -32,56 +32,7 @@ describe('PackagistDependencyVersion', function () { repo: 'the-one-package', version: 'v4.0.0', }) - ).to.be.rejectedWith('dependency vendor or repo not specified') - }) - - it('should throw NotFound when dependency not specified (when using default release)', async function () { - await expect( - PackagistDependencyVersion.prototype.getDependencyVersion({ - json: fullPackagistJson, - user: 'frodo', - repo: 'the-one-package', - }) - ).to.be.rejectedWith('dependency vendor or repo not specified') - }) - - it('should throw NotFound when dependency not specified (when using specified release)', async function () { - const fullPackagistJson = { - packages: { - 'frodo/the-one-package': [ - { - version: 'v3.0.0', - require: { php: '^7.4 || 8' }, - }, - { - version: 'v2.0.0', - require: { php: '^7.2' }, - }, - { - version: 'v1.0.0', - require: '__unset', - }, - ], - }, - } - await expect( - PackagistDependencyVersion.prototype.getDependencyVersion({ - json: fullPackagistJson, - user: 'frodo', - repo: 'the-one-package', - version: 'v1.0.0', - }) - ).to.be.rejectedWith('dependency vendor or repo not specified') - }) - - it('should throw NotFound if dependency was not specified', async function () { - await expect( - PackagistDependencyVersion.prototype.getDependencyVersion({ - json: fullPackagistJson, - user: 'frodo', - repo: 'the-one-package', - }) - ).to.be.rejectedWith('dependency vendor or repo not specified') + ).to.be.rejectedWith('invalid version') }) it('should return dependency version for the default release', async function () { From a6fd477f7c23a73f18523dbcfd65907302913c9b Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Wed, 14 Sep 2022 15:37:12 +0200 Subject: [PATCH 21/23] add missing unit tests --- .../packagist-dependency-version.spec.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 90925d82ded7d..665a22f927000 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -12,6 +12,13 @@ describe('PackagistDependencyVersion', function () { version: 'v3.0.0', require: { php: '^7.4 || 8', 'twig/twig': '~1.28|~2.0' }, }, + { + version: 'v2.5.0', + require: '__unset', + }, + { + version: 'v2.4.0', + }, { version: 'v2.0.0', require: { php: '^7.2', 'twig/twig': '~1.20|~1.30' }, @@ -24,7 +31,7 @@ describe('PackagistDependencyVersion', function () { }, } - it('should throw NotFound when package version is missing', async function () { + it('should throw NotFound when package version is missing in the response', async function () { await expect( PackagistDependencyVersion.prototype.getDependencyVersion({ json: fullPackagistJson, @@ -35,6 +42,28 @@ describe('PackagistDependencyVersion', function () { ).to.be.rejectedWith('invalid version') }) + it('should throw NotFound when `require` section is missing in the response', async function () { + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + version: 'v2.5.0', + }) + ).to.be.rejectedWith('version requirement not found') + }) + + it('should throw NotFound when `require` section in the response has the value of __unset (thank you, Packagist API :p)', async function () { + await expect( + PackagistDependencyVersion.prototype.getDependencyVersion({ + json: fullPackagistJson, + user: 'frodo', + repo: 'the-one-package', + version: 'v2.4.0', + }) + ).to.be.rejectedWith('version requirement not found') + }) + it('should return dependency version for the default release', async function () { expect( await PackagistDependencyVersion.prototype.getDependencyVersion({ From 126eb4294e4c3aa86bd785188eafb54a3e99c168 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Wed, 14 Sep 2022 21:57:03 +0200 Subject: [PATCH 22/23] Update services/packagist/packagist-dependency-version.spec.js Co-authored-by: chris48s --- services/packagist/packagist-dependency-version.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 665a22f927000..4d615bc8b24ce 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -48,7 +48,7 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - version: 'v2.5.0', + version: 'v2.4.0', }) ).to.be.rejectedWith('version requirement not found') }) From becfc0ec49cafe95427d384173d3b267cb3b6762 Mon Sep 17 00:00:00 2001 From: Paula Barszcz Date: Wed, 14 Sep 2022 21:57:19 +0200 Subject: [PATCH 23/23] Update services/packagist/packagist-dependency-version.spec.js Co-authored-by: chris48s --- services/packagist/packagist-dependency-version.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/packagist/packagist-dependency-version.spec.js b/services/packagist/packagist-dependency-version.spec.js index 4d615bc8b24ce..b03b2e39e6ee5 100644 --- a/services/packagist/packagist-dependency-version.spec.js +++ b/services/packagist/packagist-dependency-version.spec.js @@ -59,7 +59,7 @@ describe('PackagistDependencyVersion', function () { json: fullPackagistJson, user: 'frodo', repo: 'the-one-package', - version: 'v2.4.0', + version: 'v2.5.0', }) ).to.be.rejectedWith('version requirement not found') })