Skip to content

Commit a55cd28

Browse files
committed
feat: getGithubReleaseStatus public api and tests
1 parent ca40a5f commit a55cd28

File tree

7 files changed

+199
-5
lines changed

7 files changed

+199
-5
lines changed

src/api/getGithubReleaseStatus.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Refer https://json-schema.org/understanding-json-schema/index.html
2+
import {FIELD_RELEASE_ID, RELEASE_DETAILS_TABLE} from "../constants.js";
3+
import db from "../db.js";
4+
5+
const schema = {
6+
schema: {
7+
querystring: {
8+
type: 'object',
9+
required: ['owner', "repo", "tag"],
10+
properties: {
11+
owner: {
12+
type: 'string',
13+
minLength: 1,
14+
maxLength: 256
15+
}, repo: {
16+
type: 'string',
17+
minLength: 1,
18+
maxLength: 256
19+
}, tag: {
20+
type: 'string',
21+
minLength: 1,
22+
maxLength: 256
23+
}
24+
}
25+
},
26+
response: {
27+
200: { //HTTP_STATUS_CODES.OK
28+
type: 'object',
29+
required: ['status', 'errors'],
30+
properties: {
31+
status: {type: 'string'},
32+
errors: {type: 'array', "items": {"type": "string"}},
33+
published: {type: 'boolean'},
34+
githubIssue: {type: 'string'},
35+
lastUpdatedDateUTC: {type: 'number'}
36+
}
37+
}
38+
}
39+
}
40+
};
41+
42+
export function getGetGithubReleaseStatusSchema() {
43+
return schema;
44+
}
45+
46+
export async function getGithubReleaseStatus(request, _reply) {
47+
// ?owner=${release.owner}&repo=${release.repo}&tag=${release.tag}
48+
const owner = request.query.owner;
49+
const repo = request.query.repo;
50+
const tag = request.query.tag;
51+
const releaseRef = `${owner}/${repo}/${tag}`;
52+
const queryObj = {};
53+
queryObj[FIELD_RELEASE_ID] = releaseRef;
54+
let existingRelease = await db.getFromIndex(RELEASE_DETAILS_TABLE, queryObj);
55+
if (!existingRelease.isSuccess) {
56+
// unexpected error
57+
throw new Error("Error getting release details from db: " + releaseRef);
58+
}
59+
existingRelease = existingRelease.documents.length === 1 ? existingRelease.documents[0] : null;
60+
const response = {
61+
status: "NO_SUCH_RELEASE",
62+
errors: [`Release not found. IF this is a recent release, please wait for 1 minute before checking again.`]
63+
};
64+
if (existingRelease) {
65+
response.published = existingRelease.published || false;
66+
response.status = existingRelease.status;
67+
response.errors = existingRelease.errors;
68+
response.githubIssue = "" + existingRelease.githubIssue;
69+
response.lastUpdatedDateUTC = existingRelease.lastUpdatedDateUTC;
70+
}
71+
return response;
72+
}

src/api/publishGithubRelease.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ async function _UpdateReleaseInfo(release, existingReleaseInfo) {
337337
let {documentId, isSuccess } = await db.put(RELEASE_DETAILS_TABLE, releaseInfo);
338338
releaseInfo.documentId = documentId;
339339
console.log(`Putting release ${releaseRef} details to db success: ${isSuccess}, documentId: ${documentId}`);
340-
return await _getReleaseInfo(release);
340+
return await _getReleaseInfo(release);
341341
}
342342
} catch (e) {
343343
console.error("Error while putting error status of release. ", e);

src/server.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {getPublishGithubReleaseSchema, publishGithubRelease} from "./api/publish
3030
import path from 'path';
3131
import { fileURLToPath } from 'url';
3232
import {initGitHubClient} from "./github.js";
33+
import {getGetGithubReleaseStatusSchema, getGithubReleaseStatus} from "./api/getGithubReleaseStatus.js";
3334

3435
const __filename = fileURLToPath(import.meta.url);
3536
const __dirname = path.dirname(__filename);
@@ -89,6 +90,12 @@ server.get('/publishGithubRelease', getPublishGithubReleaseSchema(), function (r
8990
return publishGithubRelease(request, reply);
9091
});
9192

93+
// public getGithubReleaseStatus api
94+
addUnAuthenticatedAPI('/getGithubReleaseStatus');
95+
server.get('/getGithubReleaseStatus', getGetGithubReleaseStatusSchema(), function (request, reply) {
96+
return getGithubReleaseStatus(request, reply);
97+
});
98+
9299
// An authenticated version of the hello api
93100
server.get('/helloAuth', getHelloSchema(), function (request, reply) {
94101
return hello(request, reply);

src/www/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
5-
<title>Hello HTML</title>
5+
<title>phcode.dev Extension Publish</title>
66
</head>
77
<body>
8-
Hello World
8+
phcode.dev extension publish services.
99
</body>
1010
</html>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*global describe, it*/
2+
import mockedFunctions from "../setupMocks.js";
3+
import * as chai from 'chai';
4+
import {getGithubReleaseStatus, getGetGithubReleaseStatusSchema} from "../../../src/api/getGithubReleaseStatus.js";
5+
import {getSimpleGetReply, getSimpleGETRequest} from '../data/simple-request.js';
6+
import Ajv from "ajv";
7+
import db from "../../../src/db.js";
8+
9+
export const AJV = new Ajv();
10+
11+
12+
let expect = chai.expect;
13+
14+
describe('unit Tests for getGithubReleaseStatus api', function () {
15+
function _getRequest(owner="owner", repo ="repo", tag= "tag") {
16+
let request = getSimpleGETRequest();
17+
request.query.owner = owner;
18+
request.query.repo = repo;
19+
request.query.tag = tag;
20+
return request;
21+
}
22+
23+
it('should getGithubReleaseStatus return no such release if no release', async function () {
24+
let helloResponse = await getGithubReleaseStatus(_getRequest(), getSimpleGetReply());
25+
expect(helloResponse).eql({
26+
"errors": [
27+
"Release not found. IF this is a recent release, please wait for 1 minute before checking again."
28+
],
29+
"status": "NO_SUCH_RELEASE"
30+
});
31+
});
32+
33+
it('should getGithubReleaseStatus return existing release details', async function () {
34+
db.getFromIndex = function (_tableName) {
35+
return {
36+
isSuccess: true,
37+
documents: [{
38+
published: false,
39+
status: "PROCESSING",
40+
errors: ["oops"],
41+
githubIssue: "5",
42+
lastUpdatedDateUTC: 1234
43+
}]};
44+
};
45+
let helloResponse = await getGithubReleaseStatus(_getRequest(), getSimpleGetReply());
46+
expect(helloResponse).eql({
47+
"errors": [
48+
"oops"
49+
],
50+
"githubIssue": "5",
51+
"lastUpdatedDateUTC": 1234,
52+
"published": false,
53+
"status": "PROCESSING"
54+
});
55+
});
56+
57+
it('should validate schemas for sample request/responses', async function () {
58+
let request = _getRequest();
59+
// request
60+
const requestValidator = AJV.compile(getGetGithubReleaseStatusSchema().schema.querystring);
61+
expect(requestValidator(request.query)).to.be.true;
62+
// response
63+
const successResponseValidator = AJV.compile(getGetGithubReleaseStatusSchema().schema.response["200"]);
64+
let response = await getGithubReleaseStatus(_getRequest(), getSimpleGetReply());
65+
expect(successResponseValidator(response)).to.be.true;
66+
});
67+
68+
it('should throw if db non success getGithubReleaseStatus', async function () {
69+
db.getFromIndex = function (_tableName) {
70+
return {isSuccess: false};
71+
};
72+
let error;
73+
try{
74+
await getGithubReleaseStatus(_getRequest(), getSimpleGetReply());
75+
} catch(e){
76+
error = e;
77+
}
78+
expect(error).to.exist;
79+
});
80+
});

test/unit/api/publishGithubRelease.spec.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,33 @@ describe('unit Tests for publishGithubRelease api', function () {
4242
S3.getObject = _getObject;
4343
});
4444

45+
let documents = {}, docID = 0;
4546
beforeEach(function () {
47+
documents = {};
4648
request = getSimpleGETRequest();
4749
reply = getSimpleGetReply();
4850
request.query.releaseRef = "org/repo:refs/tags/gitTag";
49-
db.getFromIndex = function (_tableName) {
51+
db.put = function (tableName, document) {
52+
let newDocID = "" + docID++;
53+
documents[tableName + ":" + newDocID] = document;
54+
return {isSuccess: true, documentId: newDocID};
55+
};
56+
db.getFromIndex = function (tableName, queryObject) {
57+
let keys = Object.keys(documents);
58+
let foundDocs =[];
59+
for(let key of keys){
60+
if(key.startsWith(tableName+":")){
61+
let doc = documents[key];
62+
let qKeys = Object.keys(queryObject);
63+
for (let qkey of qKeys){
64+
if(doc[qkey] === queryObject[qkey]){
65+
foundDocs.push(doc);
66+
}
67+
}
68+
}
69+
}
5070
return {isSuccess: true,
51-
documents:[]
71+
documents:foundDocs
5272
};
5373
};
5474
db.query = function () {

test/unit/setupMocks.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ async function githubRequestFnMock(url, options) {
2929
}
3030
throw {status: 404};
3131
}
32+
if(url.startsWith("POST /repos/") && url.endsWith("/issues") ){ // issue related api
33+
return {
34+
data: {
35+
number: 1,
36+
html_url: "https://github.com/owner/repo/issues/1"
37+
}
38+
};
39+
}
40+
if(url.startsWith("POST /repos/") && url.endsWith("/comments") ){ // issue related api
41+
return {
42+
data: {
43+
html_url: "https://github.com/owner/repo/issues/1#issuecomment-1370538185"
44+
}
45+
};
46+
}
3247
}
3348

3449
const MOCKED_ENV_VAR = "mocked_env_var";

0 commit comments

Comments
 (0)