Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,22 @@ create.comment({account, token, repository, pullRequest, comment});

#### Read

Usage to be defined.
The read function will return a list of review comments on a pull request.

```
import { read } from 'github-comment-manager';

read.comments({account, token, repository, pullRequest});
```

| Parameter | Description |
| ----------- | ----------------------------------------- |
| account | Github account username |
| token | Github account access token |
| repository | Repository to retrieve comments from |
| pullRequest | Pull request number to read comments from |

The example response can be found [HERE](https://developer.github.com/v3/issues/comments/#response).

#### Update

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"src/**/*.js"
],
"exclude": [
"src/**/*.test.js"
"src/**/*.test.js",
"src/index.js"
],
"sourceMap": true,
"instrument": true,
Expand Down
33 changes: 7 additions & 26 deletions src/actions/create.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,12 @@
import { promisify } from 'util';
import request from 'request';
import githubApi from '../utilities/githubApi';

const comment = ({ account, token, repository, comment, pullRequest }) =>
new Promise((resolve, reject) => {
const postCommentOptions = {
url: `https://api.github.com/repos/${account}/${repository}/issues/${pullRequest}/comments`,
headers: {
Authorization: `Basic ${new Buffer(`${account}:${token}`).toString(
'base64'
)}`,
'User-Agent': account
},
body: `{"body": "${comment}"}`
};

const post = promisify(request.post);

post(postCommentOptions)
.then(({ body, statusCode }) => {
if (isBadResult(statusCode)) throw body;
return body;
})
.then(resolve)
.catch(reject);
});

const isBadResult = code => !`${code}`.startsWith('2');
githubApi.post(
`/repos/${account}/${repository}/issues/${pullRequest}/comments`,
account,
token,
comment
);

export default {
comment
Expand Down
38 changes: 13 additions & 25 deletions src/actions/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import sinon from 'sinon';
import chai from 'chai';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import request from 'request';
import create from './create';
import githubApi from '../utilities/githubApi';

chai.use(sinonChai);
chai.use(chaiAsPromised);
Expand All @@ -26,15 +26,10 @@ describe('create', () => {
const comment = 'I am a new comment';
const pullRequest = 9000;

const error = null;
const responseBody = 'success';
const response = { body: responseBody, statusCode: '200' };
const postStub = sandbox
.stub(request, 'post')
.callsArgWith(1, error, response, responseBody);
const apiStub = sandbox.stub(githubApi, 'post').resolves();

// Exercise.
await create.comment({
const createAction = create.comment({
account,
token,
repository,
Expand All @@ -43,31 +38,24 @@ describe('create', () => {
});

// Verify.
postStub.should.have.been.calledOnce;
postStub.firstCall.args[0].url.should.equal(
`https://api.github.com/repos/tools/${repository}/issues/${pullRequest}/comments`
);
postStub.firstCall.args[0].headers.Authorization.should.equal(
'Basic dG9vbHM6c3VwZXItc2VjdXJlLXRva2Vu'
await createAction.should.be.fulfilled;
apiStub.should.have.been.calledOnce;
apiStub.should.have.been.calledWith(
`/repos/${account}/${repository}/issues/${pullRequest}/comments`,
account,
token,
comment
);
postStub.firstCall.args[0].headers['User-Agent'].should.equal(account);
postStub.firstCall.args[0].body.should.equal(`{"body": "${comment}"}`);
});

it('should reject with an error when a none 2xx status code is received', () => {
it('should reject when there is an error', () => {
// Setup.
const account = 'tools';
const token = 'super-secure-token';
const repository = 'github-comment-manager';
const comment = 'I am a new comment';
const pullRequest = 9000;

const error = null;
const responseBody = 'Not Found';
const response = { body: responseBody, statusCode: '404' };
sandbox
.stub(request, 'post')
.callsArgWith(1, error, response, responseBody);
sandbox.stub(githubApi, 'post').rejects();

// Exercise.
const createAction = create.comment({
Expand All @@ -79,7 +67,7 @@ describe('create', () => {
});

// Verify.
return createAction.should.have.rejectedWith(responseBody);
return createAction.should.have.rejected;
});
});
});
68 changes: 8 additions & 60 deletions src/actions/read.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,11 @@
import { createApolloFetch } from 'apollo-fetch';

const apolloFetch = createApolloFetch({
uri: 'https://api.github.com/graphql'
});

const comments = ({ account, token, repository, pullRequest }) => {
setAuthentication(token);

return apolloFetch({
query: `query IssueCount($owner: String!, $repository: String!, $pullRequest: Int!) {
repository(owner: $owner, name: $repository) {
pullRequest(number: $pullRequest) {
comments(first: 10) {
edges {
node {
body
author {
login
}
databaseId
}
}
}
}
}
}`,
variables: {
repository,
pullRequest,
owner: account
}
})
.then(processAnyErrors)
.then(processComments);
};

const setAuthentication = accountkey => {
apolloFetch.use(({ options }, next) => {
if (!options.headers) {
// eslint-disable-next-line no-param-reassign
options.headers = {
authorization: `bearer ${accountkey}`
};
}
next();
});
};

const processAnyErrors = response => {
if (response.errors) throw response.errors;
return response;
};

const processComments = response =>
response.data.repository.pullRequest.comments.edges.map(result => ({
id: result.node.databaseId,
comment: result.node.body,
author: result.node.author
}));
import githubApi from '../utilities/githubApi';

const comments = ({ account, token, repository, pullRequest }) =>
githubApi.get(
`/repos/${account}/${repository}/issues/${pullRequest}/comments`,
account,
token
);

export default {
comments
Expand Down
68 changes: 68 additions & 0 deletions src/actions/read.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import sinon from 'sinon';
import chai from 'chai';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import read from './read';
import githubApi from '../utilities/githubApi';

chai.use(sinonChai);
chai.use(chaiAsPromised);

describe('read', () => {
let sandbox;

beforeEach(() => {
sandbox = sinon.createSandbox();
});

afterEach(() => sandbox.restore());

describe('comment', () => {
it('should read the PR comments', async () => {
// Setup.
const account = 'tools';
const token = 'super-secure-token';
const repository = 'github-comment-manager';
const pullRequest = 9000;

const apiStub = sandbox.stub(githubApi, 'get').resolves();

// Exercise.
const readAction = read.comments({
account,
token,
repository,
pullRequest
});

// Verify.
await readAction.should.be.fulfilled;
apiStub.should.have.been.calledOnce;
apiStub.should.have.been.calledWith(
`/repos/${account}/${repository}/issues/${pullRequest}/comments`,
account,
token
);
});

it('should reject when there is an error', () => {
// Setup.
const account = 'tools';
const token = 'super-secure-token';
const repository = 'github-comment-manager';
const pullRequest = 9000;
sandbox.stub(githubApi, 'get').rejects();

// Exercise.
const readAction = read.comments({
account,
token,
repository,
pullRequest
});

// Verify.
return readAction.should.have.rejected;
});
});
});
31 changes: 6 additions & 25 deletions src/actions/remove.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
import { promisify } from 'util';
import request from 'request';
import githubApi from '../utilities/githubApi';

const comment = ({ account, token, repository, commentId }) =>
new Promise((resolve, reject) => {
const removeCommentOptions = {
url: `https://api.github.com/repos/${account}/${repository}/issues/comments/${commentId}`,
headers: {
Authorization: `Basic ${new Buffer(`${account}:${token}`).toString(
'base64'
)}`,
'User-Agent': account
}
};

const remove = promisify(request.delete);

remove(removeCommentOptions)
.then(({ body, statusCode }) => {
if (isBadResult(statusCode)) throw body;
return body;
})
.then(resolve)
.catch(reject);
});

const isBadResult = code => !`${code}`.startsWith('2');
githubApi.remove(
`/repos/${account}/${repository}/issues/comments/${commentId}`,
account,
token
);

export default {
comment
Expand Down
Loading