From 170d29efcc207bb244df5c78c8fe81b2dfffb6ed Mon Sep 17 00:00:00 2001
From: Piepmatz <3590829+cptpiepmatz@users.noreply.github.com>
Date: Wed, 30 Aug 2023 19:38:57 +0200
Subject: [PATCH] Add dynamic TOML support via [DynamicToml] Service (#9517)

* exported BaseTomlService

* added dynamic-toml service

* added dynamic-toml tester

* fixed dynamic-toml tests
---
 core/base-service/index.js               |   2 +
 services/dynamic/dynamic-toml.service.js |  54 ++++++++++++
 services/dynamic/dynamic-toml.tester.js  | 107 +++++++++++++++++++++++
 3 files changed, 163 insertions(+)
 create mode 100644 services/dynamic/dynamic-toml.service.js
 create mode 100644 services/dynamic/dynamic-toml.tester.js

diff --git a/core/base-service/index.js b/core/base-service/index.js
index 5808b6211d..25fad0e0f3 100644
--- a/core/base-service/index.js
+++ b/core/base-service/index.js
@@ -3,6 +3,7 @@ import BaseJsonService from './base-json.js'
 import BaseGraphqlService from './base-graphql.js'
 import BaseStaticService from './base-static.js'
 import BaseSvgScrapingService from './base-svg-scraping.js'
+import BaseTomlService from './base-toml.js'
 import BaseXmlService from './base-xml.js'
 import BaseYamlService from './base-yaml.js'
 import deprecatedService from './deprecated-service.js'
@@ -23,6 +24,7 @@ export {
   BaseGraphqlService,
   BaseStaticService,
   BaseSvgScrapingService,
+  BaseTomlService,
   BaseXmlService,
   BaseYamlService,
   deprecatedService,
diff --git a/services/dynamic/dynamic-toml.service.js b/services/dynamic/dynamic-toml.service.js
new file mode 100644
index 0000000000..950d9ab085
--- /dev/null
+++ b/services/dynamic/dynamic-toml.service.js
@@ -0,0 +1,54 @@
+import { MetricNames } from '../../core/base-service/metric-helper.js'
+import { BaseTomlService, queryParams } from '../index.js'
+import { createRoute } from './dynamic-helpers.js'
+import jsonPath from './json-path.js'
+
+export default class DynamicToml extends jsonPath(BaseTomlService) {
+  static enabledMetrics = [MetricNames.SERVICE_RESPONSE_SIZE]
+  static route = createRoute('toml')
+  static openApi = {
+    '/badge/dynamic/toml': {
+      get: {
+        summary: 'Dynamic TOML Badge',
+        description: `<p>
+          The Dynamic TOML Badge allows you to extract an arbitrary value from any
+          TOML Document using a JSONPath selector and show it on a badge.
+        </p>`,
+        parameters: queryParams(
+          {
+            name: 'url',
+            description: 'The URL to a TOML document',
+            required: true,
+            example:
+              'https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml',
+          },
+          {
+            name: 'query',
+            description:
+              'A <a href="https://jsonpath.com/">JSONPath</a> expression that will be used to query the document',
+            required: true,
+            example: '$.title',
+          },
+          {
+            name: 'prefix',
+            description: 'Optional prefix to append to the value',
+            example: '[',
+          },
+          {
+            name: 'suffix',
+            description: 'Optional suffix to append to the value',
+            example: ']',
+          },
+        ),
+      },
+    },
+  }
+
+  async fetch({ schema, url, httpErrors }) {
+    return this._requestToml({
+      schema,
+      url,
+      httpErrors,
+    })
+  }
+}
diff --git a/services/dynamic/dynamic-toml.tester.js b/services/dynamic/dynamic-toml.tester.js
new file mode 100644
index 0000000000..21988a1103
--- /dev/null
+++ b/services/dynamic/dynamic-toml.tester.js
@@ -0,0 +1,107 @@
+import { createServiceTester } from '../tester.js'
+export const t = await createServiceTester()
+
+t.create('No URL specified')
+  .get('.json?query=$.name&label=Package Name')
+  .expectBadge({
+    label: 'Package Name',
+    message: 'invalid query parameter: url',
+    color: 'red',
+  })
+
+t.create('No query specified')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&label=Package Name',
+  )
+  .expectBadge({
+    label: 'Package Name',
+    message: 'invalid query parameter: query',
+    color: 'red',
+  })
+
+t.create('TOML from url')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.title',
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'TOML Example',
+    color: 'blue',
+  })
+
+t.create('TOML from url | multiple results')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.database.data[0][*]',
+  )
+  .expectBadge({ label: 'custom badge', message: 'delta, phi' })
+
+t.create('TOML from url | caching with new query params')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.owner.name',
+  )
+  .expectBadge({ label: 'custom badge', message: 'Tom Preston-Werner' })
+
+t.create('TOML from url | with prefix & suffix & label')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.database.temp_targets.cpu&prefix=%2B&suffix=°C&label=CPU Temp Target',
+  )
+  .expectBadge({ label: 'CPU Temp Target', message: '+79.5°C' })
+
+t.create('TOML from url | object doesnt exist')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.does_not_exist',
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'no result',
+    color: 'lightgrey',
+  })
+
+t.create('TOML from url | invalid url')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/not-a-file.toml&query=$.version',
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'resource not found',
+    color: 'red',
+  })
+
+t.create('TOML from url | user color overrides default')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/toml-spec-example.toml&query=$.title&color=10ADED',
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'TOML Example',
+    color: '#10aded',
+  })
+
+t.create('TOML from url | error color overrides default')
+  .get(
+    '.json?url=https://raw.githubusercontent.com/squirrelchat/smol-toml/mistress/bench/testfiles/not-a-file.toml&query=$.version',
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'resource not found',
+    color: 'red',
+  })
+
+t.create('TOML from url | error color overrides user specified')
+  .get('.json?query=$.version&color=10ADED')
+  .expectBadge({
+    label: 'custom badge',
+    message: 'invalid query parameter: url',
+    color: 'red',
+  })
+
+t.create('TOML contains a string')
+  .get('.json?url=https://example.test/toml&query=$.foo,')
+  .intercept(nock =>
+    nock('https://example.test').get('/toml').reply(200, '"foo"'),
+  )
+  .expectBadge({
+    label: 'custom badge',
+    message: 'unparseable toml response',
+    color: 'lightgrey',
+  })
-- 
GitLab