Skip to content

Commit bdbacf2

Browse files
Search using GitHub link in /issues api (#1665)
* feat : adds test to check if query string passed is github issue link * test : adds test for fetch issues by link * chore : adds dev flag * fix : adds await in fetch issue function * fix : adds dev query to test
1 parent 8453372 commit bdbacf2

File tree

4 files changed

+160
-3
lines changed

4 files changed

+160
-3
lines changed

controllers/issues.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const issuesService = require("../services/issuesService");
22
const tasks = require("../models/tasks");
33
const { SOMETHING_WENT_WRONG } = require("../constants/errorMessages");
4+
const githubService = require("../services/githubService");
45

56
/**
67
* Get the issues of the repo
@@ -10,9 +11,18 @@ const { SOMETHING_WENT_WRONG } = require("../constants/errorMessages");
1011

1112
const getIssues = async (req, res) => {
1213
try {
13-
const { q: queryString } = req.query;
14+
const { q: queryString, dev } = req.query;
1415
let issues = {};
15-
if (queryString) {
16+
const githubOrg = config.get("githubApi.org");
17+
const githubIssuerUrlPattern = new RegExp(`^https://github.com/${githubOrg}/.+/issues/\\d+$`);
18+
19+
if (githubIssuerUrlPattern.test(queryString) && dev === "true") {
20+
const url = new URL(queryString);
21+
const issueUrlPaths = url.pathname.split("/");
22+
const repositoryName = issueUrlPaths[2];
23+
const issueNumber = issueUrlPaths[4];
24+
issues.data = [await githubService.fetchIssuesById(repositoryName, issueNumber)];
25+
} else if (queryString) {
1626
const searchedIssues = await issuesService.searchOrgIssues(queryString);
1727
issues.data = searchedIssues?.data?.items ?? [];
1828
} else {

services/githubService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ const fetchIssuesById = async (repositoryName, issueId) => {
281281
logger.error(`GitHub API request failed. Status: ${res.status}, URL: ${url}`);
282282
return null;
283283
}
284-
return res.json();
284+
return await res.json();
285285
} catch (err) {
286286
logger.error(`Error while fetching issues: ${err}`);
287287
throw err;

test/fixtures/issues/issues.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const issuesData = {
2+
url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679",
3+
repository_url: "https://api.github.com/repos/Real-Dev-Squad/website-www",
4+
labels_url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679/labels{/name}",
5+
comments_url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679/comments",
6+
events_url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679/events",
7+
html_url: "https://github.com/Real-Dev-Squad/website-www/issues/679",
8+
id: 1921418442,
9+
node_id: "I_kwDOEGmlk85yhoTK",
10+
number: 679,
11+
title: "[Live-Site] - Create design doc for Analytics ",
12+
user: {
13+
login: "SanketDhabarde",
14+
id: 40385118,
15+
node_id: "MDQ6VXNlcjQwMzg1MTE4",
16+
avatar_url: "https://avatars.githubusercontent.com/u/40385118?v=4",
17+
gravatar_id: "",
18+
url: "https://api.github.com/users/SanketDhabarde",
19+
html_url: "https://github.com/SanketDhabarde",
20+
followers_url: "https://api.github.com/users/SanketDhabarde/followers",
21+
following_url: "https://api.github.com/users/SanketDhabarde/following{/other_user}",
22+
gists_url: "https://api.github.com/users/SanketDhabarde/gists{/gist_id}",
23+
starred_url: "https://api.github.com/users/SanketDhabarde/starred{/owner}{/repo}",
24+
subscriptions_url: "https://api.github.com/users/SanketDhabarde/subscriptions",
25+
organizations_url: "https://api.github.com/users/SanketDhabarde/orgs",
26+
repos_url: "https://api.github.com/users/SanketDhabarde/repos",
27+
events_url: "https://api.github.com/users/SanketDhabarde/events{/privacy}",
28+
received_events_url: "https://api.github.com/users/SanketDhabarde/received_events",
29+
type: "User",
30+
site_admin: false,
31+
},
32+
labels: [
33+
{
34+
id: 5236471172,
35+
node_id: "LA_kwDOEGmlk88AAAABOB41hA",
36+
url: "https://api.github.com/repos/Real-Dev-Squad/website-www/labels/live-site",
37+
name: "live-site",
38+
color: "FA3DCD",
39+
default: false,
40+
description: "",
41+
},
42+
],
43+
state: "open",
44+
locked: false,
45+
assignee: {
46+
login: "SanketDhabarde",
47+
id: 40385118,
48+
node_id: "MDQ6VXNlcjQwMzg1MTE4",
49+
avatar_url: "https://avatars.githubusercontent.com/u/40385118?v=4",
50+
gravatar_id: "",
51+
url: "https://api.github.com/users/SanketDhabarde",
52+
html_url: "https://github.com/SanketDhabarde",
53+
followers_url: "https://api.github.com/users/SanketDhabarde/followers",
54+
following_url: "https://api.github.com/users/SanketDhabarde/following{/other_user}",
55+
gists_url: "https://api.github.com/users/SanketDhabarde/gists{/gist_id}",
56+
starred_url: "https://api.github.com/users/SanketDhabarde/starred{/owner}{/repo}",
57+
subscriptions_url: "https://api.github.com/users/SanketDhabarde/subscriptions",
58+
organizations_url: "https://api.github.com/users/SanketDhabarde/orgs",
59+
repos_url: "https://api.github.com/users/SanketDhabarde/repos",
60+
events_url: "https://api.github.com/users/SanketDhabarde/events{/privacy}",
61+
received_events_url: "https://api.github.com/users/SanketDhabarde/received_events",
62+
type: "User",
63+
site_admin: false,
64+
},
65+
assignees: [
66+
{
67+
login: "SanketDhabarde",
68+
id: 40385118,
69+
node_id: "MDQ6VXNlcjQwMzg1MTE4",
70+
avatar_url: "https://avatars.githubusercontent.com/u/40385118?v=4",
71+
gravatar_id: "",
72+
url: "https://api.github.com/users/SanketDhabarde",
73+
html_url: "https://github.com/SanketDhabarde",
74+
followers_url: "https://api.github.com/users/SanketDhabarde/followers",
75+
following_url: "https://api.github.com/users/SanketDhabarde/following{/other_user}",
76+
gists_url: "https://api.github.com/users/SanketDhabarde/gists{/gist_id}",
77+
starred_url: "https://api.github.com/users/SanketDhabarde/starred{/owner}{/repo}",
78+
subscriptions_url: "https://api.github.com/users/SanketDhabarde/subscriptions",
79+
organizations_url: "https://api.github.com/users/SanketDhabarde/orgs",
80+
repos_url: "https://api.github.com/users/SanketDhabarde/repos",
81+
events_url: "https://api.github.com/users/SanketDhabarde/events{/privacy}",
82+
received_events_url: "https://api.github.com/users/SanketDhabarde/received_events",
83+
type: "User",
84+
site_admin: false,
85+
},
86+
],
87+
milestone: null,
88+
comments: 0,
89+
created_at: "2023-10-02T07:51:23Z",
90+
updated_at: "2023-10-02T07:58:02Z",
91+
closed_at: null,
92+
author_association: "NONE",
93+
active_lock_reason: null,
94+
body: "### Description\r\nCurrently, the live site has screen share functionality which will be helpful to host the session and users will join with different rules with specific access.\r\n\r\nNow as a part of analytics, we will show the number of users in the stream and the session analytics like the session time over, limit, etc.\r\n\r\nThe analytics can be in two forms, Chart and Table view, which will be more impactful.\r\n\r\n### UX\r\nhttps://www.figma.com/file/2VtPGJH61Qp0iarkKW6KTO/Live-Site-Detailed-Designs?type=design&node-id=0-1&mode=design&t=vJw7PtDFVzwKkdvc-0\r\n\r\n### Useful Reference\r\nhttps://www.100ms.live/docs/server-side/v2/api-reference/analytics/overview",
95+
reactions: {
96+
url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679/reactions",
97+
total_count: 0,
98+
"+1": 0,
99+
"-1": 0,
100+
laugh: 0,
101+
hooray: 0,
102+
confused: 0,
103+
heart: 0,
104+
rocket: 0,
105+
eyes: 0,
106+
},
107+
timeline_url: "https://api.github.com/repos/Real-Dev-Squad/website-www/issues/679/timeline",
108+
performed_via_github_app: null,
109+
state_reason: null,
110+
score: 1,
111+
};
112+
113+
const issuesHtmlUrl = "https://github.com/Real-Dev-Squad/website-www/issues/679";
114+
module.exports = { issuesData, issuesHtmlUrl };

test/integration/issues.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const chai = require("chai");
2+
const sinon = require("sinon");
3+
const { expect } = chai;
4+
const chaiHttp = require("chai-http");
5+
const app = require("../../server");
6+
const cleanDb = require("../utils/cleanDb");
7+
const githubService = require("../../services/githubService");
8+
const issuesMockData = require("../fixtures/issues/issues");
9+
10+
chai.use(chaiHttp);
11+
12+
describe("Issues", function () {
13+
afterEach(async function () {
14+
sinon.restore();
15+
await cleanDb();
16+
});
17+
18+
describe("GET /issues fetch github issues", function () {
19+
it("Should return issue when valid github page url is passed", async function () {
20+
const fetchIssuesByIdStub = sinon.stub(githubService, "fetchIssuesById").resolves(issuesMockData.issuesData);
21+
const res = await chai.request(app).get("/issues").query({ q: issuesMockData.issuesHtmlUrl, dev: true });
22+
expect(res).to.have.status(200);
23+
expect(fetchIssuesByIdStub.calledOnce).to.be.equal(true);
24+
expect(res.body.message).to.equal("Issues returned successfully!");
25+
expect(res.body.issues).to.deep.equal([issuesMockData.issuesData]);
26+
});
27+
it("Should not call fetch issues by id function when random string is passed", async function () {
28+
const fetchIssuesByIdSpy = sinon.spy(githubService, "fetchIssuesById");
29+
await chai.request(app).get("/issues").query({ q: "abc+def" });
30+
expect(fetchIssuesByIdSpy.calledOnce).to.be.equal(false);
31+
});
32+
});
33+
});

0 commit comments

Comments
 (0)