Skip to content

Commit

Permalink
Adds util functions and changes configs (#25)
Browse files Browse the repository at this point in the history
* fix: add npm test

* feat: mocks jwt sign function

* fix: lint issue

* feat: add pull request template

* feat: adds config and util functions
  • Loading branch information
Ajeyakrishna-k authored Dec 12, 2023
1 parent 94cbd5c commit 2486813
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 37 deletions.
37 changes: 24 additions & 13 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { env } from '../types/global.types';
import { MISSED_UPDATES_DEVELOPMENT_ROLE_ID, MISSED_UPDATES_PROD_ROLE_ID, MISSED_UPDATES_STAGING_ROLE_ID } from '../constants/commons';
import { RDS_BASE_API_URL, RDS_BASE_DEVELOPMENT_API_URL, RDS_BASE_STAGING_API_URL } from '../constants/urls';
import { env, environment } from '../types/global.types';

export const handleConfig = (env: env) => {
let baseUrl: string;
if (env.CURRENT_ENVIRONMENT) {
if (env.CURRENT_ENVIRONMENT.toLowerCase() === 'production') {
baseUrl = 'https://api.realdevsquad.com';
} else {
baseUrl = 'https://staging-api.realdevsquad.com';
}
} else {
baseUrl = 'https://staging-api.realdevsquad.com';
}
return { baseUrl };
const config = (env: env) => {
const environment: environment = {
production: {
RDS_BASE_API_URL: RDS_BASE_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_PROD_ROLE_ID,
},
staging: {
RDS_BASE_API_URL: RDS_BASE_STAGING_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_STAGING_ROLE_ID,
},
default: {
RDS_BASE_API_URL: RDS_BASE_DEVELOPMENT_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_DEVELOPMENT_ROLE_ID,
},
};

return environment[env.CURRENT_ENVIRONMENT] || environment.default;
};
export default config;
3 changes: 3 additions & 0 deletions src/constants/commons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const MISSED_UPDATES_PROD_ROLE_ID = '1183553844811153458';
export const MISSED_UPDATES_STAGING_ROLE_ID = '1183553844811153458';
export const MISSED_UPDATES_DEVELOPMENT_ROLE_ID = '1181214205081296896';
7 changes: 7 additions & 0 deletions src/constants/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const RDS_BASE_API_URL = 'https://api.realdevsquad.com';
export const RDS_BASE_STAGING_API_URL = 'https://staging-api.realdevsquad.com';
export const RDS_BASE_DEVELOPMENT_API_URL = 'http://localhost:3000'; // If needed, modify the URL to your local API server run through ngrok

export const DISCORD_BOT_API_URL = 'env';
export const DISCORD_BOT_STAGING_API_URL = '';
export const DISCORD_BOT_DEVELOPMENT_API_URL = '';
35 changes: 35 additions & 0 deletions src/tests/arrayUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { chunks } from '../utils/arrayUtils';

describe('chunks function', () => {
it('should return an empty array if size is less than 1', () => {
expect(chunks([1, 2, 3], 0)).toEqual([]);
});

it('should return an empty array if the input array is empty', () => {
expect(chunks([], 2)).toEqual([]);
});

it('should split the array into chunks of the specified size', () => {
const inputArray = [1, 2, 3, 4, 5, 6];
const size = 2;
const expectedResult = [
[1, 2],
[3, 4],
[5, 6],
];
expect(chunks(inputArray, size)).toEqual(expectedResult);
});

it('should split the array into chunks of size 1 if size is not specified', () => {
const inputArray = [1, 2, 3, 4, 5, 6];
const expectedResult = [[1], [2], [3], [4], [5], [6]];
expect(chunks(inputArray)).toEqual(expectedResult);
});

it('should not modify the original array', () => {
const inputArray = [1, 2, 3, 4, 5, 6];
const size = 2;
chunks(inputArray, size);
expect(inputArray).toEqual(inputArray);
});
});
69 changes: 48 additions & 21 deletions src/tests/generateJwt.test.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
import jwt from '@tsndr/cloudflare-worker-jwt';

import { generateJwt } from '../utils/generateJwt';
import { generateDiscordBotJwt, generateJwt } from '../utils/generateJwt';
import { privateKey } from './config/keys';

describe('Mock test', () => {
describe('Generate Jwt', () => {
let signSpy: jest.SpyInstance<Promise<string>>;
beforeEach(() => {
signSpy = jest.spyOn(jwt, 'sign');
});
afterEach(() => {
signSpy.mockReset();
});
test('Generate JWT function works', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(authToken).not.toBeUndefined();
});
test('Should call sign method', async () => {
signSpy.mockResolvedValue('Hello');
await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(signSpy).toBeCalledTimes(1);
});
test('Should return promise without await', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(authToken).toBeInstanceOf(Promise);
describe('For Rds Backend', () => {
test('Generate JWT function works', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(authToken).not.toBeUndefined();
});
test('Should call sign method', async () => {
signSpy.mockResolvedValue('Hello');
await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(signSpy).toBeCalledTimes(1);
});
test('Should return promise without await', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey });
expect(authToken).toBeInstanceOf(Promise);
});
test('Throws an error if generation fails', async () => {
signSpy.mockRejectedValue('Error');
await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey }).catch((err) => {
expect(err).toBeInstanceOf(Error);
expect(err.message).toEqual('Error in generating the auth token');
});
});
});
test('Throws an error if generation fails', async () => {
signSpy.mockRejectedValue('Error');
await generateJwt({ CRON_JOB_PRIVATE_KEY: privateKey }).catch((err) => {
expect(err).toBeInstanceOf(Error);
expect(err.message).toEqual('Error in generating the auth token');

describe('For Discord Bot', () => {
test('Generate JWT function works', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = await generateDiscordBotJwt({ DISCORD_BOT_PRIVATE_KEY: privateKey });
expect(authToken).not.toBeUndefined();
});
test('Should call sign method', async () => {
signSpy.mockResolvedValue('Hello');
await generateDiscordBotJwt({ DISCORD_BOT_PRIVATE_KEY: privateKey });
expect(signSpy).toBeCalledTimes(1);
});
test('Should return promise without await', async () => {
signSpy.mockResolvedValue('Hello');
const authToken = generateDiscordBotJwt({ DISCORD_BOT_PRIVATE_KEY: privateKey });
expect(authToken).toBeInstanceOf(Promise);
});
test('Throws an error if generation fails', async () => {
signSpy.mockRejectedValue('Error');
await generateDiscordBotJwt({ DISCORD_BOT_PRIVATE_KEY: privateKey }).catch((err) => {
expect(err).toBeInstanceOf(Error);
expect(err.message).toEqual('Error in generating the auth token');
});
});
});
});
28 changes: 27 additions & 1 deletion src/types/global.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
export type env = {
[key: string]: string;
[key: string]: any;
};

export type environment = {
[key: string]: variables;
};
export type variables = {
RDS_BASE_API_URL: string;
DISCORD_BOT_API_URL: string;
MISSED_UPDATES_ROLE_ID: string;
};

export type NicknameUpdateResponseType = {
Expand All @@ -10,3 +19,20 @@ export type NicknameUpdateResponseType = {
unsuccessfulNicknameUpdates: number;
};
};

export type DiscordUserIdList = {
usersToAddRole: string[];
tasks: number;
missedUpdatesTasks: number;
cursor: string;
};

export interface DiscordUserRole {
userid: string;
roleid: string;
}
export type DiscordRoleUpdatedList = {
userid: string;
roleid: string;
success: boolean;
};
19 changes: 19 additions & 0 deletions src/utils/arrayUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Creates an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.
* description credit: https://lodash.com/docs/4.17.15#chunk
* source code inspiration https://youmightnotneed.com/lodash#chunk
* @param {array}: array to be splitted into groups
* @param {size}: size of array groups
* @return {array}: array of arrays of elements split into groups the length of size.
*/
export const chunks = (array: any[], size: number = 1): any[][] => {
if (!Array.isArray(array) || size < 1) {
return [];
}
const temp = [...array];
const result = [];
while (temp.length) {
result.push(temp.splice(0, size));
}
return result;
};
15 changes: 15 additions & 0 deletions src/utils/generateJwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,18 @@ export const generateJwt = async (env: env) => {
throw new Error('Error in generating the auth token');
}
};

export const generateDiscordBotJwt = async (env: env) => {
try {
const authToken = await jwt.sign(
{
exp: Math.floor(Date.now() / 1000) + 2,
},
env.DISCORD_BOT_PRIVATE_KEY,
{ algorithm: 'RS256' },
);
return authToken;
} catch (err) {
throw new Error('Error in generating the auth token');
}
};
9 changes: 7 additions & 2 deletions wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ main = "src/worker.ts"
compatibility_date = "2023-07-17"



[env.staging]
kv_namespaces = [
{ binding = "CronJobsTimestamp", id = "509cd24483a24ddcb79f85f657274508" }
]
services = [
{ binding = "DISCORD_BOT", service = "discord-slash-commands", environment = "staging" }
]

[env.production]
kv_namespaces = [
{ binding = "CronJobsTimestamp", id = "3a10f726c95d4afea9dee5fd00f029b9" }
]
services = [
{ binding = "DISCORD_BOT", service = "discord-slash-commands", environment = "production" }
]

[triggers]
crons = ["0 */4 * * *", "0 */6 * * *"]
crons = ["0 */4 * * *", "0 */6 * * *","0 */12 * * *" ]

# # Durable Object binding - For more information: https://developers.cloudflare.com/workers/runtime-apis/durable-objects
# [[durable_objects]]
Expand Down

0 comments on commit 2486813

Please sign in to comment.