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))
}