Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds util functions and changes configs #25

Merged
merged 8 commits into from
Dec 12, 2023
Merged
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';
heyrandhir marked this conversation as resolved.
Show resolved Hide resolved
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,
heyrandhir marked this conversation as resolved.
Show resolved Hide resolved
},
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 * * *" ]
heyrandhir marked this conversation as resolved.
Show resolved Hide resolved

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