Skip to content

Commit

Permalink
chore: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
HasithDeAlwis committed Sep 5, 2024
1 parent fd09611 commit 9b2523d
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 53 deletions.
4 changes: 2 additions & 2 deletions apps/discord-to-github-bot/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const URLS = {
}

export const GITHUB_CONFIGS = {
OWNER: 'cuHacking',
OWNER: 'cuhacking',
REPO: '2025',
ISSUE_TEMPLATE_PATH: '/.github/ISSUE_TEMPLATE/',
ISSUE_TEMPLATE_PATH: '/.github/ISSUE_TEMPLATE',
}
15 changes: 10 additions & 5 deletions apps/discord-to-github-bot/src/controllers/issue-controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { gaurdAgainstInvalidGetIssueParams, getAllGitHubIssues } from '../services/get-issue-templates.js'
import { gaurdAgainstInvalidGetIssueParams, getAllGitHubIssues, getIssueTemplateNames } from '../services/get-issue-templates.js'
import { getAccessToken } from '../services/auth.js'

export async function getAllIssues(req: Record<string, any>) {
const params = req.query
if (!gaurdAgainstInvalidGetIssueParams(params)) {
return
return // SEND AN ERROR HERE --> TODO effective error handling!!
}

const { discordID } = params
const accessToken = getAccessToken(discordID)
const allIssues = getAllGitHubIssues(accessToken)
return allIssues
const accessToken = await getAccessToken(discordID)
// ADD LOGIC HERE TO GET A SINGLE ISSUE
const allIssues = await getAllGitHubIssues(accessToken)
if (!allIssues) // TODO Better error handling
return
// Get all the issue template names
const formatedIssues = getIssueTemplateNames(allIssues)
return formatedIssues
}
12 changes: 12 additions & 0 deletions apps/discord-to-github-bot/src/middleware/error-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { NextFunction, Request, Response } from 'express'
import type { HttpException } from '../exceptions/exception'
import { APP_ERROR_MESSAGE } from '../constants/constant'

function errorMiddleware(error: HttpException, request: Request, response: Response, _next: NextFunction) {
const status = error.status ? error.status : 500
const message = status === 500 ? APP_ERROR_MESSAGE.serverError : error.message
const errors = error.error
response.status(status).send({ status, message, error: errors })
}

export default errorMiddleware
7 changes: 4 additions & 3 deletions apps/discord-to-github-bot/src/routes/issue-routes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Router } from 'express'
import { getAllIssues } from '../controllers/issue-controller.js'
import { getAllIssues } from '../controllers/issue-controller'

const issueRouter = Router()

issueRouter.get('/issues', (req, res) => {
res.send(getAllIssues(req))
issueRouter.get('/issues', async (req, res) => {
const response = await getAllIssues(req)
res.status(200).send(response)
})

export default issueRouter
3 changes: 2 additions & 1 deletion apps/discord-to-github-bot/src/services/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function generateServerLink(discordChannelID: string) {
return `${URLS.DISCORD_URL}/channels/${discordChannelID}`
}

export function getAccessToken(_discordID: string): string {
export async function getAccessToken(_discordID: string): Promise<string> {
// The acutal funciton here would query the DB
return process.env.GITHUB_PERSONAL_ACCESS_TOKEN_FOR_CUHACKING ?? ''
}
18 changes: 13 additions & 5 deletions apps/discord-to-github-bot/src/services/get-issue-templates.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Octokit } from '@octokit/core'
import { GITHUB_CONFIGS } from '@src/constants.js'
import { GITHUB_CONFIGS } from '@src/constants'
import type { OctokitRepoContentResponse } from '@src/types/github-issue'

export async function getAllGitHubIssues(accessToken: string) {
if (!accessToken)
return
try {
const octokit = new Octokit({ auth: accessToken })
// Integration tests
const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
owner: GITHUB_CONFIGS.OWNER,
repo: GITHUB_CONFIGS.REPO,
Expand All @@ -15,27 +17,33 @@ export async function getAllGitHubIssues(accessToken: string) {
return response
}
catch {
throw new Error('An error')
throw new Error('AN ERROR') // TODO better error handling
}
}

export function gaurdAgainstInvalidGetIssueParams(obj: any): obj is { discordID: string } {
if (typeof obj !== 'object' || obj === null)
return false

return (
typeof obj === 'object'
&& obj !== null
&& typeof obj.discordID === 'string'
&& (obj.issueName === undefined || typeof obj.issueName === 'string')
)
}

export function getIssue(issueTemplate: string) {
return issueTemplate
}

export function getIssueTemplateNames(allIssues: GitHubAPIRepoContentResponse[]): string[] {
return allIssues.map((issue) => {
export function getIssueTemplateNames(allIssues: OctokitRepoContentResponse): string[] {
const issueData = allIssues.data

if (!Array.isArray(issueData))
return []

// a map of the issue names in an array
return issueData.map((issue) => {
return issue.name
})
}
Empty file.
10 changes: 3 additions & 7 deletions apps/discord-to-github-bot/src/types/github-issue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export interface GitHubIssue {
title: string
labels: string[]
body: string
milestone: number
assignees: string[]
}
import type { Endpoints } from '@octokit/types'

export type OctokitRepoContentResponse = Endpoints['GET /repos/{owner}/{repo}/contents/{path}']['response']
17 changes: 13 additions & 4 deletions apps/discord-to-github-bot/tests/integration/issue.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import request from 'supertest'
import app from '@src/server'
import { describe, expect, it } from 'vitest'
import { URLS } from '../../config'

describe('get-issue template integration tests', () => {
it('should send an object back of all issues', async () => {
const res = await request(app).get('/api/issues')
const url = res.headers.location
expect(url).toBe(``)
const res = await request(app).get('/api/issues?discordID=123')
expect(res.body).toStrictEqual([
'architectural-design-record--adr-.md',
'bug_report.md',
'feature-improvement.md',
'task.md',
])
})
it ('should return the content of a bug issue', async () => {
const res = await request(app).get('/api/issue?discordID=123&issueName=bug_report.md')
expect(res.body).toEqual(
'EXAMPLE OF A BUG REPORT CONTENT, INCOMPLETE FOR THE DEMO',
)
})
})
4 changes: 2 additions & 2 deletions apps/discord-to-github-bot/tests/unit/auth.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import process from 'node:process'
import { describe, expect, it, vi } from 'vitest'
import { describe, expect, it } from 'vitest'
import { generateOAuthLink, generateServerLink, getAccessToken } from '@services/auth'

const OAUTH_URL = `http://localhost:3333/api/auth/github?id=1193362882302320751`
const DISCORD_SERVER_URL = `https://discord.com/channels/1193362882302320751`
const DISCORD_SERVER_ID = '1193362882302320751'

describe('authentication tests', () => {
// We would have to mock data to do this
it('should generate an OAUTH link for the user to click on', () => {
const res = generateOAuthLink(DISCORD_SERVER_ID)
expect(res).toBe(OAUTH_URL)
Expand Down
43 changes: 21 additions & 22 deletions apps/discord-to-github-bot/tests/unit/issue.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { describe, expect, it } from 'vitest'
import { getAllIssues, getIssue, getIssueTemplateNames } from '@services/get-issue-templates'
import { getIssue, getIssueTemplateNames } from '@services/get-issue-templates'
import { gaurdAgainstInvalidIssues } from '@services/create-issue'

describe('retrieving issue tests', () => {
it('should recieve the name of all issue tempaltes', () => {
const res = getAllIssues()
expect(res).toBe(['architectural-design-record--adr-.md', 'bug_report.md', 'feature-improvement.md', 'task.md'])
})
it('should recieve the issue template for a Bug Report', () => {
const res = getIssue('bug_report.md')
expect(res.name).toBe('Bug Report')
Expand All @@ -29,23 +25,26 @@ describe('retrieving issue tests', () => {
})

it('should return an array with all the issue template names', () => {
const mockIssueTemplates = [
{
name: 'template-1.md',
content: 'content 1',
labels: ['label 1'],
},
{
name: 'template-2.md',
content: 'content 2',
labels: ['label 1', 'label 2'],
},
{
name: 'template-3.md',
content: 'content 3',
labels: ['label 3'],
},
]
const mockIssueTemplates = {
data:
[
{
name: 'template-1.md',
content: 'content 1',
labels: ['label 1'],
},
{
name: 'template-2.md',
content: 'content 2',
labels: ['label 1', 'label 2'],
},
{
name: 'template-3.md',
content: 'content 3',
labels: ['label 3'],
},
],
}
const res = getIssueTemplateNames(mockIssueTemplates)
expect(res).toStrictEqual(['template-1.md', 'template-2.md', 'template-3.md'])
})
Expand Down
4 changes: 2 additions & 2 deletions apps/discord-to-github-bot/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import path from 'node:path'
import { defineConfig } from 'vitest/config'
// TODO: refactor after monorepo migration
// see: https://vitest.dev/guide/workspace.html
const config = defineConfig({
test: {
include: ['tests/unit/**/*.ts'],
include: ['tests/unit/**/*.ts', 'tests/integration/**/*.ts'],
name: 'discord-to-github-bot',
environment: 'node',
alias: {
'@services/': new URL('./src/services/', import.meta.url).pathname,
'@src/': new URL('./src/', import.meta.url).pathname,
},
},
})
Expand Down

0 comments on commit 9b2523d

Please sign in to comment.