From a73026faa923aab862ccfa83aab311ae77ec25d0 Mon Sep 17 00:00:00 2001
From: guoxudong <guoxd@jihulab.com>
Date: Mon, 5 Sep 2022 06:32:23 +0800
Subject: [PATCH] feat: add [gitlab]-helper for encapsulate docs and err
 (#8295)

* feat: add gitlab-helper for encapsulate docs and err

* update merge requests

* fix mr example

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
---
 .../gitlab/gitlab-contributors.service.js     | 20 ++-------
 services/gitlab/gitlab-coverage.service.js    | 16 +++----
 services/gitlab/gitlab-helper.js              | 19 ++++++++
 services/gitlab/gitlab-issues.service.js      | 12 +----
 services/gitlab/gitlab-license.service.js     | 20 ++-------
 services/gitlab/gitlab-license.tester.js      |  2 +-
 .../gitlab/gitlab-merge-requests.service.js   | 45 ++++++++++---------
 .../gitlab/gitlab-pipeline-status.service.js  | 12 +++--
 services/gitlab/gitlab-release.service.js     | 10 +----
 services/gitlab/gitlab-tag.service.js         | 10 +----
 services/gitlab/gitlab-tag.tester.js          |  2 +-
 11 files changed, 68 insertions(+), 100 deletions(-)
 create mode 100644 services/gitlab/gitlab-helper.js

diff --git a/services/gitlab/gitlab-contributors.service.js b/services/gitlab/gitlab-contributors.service.js
index 00ebb6ad9b..5b8bb08dba 100644
--- a/services/gitlab/gitlab-contributors.service.js
+++ b/services/gitlab/gitlab-contributors.service.js
@@ -1,6 +1,7 @@
 import Joi from 'joi'
 import { optionalUrl, nonNegativeInteger } from '../validators.js'
 import { renderContributorBadge } from '../contributor-count.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 const schema = Joi.object({ 'x-total': nonNegativeInteger }).required()
@@ -9,19 +10,6 @@ const queryParamSchema = Joi.object({
   gitlab_url: optionalUrl,
 }).required()
 
-const documentation = `
-<p>
-  You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. gitlab-org/gitlab )
-</p>
-`
-
-const customDocumentation = `
-<p>
-  Note that only network-accessible jihulab.com and other self-managed GitLab instances are supported.
-  You may use your GitLab Project Id (e.g. 13953) or your Project Path (e.g. gitlab-cn/gitlab ) in <a href="https://jihulab.com">https://jihulab.com</a>
-</p>
-`
-
 export default class GitlabContributors extends GitLabBase {
   static category = 'activity'
   static route = {
@@ -46,7 +34,7 @@ export default class GitlabContributors extends GitLabBase {
         project: 'gitlab-cn/gitlab',
       },
       staticPreview: this.render({ contributorCount: 415 }),
-      documentation: customDocumentation,
+      documentation,
     },
   ]
 
@@ -64,9 +52,7 @@ export default class GitlabContributors extends GitLabBase {
           project
         )}/repository/contributors`,
         options: { searchParams: { page: '1', per_page: '1' } },
-        errorMessages: {
-          404: 'project not found',
-        },
+        errorMessages: errorMessagesFor('project not found'),
       })
     )
     const data = this.constructor._validate(res.headers, schema)
diff --git a/services/gitlab/gitlab-coverage.service.js b/services/gitlab/gitlab-coverage.service.js
index adfadc4132..a39354c996 100644
--- a/services/gitlab/gitlab-coverage.service.js
+++ b/services/gitlab/gitlab-coverage.service.js
@@ -2,6 +2,7 @@ import Joi from 'joi'
 import { coveragePercentage } from '../color-formatters.js'
 import { optionalUrl } from '../validators.js'
 import { BaseSvgScrapingService, NotFound } from '../index.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 
 const schema = Joi.object({
   message: Joi.string()
@@ -14,7 +15,7 @@ const queryParamSchema = Joi.object({
   job_name: Joi.string(),
 }).required()
 
-const documentation = `
+const moreDocs = `
 <p>
   Important: If your project is publicly visible, but the badge is like this:
   <img src="https://img.shields.io/badge/coverage-not&nbsp;set&nbsp;up-red" alt="coverage not set up"/>
@@ -54,7 +55,7 @@ export default class GitlabCoverage extends BaseSvgScrapingService {
         branch: 'master',
       },
       staticPreview: this.render({ coverage: 67 }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
     {
       title: 'Gitlab code coverage (specific job)',
@@ -65,14 +66,14 @@ export default class GitlabCoverage extends BaseSvgScrapingService {
       },
       queryParams: { job_name: 'test coverage report' },
       staticPreview: this.render({ coverage: 96 }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
     {
       title: 'Gitlab code coverage (self-managed)',
       namedParams: { user: 'GNOME', repo: 'at-spi2-core', branch: 'master' },
       queryParams: { gitlab_url: 'https://gitlab.gnome.org' },
       staticPreview: this.render({ coverage: 93 }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
     {
       title: 'Gitlab code coverage (self-managed, specific job)',
@@ -82,7 +83,7 @@ export default class GitlabCoverage extends BaseSvgScrapingService {
         job_name: 'unit-test',
       },
       staticPreview: this.render({ coverage: 93 }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
   ]
 
@@ -100,10 +101,7 @@ export default class GitlabCoverage extends BaseSvgScrapingService {
     // it is recommended to not use the query param at all if not required
     jobName = jobName ? `?job=${jobName}` : ''
     const url = `${baseUrl}/${user}/${repo}/badges/${branch}/coverage.svg${jobName}`
-    const errorMessages = {
-      401: 'repo not found',
-      404: 'repo not found',
-    }
+    const errorMessages = errorMessagesFor('project not found')
     return this._requestSvg({
       schema,
       url,
diff --git a/services/gitlab/gitlab-helper.js b/services/gitlab/gitlab-helper.js
new file mode 100644
index 0000000000..d1f24ebba1
--- /dev/null
+++ b/services/gitlab/gitlab-helper.js
@@ -0,0 +1,19 @@
+const documentation = `
+<p>
+  You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. 
+  <a href="https://gitlab.com/gitlab-org/gitlab" target="_blank" >gitlab-org/gitlab</a> ).
+  Note that only internet-accessible GitLab instances are supported, for example 
+  <a href="https://jihulab.com" target="_blank" >https://jihulab.com</a>, 
+  <a href="https://gitlab.gnome.org" target="_blank" >https://gitlab.gnome.org</a>, or 
+  <a href="https://gitlab.com" target="_blank" >https://gitlab.com</a>.
+</p>
+`
+
+function errorMessagesFor(notFoundMessage = 'project not found') {
+  return {
+    401: notFoundMessage,
+    404: notFoundMessage,
+  }
+}
+
+export { documentation, errorMessagesFor }
diff --git a/services/gitlab/gitlab-issues.service.js b/services/gitlab/gitlab-issues.service.js
index 2e8b6b3e20..ad86069f95 100644
--- a/services/gitlab/gitlab-issues.service.js
+++ b/services/gitlab/gitlab-issues.service.js
@@ -1,6 +1,7 @@
 import Joi from 'joi'
 import { optionalUrl, nonNegativeInteger } from '../validators.js'
 import { metric } from '../text-formatters.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 const schema = Joi.object({
@@ -18,13 +19,6 @@ const queryParamSchema = Joi.object({
   gitlab_url: optionalUrl,
 }).required()
 
-const documentation = `
-<p>
-  You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. gitlab-org/gitlab ).
-  Note that only internet-accessible GitLab instances are supported, for example https://jihulab.com, https://gitlab.gnome.org, or https://gitlab.com/.
-</p>
-`
-
 const labelDocumentation = `
 <p>
   If you want to use multiple labels then please use commas (<code>,</code>) to separate them, e.g. <code>foo,bar</code>.
@@ -243,9 +237,7 @@ export default class GitlabIssues extends GitLabBase {
         project
       )}/issues_statistics`,
       options: labels ? { searchParams: { labels } } : undefined,
-      errorMessages: {
-        404: 'project not found',
-      },
+      errorMessages: errorMessagesFor('project not found'),
     })
   }
 
diff --git a/services/gitlab/gitlab-license.service.js b/services/gitlab/gitlab-license.service.js
index 776d270017..254696121c 100644
--- a/services/gitlab/gitlab-license.service.js
+++ b/services/gitlab/gitlab-license.service.js
@@ -1,6 +1,7 @@
 import Joi from 'joi'
 import { optionalUrl } from '../validators.js'
 import { renderLicenseBadge } from '../licenses.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 const schema = Joi.object({
@@ -13,19 +14,6 @@ const queryParamSchema = Joi.object({
   gitlab_url: optionalUrl,
 }).required()
 
-const documentation = `
-<p>
-  You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. gitlab-org/gitlab )
-</p>
-`
-
-const customDocumentation = `
-<p>
-  Note that only internet-accessible GitLab instances are supported, for example https://jihulab.com, https://gitlab.gnome.org, or https://gitlab.com/.
-  You may use your GitLab Project Id (e.g. 13953) or your Project Path (e.g. gitlab-cn/gitlab ) in <a href="https://jihulab.com">https://jihulab.com</a>
-</p>
-`
-
 export default class GitlabLicense extends GitLabBase {
   static category = 'license'
 
@@ -59,7 +47,7 @@ export default class GitlabLicense extends GitLabBase {
         message: 'MIT License',
         color: 'green',
       },
-      documentation: customDocumentation,
+      documentation,
     },
   ]
 
@@ -79,9 +67,7 @@ export default class GitlabLicense extends GitLabBase {
       schema,
       url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`,
       options: { searchParams: { license: '1' } },
-      errorMessages: {
-        404: 'repo not found',
-      },
+      errorMessages: errorMessagesFor('project not found'),
     })
   }
 
diff --git a/services/gitlab/gitlab-license.tester.js b/services/gitlab/gitlab-license.tester.js
index 10a4e07898..9769a625f3 100644
--- a/services/gitlab/gitlab-license.tester.js
+++ b/services/gitlab/gitlab-license.tester.js
@@ -34,7 +34,7 @@ t.create('License for unknown repo')
   .get('/user1/gitlab-does-not-have-this-repo.json')
   .expectBadge({
     label: 'license',
-    message: 'repo not found',
+    message: 'project not found',
     color: 'red',
   })
 
diff --git a/services/gitlab/gitlab-merge-requests.service.js b/services/gitlab/gitlab-merge-requests.service.js
index 1cc353a222..bc7f7b88a1 100644
--- a/services/gitlab/gitlab-merge-requests.service.js
+++ b/services/gitlab/gitlab-merge-requests.service.js
@@ -1,6 +1,7 @@
 import Joi from 'joi'
 import { optionalUrl, nonNegativeInteger } from '../validators.js'
 import { metric } from '../text-formatters.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 // The total number of MR is in the `x-total` field in the headers.
@@ -15,20 +16,22 @@ const queryParamSchema = Joi.object({
   gitlab_url: optionalUrl,
 }).required()
 
-const documentation = `
+const more = `
 <p>
-  You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. gitlab-org/gitlab ).
-  Note that only internet-accessible GitLab instances are supported, for example https://jihulab.com, https://gitlab.gnome.org, or https://gitlab.com/.
   <a href="https://docs.gitlab.com/ee/user/gitlab_com/index.html#pagination-response-headers">GitLab's API </a> only reports up to 10k Merge Requests, so badges for projects that have more than 10k will not have an exact count.
 </p>
 `
 
-const labelDocumentation = `
+const labelText = `
 <p>
   If you want to use multiple labels then please use commas (<code>,</code>) to separate them, e.g. <code>foo,bar</code>.
 </p>
 `
 
+const defaultDocumentation = documentation + more
+
+const labelDocumentation = documentation + labelText + more
+
 export default class GitlabMergeRequests extends GitLabBase {
   static category = 'issue-tracking'
 
@@ -51,7 +54,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '1.4k open',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab merge requests',
@@ -65,7 +68,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '1.4k',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab merge requests by-label',
@@ -82,7 +85,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '3 open',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab merge requests by-label',
@@ -99,7 +102,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '3',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab closed merge requests',
@@ -113,7 +116,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: 'more than 10k closed',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab closed merge requests',
@@ -127,7 +130,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: 'more than 10k',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab closed merge requests by-label',
@@ -144,7 +147,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '32 closed',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab closed merge requests by-label',
@@ -161,7 +164,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '32',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab all merge requests',
@@ -175,7 +178,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: 'more than 10k all',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab all merge requests',
@@ -189,7 +192,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: 'more than 10k',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab all merge requests by-label',
@@ -206,7 +209,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '12',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab locked merge requests',
@@ -220,7 +223,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '0 locked',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab locked merge requests by-label',
@@ -237,7 +240,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '0 locked',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
     {
       title: 'GitLab merged merge requests',
@@ -251,7 +254,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: 'more than 10k merged',
         color: 'blue',
       },
-      documentation,
+      documentation: defaultDocumentation,
     },
     {
       title: 'GitLab merged merge requests by-label',
@@ -268,7 +271,7 @@ export default class GitlabMergeRequests extends GitLabBase {
         message: '68 merged',
         color: 'blue',
       },
-      documentation: documentation + labelDocumentation,
+      documentation: labelDocumentation,
     },
   ]
 
@@ -311,9 +314,7 @@ export default class GitlabMergeRequests extends GitLabBase {
             labels,
           },
         },
-        errorMessages: {
-          404: 'project not found',
-        },
+        errorMessages: errorMessagesFor('project not found'),
       })
     )
     return this.constructor._validate(res.headers, schema)
diff --git a/services/gitlab/gitlab-pipeline-status.service.js b/services/gitlab/gitlab-pipeline-status.service.js
index ebeb6bc943..dbd0cdbcd1 100644
--- a/services/gitlab/gitlab-pipeline-status.service.js
+++ b/services/gitlab/gitlab-pipeline-status.service.js
@@ -2,6 +2,7 @@ import Joi from 'joi'
 import { isBuildStatus, renderBuildStatusBadge } from '../build-status.js'
 import { optionalUrl } from '../validators.js'
 import { BaseSvgScrapingService, NotFound, redirector } from '../index.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 
 const badgeSchema = Joi.object({
   message: Joi.alternatives()
@@ -14,7 +15,7 @@ const queryParamSchema = Joi.object({
   branch: Joi.string(),
 }).required()
 
-const documentation = `
+const moreDocs = `
 <p>
   Important: You must use the Project Path, not the Project Id. Additionally, if your project is publicly visible, but the badge is like this:
   <img src="https://img.shields.io/badge/build-not&nbsp;found-red" alt="build not found"/>
@@ -51,14 +52,14 @@ class GitlabPipelineStatus extends BaseSvgScrapingService {
       namedParams: { project: 'gitlab-org/gitlab' },
       queryParams: { branch: 'master' },
       staticPreview: this.render({ status: 'passed' }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
     {
       title: 'Gitlab pipeline status (self-managed)',
       namedParams: { project: 'GNOME/pango' },
       queryParams: { gitlab_url: 'https://gitlab.gnome.org', branch: 'master' },
       staticPreview: this.render({ status: 'passed' }),
-      documentation,
+      documentation: documentation + moreDocs,
     },
   ]
 
@@ -72,10 +73,7 @@ class GitlabPipelineStatus extends BaseSvgScrapingService {
       url: `${baseUrl}/${decodeURIComponent(
         project
       )}/badges/${branch}/pipeline.svg`,
-      errorMessages: {
-        401: 'repo not found',
-        404: 'repo not found',
-      },
+      errorMessages: errorMessagesFor('project not found'),
     })
   }
 
diff --git a/services/gitlab/gitlab-release.service.js b/services/gitlab/gitlab-release.service.js
index 10f50420a7..51f3c37291 100644
--- a/services/gitlab/gitlab-release.service.js
+++ b/services/gitlab/gitlab-release.service.js
@@ -2,6 +2,7 @@ import Joi from 'joi'
 import { optionalUrl } from '../validators.js'
 import { latest, renderVersionBadge } from '../version.js'
 import { NotFound } from '../index.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 const schema = Joi.array().items(
@@ -21,11 +22,6 @@ const queryParamSchema = Joi.object({
     .default('created_at'),
 }).required()
 
-const documentation = `
-<p>
-  You may use your GitLab Project Id (e.g. 25813592) or your Project Path (e.g. megabyte-labs/dockerfile/ci-pipeline/ansible-lint)
-</p>
-`
 const commonProps = {
   namedParams: {
     project: 'shields-ops-group/tag-test',
@@ -102,9 +98,7 @@ export default class GitLabRelease extends GitLabBase {
     return this.fetchPaginatedArrayData({
       schema,
       url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}/releases`,
-      errorMessages: {
-        404: 'project not found',
-      },
+      errorMessages: errorMessagesFor('project not found'),
       options: {
         searchParams: { order_by: orderBy },
       },
diff --git a/services/gitlab/gitlab-tag.service.js b/services/gitlab/gitlab-tag.service.js
index ce5aa084f7..534d371972 100644
--- a/services/gitlab/gitlab-tag.service.js
+++ b/services/gitlab/gitlab-tag.service.js
@@ -4,6 +4,7 @@ import { optionalUrl } from '../validators.js'
 import { latest } from '../version.js'
 import { addv } from '../text-formatters.js'
 import { NotFound } from '../index.js'
+import { documentation, errorMessagesFor } from './gitlab-helper.js'
 import GitLabBase from './gitlab-base.js'
 
 const schema = Joi.array().items(
@@ -18,11 +19,6 @@ const queryParamSchema = Joi.object({
   sort: Joi.string().valid('date', 'semver').default('date'),
 }).required()
 
-const documentation = `
-<p>
-  You may use your GitLab Project Id (e.g. 25813592) or your Project Path (e.g. megabyte-labs/dockerfile/ci-pipeline/ansible-lint)
-</p>
-`
 const commonProps = {
   namedParams: {
     project: 'shields-ops-group/tag-test',
@@ -96,9 +92,7 @@ export default class GitlabTag extends GitLabBase {
         project
       )}/repository/tags`,
       options: { searchParams: { order_by: 'updated' } },
-      errorMessages: {
-        404: 'repo not found',
-      },
+      errorMessages: errorMessagesFor('project not found'),
     })
   }
 
diff --git a/services/gitlab/gitlab-tag.tester.js b/services/gitlab/gitlab-tag.tester.js
index 8cd9a008bf..f3d78bf249 100644
--- a/services/gitlab/gitlab-tag.tester.js
+++ b/services/gitlab/gitlab-tag.tester.js
@@ -28,7 +28,7 @@ t.create('Tag (custom instance)')
 
 t.create('Tag (repo not found)')
   .get('/fdroid/nonexistant.json')
-  .expectBadge({ label: 'tag', message: 'repo not found' })
+  .expectBadge({ label: 'tag', message: 'project not found' })
 
 t.create('Tag (no tags)')
   .get('/fdroid/fdroiddata.json')
-- 
GitLab