Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with custom logo generation in badge-maker (#9644) #9645

Closed
wants to merge 8 commits into from
2 changes: 2 additions & 0 deletions badge-maker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ The format is the following:
message: 'passed', // (Required) Badge message
labelColor: '#555', // (Optional) Label color
color: '#4c1', // (Optional) Message color
logoBase64: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iOCIgZmlsbD0iI2IxY2U1NiIvPjxwYXRoIGQ9Ik04IDBoMjR2NjRIOGMtNC40MzIgMC04LTMuNTY4LTgtOFY4YzAtNC40MzIgMy41NjgtOCA4LTh6IiBmaWxsPSIjNWQ1ZDVkIi8+PC9zdmc+' // (Optional) Any custom logo can be passed in a URL parameter by base64 encoding
links: ['https://example.com', 'https://example.com'], // (Optional) Links array of maximum two links

// (Optional) One of: 'plastic', 'flat', 'flat-square', 'for-the-badge' or 'social'
// Each offers a different visual design.
Expand Down
2 changes: 2 additions & 0 deletions badge-maker/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ interface Format {
labelColor?: string
color?: string
style?: 'plastic' | 'flat' | 'flat-square' | 'for-the-badge' | 'social'
logoBase64?: string
links?: Array<string>
zavoloklom marked this conversation as resolved.
Show resolved Hide resolved
}

export declare class ValidationError extends Error {}
Expand Down
3 changes: 2 additions & 1 deletion badge-maker/lib/badge-renderers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const anafanafo = require('anafanafo')
const { brightness } = require('./color')
const { XmlElement, ElementList } = require('./xml')
const { DEFAULT_LOGO_HEIGHT } = require('./constants')

// https://github.com/badges/shields/pull/1132
const FONT_SCALE_UP_FACTOR = 10
Expand Down Expand Up @@ -53,7 +54,7 @@ function shouldWrapBodyWithLink({ links }) {
}

function getLogoElement({ logo, horizPadding, badgeHeight, logoWidth }) {
const logoHeight = 14
const logoHeight = DEFAULT_LOGO_HEIGHT
if (!logo) return ''
return new XmlElement({
name: 'image',
Expand Down
33 changes: 30 additions & 3 deletions badge-maker/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,30 @@ function _validate(format) {
throw new ValidationError('Field `message` is required')
}

const stringFields = ['labelColor', 'color', 'message', 'label']
const stringFields = ['labelColor', 'color', 'message', 'label', 'logoBase64']
stringFields.forEach(function (field) {
if (field in format && typeof format[field] !== 'string') {
throw new ValidationError(`Field \`${field}\` must be of type string`)
}
})

if ('links' in format) {
if (!Array.isArray(format.links)) {
zavoloklom marked this conversation as resolved.
Show resolved Hide resolved
throw new ValidationError('Field `links` must be an array of strings')
} else {
if (format.links.length > 2) {
throw new ValidationError(
'Field `links` must not have more than 2 elements',
)
}
format.links.forEach(function (field) {
if (typeof field !== 'string') {
throw new ValidationError('Field `links` must be an array of strings')
}
})
}
}

const styleValues = [
'plastic',
'flat',
Expand All @@ -38,7 +55,15 @@ function _validate(format) {
}

function _clean(format) {
const expectedKeys = ['label', 'message', 'labelColor', 'color', 'style']
const expectedKeys = [
'label',
'message',
'labelColor',
'color',
'style',
'logoBase64',
'links',
]

const cleaned = {}
Object.keys(format).forEach(key => {
Expand All @@ -65,7 +90,9 @@ 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.logoBase64 (Optional) Logo data URL
* @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
*/
Expand Down
26 changes: 26 additions & 0 deletions badge-maker/lib/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ describe('makeBadge function', function () {
style: 'flat',
}),
).to.satisfy(isSvg)
expect(
makeBadge({
label: 'build',
message: 'passed',
color: 'green',
style: 'flat',
labelColor: 'blue',
logoBase64: 'data:image/svg+xml;base64,PHN2ZyB4bWxu',
links: ['https://example.com', 'https://example.com'],
}),
).to.satisfy(isSvg)
})

it('should throw a ValidationError with invalid inputs', function () {
Expand All @@ -46,6 +57,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', logoBase64: 7 }),
).to.throw(ValidationError, 'Field `logoBase64` must be of type string')
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', links: ['1', '2', '3'] }),
).to.throw(
ValidationError,
'Field `links` must not have more than 2 elements',
)
expect(() =>
makeBadge({ label: 'build', message: 'passed', format: 'png' }),
).to.throw(ValidationError, "Unexpected field 'format'")
Expand Down
8 changes: 1 addition & 7 deletions badge-maker/lib/make-badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ module.exports = function makeBadge({
color,
labelColor,
logo,
logoPosition,
logoSize,
logoWidth,
links = ['', ''],
}) {
// String coercion and whitespace removal.
Expand All @@ -31,7 +29,6 @@ module.exports = function makeBadge({
return JSON.stringify({
label,
message,
logoWidth,
// Only call normalizeColor for the JSON case: this is handled
// internally by toSvgColor in the SVG case.
color: normalizeColor(color),
Expand All @@ -47,16 +44,13 @@ module.exports = function makeBadge({
throw new Error(`Unknown badge style: '${style}'`)
}

logoWidth = +logoWidth || (logo ? DEFAULT_LOGO_HEIGHT : 0)

return stripXmlWhitespace(
render({
label,
message,
links,
logo,
logoPosition,
logoWidth,
logoWidth: logo ? DEFAULT_LOGO_HEIGHT : 0,
logoSize,
logoPadding: logo && label.length ? 3 : 0,
color: toSvgColor(color),
Expand Down
Loading