diff --git a/src/contributors/__tests__/add.js b/src/contributors/__tests__/add.js index 1860b0be..b5cbbdf2 100644 --- a/src/contributors/__tests__/add.js +++ b/src/contributors/__tests__/add.js @@ -26,6 +26,12 @@ function fixtures() { profile: 'www.profile.url', contributions: [{type: 'blog', url: 'www.blog.url/path'}, 'code'], }, + { + name: 'Missing Login', + avatar_url: 'www.avatar.url', + profile: 'www.profile.url', + contributions: ['code'], + }, ], } return {options} @@ -71,8 +77,8 @@ test('add new contributor at the end of the list of contributors', () => { return addContributor(options, username, contributions, mockInfoFetcher).then( contributors => { - expect(contributors.length).toBe(3) - expect(contributors[2]).toEqual({ + expect(contributors.length).toBe(options.contributors.length + 1) + expect(contributors[options.contributors.length]).toEqual({ login: 'login3', name: 'Some name', avatar_url: 'www.avatar.url', @@ -91,8 +97,8 @@ test('add new contributor at the end of the list of contributors with a url link return addContributor(options, username, contributions, mockInfoFetcher).then( contributors => { - expect(contributors.length).toBe(3) - expect(contributors[2]).toEqual({ + expect(contributors.length).toBe(options.contributors.length + 1) + expect(contributors[options.contributors.length]).toEqual({ login: 'login3', name: 'Some name', avatar_url: 'www.avatar.url', @@ -133,7 +139,7 @@ test(`should update an existing contributor's contributions if a new type is add const contributions = ['bug'] return addContributor(options, username, contributions, mockInfoFetcher).then( contributors => { - expect(contributors.length).toBe(2) + expect(contributors.length).toBe(options.contributors.length) expect(contributors[0]).toEqual({ login: 'login1', name: 'Some name', @@ -171,7 +177,7 @@ test(`should update an existing contributor's contributions if a new type is add return addContributor(options, username, contributions, mockInfoFetcher).then( contributors => { - expect(contributors.length).toBe(2) + expect(contributors.length).toBe(options.contributors.length) expect(contributors[0]).toEqual({ login: 'login1', name: 'Some name', diff --git a/src/contributors/add.js b/src/contributors/add.js index 7f7555dd..63a44d76 100644 --- a/src/contributors/add.js +++ b/src/contributors/add.js @@ -27,7 +27,10 @@ function updateContributor(options, contributor, contributions) { function updateExistingContributor(options, username, contributions) { return options.contributors.map(contributor => { - if (username.toLowerCase() !== contributor.login.toLowerCase()) { + if ( + !contributor.login || + username.toLowerCase() !== contributor.login.toLowerCase() + ) { return contributor } return updateContributor(options, contributor, contributions) @@ -51,7 +54,10 @@ module.exports = function addContributor( ) { // case insensitive find const exists = _.find(contributor => { - return contributor.login.toLowerCase() === username.toLowerCase() + return ( + contributor.login && + contributor.login.toLowerCase() === username.toLowerCase() + ) }, options.contributors) if (exists) { diff --git a/src/contributors/prompt.js b/src/contributors/prompt.js index cf699765..232cc356 100644 --- a/src/contributors/prompt.js +++ b/src/contributors/prompt.js @@ -35,6 +35,7 @@ function getQuestions(options, username, contributions) { return options.contributors .filter( entry => + entry.login && entry.login.toLowerCase() === answers.username.toLowerCase(), ) .reduce( @@ -48,6 +49,7 @@ function getQuestions(options, username, contributions) { const previousContributions = options.contributors .filter( entry => + entry.login && entry.login.toLowerCase() === answers.username.toLowerCase(), ) .reduce( diff --git a/src/generate/__tests__/fixtures/contributors.json b/src/generate/__tests__/fixtures/contributors.json index ca834fe7..7872bd3b 100644 --- a/src/generate/__tests__/fixtures/contributors.json +++ b/src/generate/__tests__/fixtures/contributors.json @@ -19,5 +19,15 @@ "profile": "http://github.com/chrisinajar", "avatar_url": "https://avatars1.githubusercontent.com/u/1500684", "contributions": ["doc"] + }, + "nologin": { + "name": "No Github Account", + "avatar_url": "https://avatars1.githubusercontent.com/u/1500684", + "contributions": ["translation"] + }, + "nologin_badrole": { + "name": "Wildly Misconfigured", + "avatar_url": "https://avatars1.githubusercontent.com/u/1500684", + "contributions": ["plumbis"] } } diff --git a/src/generate/__tests__/format-contribution-type.js b/src/generate/__tests__/format-contribution-type.js index d3a14e0e..5b242d16 100644 --- a/src/generate/__tests__/format-contribution-type.js +++ b/src/generate/__tests__/format-contribution-type.js @@ -153,3 +153,13 @@ test('throw a helpful error on unknown type', () => { formatContributionType(options, contributor, 'docs'), ).toThrowError('Unknown contribution type docs for contributor kentcdodds') }) + +test('throw a helpful error on unknown type and no login', () => { + const contributor = contributors.nologin_badrole + const {options} = fixtures() + expect(() => + formatContributionType(options, contributor, 'docs'), + ).toThrowError( + 'Unknown contribution type docs for contributor Wildly Misconfigured', + ) +}) diff --git a/src/generate/__tests__/format-contributor.js b/src/generate/__tests__/format-contributor.js index 7bc0b750..8182ea2e 100644 --- a/src/generate/__tests__/format-contributor.js +++ b/src/generate/__tests__/format-contributor.js @@ -65,3 +65,13 @@ test('format contributor with pipes in their name', () => { expect(formatContributor(options, contributor)).toBe(expected) }) + +test('format contributor with no github account', () => { + const contributor = contributors.nologin + const {options} = fixtures() + + const expected = + '
No Github Account
[🌍](#translation "Translation")' + + expect(formatContributor(options, contributor)).toBe(expected) +}) diff --git a/src/generate/format-contribution-type.js b/src/generate/format-contribution-type.js index 482c62f8..78843ea0 100644 --- a/src/generate/format-contribution-type.js +++ b/src/generate/format-contribution-type.js @@ -19,9 +19,8 @@ module.exports = function formatContribution( if (!type) { throw new Error( - `Unknown contribution type ${contribution} for contributor ${ - contributor.login - }`, + `Unknown contribution type ${contribution} for contributor ${contributor.login || + contributor.name}`, ) } @@ -32,7 +31,8 @@ module.exports = function formatContribution( options, } - let url = `#${contribution}-${contributor.login}` + let url = getUrl(contribution, contributor) + if (contribution.url) { url = contribution.url } else if (type.link) { @@ -41,3 +41,11 @@ module.exports = function formatContribution( return linkTemplate(_.assign({url}, templateData)) } + +function getUrl(contribution, contributor) { + if (contributor.login) { + return `#${contribution}-${contributor.login}` + } else { + return `#${contribution}` + } +} diff --git a/src/generate/format-contributor.js b/src/generate/format-contributor.js index b8e65672..2b67ca4d 100644 --- a/src/generate/format-contributor.js +++ b/src/generate/format-contributor.js @@ -7,6 +7,9 @@ const avatarTemplate = _.template( const avatarBlockTemplate = _.template( '[<%= avatar %>
<%= name %>](<%= contributor.profile %>)', ) +const avatarBlockTemplateNoProfile = _.template( + '<%= avatar %>
<%= name %>', +) const contributorTemplate = _.template( '<%= avatarBlock %>
<%= contributions %>', ) @@ -15,15 +18,20 @@ const defaultImageSize = 100 function defaultTemplate(templateData) { const avatar = avatarTemplate(templateData) - const avatarBlock = avatarBlockTemplate( - _.assign( - { - name: escapeName(templateData.contributor.name), - avatar, - }, - templateData, - ), + const avatarBlockTemplateData = _.assign( + { + name: escapeName(templateData.contributor.name), + avatar, + }, + templateData, ) + let avatarBlock = null + + if (templateData.contributor.profile) { + avatarBlock = avatarBlockTemplate(avatarBlockTemplateData) + } else { + avatarBlock = avatarBlockTemplateNoProfile(avatarBlockTemplateData) + } return contributorTemplate(_.assign({avatarBlock}, templateData)) }