From d4816720c21e3fd7832785f174771096a2ea3d7b Mon Sep 17 00:00:00 2001 From: Sergey Kupletsky Date: Sun, 8 Oct 2023 18:08:22 +0200 Subject: [PATCH] fix issue with custom logo generation (#9644) * allow `logo`, `logoPosition`, `logoWidth`, and `links` as expected keys * add validation for `logo`, `logoPosition`, `logoWidth`, and `links` keys * add validation tests --- badge-maker/index.d.ts | 4 ++++ badge-maker/lib/index.js | 39 ++++++++++++++++++++++++++++++++--- badge-maker/lib/index.spec.js | 28 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/badge-maker/index.d.ts b/badge-maker/index.d.ts index 38d71e22b8344..846beb05ada09 100644 --- a/badge-maker/index.d.ts +++ b/badge-maker/index.d.ts @@ -4,6 +4,10 @@ interface Format { labelColor?: string color?: string style?: 'plastic' | 'flat' | 'flat-square' | 'for-the-badge' | 'social' + logo?: string + logoPosition?: number + logoWidth?: number + links?: Array } export declare class ValidationError extends Error {} diff --git a/badge-maker/lib/index.js b/badge-maker/lib/index.js index 051c3d84e9c7b..387128cf17f81 100644 --- a/badge-maker/lib/index.js +++ b/badge-maker/lib/index.js @@ -16,13 +16,32 @@ function _validate(format) { throw new ValidationError('Field `message` is required') } - const stringFields = ['labelColor', 'color', 'message', 'label'] + const stringFields = ['labelColor', 'color', 'message', 'label', 'logo'] stringFields.forEach(function (field) { if (field in format && typeof format[field] !== 'string') { throw new ValidationError(`Field \`${field}\` must be of type string`) } }) + const numberFields = ['logoWidth', 'logoPosition'] + numberFields.forEach(function (field) { + if (field in format && typeof format[field] !== 'number') { + throw new ValidationError(`Field \`${field}\` must be of type number`) + } + }) + + if ('links' in format) { + if (!Array.isArray(format.links)) { + throw new ValidationError('Field `links` must be an array of strings') + } else { + format.links.forEach(function (field) { + if (typeof field !== 'string') { + throw new ValidationError('Field `links` must be an array of strings') + } + }) + } + } + const styleValues = [ 'plastic', 'flat', @@ -38,7 +57,17 @@ function _validate(format) { } function _clean(format) { - const expectedKeys = ['label', 'message', 'labelColor', 'color', 'style'] + const expectedKeys = [ + 'label', + 'message', + 'labelColor', + 'color', + 'style', + 'logo', + 'logoPosition', + 'logoWidth', + 'links', + ] const cleaned = {} Object.keys(format).forEach(key => { @@ -65,7 +94,11 @@ function _clean(format) { * @param {string} format.message (Required) Badge message (e.g: 'passing') * @param {string} format.labelColor (Optional) Label color * @param {string} format.color (Optional) Message color - * @param {string} format.style (Optional) Visual style e.g: 'flat' + * @param {string} format.style (Optional) Visual style (e.g: 'flat') + * @param {string} format.logo (Optional) Logo data URL + * @param {number} format.logoPosition (Optional) Logo position (e.g: 40) + * @param {number} format.logoWidth (Optional) Logo width (e.g: 40) + * @param {Array} format.links (Optional) Links array (e.g: ['https://example.com', 'https://example.com']) * @returns {string} Badge in SVG format * @see https://github.com/badges/shields/tree/master/badge-maker/README.md */ diff --git a/badge-maker/lib/index.spec.js b/badge-maker/lib/index.spec.js index 839aa061e4ff1..6135c51738ad1 100644 --- a/badge-maker/lib/index.spec.js +++ b/badge-maker/lib/index.spec.js @@ -25,6 +25,19 @@ describe('makeBadge function', function () { style: 'flat', }), ).to.satisfy(isSvg) + expect( + makeBadge({ + label: 'build', + message: 'passed', + color: 'green', + style: 'flat', + labelColor: 'blue', + logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxu', + logoWidth: 20, + logoPosition: 10, + links: ['https://example.com', 'https://example.com'], + }), + ).to.satisfy(isSvg) }) it('should throw a ValidationError with invalid inputs', function () { @@ -46,6 +59,21 @@ describe('makeBadge function', function () { expect(() => makeBadge({ label: 'build', message: 'passed', labelColor: 7 }), ).to.throw(ValidationError, 'Field `labelColor` must be of type string') + expect(() => + makeBadge({ label: 'build', message: 'passed', logo: 7 }), + ).to.throw(ValidationError, 'Field `logo` must be of type string') + expect(() => + makeBadge({ label: 'build', message: 'passed', logoPosition: '7' }), + ).to.throw(ValidationError, 'Field `logoPosition` must be of type number') + expect(() => + makeBadge({ label: 'build', message: 'passed', logoWidth: '7' }), + ).to.throw(ValidationError, 'Field `logoWidth` must be of type number') + expect(() => + makeBadge({ label: 'build', message: 'passed', links: 'test' }), + ).to.throw(ValidationError, 'Field `links` must be an array of strings') + expect(() => + makeBadge({ label: 'build', message: 'passed', links: [1] }), + ).to.throw(ValidationError, 'Field `links` must be an array of strings') expect(() => makeBadge({ label: 'build', message: 'passed', format: 'png' }), ).to.throw(ValidationError, "Unexpected field 'format'")