Skip to content
Open
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
9 changes: 9 additions & 0 deletions lib/GitHub.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Repository from './Repository';
import Organization from './Organization';
import Team from './Team';
import Markdown from './Markdown';
import Watching from './Watching';

/**
* GitHub encapsulates the functionality to create various API wrapper objects.
Expand Down Expand Up @@ -113,6 +114,14 @@ class GitHub {
return new Markdown(this.__auth, this.__apiBase);
}

/**
* Create a new Watching wrapper
* @return {Watching}
*/
watching() {
return new Watching(this.__auth, this.__apiBase);
}

/**
* Computes the full repository name
* @param {string} user - the username (or the full name)
Expand Down
95 changes: 95 additions & 0 deletions lib/Watching.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @file
* @copyright 2016 Matt Smith (Development Seed)
* @license Licensed under {@link https://spdx.org/licenses/BSD-3-Clause-Clear.html BSD-3-Clause-Clear}.
* Github.js is freely distributable.
*/

import Requestable from './Requestable';
import debug from 'debug';
const log = debug('github:watching');

/**
* Watching a Repository registers the user to receive notifications on new discussions, as well as events in the user's
* activity feed.
*/
export default class Watching extends Requestable {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment we use module.exports for exporting classes. I'm not sure about the reason as this was made by @clayreimann but I think it's because we aren't using the babel plugin to revert the export of defaults to the behavior of Babel 5.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know there was such a plugin. I forget the exact reason that we're using module.exports but it boiled down to nothing works if you use the export default syntax.

If there's a plugin that fixes things while allowing us to use the new syntax then I'm all for it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've used that plugin before as well. I'll get it wired up.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to do it in a separate PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit is already in, it was a two line change and doesn't require me to change this. I can do that if you like though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I do a separate PR for this, then I'll tackle the babel-runtime issue as well. I'll crank that out real quick.

Copy link
Copy Markdown
Member Author

@mtscout6 mtscout6 Jul 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright it is in PR #366 We should hold off on this PR until that one is done because of this line.

/**
* Watching wrapper
* @param {Requestable.auth} [auth] - information required to authenticate to Github
* @param {string} [apiBase=https://api.github.com] - the base Github API URL
*/
constructor(auth, apiBase) {
super(auth, apiBase);
}

/**
* Get Watchers for repo
* @see https://developer.github.com/v3/activity/watching/#list-watchers
* @param {string} owner - username or organization
* @param {string} repo - repo name
* @param {Requestable.callback} [cb] - list of watchers
* @return {Promise} - the promise for the http request
*/
listWatchers(owner, repo, cb) {
log(`Fetching watchers for ${owner}/${repo}`);
return this._requestAllPages(`/repos/${owner}/${repo}/subscribers`, undefined, cb);
}

/**
* Subscribe to repo
* @see https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
* @param {string} owner - username or organization
* @param {string} repo - repo name
* @param {Requestable.callback} [cb] - subscription status
* @return {Promise} - the promise for the http request
*/
subscribe(owner, repo, cb) {
log(`Subscribing to ${owner}/${repo}`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this and the other logs. Possibly we might want to use them only for weird situations. Any opinion @clayreimann?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the logs only run if they are enabled, the idea with including them is that when we need extra information we have the tooling in place to help track down an end-user reported issue. (Logs are enabled via the DEBUG command-line argument or flipping the switch in your browser)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was, is there any sense in this specific case in stating the obvious. For example you call something.subscribe() and you read on the console "You have called the subscribe method".

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since they don't get output unless you explicitly turn them on I don't see the harm here. This can be useful for diagnostic purposes when needed. There is logging of this sort in the base class, however if you enable it there you enable it for everything in this library. Having these here will allow you to only turn on logging in this section.

return this._setSubscription(owner, repo, true, cb);
}

/**
* Ignore a repo
* @see https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
* @param {string} owner - username or organization
* @param {string} repo - repo name
* @param {Requestable.callback} [cb] - subscription status
* @return {Promise} - the promise for the http request
*/
ignore(owner, repo, cb) {
log(`Ignoring ${owner}/${repo}`);
return this._setSubscription(owner, repo, false, cb);
}

/**
* Remove all subscription settings for repo
* @see https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
* @param {string} owner - username or organization
* @param {string} repo - repo name
* @param {Requestable.callback} [cb] - subscription status
* @return {Promise} - the promise for the http request
*/
removeSubscription(owner, repo, cb) {
log(`Removing subscription settings for ${owner}/${repo}`);
return this._request204or404(`/repos/${owner}/${repo}/subscription`, undefined, cb, 'DELETE');
}

/**
* General subscription method
* @private
* @see https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
* @param {string} owner - username or organization
* @param {string} repo - repo name
* @param {boolean} subscribed - subscribed or ignored
* @param {Requestable.callback} [cb] - subscription status
* @return {Promise} - the promise for the http request
*/
_setSubscription(owner, repo, subscribed, cb) {
log(`Subscribing to ${owner}/${repo}`);
return this._request('PUT', `/repos/${owner}/${repo}/subscription`, {
subscribed,
ignored: !subscribed
}, cb);
}
}
4 changes: 4 additions & 0 deletions test/fixtures/alt-user.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"USERNAME": "mtscout6-test",
"PASSWORD": "test1324"
}
5 changes: 1 addition & 4 deletions test/team.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import expect from 'must';

import Github from '../lib/GitHub';
import testUser from './fixtures/user.json';
import altUser from './fixtures/alt-user.json';
import {assertFailure} from './helpers/callbacks';
import getTestRepoName from './helpers/getTestRepoName';

const altUser = {
USERNAME: 'mtscout6-test'
};

function createTestTeam() {
const name = getTestRepoName();

Expand Down
79 changes: 79 additions & 0 deletions test/watching.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import expect from 'must';

import Github from '../lib/GitHub';
import testUser from './fixtures/user.json';
import altUser from './fixtures/alt-user.json';
import getTestRepoName from './helpers/getTestRepoName';

describe('Watching', function() {
const testRepoName = getTestRepoName();
let githubUser;
let githubAltUser;
let organization;

before(function() {
githubUser = new Github({
username: testUser.USERNAME,
password: testUser.PASSWORD,
auth: 'basic'
});

githubAltUser = new Github({
username: altUser.USERNAME,
password: altUser.PASSWORD,
auth: 'basic'
});

organization = githubUser.getOrganization(testUser.ORGANIZATION);

const options = {
name: testRepoName,
description: 'test repo watchers',
homepage: 'https://github.com/',
private: false,
has_issues: false, // eslint-disable-line
has_wiki: false, // eslint-disable-line
has_downloads: false // eslint-disable-line
};

return organization.createRepo(options);
});

it('should list watchers', function() {
return githubUser.watching()
.listWatchers(testUser.ORGANIZATION, 'fixed-test-repo-1')
.then(({data}) => {
const watchers = data.map((x) => x.login);
expect(watchers).must.include('mikedeboertest');
});
});

it('should add a subscription to a repo', function() {
const watching = githubAltUser.watching();

return watching.subscribe(testUser.ORGANIZATION, testRepoName)
.then(({data}) => {
expect(data.subscribed).to.be.true();
expect(data.ignored).to.be.false();
});
});

it('should ignore a repo', function() {
const watching = githubAltUser.watching();

return watching.ignore(testUser.ORGANIZATION, testRepoName)
.then(({data}) => {
expect(data.subscribed).to.be.false();
expect(data.ignored).to.be.true();
});
});

it('should remove subscription settings', function() {
const watching = githubAltUser.watching();

return watching.removeSubscription(testUser.ORGANIZATION, testRepoName)
.then((result) => {
expect(result).to.be.true();
});
});
});