Skip to content

Commit 2aa5c11

Browse files
mtscout6clayreimann
authored andcommitted
feature(team): add organizaiton team api
1 parent aa7ba49 commit 2aa5c11

File tree

11 files changed

+380
-8
lines changed

11 files changed

+380
-8
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ end_of_line = lf
77
charset = utf-8
88
trim_trailing_whitespace = true
99
insert_final_newline = true
10+
max_line_length = 120
1011

1112
[{*.yml,package.json}]
1213
indent_size = 2

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
sudo: false
12
language: node_js
23
node_js:
34
- '5'

lib/GitHub.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Search from './Search';
1313
import RateLimit from './RateLimit';
1414
import Repository from './Repository';
1515
import Organization from './Organization';
16+
import Team from './Team';
1617
import Markdown from './Markdown';
1718

1819
/**
@@ -59,6 +60,15 @@ class GitHub {
5960
return new Organization(organization, this.__auth, this.__apiBase);
6061
}
6162

63+
/**
64+
* create a new Team wrapper
65+
* @param {string} teamId - the name of the team
66+
* @return {team}
67+
*/
68+
getTeam(teamId) {
69+
return new Team(teamId, this.__auth, this.__apiBase);
70+
}
71+
6272
/**
6373
* Create a new Repository wrapper
6474
* @param {string} user - the user who owns the respository

lib/Organization.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,32 @@ class Organization extends Requestable {
6767
listMembers(options, cb) {
6868
return this._request('GET', `/orgs/${this.__name}/members`, options, cb);
6969
}
70+
71+
/**
72+
* List the Teams in the Organization
73+
* @see https://developer.github.com/v3/orgs/teams/#list-teams
74+
* @param {Requestable.callback} [cb] - will receive the list of teams
75+
* @return {Promise} - the promise for the http request
76+
*/
77+
getTeams(cb) {
78+
return this._requestAllPages(`/orgs/${this.__name}/teams`, undefined, cb);
79+
}
80+
81+
/**
82+
* Create a team
83+
* @see https://developer.github.com/v3/orgs/teams/#create-team
84+
* @param {object} options - Team creation parameters
85+
* @param {string} options.name - The name of the team
86+
* @param {string} [options.description] - Team description
87+
* @param {string} [options.repo_names] - Repos to add the team to
88+
* @param {string} [options.privacy=secret] - The level of privacy the team should have. Can be either one
89+
* of: `secret`, or `closed`
90+
* @param {Requestable.callback} [cb] - will receive the created team
91+
* @return {Promise} - the promise for the http request
92+
*/
93+
createTeam(options, cb) {
94+
return this._request('POST', `/orgs/${this.__name}/teams`, options, cb);
95+
}
7096
}
7197

7298
module.exports = Organization;

lib/Requestable.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,11 @@ class Requestable {
168168
* @param {string} path - the path to request
169169
* @param {Object} data - any query parameters for the request
170170
* @param {Requestable.callback} cb - the callback that will receive `true` or `false`
171+
* @param {method} [method=GET] - HTTP Method to use
171172
* @return {Promise} - the promise for the http request
172173
*/
173-
_request204or404(path, data, cb) {
174-
return this._request('GET', path, data)
174+
_request204or404(path, data, cb, method = 'GET') {
175+
return this._request(method, path, data)
175176
.then(function success(response) {
176177
if (cb) {
177178
cb(null, true, response);

lib/Team.js

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/**
2+
* @file
3+
* @copyright 2016 Matt Smith (Development Seed)
4+
* @license Licensed under {@link https://spdx.org/licenses/BSD-3-Clause-Clear.html BSD-3-Clause-Clear}.
5+
* Github.js is freely distributable.
6+
*/
7+
8+
import Requestable from './Requestable';
9+
import debug from 'debug';
10+
const log = debug('github:team');
11+
12+
/**
13+
* A Team allows scoping of API requests to a particular Github Organization Team.
14+
*/
15+
class Team extends Requestable {
16+
/**
17+
* Create a Team.
18+
* @param {string} [teamId] - the id for the team
19+
* @param {Requestable.auth} [auth] - information required to authenticate to Github
20+
* @param {string} [apiBase=https://api.github.com] - the base Github API URL
21+
*/
22+
constructor(teamId, auth, apiBase) {
23+
super(auth, apiBase);
24+
this.__teamId = teamId;
25+
}
26+
27+
/**
28+
* Get Team information
29+
* @see https://developer.github.com/v3/orgs/teams/#get-team
30+
* @param {Requestable.callback} [cb] - will receive the team
31+
* @return {Promise} - the promise for the http request
32+
*/
33+
getTeam(cb) {
34+
log(`Fetching Team ${this.__teamId}`);
35+
return this._request('Get', `/teams/${this.__teamId}`, undefined, cb);
36+
}
37+
38+
/**
39+
* List the Team's repositories
40+
* @see https://developer.github.com/v3/orgs/teams/#list-team-repos
41+
* @param {Requestable.callback} [cb] - will receive the list of repositories
42+
* @return {Promise} - the promise for the http request
43+
*/
44+
getRepos(cb) {
45+
log(`Fetching repositories for Team ${this.__teamId}`);
46+
return this._requestAllPages(`/teams/${this.__teamId}/repos`, undefined, cb);
47+
}
48+
49+
/**
50+
* Edit Team information
51+
* @see https://developer.github.com/v3/orgs/teams/#edit-team
52+
* @param {object} options - Parameters for team edit
53+
* @param {string} options.name - The name of the team
54+
* @param {string} [options.description] - Team description
55+
* @param {string} [options.repo_names] - Repos to add the team to
56+
* @param {string} [options.privacy=secret] - The level of privacy the team should have. Can be either one
57+
* of: `secret`, or `closed`
58+
* @param {Requestable.callback} [cb] - will receive the updated team
59+
* @return {Promise} - the promise for the http request
60+
*/
61+
editTeam(options, cb) {
62+
log(`Editing Team ${this.__teamId}`);
63+
return this._request('PATCH', `/teams/${this.__teamId}`, options, cb);
64+
}
65+
66+
/**
67+
* List the users who are members of the Team
68+
* @see https://developer.github.com/v3/orgs/teams/#list-team-members
69+
* @param {object} options - Parameters for listing team users
70+
* @param {string} [options.role=all] - can be one of: `all`, `maintainer`, or `member`
71+
* @param {Requestable.callback} [cb] - will receive the list of users
72+
* @return {Promise} - the promise for the http request
73+
*/
74+
listMembers(options, cb) {
75+
log(`Getting members of Team ${this.__teamId}`);
76+
return this._requestAllPages(`/teams/${this.__teamId}/members`, options, cb);
77+
}
78+
79+
/**
80+
* Get Team membership status for a user
81+
* @see https://developer.github.com/v3/orgs/teams/#get-team-membership
82+
* @param {string} username - can be one of: `all`, `maintainer`, or `member`
83+
* @param {Requestable.callback} [cb] - will receive the membership status of a user
84+
* @return {Promise} - the promise for the http request
85+
*/
86+
getMembership(username, cb) {
87+
log(`Getting membership of user ${username} in Team ${this.__teamId}`);
88+
return this._request('GET', `/teams/${this.__teamId}/memberships/${username}`, undefined, cb);
89+
}
90+
91+
/**
92+
* Add a member to the Team
93+
* @see https://developer.github.com/v3/orgs/teams/#add-team-membership
94+
* @param {string} username - can be one of: `all`, `maintainer`, or `member`
95+
* @param {object} options - Parameters for adding a team member
96+
* @param {string} [options.role=member] - The role that this user should have in the team. Can be one
97+
* of: `member`, or `maintainer`
98+
* @param {Requestable.callback} [cb] - will receive the membership status of added user
99+
* @return {Promise} - the promise for the http request
100+
*/
101+
addMembership(username, options, cb) {
102+
log(`Adding user ${username} to Team ${this.__teamId}`);
103+
return this._request('PUT', `/teams/${this.__teamId}/memberships/${username}`, options, cb);
104+
}
105+
106+
/**
107+
* Get repo management status for team
108+
* @see https://developer.github.com/v3/orgs/teams/#remove-team-membership
109+
* @param {string} owner - Organization name
110+
* @param {string} repo - Repo name
111+
* @param {Requestable.callback} [cb] - will receive the membership status of added user
112+
* @return {Promise} - the promise for the http request
113+
*/
114+
isManagedRepo(owner, repo, cb) {
115+
log(`Getting repo management by Team ${this.__teamId} for repo ${owner}/${repo}`);
116+
return this._request204or404(`/teams/${this.__teamId}/repos/${owner}/${repo}`, undefined, cb);
117+
}
118+
119+
/**
120+
* Add or Update repo management status for team
121+
* @see https://developer.github.com/v3/orgs/teams/#add-or-update-team-repository
122+
* @param {string} owner - Organization name
123+
* @param {string} repo - Repo name
124+
* @param {object} options - Parameters for adding or updating repo management for the team
125+
* @param {string} [options.permission] - The permission to grant the team on this repository. Can be one
126+
* of: `pull`, `push`, or `admin`
127+
* @param {Requestable.callback} [cb] - will receive the membership status of added user
128+
* @return {Promise} - the promise for the http request
129+
*/
130+
manageRepo(owner, repo, options, cb) {
131+
log(`Adding or Updating repo management by Team ${this.__teamId} for repo ${owner}/${repo}`);
132+
return this._request204or404(`/teams/${this.__teamId}/repos/${owner}/${repo}`, options, cb, 'PUT');
133+
}
134+
135+
/**
136+
* Remove repo management status for team
137+
* @see https://developer.github.com/v3/orgs/teams/#remove-team-repository
138+
* @param {string} owner - Organization name
139+
* @param {string} repo - Repo name
140+
* @param {Requestable.callback} [cb] - will receive the membership status of added user
141+
* @return {Promise} - the promise for the http request
142+
*/
143+
unmanageRepo(owner, repo, cb) {
144+
log(`Remove repo management by Team ${this.__teamId} for repo ${owner}/${repo}`);
145+
return this._request204or404(`/teams/${this.__teamId}/repos/${owner}/${repo}`, undefined, cb, 'DELETE');
146+
}
147+
148+
/**
149+
* Delete Team
150+
* @see https://developer.github.com/v3/orgs/teams/#delete-team
151+
* @param {Requestable.callback} [cb] - will receive the list of repositories
152+
* @return {Promise} - the promise for the http request
153+
*/
154+
deleteTeam(cb) {
155+
log(`Deleting Team ${this.__teamId}`);
156+
return this._request204or404(`/teams/${this.__teamId}`, undefined, cb, 'DELETE');
157+
}
158+
}
159+
160+
module.exports = Team;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"codecov": "^1.0.1",
6262
"del": "^2.2.0",
6363
"eslint-config-google": "^0.5.0",
64+
"eslint-plugin-mocha": "^2.2.0",
6465
"gulp": "^3.9.0",
6566
"gulp-babel": "^6.1.2",
6667
"gulp-eslint": "^2.0.0",

test/.eslintrc.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
extends: ../.eslintrc.yaml
3+
plugins:
4+
- mocha
35
env:
46
mocha: true
57
rules:
68
handle-callback-err: off
9+
mocha/no-exclusive-tests: 2

test/auth.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe('Github', function() {
5151
done();
5252
} catch (e) {
5353
try {
54-
if (err && err.request.headers['x-ratelimit-remaining'] === '0') {
54+
if (err && err.response.headers['x-ratelimit-remaining'] === '0') {
5555
done();
5656
return;
5757
}

test/organization.spec.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,11 @@ describe('Organization', function() {
4242
}).catch(done);
4343
});
4444

45-
it('should test for membership', function(done) {
46-
organization.isMember(MEMBER_NAME)
45+
it('should test for membership', function() {
46+
return organization.isMember(MEMBER_NAME)
4747
.then(function(isMember) {
4848
expect(isMember).to.be.true();
49-
done();
50-
}).catch(done);
49+
});
5150
});
5251
});
5352

@@ -59,7 +58,7 @@ describe('Organization', function() {
5958
organization = github.getOrganization(testUser.ORGANIZATION);
6059
});
6160

62-
it('should create an organisation repo', function(done) {
61+
it('should create an organization repo', function(done) {
6362
const options = {
6463
name: testRepoName,
6564
description: 'test create organization repo',
@@ -76,5 +75,31 @@ describe('Organization', function() {
7675
done();
7776
}));
7877
});
78+
79+
// TODO: The longer this is in place the slower it will get if we don't cleanup random test teams
80+
it('should list the teams in the organization', function() {
81+
return organization.getTeams()
82+
.then(({data}) => {
83+
const hasTeam = data.reduce(
84+
(found, member) => member.slug === 'fixed-test-team-1' || found,
85+
false);
86+
87+
expect(hasTeam).to.be.true();
88+
});
89+
});
90+
91+
it('should create an organization team', function(done) {
92+
const options = {
93+
name: testRepoName,
94+
description: 'Created by unit tests',
95+
privacy: 'secret'
96+
};
97+
98+
organization.createTeam(options, assertSuccessful(done, function(err, team) {
99+
expect(team.name).to.equal(testRepoName);
100+
expect(team.organization.login).to.equal(testUser.ORGANIZATION); // jscs:ignore
101+
done();
102+
}));
103+
});
79104
});
80105
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy