Skip to content

Commit 42b24d2

Browse files
authored
fix: trim whitespace in user handling functions and update tests (#792)
1 parent 0705009 commit 42b24d2

6 files changed

Lines changed: 67 additions & 3 deletions

File tree

src/config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ export const config = {
99
return parseInt(process.env.EXIT_CODE_ON_MISMATCH ?? '0') || 0
1010
},
1111
get ignoredUsers(): string[] {
12-
return process.env.IGNORED_USERS?.toLowerCase().split(',') ?? []
12+
return (
13+
process.env.IGNORED_USERS?.toLowerCase()
14+
.split(',')
15+
.map((user) => user.trim()) ?? []
16+
)
1317
},
1418
get githubPrivateKey(): string {
1519
return Buffer.from(process.env.GITHUB_PRIVATE_KEY, 'base64').toString('utf-8')

src/github.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export async function getGithubUsersFromGithub(): Promise<Set<string>> {
4949
export function formatUserList(users): Set<string> {
5050
return new Set(
5151
users
52-
.map((user) => user.login?.toLowerCase())
52+
.map((user) => user.login?.trim().toLowerCase())
5353
.flat()
5454
.filter(Boolean),
5555
)
@@ -83,6 +83,7 @@ export async function addUsersToGitHubOrg(users: Set<string>): Promise<Operation
8383

8484
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
8585
export async function addUserToGitHubOrg(user: string): Promise<{ error: OperationError } | boolean> {
86+
user = user.trim()
8687
const octokit = mod.getAuthenticatedOctokit()
8788
if (config.ignoredUsers.includes(user.toLowerCase())) {
8889
console.log(`Ignoring add for ${user}`)
@@ -126,6 +127,7 @@ export async function removeUsersFromGitHubOrg(users: Set<string>): Promise<Oper
126127

127128
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
128129
export async function removeUserFromGitHubOrg(user: string): Promise<{ error: OperationError } | boolean> {
130+
user = user.trim()
129131
const octokit = mod.getAuthenticatedOctokit()
130132
if (config.ignoredUsers.includes(user.toLowerCase())) {
131133
console.log(`Ignoring remove for ${user}`)

src/google.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function formatUserList(users): Set<string> {
4545
return new Set(
4646
users
4747
.filter((user) => !user.suspended && !user.archived)
48-
.map((user) => user.customSchemas?.Accounts?.github?.map((account) => account.value?.toLowerCase()))
48+
.map((user) => user.customSchemas?.Accounts?.github?.map((account) => account.value?.trim().toLowerCase()))
4949
.flat()
5050
.filter(Boolean),
5151
)

tests/config.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ describe('ignoredUsers', () => {
6464
process.env.IGNORED_USERS = 'user1,user2,user3,USER4'
6565
expect(mod.config.ignoredUsers).toMatchSnapshot()
6666
})
67+
it('getIgnoredUsers trims whitespace around entries', () => {
68+
process.env.IGNORED_USERS = ' user1, user2 ,user3 '
69+
expect(mod.config.ignoredUsers).toEqual(['user1', 'user2', 'user3'])
70+
})
6771
})
6872

6973
describe('githubPrivateKey', () => {

tests/github.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,48 @@ describe('github integration', () => {
182182
const response = [{ login: 'chrisns' }, { login: 'chrisns' }, { login: 'foo' }, {}]
183183
return expect(mod.formatUserList(response)).toEqual(new Set(['chrisns', 'foo']))
184184
})
185+
186+
it('formatUserList trims leading and trailing whitespace from logins', () => {
187+
const response = [{ login: ' chrisns' }, { login: 'foo ' }, { login: ' bar ' }]
188+
return expect(mod.formatUserList(response)).toEqual(new Set(['chrisns', 'foo', 'bar']))
189+
})
190+
191+
it('addUserToGitHubOrg trims whitespace before checking ignored users', () => {
192+
jest.spyOn(config, 'ignoredUsers', 'get').mockReturnValue(['foo'])
193+
return expect(mod.addUserToGitHubOrg(' foo ')).resolves.toBe(false)
194+
})
195+
196+
it('addUserToGitHubOrg trims whitespace before looking up the username', async () => {
197+
const fakeOctokit = {
198+
orgs: {
199+
createInvitation: jest.fn().mockResolvedValue(true),
200+
},
201+
}
202+
jest.spyOn(config, 'githubOrg', 'get').mockReturnValue('myorg')
203+
const getUserIdSpy = jest.spyOn(mod, 'getUserIdFromUsername').mockResolvedValue(123)
204+
// @ts-expect-error mock service isn't a complete implementation, so being lazy and just doing the bare minimum
205+
jest.spyOn(mod, 'getAuthenticatedOctokit').mockReturnValue(fakeOctokit)
206+
const result = await mod.addUserToGitHubOrg(' foo ')
207+
expect(result).toBe(true)
208+
expect(getUserIdSpy).toHaveBeenCalledWith('foo')
209+
})
210+
211+
it('removeUserFromGitHubOrg trims whitespace before checking ignored users', () => {
212+
jest.spyOn(config, 'ignoredUsers', 'get').mockReturnValue(['foo'])
213+
return expect(mod.removeUserFromGitHubOrg(' foo ')).resolves.toBe(false)
214+
})
215+
216+
it('removeUserFromGitHubOrg trims whitespace before calling the API', async () => {
217+
const fakeOctokit = {
218+
orgs: {
219+
removeMembershipForUser: jest.fn().mockResolvedValue(true),
220+
},
221+
}
222+
jest.spyOn(config, 'githubOrg', 'get').mockReturnValue('myorg')
223+
// @ts-expect-error mock service isn't a complete implementation, so being lazy and just doing the bare minimum
224+
jest.spyOn(mod, 'getAuthenticatedOctokit').mockReturnValue(fakeOctokit)
225+
const result = await mod.removeUserFromGitHubOrg(' foo ')
226+
expect(result).toBe(true)
227+
expect(fakeOctokit.orgs.removeMembershipForUser).toHaveBeenCalledWith(expect.objectContaining({ username: 'foo' }))
228+
})
185229
})

tests/google.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,14 @@ describe('google integration', () => {
8282
const result = mod.formatUserList(users)
8383
expect(result).toEqual(new Set(['active']))
8484
})
85+
86+
it('formatUserList trims leading and trailing whitespace from handles', () => {
87+
const users = [
88+
{ customSchemas: { Accounts: { github: [{ value: ' chrisns' }] } }, suspended: false, archived: false },
89+
{ customSchemas: { Accounts: { github: [{ value: 'foo ' }] } }, suspended: false, archived: false },
90+
{ customSchemas: { Accounts: { github: [{ value: ' bar ' }] } }, suspended: false, archived: false },
91+
]
92+
const result = mod.formatUserList(users)
93+
expect(result).toEqual(new Set(['chrisns', 'foo', 'bar']))
94+
})
8595
})

0 commit comments

Comments
 (0)