-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adds cron tab and handler functions
- Loading branch information
1 parent
5c8a942
commit 847c72b
Showing
8 changed files
with
296 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import config from '../config/config'; | ||
import { DiscordRoleUpdatedList, DiscordUserRole, env } from '../types/global.types'; | ||
import { generateDiscordBotJwt } from '../utils/generateJwt'; | ||
|
||
export const updateUserRoles = async (env: env, payload: DiscordUserRole[]): Promise<DiscordRoleUpdatedList> => { | ||
try { | ||
const url = config(env).DISCORD_BOT_API_URL; | ||
const token = await generateDiscordBotJwt(env); | ||
|
||
const response = await env.DISCORD_BOT.fetch(`${url}/roles?action=add-role`, { | ||
method: 'POST', | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(payload), | ||
}); | ||
if (!response.ok) { | ||
throw Error(`Role Update failed with status: ${response.status}`); | ||
} | ||
const data: DiscordRoleUpdatedList = await response.json(); | ||
return data; | ||
} catch (error) { | ||
console.error('Error while updating discord user roles'); | ||
throw error; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import config from '../config/config'; | ||
import { DiscordUserIdList, env } from '../types/global.types'; | ||
import { generateJwt } from '../utils/generateJwt'; | ||
|
||
export const getMissedUpdatesUsers = async (env: env) => { | ||
try { | ||
const url = config(env).RDS_BASE_API_URL; | ||
const token = await generateJwt(env); | ||
const response = await fetch(`${url}/tasks/users/discord?q=status:missed-updates`, { | ||
method: 'GET', | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
if (!response.ok) { | ||
throw new Error(`Fetch call to get user discord details failed with status: ${response.status}`); | ||
} | ||
|
||
const data: DiscordUserIdList = await response.json(); | ||
return data; | ||
} catch (error) { | ||
console.error('Error occurrent while fetching discord user details'); | ||
throw error; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
export const missedUpdatesUsersMock = { | ||
usersToAddRole: ['user1', 'user2'], | ||
tasks: 10, | ||
missedUpdatesTasks: 5, | ||
cursor: 'some-cursor', | ||
}; | ||
export const missedUpdatesUsersMockWithNoUsers = { | ||
usersToAddRole: [], | ||
tasks: 10, | ||
missedUpdatesTasks: 5, | ||
}; | ||
export const missedUpdatesUsersMockWithoutCursor = { | ||
usersToAddRole: ['user1', 'user2'], | ||
tasks: 10, | ||
missedUpdatesTasks: 5, | ||
}; | ||
|
||
export const updateRolesResponseMock = { | ||
userid: 'user1', | ||
roleid: '1', | ||
success: true, | ||
}; | ||
export const discordUserRoleMock = [ | ||
{ userid: 'user1', roleid: '1' }, | ||
{ userid: 'user2', roleid: '2' }, | ||
]; | ||
|
||
export const discordRoleUpdateResult = [ | ||
{ | ||
userid: '1', | ||
roleid: '2', | ||
success: true, | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { addMissedUpdatesRole } from '../../handlers/scheduledEventHandler'; | ||
import { updateUserRoles } from '../../services/discordBotServices'; | ||
import { getMissedUpdatesUsers } from '../../services/rdsBackendService'; | ||
import { | ||
missedUpdatesUsersMock, | ||
missedUpdatesUsersMockWithNoUsers, | ||
missedUpdatesUsersMockWithoutCursor, | ||
} from '../fixtures/missedRoleHandler'; | ||
|
||
jest.mock('.../../../../services/rdsBackendService', () => ({ | ||
getMissedUpdatesUsers: jest.fn(), | ||
})); | ||
jest.mock('.../../../../services/discordBotServices', () => ({ | ||
updateUserRoles: jest.fn(), | ||
})); | ||
describe('addMissedUpdatesRole', () => { | ||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should call getMissedUpdatesUsers and updateUserRoles when there are users to add role', async () => { | ||
(getMissedUpdatesUsers as jest.Mock) | ||
.mockResolvedValueOnce(missedUpdatesUsersMock) | ||
.mockResolvedValueOnce(missedUpdatesUsersMockWithoutCursor); | ||
await addMissedUpdatesRole({}); | ||
expect(getMissedUpdatesUsers).toHaveBeenCalledTimes(2); | ||
expect(updateUserRoles).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
it('should not call updateUserRoles when there are no users to add role', async () => { | ||
(getMissedUpdatesUsers as jest.Mock).mockResolvedValueOnce(missedUpdatesUsersMockWithNoUsers); | ||
|
||
await addMissedUpdatesRole({}); | ||
expect(getMissedUpdatesUsers).toHaveBeenCalledTimes(1); | ||
expect(updateUserRoles).toHaveBeenCalledTimes(0); | ||
}); | ||
|
||
it('should create chunks of userId and update roles multiple times when count is greater than 25', async () => { | ||
const mockValue: any = { ...missedUpdatesUsersMockWithoutCursor, usersToAddRole: new Array(75).fill('id') }; | ||
(getMissedUpdatesUsers as jest.Mock).mockResolvedValueOnce(mockValue); | ||
|
||
await addMissedUpdatesRole({}); | ||
expect(getMissedUpdatesUsers).toHaveBeenCalledTimes(1); | ||
expect(updateUserRoles).toHaveBeenCalledTimes(3); | ||
}); | ||
|
||
it('should handle errors', async () => { | ||
(getMissedUpdatesUsers as jest.Mock).mockRejectedValueOnce(new Error('Error fetching missed updates users')); | ||
const consoleSpy = jest.spyOn(console, 'error'); | ||
await addMissedUpdatesRole({}); | ||
expect(consoleSpy).toHaveBeenCalledWith('Error while adding missed updates roles'); | ||
}); | ||
|
||
it('should continue updating user roles even when a call fails', async () => { | ||
(updateUserRoles as jest.Mock).mockRejectedValueOnce(new Error('Error occurred')); | ||
const consoleSpy = jest.spyOn(console, 'error'); | ||
const mockValue: any = { ...missedUpdatesUsersMockWithoutCursor, usersToAddRole: new Array(75).fill('id') }; | ||
(getMissedUpdatesUsers as jest.Mock).mockResolvedValueOnce(mockValue); | ||
await addMissedUpdatesRole({}); | ||
expect(getMissedUpdatesUsers).toHaveBeenCalledTimes(1); | ||
expect(consoleSpy).toHaveBeenCalledTimes(1); | ||
expect(updateUserRoles).toHaveBeenCalledTimes(3); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import config from '../../config/config'; | ||
import { updateUserRoles } from '../../services/discordBotServices'; | ||
import { discordRoleUpdateResult, discordUserRoleMock } from '../fixtures/missedRoleHandler'; | ||
|
||
jest.mock('../../utils/generateJwt', () => ({ | ||
generateDiscordBotJwt: jest.fn().mockResolvedValueOnce('mocked-jwt-token'), | ||
})); | ||
describe('discordBotService', () => { | ||
describe('updateUserRoles', () => { | ||
let fetchSpy: jest.Mock<any, any, any>; | ||
beforeEach(() => { | ||
fetchSpy = jest.fn(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should make a successful API call and return the expected data', async () => { | ||
fetchSpy.mockResolvedValueOnce({ | ||
ok: true, | ||
status: 200, | ||
json: jest.fn().mockResolvedValueOnce(discordRoleUpdateResult), | ||
} as unknown as Response); | ||
const result = await updateUserRoles({ DISCORD_BOT: { fetch: fetchSpy } }, discordUserRoleMock); | ||
|
||
expect(fetchSpy).toHaveBeenCalledWith(`${config({}).DISCORD_BOT_API_URL}/roles?action=add-role`, { | ||
method: 'POST', | ||
headers: { | ||
Authorization: 'Bearer mocked-jwt-token', | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(discordUserRoleMock), | ||
}); | ||
expect(result).toEqual([...discordRoleUpdateResult]); | ||
}); | ||
|
||
it('should throw error when api call fails', async () => { | ||
fetchSpy.mockResolvedValueOnce({ | ||
ok: false, | ||
status: 400, | ||
} as unknown as Response); | ||
await expect(updateUserRoles({ DISCORD_BOT: { fetch: fetchSpy } }, [])).rejects.toThrow('Role Update failed with status: 400'); | ||
}); | ||
it('should handle unknown errors', async () => { | ||
const consoleSpy = jest.spyOn(console, 'error'); | ||
fetchSpy.mockRejectedValueOnce(new Error('Error occurred')); | ||
await expect(updateUserRoles({ DISCORD_BOT: { fetch: fetchSpy } }, [])).rejects.toThrow('Error occurred'); | ||
expect(consoleSpy).toHaveBeenCalledWith('Error while updating discord user roles'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import config from '../../config/config'; | ||
import { getMissedUpdatesUsers } from '../../services/rdsBackendService'; | ||
import { missedUpdatesUsersMock } from '../fixtures/missedRoleHandler'; | ||
|
||
jest.mock('../../utils/generateJwt', () => ({ | ||
generateJwt: jest.fn().mockResolvedValueOnce('mocked-jwt-token'), | ||
})); | ||
|
||
describe('rdsBackendService', () => { | ||
describe('updateUserRoles', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should make a successful API call and return the expected data', async () => { | ||
jest.spyOn(global, 'fetch').mockResolvedValueOnce({ | ||
ok: true, | ||
status: 200, | ||
json: jest.fn().mockResolvedValueOnce(missedUpdatesUsersMock), | ||
} as unknown as Response); | ||
const result = await getMissedUpdatesUsers({}); | ||
|
||
expect(fetch).toHaveBeenCalledWith(`${config({}).RDS_BASE_API_URL}/tasks/users/discord?q=status:missed-updates`, { | ||
method: 'GET', | ||
headers: { | ||
Authorization: 'Bearer mocked-jwt-token', | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
expect(result).toEqual({ ...missedUpdatesUsersMock }); | ||
}); | ||
|
||
it('should throw error when api call fails', async () => { | ||
jest.spyOn(global, 'fetch').mockResolvedValueOnce({ | ||
ok: false, | ||
status: 400, | ||
} as unknown as Response); | ||
await expect(getMissedUpdatesUsers({})).rejects.toThrow('Fetch call to get user discord details failed with status: 400'); | ||
}); | ||
|
||
it('should handle unknown errors', async () => { | ||
const consoleSpy = jest.spyOn(console, 'error'); | ||
jest.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Error occurred')); | ||
await expect(getMissedUpdatesUsers({})).rejects.toThrow('Error occurred'); | ||
expect(consoleSpy).toHaveBeenCalledWith('Error occurrent while fetching discord user details'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters