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

Add pullrequests/:id route to fetch PRs of a given id of user using GitHub API #90

Merged
merged 12 commits into from
Dec 3, 2020
Merged
5 changes: 5 additions & 0 deletions config/custom-environment-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ module.exports = {
__format: 'boolean'
},

githubApi: {
baseUrl: 'GITHUB_API_BASE_URL',
org: 'GITHUB_ORGANISATION'
},

githubOauth: {
clientId: 'GITHUB_CLIENT_ID',
clientSecret: 'GITHUB_CLIENT_SECRET'
Expand Down
5 changes: 5 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ module.exports = {
enableFileLogs: true,
enableConsoleLogs: false,

githubApi: {
baseUrl: 'https://api.github.com',
org: 'Real-Dev-Squad'
},

githubOauth: {
clientId: '<clientId>',
clientSecret: '<clientSecret>'
Expand Down
48 changes: 48 additions & 0 deletions controllers/pullRequestsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const logger = require('../utils/logger')
const githubService = require('../services/githubService')

/**
* Collects all pull requests and sends only required data for each pull request
*
* @param req {Object} - Express request object
* @param res {Object} - Express response object
*/

const getPRdetails = async (req, res) => {
try {
const { data } = await githubService.fetchPRsByUser(req.params.id)

if (data.total_count) {
const allPRs = []
data.items.forEach(({ title, html_url: url, state, created_at: createdAt, updated_at: updatedAt, draft, labels, assignees }) => {
const allAssignees = assignees.map(object => object.login)
const allLabels = labels.map(object => object.name)
allPRs.push({
title,
state,
createdAt,
updatedAt,
url,
readyForReview: state === 'closed' ? false : !draft,
labels: allLabels,
assignees: allAssignees
})
})
return res.json({
message: 'Pull requests returned successfully!',
pullRequests: allPRs
})
}
return res.json({
message: 'No pull requests found!',
pullRequests: []
})
} catch (err) {
logger.error(`Error while processing pull requests: ${err}`)
return res.boom.badImplementation('Something went wrong please contact admin')
}
}

module.exports = {
getPRdetails
}
1 change: 1 addition & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ app.use('/healthcheck', require('./healthCheck.js'))
app.use('/auth', require('./auth.js'))
app.use('/users', require('./users.js'))
app.use('/members', require('./members.js'))
app.use('/pullrequests', require('./pullrequests.js'))

module.exports = app
37 changes: 37 additions & 0 deletions routes/pullrequests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const express = require('express')
const router = express.Router()
const pullRequestController = require('../controllers/pullRequestsController')

/**
* @swagger
* /pullrequests/:id:
* get:
* summary: Pull Requests by a user in Real Dev Squad
* tags:
* - Pull Requests
* responses:
* 200:
* description: Pull Requests
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: Pull requests returned successfully!
* pullRequests:
* type: array
* items:
* $ref: '#/components/schemas/pullRequests'
* 500:
* description: badImplementation
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/errors/badImplementation'
*/

router.get('/:id', pullRequestController.getPRdetails)

module.exports = router
31 changes: 31 additions & 0 deletions services/githubService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const logger = require('../utils/logger')
const config = require('config')
const { fetch } = require('../utils/fetch')
const { fetchUser } = require('../models/users')

/**
* Fetches the pull requests in Real-Dev-Squad by user using GitHub API
*
* @param req {Object} - Express request object
* @param res {Object} - Express response object
*/

const fetchPRsByUser = async (id) => {
try {
const { user } = await fetchUser(id)
const url = `${config.get('githubApi.baseUrl')}/search/issues?q=org:${config.get('githubApi.org')}+author:${user.github_id}+type:pr`
return fetch(url, 'get', null, null, null, {
auth: {
username: config.get('githubOauth.clientId'),
password: config.get('githubOauth.clientSecret')
}
})
} catch (err) {
logger.error(`Error while fetching pull requests: ${err}`)
throw err
}
}

module.exports = {
fetchPRsByUser
}
6 changes: 4 additions & 2 deletions lib/fetch.js → utils/fetch.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const axios = require('axios')
const logger = require('../utils/logger')
const logger = require('./logger')

/**
* Used for network calls
Expand Down Expand Up @@ -29,4 +29,6 @@ const fetch = async (url, method = 'get', params = null, data = null, headers =
}
}

module.exports = fetch
module.exports = {
fetch
}
31 changes: 31 additions & 0 deletions utils/swaggerDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,37 @@ const swaggerOptions = {
}
}
},
pullRequests: {
type: 'object',
properties: {
title: {
type: 'string'
},
url: {
type: 'string'
},
state: {
type: 'string'
},
createdAt: {
type: 'string'
},
updatedAt: {
type: 'string'
},
readyForReview: {
type: 'boolean'
},
labels: {
type: 'array',
items: []
},
assignees: {
type: 'array',
items: []
}
}
},
users: {
type: 'object',
properties: {
Expand Down