From bc96f0e25fc6bb1d09ab564040a6938f1fe0422a Mon Sep 17 00:00:00 2001 From: Pierre-Yves B Date: Wed, 13 Feb 2019 17:14:12 +0000 Subject: [PATCH] Example keywords validation (#2956) This pull request closes #2551: making sure that the keywords don't already appear in the example's title. I also added validation that checks that they are at least two characters long, as this is enforced by the homepage when type your search. --- core/base-service/transform-example.js | 28 +++++++++++++++++++ core/base-service/transform-example.spec.js | 21 ++++++++++++++ .../cii-best-practices.service.js | 2 +- services/cran/cran.service.js | 2 -- services/date/date.service.js | 2 +- .../github/github-commit-activity.service.js | 6 ++-- .../github/github-commit-status.service.js | 2 +- .../github/github-commits-since.service.js | 4 --- .../github/github-issue-detail.service.js | 2 +- services/github/github-issues.service.js | 10 ++----- services/github/github-license.service.js | 2 +- services/jira/jira-issue.service.js | 1 - services/jira/jira-sprint.service.js | 2 +- services/jsdelivr/jsdelivr-base.js | 4 +-- .../jsdelivr/jsdelivr-hits-github.service.js | 11 +------- .../jsdelivr/jsdelivr-hits-npm.service.js | 11 +------- .../leanpub/leanpub-book-summary.service.js | 4 --- services/luarocks/luarocks.service.js | 1 - services/pypi/pypi-djversions.service.js | 2 +- services/pypi/pypi-pyversions.service.js | 1 - services/redmine/redmine.service.js | 2 -- services/requires/requires.service.js | 2 -- .../vaadin-directory.service.js | 27 ++++-------------- .../visual-studio-marketplace-base.js | 2 -- .../wordpress/wordpress-version.service.js | 1 - 25 files changed, 70 insertions(+), 82 deletions(-) diff --git a/core/base-service/transform-example.js b/core/base-service/transform-example.js index 12ca1175e4..602ad533bf 100644 --- a/core/base-service/transform-example.js +++ b/core/base-service/transform-example.js @@ -85,6 +85,34 @@ function validateExample(example, index, ServiceClass) { ) } + if (example.keywords) { + // Make sure the keywords are at least two characters long. + const tinyKeywords = example.keywords.filter(k => k.length < 2) + if (tinyKeywords.length) { + throw Error( + `In example for ${ + ServiceClass.name + } at index ${index}, keywords contains words that are less than two characters long: ${tinyKeywords.join( + ', ' + )}` + ) + } + // Make sure none of the keywords are already included in the title. + const title = (example.title || ServiceClass.name).toLowerCase() + const redundantKeywords = example.keywords.filter(k => + title.includes(k.toLowerCase()) + ) + if (redundantKeywords.length) { + throw Error( + `In example for ${ + ServiceClass.name + } at index ${index}, keywords contains words that are already in the title: ${redundantKeywords.join( + ', ' + )}` + ) + } + } + return result } diff --git a/core/base-service/transform-example.spec.js b/core/base-service/transform-example.spec.js index 5ccb3da4b6..558cd6e523 100644 --- a/core/base-service/transform-example.spec.js +++ b/core/base-service/transform-example.spec.js @@ -7,9 +7,11 @@ describe('validateExample function', function() { it('passes valid examples', function() { const validExamples = [ { + title: 'Package manager versioning badge', staticPreview: { message: '123' }, pattern: 'dt/:package', namedParams: { package: 'mypackage' }, + keywords: ['semver', 'management'], }, ] @@ -42,6 +44,25 @@ describe('validateExample function', function() { exampleUrl: 'dt/mypackage', }, { previewUrl: 'dt/mypackage' }, + { + staticPreview: { message: '123' }, + pattern: 'dt/:package', + namedParams: { package: 'mypackage' }, + keywords: ['a'], // Keyword too short. + }, + { + staticPreview: { message: '123' }, + pattern: 'dt/:package', + namedParams: { package: 'mypackage' }, + keywords: ['mockService'], // No title and keyword matching the class name. + }, + { + title: 'Package manager versioning badge', + staticPreview: { message: '123' }, + pattern: 'dt/:package', + namedParams: { package: 'mypackage' }, + keywords: ['version'], // Keyword included in title. + }, ] invalidExamples.forEach(example => { diff --git a/services/cii-best-practices/cii-best-practices.service.js b/services/cii-best-practices/cii-best-practices.service.js index 3b99ef99dd..27a35e1273 100644 --- a/services/cii-best-practices/cii-best-practices.service.js +++ b/services/cii-best-practices/cii-best-practices.service.js @@ -12,7 +12,7 @@ const ciiBestPracticesSchema = Joi.object({ tiered_percentage: Joi.number().required(), }).required() -const keywords = ['cii', 'cii best practices', 'core infrastructure initiative'] +const keywords = ['core infrastructure initiative'] module.exports = class CIIBestPracticesService extends BaseJsonService { static render({ message, color }) { diff --git a/services/cran/cran.service.js b/services/cran/cran.service.js index 4d306fa5a3..3a9638b731 100644 --- a/services/cran/cran.service.js +++ b/services/cran/cran.service.js @@ -38,7 +38,6 @@ class CranLicense extends BaseCranService { title: 'CRAN/METACRAN', namedParams: { packageName: 'devtools' }, staticPreview: this.render({ license: 'GPL (>= 2)' }), - keywords: ['R'], }, ] } @@ -75,7 +74,6 @@ class CranVersion extends BaseCranService { title: 'CRAN/METACRAN', namedParams: { packageName: 'devtools' }, staticPreview: this.render({ version: '2.0.1' }), - keywords: ['R'], }, ] } diff --git a/services/date/date.service.js b/services/date/date.service.js index 263c355430..f3727a8e6a 100644 --- a/services/date/date.service.js +++ b/services/date/date.service.js @@ -46,7 +46,7 @@ module.exports = class Date extends BaseService { pattern: ':timestamp', namedParams: { timestamp: '1540814400' }, staticPreview: this.render({ relativeDateString: '2 days ago' }), - keywords: ['date', 'time', 'countdown', 'countup', 'moment'], + keywords: ['time', 'countdown', 'countup', 'moment'], documentation, }, ] diff --git a/services/github/github-commit-activity.service.js b/services/github/github-commit-activity.service.js index 36a2c150a5..e1a8522cd3 100644 --- a/services/github/github-commit-activity.service.js +++ b/services/github/github-commit-activity.service.js @@ -38,7 +38,7 @@ module.exports = class GithubCommitActivity extends LegacyService { message: '457/year', color: 'blue', }, - keywords: ['GitHub', 'commit', 'commits', 'activity'], + keywords: ['commits'], documentation, }, { @@ -50,7 +50,7 @@ module.exports = class GithubCommitActivity extends LegacyService { message: '38/month', color: 'blue', }, - keywords: ['GitHub', 'commit', 'commits', 'activity'], + keywords: ['commits'], documentation, }, { @@ -62,7 +62,7 @@ module.exports = class GithubCommitActivity extends LegacyService { message: '9/week', color: 'blue', }, - keywords: ['GitHub', 'commit', 'commits', 'activity'], + keywords: ['commits'], documentation, }, ] diff --git a/services/github/github-commit-status.service.js b/services/github/github-commit-status.service.js index 7a5cbdabf5..fb25948359 100644 --- a/services/github/github-commit-status.service.js +++ b/services/github/github-commit-status.service.js @@ -40,7 +40,7 @@ module.exports = class GithubCommitStatus extends LegacyService { message: 'in master', color: 'brightgreen', }, - keywords: ['branch', 'merge'], + keywords: ['branch'], documentation, }, ] diff --git a/services/github/github-commits-since.service.js b/services/github/github-commits-since.service.js index 923bd8cdfa..0b7687a2be 100644 --- a/services/github/github-commits-since.service.js +++ b/services/github/github-commits-since.service.js @@ -8,8 +8,6 @@ const { const { makeLogo: getLogo } = require('../../lib/logos') const { documentation } = require('./github-helpers') -const keywords = ['GitHub', 'commit'] - // This legacy service should be rewritten to use e.g. BaseJsonService. // // Tips for rewriting: @@ -42,7 +40,6 @@ module.exports = class GithubCommitsSince extends LegacyService { message: '4225', color: 'blue', }, - keywords, documentation, }, { @@ -57,7 +54,6 @@ module.exports = class GithubCommitsSince extends LegacyService { message: '157', color: 'blue', }, - keywords, documentation, }, ] diff --git a/services/github/github-issue-detail.service.js b/services/github/github-issue-detail.service.js index 355defbea7..2f6e19b0a3 100644 --- a/services/github/github-issue-detail.service.js +++ b/services/github/github-issue-detail.service.js @@ -16,7 +16,7 @@ const { } = require('./github-helpers') const commonExampleAttrs = { - keywords: ['issue', 'pullrequest', 'detail'], + keywords: ['pullrequest', 'detail'], documentation, } diff --git a/services/github/github-issues.service.js b/services/github/github-issues.service.js index 0c4ca95e61..4b9ba49920 100644 --- a/services/github/github-issues.service.js +++ b/services/github/github-issues.service.js @@ -42,7 +42,6 @@ module.exports = class GithubIssues extends LegacyService { message: '167 open', color: 'yellow', }, - keywords: ['issue'], documentation, }, { @@ -57,7 +56,6 @@ module.exports = class GithubIssues extends LegacyService { message: '167', color: 'yellow', }, - keywords: ['issue'], documentation, }, { @@ -73,7 +71,6 @@ module.exports = class GithubIssues extends LegacyService { message: '110 open', color: 'yellow', }, - keywords: ['issue', 'label'], documentation, }, { @@ -89,7 +86,6 @@ module.exports = class GithubIssues extends LegacyService { message: '110', color: 'yellow', }, - keywords: ['issue', 'label'], documentation, }, { @@ -104,7 +100,6 @@ module.exports = class GithubIssues extends LegacyService { message: '899 closed', color: 'yellow', }, - keywords: ['issue'], documentation, }, { @@ -119,7 +114,6 @@ module.exports = class GithubIssues extends LegacyService { message: '899', color: 'yellow', }, - keywords: ['issue'], documentation, }, { @@ -195,7 +189,7 @@ module.exports = class GithubIssues extends LegacyService { message: '8 open', color: 'yellow', }, - keywords: ['pullrequests', 'pr', 'label'], + keywords: ['pullrequests', 'pr'], documentation, }, { @@ -211,7 +205,7 @@ module.exports = class GithubIssues extends LegacyService { message: '8', color: 'yellow', }, - keywords: ['pullrequests', 'pr', 'label'], + keywords: ['pullrequests', 'pr'], documentation, }, ] diff --git a/services/github/github-license.service.js b/services/github/github-license.service.js index f896f9dc67..e8f83e66de 100644 --- a/services/github/github-license.service.js +++ b/services/github/github-license.service.js @@ -37,7 +37,7 @@ module.exports = class GithubLicense extends LegacyService { message: 'MIT', color: 'green', }, - keywords: ['GitHub', 'license'], + keywords: ['license'], documentation, }, ] diff --git a/services/jira/jira-issue.service.js b/services/jira/jira-issue.service.js index 214a50c0da..59bcd2b335 100644 --- a/services/jira/jira-issue.service.js +++ b/services/jira/jira-issue.service.js @@ -62,7 +62,6 @@ module.exports = class JiraIssue extends JiraBase { statusName: 'Resolved', statusColor: 'green', }), - keywords: ['jira', 'issue'], }, ] } diff --git a/services/jira/jira-sprint.service.js b/services/jira/jira-sprint.service.js index 9e95017b3d..0bf1f31cdc 100644 --- a/services/jira/jira-sprint.service.js +++ b/services/jira/jira-sprint.service.js @@ -70,7 +70,7 @@ module.exports = class JiraSprint extends JiraBase { numTotalIssues: 28, }), documentation, - keywords: ['jira', 'sprint', 'issues'], + keywords: ['issues'], }, ] } diff --git a/services/jsdelivr/jsdelivr-base.js b/services/jsdelivr/jsdelivr-base.js index bb8d3bfd5c..9679b23365 100644 --- a/services/jsdelivr/jsdelivr-base.js +++ b/services/jsdelivr/jsdelivr-base.js @@ -8,8 +8,6 @@ const schema = Joi.object({ total: Joi.number().required(), }).required() -const keywords = ['jsDelivr', 'hits'] - const periodMap = { hd: 'day', hw: 'week', @@ -36,4 +34,4 @@ class BaseJsDelivrService extends BaseJsonService { } } -module.exports = { schema, keywords, periodMap, BaseJsDelivrService } +module.exports = { schema, periodMap, BaseJsDelivrService } diff --git a/services/jsdelivr/jsdelivr-hits-github.service.js b/services/jsdelivr/jsdelivr-hits-github.service.js index 27f7514fe7..f1f9930dc2 100644 --- a/services/jsdelivr/jsdelivr-hits-github.service.js +++ b/services/jsdelivr/jsdelivr-hits-github.service.js @@ -1,11 +1,6 @@ 'use strict' -const { - schema, - keywords, - periodMap, - BaseJsDelivrService, -} = require('./jsdelivr-base') +const { schema, periodMap, BaseJsDelivrService } = require('./jsdelivr-base') module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { static get route() { @@ -39,7 +34,6 @@ module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { repo: 'jquery', }, staticPreview: this.render({ period: 'hd', hits: 272042 }), - keywords, }, { title: 'jsDelivr Hits (GitHub)', @@ -49,7 +43,6 @@ module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { repo: 'jquery', }, staticPreview: this.render({ period: 'hw', hits: 2156336 }), - keywords, }, { title: 'jsDelivr Hits (GitHub)', @@ -59,7 +52,6 @@ module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { repo: 'jquery', }, staticPreview: this.render({ period: 'hm', hits: 9809876 }), - keywords, }, { title: 'jsDelivr Hits (GitHub)', @@ -69,7 +61,6 @@ module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { repo: 'jquery', }, staticPreview: this.render({ period: 'hy', hits: 95317723 }), - keywords, }, ] } diff --git a/services/jsdelivr/jsdelivr-hits-npm.service.js b/services/jsdelivr/jsdelivr-hits-npm.service.js index 3ac0e1aebb..9a1b67a845 100644 --- a/services/jsdelivr/jsdelivr-hits-npm.service.js +++ b/services/jsdelivr/jsdelivr-hits-npm.service.js @@ -1,11 +1,6 @@ 'use strict' -const { - schema, - keywords, - periodMap, - BaseJsDelivrService, -} = require('./jsdelivr-base') +const { schema, periodMap, BaseJsDelivrService } = require('./jsdelivr-base') module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { static get route() { @@ -38,7 +33,6 @@ module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { packageName: 'jquery', }, staticPreview: this.render({ period: 'hd', hits: 31471644 }), - keywords, }, { title: 'jsDelivr Hits (npm)', @@ -47,7 +41,6 @@ module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { packageName: 'jquery', }, staticPreview: this.render({ period: 'hw', hits: 209922436 }), - keywords, }, { title: 'jsDelivr Hits (npm)', @@ -56,7 +49,6 @@ module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { packageName: 'jquery', }, staticPreview: this.render({ period: 'hm', hits: 920101789 }), - keywords, }, { title: 'jsDelivr Hits (npm)', @@ -65,7 +57,6 @@ module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { packageName: 'jquery', }, staticPreview: this.render({ period: 'hy', hits: 10576760414 }), - keywords, }, ] } diff --git a/services/leanpub/leanpub-book-summary.service.js b/services/leanpub/leanpub-book-summary.service.js index 0aafddb0f3..ba4535189b 100644 --- a/services/leanpub/leanpub-book-summary.service.js +++ b/services/leanpub/leanpub-book-summary.service.js @@ -9,8 +9,6 @@ const bookSummarySchema = Joi.object({ total_copies_sold: Joi.number().required(), }).required() -const keywords = ['leanpub'] - module.exports = class LeanpubBookSummaryService extends BaseJsonService { static render({ label, message }) { return { @@ -36,7 +34,6 @@ module.exports = class LeanpubBookSummaryService extends BaseJsonService { book: 'juice-shop', }, staticPreview: this.render({ label: 'pages', message: 226 }), - keywords, }, { title: 'Leanpub Book Total Copies Sold', @@ -45,7 +42,6 @@ module.exports = class LeanpubBookSummaryService extends BaseJsonService { book: 'juice-shop', }, staticPreview: this.render({ label: 'sold', message: 2691 }), - keywords, }, ] } diff --git a/services/luarocks/luarocks.service.js b/services/luarocks/luarocks.service.js index c5f4a414d0..67a8fe00f8 100644 --- a/services/luarocks/luarocks.service.js +++ b/services/luarocks/luarocks.service.js @@ -39,7 +39,6 @@ module.exports = class Luarocks extends LegacyService { message: 'v0.23.0-1', color: 'brightgreen', }, - keywords: ['lua'], }, ] } diff --git a/services/pypi/pypi-djversions.service.js b/services/pypi/pypi-djversions.service.js index e1c12085a7..77399444b7 100644 --- a/services/pypi/pypi-djversions.service.js +++ b/services/pypi/pypi-djversions.service.js @@ -23,7 +23,7 @@ module.exports = class PypiDjangoVersions extends PypiBase { pattern: ':packageName', namedParams: { packageName: 'djangorestframework' }, staticPreview: this.render({ versions: ['1.11', '2.0', '2.1'] }), - keywords: ['python', 'django'], + keywords: ['python'], }, ] } diff --git a/services/pypi/pypi-pyversions.service.js b/services/pypi/pypi-pyversions.service.js index dbd784f666..611cbcbc15 100644 --- a/services/pypi/pypi-pyversions.service.js +++ b/services/pypi/pypi-pyversions.service.js @@ -23,7 +23,6 @@ module.exports = class PypiPythonVersions extends PypiBase { pattern: ':packageName', namedParams: { packageName: 'Django' }, staticPreview: this.render({ versions: ['3.5', '3.6', '3.7'] }), - keywords: ['python'], }, ] } diff --git a/services/redmine/redmine.service.js b/services/redmine/redmine.service.js index 26a74a8c1e..cf3dc4a7cc 100644 --- a/services/redmine/redmine.service.js +++ b/services/redmine/redmine.service.js @@ -53,7 +53,6 @@ class RedminePluginRating extends BaseRedminePluginRating { title: 'Plugin on redmine.org', namedParams: { plugin: 'redmine_xlsx_format_issue_exporter' }, staticPreview: this.render({ rating: 5 }), - keywords: ['redmine', 'plugin'], }, ] } @@ -81,7 +80,6 @@ class RedminePluginStars extends BaseRedminePluginRating { title: 'Plugin on redmine.org', namedParams: { plugin: 'redmine_xlsx_format_issue_exporter' }, staticPreview: this.render({ rating: 5 }), - keywords: ['redmine', 'plugin'], }, ] } diff --git a/services/requires/requires.service.js b/services/requires/requires.service.js index 409307b679..cd04a5032a 100644 --- a/services/requires/requires.service.js +++ b/services/requires/requires.service.js @@ -58,7 +58,6 @@ module.exports = class RequiresIo extends BaseJsonService { pattern: ':service/:user/:repo', namedParams: { service: 'github', user: 'celery', repo: 'celery' }, staticPreview: this.render({ status: 'up-to-date' }), - keywords: ['requires'], }, { title: 'Requires.io (branch)', @@ -70,7 +69,6 @@ module.exports = class RequiresIo extends BaseJsonService { branch: 'master', }, staticPreview: this.render({ status: 'up-to-date' }), - keywords: ['requires'], }, ] } diff --git a/services/vaadin-directory/vaadin-directory.service.js b/services/vaadin-directory/vaadin-directory.service.js index 01303c6f42..b63878f0f0 100644 --- a/services/vaadin-directory/vaadin-directory.service.js +++ b/services/vaadin-directory/vaadin-directory.service.js @@ -35,7 +35,7 @@ class VaadinDirectoryRating extends LegacyService { message: '5.0/5', color: 'brightgreen', }, - keywords: ['vaadin-directory', 'vaadin directory', 'rating'], + keywords: ['vaadin-directory', 'rating'], }, { title: 'Vaadin Directory', @@ -46,7 +46,7 @@ class VaadinDirectoryRating extends LegacyService { message: starRating(4.75), color: 'brightgreen', }, - keywords: ['vaadin-directory', 'vaadin directory', 'star', 'stars'], + keywords: ['vaadin-directory', 'star', 'stars'], }, { title: 'Vaadin Directory', @@ -57,12 +57,7 @@ class VaadinDirectoryRating extends LegacyService { message: '6 total', color: 'yellow', }, - keywords: [ - 'vaadin-directory', - 'vaadin directory', - 'rating-count', - 'rating count', - ], + keywords: ['vaadin-directory', 'rating-count', 'rating count'], }, ] } @@ -92,12 +87,7 @@ class VaadinDirectoryVersion extends LegacyService { message: 'v5.3.0-alpha4', color: '00b4f0', }, - keywords: [ - 'vaadin-directory', - 'vaadin directory', - 'version', - 'latest version', - ], + keywords: ['vaadin-directory', 'version', 'latest version'], }, ] } @@ -127,7 +117,7 @@ class VaadinDirectoryStatus extends LegacyService { message: 'published', color: '00b4f0', }, - keywords: ['vaadin-directory', 'vaadin directory', 'status'], + keywords: ['vaadin-directory', 'status'], }, ] } @@ -157,12 +147,7 @@ class VaadinDirectoryReleaseDate extends LegacyService { message: 'last wednesday', color: 'brightgreen', }, - keywords: [ - 'vaadin-directory', - 'vaadin directory', - 'date', - 'latest release date', - ], + keywords: ['vaadin-directory', 'date', 'latest release date'], }, ] } diff --git a/services/visual-studio-marketplace/visual-studio-marketplace-base.js b/services/visual-studio-marketplace/visual-studio-marketplace-base.js index f1ef2295f8..c414dedb83 100644 --- a/services/visual-studio-marketplace/visual-studio-marketplace-base.js +++ b/services/visual-studio-marketplace/visual-studio-marketplace-base.js @@ -47,8 +47,6 @@ module.exports = class VisualStudioMarketplaceBase extends BaseJsonService { static get keywords() { return [ 'vscode', - 'visual studio', - 'azure devops', 'tfs', 'vsts', 'visual-studio-marketplace', diff --git a/services/wordpress/wordpress-version.service.js b/services/wordpress/wordpress-version.service.js index 2819fcec7e..a5962c35b3 100644 --- a/services/wordpress/wordpress-version.service.js +++ b/services/wordpress/wordpress-version.service.js @@ -49,7 +49,6 @@ function VersionForExtensionType(extensionType) { title: `Wordpress ${capt} Version`, namedParams: { slug: exampleSlug }, staticPreview: this.render({ response: { version: 2.5 } }), - keywords: ['wordpress'], }, ] }