Hello world github/linguist#1 cool, and #1!
\n'); 28 | done(); 29 | }).catch(done); 30 | }); 31 | 32 | it('should convert markdown to html as GFM', function(done) { 33 | const options = { 34 | text: 'Hello world github/linguist#1 **cool**, and #1!', 35 | mode: 'gfm', 36 | context: 'github/gollum', 37 | }; 38 | markdown.render(options) 39 | .then(function({data: html}) { 40 | expect(html).to.be('Hello world github/linguist#1 cool, and gollum#1!
'); // eslint-disable-line 41 | done(); 42 | }).catch(done); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/organization.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import testUser from './fixtures/user.js'; 5 | import {assertSuccessful, assertArray} from './helpers/callbacks'; 6 | import getTestRepoName from './helpers/getTestRepoName'; 7 | 8 | describe('Organization', function() { 9 | let github; 10 | const ORG_NAME = 'github-tools'; 11 | const MEMBER_NAME = 'clayreimann'; 12 | let createdProject; 13 | 14 | before(function() { 15 | github = new Github({ 16 | username: testUser.USERNAME, 17 | password: testUser.PASSWORD, 18 | auth: 'basic', 19 | }); 20 | createdProject = undefined; 21 | }); 22 | 23 | after(function() { 24 | if (createdProject) { 25 | return github.getProject(createdProject.id).deleteProject(); 26 | } 27 | }); 28 | 29 | describe('reading', function() { 30 | let organization; 31 | 32 | before(function() { 33 | organization = github.getOrganization(ORG_NAME); 34 | }); 35 | 36 | it('should show user\'s organisation repos', function(done) { 37 | organization.getRepos(assertArray(done)); 38 | }); 39 | 40 | it('should list the users in the organization', function(done) { 41 | organization.listMembers() 42 | .then(function({data: members}) { 43 | expect(members).to.be.an.array(); 44 | 45 | const hasClayReimann = members.some((member) => member.login === MEMBER_NAME); 46 | expect(hasClayReimann).to.be.true(); 47 | 48 | done(); 49 | }).catch(done); 50 | }); 51 | 52 | it('should test for membership', function() { 53 | return organization.isMember(MEMBER_NAME) 54 | .then(function(isMember) { 55 | expect(isMember).to.be.true(); 56 | }); 57 | }); 58 | }); 59 | 60 | describe('creating/updating', function() { 61 | let organization; 62 | const testRepoName = getTestRepoName(); 63 | 64 | before(function() { 65 | organization = github.getOrganization(testUser.ORGANIZATION); 66 | }); 67 | 68 | it('should create an organization repo', function(done) { 69 | const options = { 70 | name: testRepoName, 71 | description: 'test create organization repo', 72 | homepage: 'https://github.com/', 73 | private: false, 74 | has_issues: true, // eslint-disable-line 75 | has_wiki: true, // eslint-disable-line 76 | has_downloads: true // eslint-disable-line 77 | }; 78 | 79 | organization.createRepo(options, assertSuccessful(done, function(err, repo) { 80 | expect(repo.name).to.equal(testRepoName); 81 | expect(repo.full_name).to.equal(`${testUser.ORGANIZATION}/${testRepoName}`); // eslint-disable-line 82 | done(); 83 | })); 84 | }); 85 | 86 | it('should create an organization team', function(done) { 87 | const options = { 88 | name: testRepoName, 89 | description: 'Created by unit tests', 90 | privacy: 'secret', 91 | }; 92 | 93 | organization.createTeam(options, assertSuccessful(done, function(err, team) { 94 | expect(team.name).to.equal(testRepoName); 95 | expect(team.organization.login).to.equal(testUser.ORGANIZATION); // jscs:ignore 96 | done(); 97 | })); 98 | }); 99 | 100 | it('should list the teams in the organization', function() { 101 | return organization.getTeams() 102 | .then(({data}) => { 103 | const hasTeam = data.some((member) => member.slug === testRepoName); 104 | 105 | expect(hasTeam).to.be.true(); 106 | }); 107 | }); 108 | 109 | it('should create a project', function(done) { 110 | organization.createProject({ 111 | name: testRepoName, 112 | body: 'body', 113 | }, assertSuccessful(done, function(err, project) { 114 | createdProject = project; 115 | expect(project).to.own('name', testRepoName); 116 | expect(project).to.own('body', 'body'); 117 | done(); 118 | })); 119 | }); 120 | 121 | it('should list repo projects', function(done) { 122 | organization.listProjects(assertSuccessful(done, function(err, projects) { 123 | expect(projects).to.be.an.array(); 124 | 125 | const hasProject = projects.some((project) => project.name === testRepoName); 126 | 127 | expect(hasProject).to.be.true(); 128 | done(); 129 | })); 130 | }); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /test/project.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import wait from './helpers/wait'; 5 | import testUser from './fixtures/user.js'; 6 | import {assertSuccessful} from './helpers/callbacks'; 7 | import getTestRepoName from './helpers/getTestRepoName'; 8 | 9 | describe('Project', function() { 10 | let github; 11 | const testRepoName = getTestRepoName(); 12 | let project; 13 | let columnId; 14 | let cardId; 15 | 16 | before(function() { 17 | github = new Github({ 18 | username: testUser.USERNAME, 19 | password: testUser.PASSWORD, 20 | auth: 'basic', 21 | }); 22 | 23 | return github 24 | .getUser() 25 | .createRepo({name: testRepoName}) 26 | .then(wait(5000)) 27 | .then(function() { 28 | const remoteRepo = github.getRepo(testUser.USERNAME, testRepoName); 29 | return remoteRepo.createProject({ 30 | name: 'test-project', 31 | body: 'body', 32 | }); 33 | }) 34 | .then(function(_project) { 35 | project = github.getProject(_project.data.id); 36 | }); 37 | }); 38 | 39 | after(function() { 40 | return github.getRepo(testUser.USERNAME, testRepoName).deleteRepo(); 41 | }); 42 | 43 | it('should get repo project', function(done) { 44 | project.getProject(assertSuccessful(done, function(err, project) { 45 | expect(project).to.own('name', 'test-project'); 46 | done(); 47 | })); 48 | }); 49 | 50 | it('should update a project', function(done) { 51 | project.updateProject({ 52 | name: 'another-test-project', 53 | body: 'another-body', 54 | }, assertSuccessful(done, function(err, project) { 55 | expect(project).to.own('name', 'another-test-project'); 56 | expect(project).to.own('body', 'another-body'); 57 | done(); 58 | })); 59 | }); 60 | 61 | it('should create a repo project column', function(done) { 62 | project.createProjectColumn({ 63 | name: 'test-column', 64 | }, assertSuccessful(done, function(err, column) { 65 | expect(column).to.own('name', 'test-column'); 66 | columnId = column.id; 67 | done(); 68 | })); 69 | }); 70 | 71 | it('should list repo project columns', function(done) { 72 | project.listProjectColumns(assertSuccessful(done, function(err, columns) { 73 | expect(columns).to.be.an.array(); 74 | expect(columns.length).to.equal(1); 75 | done(); 76 | })); 77 | }); 78 | 79 | it('should get repo project column', function(done) { 80 | project.getProjectColumn(columnId, assertSuccessful(done, function(err, project) { 81 | expect(project).to.own('name', 'test-column'); 82 | done(); 83 | })); 84 | }); 85 | 86 | it('should update a repo project column', function(done) { 87 | project.updateProjectColumn(columnId, { 88 | name: 'another-test-column', 89 | }, assertSuccessful(done, function(err, column) { 90 | expect(column).to.own('name', 'another-test-column'); 91 | done(); 92 | })); 93 | }); 94 | 95 | it('should create repo project card', function(done) { 96 | project.createProjectCard(columnId, { 97 | note: 'test-card', 98 | }, assertSuccessful(done, function(err, card) { 99 | expect(card).to.own('note', 'test-card'); 100 | cardId = card.id; 101 | done(); 102 | })); 103 | }); 104 | 105 | it('should list cards of a project', function(done) { 106 | project.listProjectCards(assertSuccessful(done, function(err, cards) { 107 | expect(cards).to.be.an.array(); 108 | expect(cards.length).to.equal(1); 109 | done(); 110 | })); 111 | }); 112 | 113 | it('should list cards of a column', function(done) { 114 | project.listColumnCards(columnId, assertSuccessful(done, function(err, cards) { 115 | expect(cards).to.be.an.array(); 116 | expect(cards.length).to.equal(1); 117 | done(); 118 | })); 119 | }); 120 | 121 | it('should get repo project card', function(done) { 122 | project.getProjectCard(cardId, assertSuccessful(done, function(err, card) { 123 | expect(card).to.own('note', 'test-card'); 124 | done(); 125 | })); 126 | }); 127 | 128 | it('should update repo project card', function(done) { 129 | project.updateProjectCard(cardId, { 130 | note: 'another-test-card', 131 | }, assertSuccessful(done, function(err, card) { 132 | expect(card).to.own('note', 'another-test-card'); 133 | done(); 134 | })); 135 | }); 136 | 137 | it('should move repo project card', function(done) { 138 | project.moveProjectCard(cardId, 'top', columnId, assertSuccessful(done, function(err, result) { 139 | expect(result).to.be(true); 140 | done(); 141 | })); 142 | }); 143 | 144 | it('should move repo project column', function(done) { 145 | project.moveProjectColumn(columnId, 'first', assertSuccessful(done, function(err, result) { 146 | expect(result).to.be(true); 147 | done(); 148 | })); 149 | }); 150 | 151 | it('should delete repo project card', function(done) { 152 | project.deleteProjectCard(cardId, assertSuccessful(done, function(err, result) { 153 | expect(result).to.be(true); 154 | done(); 155 | })); 156 | }); 157 | 158 | it('should delete repo project column', function(done) { 159 | project.deleteProjectColumn(columnId, assertSuccessful(done, function(err, result) { 160 | expect(result).to.be(true); 161 | done(); 162 | })); 163 | }); 164 | 165 | it('should delete repo project', function(done) { 166 | project.deleteProject(assertSuccessful(done, function(err, result) { 167 | expect(result).to.be(true); 168 | done(); 169 | })); 170 | }); 171 | }); 172 | -------------------------------------------------------------------------------- /test/rate-limit.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import testUser from './fixtures/user.js'; 5 | import {assertSuccessful} from './helpers/callbacks'; 6 | 7 | describe('RateLimit', function() { 8 | let github; 9 | let rateLimit; 10 | 11 | before(function() { 12 | github = new Github({ 13 | username: testUser.USERNAME, 14 | password: testUser.PASSWORD, 15 | auth: 'basic', 16 | }); 17 | 18 | rateLimit = github.getRateLimit(); 19 | }); 20 | 21 | it('should get rate limit', function(done) { 22 | rateLimit.getRateLimit(assertSuccessful(done, function(err, rateInfo) { 23 | const rate = rateInfo.rate; 24 | 25 | expect(rate).to.be.an.object(); 26 | expect(rate).to.have.own('limit'); 27 | expect(rate).to.have.own('remaining'); 28 | expect(rate.limit).to.be.a.number(); 29 | expect(rate.remaining).to.be.a.number(); 30 | expect(rate.remaining).to.be.at.most(rateInfo.rate.limit); 31 | 32 | done(); 33 | })); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/repository.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import wait from './helpers/wait'; 5 | import testUser from './fixtures/user.js'; 6 | import loadImage from './fixtures/imageBlob'; 7 | import {assertSuccessful, assertFailure} from './helpers/callbacks'; 8 | import getTestRepoName from './helpers/getTestRepoName'; 9 | 10 | describe('Repository', function() { 11 | let github; 12 | let user; 13 | let imageB64; 14 | let imageBlob; 15 | const testRepoName = getTestRepoName(); 16 | const v10SHA = '20fcff9129005d14cc97b9d59b8a3d37f4fb633b'; 17 | const statusUrl = 18 | 'https://api.github.com/repos/github-tools/github/statuses/20fcff9129005d14cc97b9d59b8a3d37f4fb633b'; 19 | 20 | before(function(done) { 21 | github = new Github({ 22 | username: testUser.USERNAME, 23 | password: testUser.PASSWORD, 24 | }); 25 | 26 | loadImage(function(b64, blob) { 27 | imageB64 = b64; 28 | imageBlob = blob; 29 | done(); 30 | }); 31 | }); 32 | 33 | describe('reading', function() { 34 | let remoteRepo; 35 | 36 | before(function() { 37 | remoteRepo = github.getRepo('github-tools', 'github'); 38 | }); 39 | 40 | it('should get repo details', function(done) { 41 | remoteRepo.getDetails(assertSuccessful(done, function(err, repo) { 42 | expect(repo).to.have.own('full_name', 'github-tools/github'); 43 | 44 | done(); 45 | })); 46 | }); 47 | 48 | it('should get blob', function(done) { 49 | remoteRepo.getSha('master', 'README.md', assertSuccessful(done, function(err, response) { 50 | remoteRepo.getBlob(response.sha, assertSuccessful(done, function(err, content) { 51 | expect(content).to.be.include('# Github.js'); 52 | 53 | done(); 54 | })); 55 | })); 56 | }); 57 | 58 | it('should get a branch', function(done) { 59 | remoteRepo.getBranch('master', assertSuccessful(done, function(err, content) { 60 | expect(content.name).to.be('master'); 61 | 62 | done(); 63 | })); 64 | }); 65 | 66 | it('should show repo contents', function(done) { 67 | remoteRepo.getContents('master', '', false, assertSuccessful(done, function(err, contents) { 68 | expect(contents).to.be.an.array(); 69 | 70 | const readme = contents.filter(function(content) { 71 | return content.path === 'README.md'; 72 | }); 73 | 74 | expect(readme).to.have.length(1); 75 | expect(readme[0]).to.have.own('type', 'file'); 76 | 77 | done(); 78 | })); 79 | }); 80 | 81 | it('should show repo content raw', function(done) { 82 | remoteRepo.getContents('master', 'README.md', 'raw', assertSuccessful(done, function(err, text) { 83 | expect(text).to.contain('# Github.js'); 84 | 85 | done(); 86 | })); 87 | }); 88 | 89 | it('should show repo readme', function(done) { 90 | remoteRepo.getReadme('master', 'raw', assertSuccessful(done, function(err, text) { 91 | expect(text).to.contain('# Github.js'); 92 | 93 | done(); 94 | })); 95 | }); 96 | 97 | it('should get ref from repo', function(done) { 98 | remoteRepo.getRef('heads/master', assertSuccessful(done)); 99 | }); 100 | 101 | it('should get tree', function(done) { 102 | remoteRepo.getTree('master', assertSuccessful(done, function(err, response) { 103 | let {tree} = response; 104 | expect(tree).to.be.an.array(); 105 | expect(tree.length).to.be.above(0); 106 | 107 | done(); 108 | })); 109 | }); 110 | 111 | it('should fork repo', function(done) { 112 | remoteRepo.fork(assertSuccessful(done)); 113 | }); 114 | 115 | it('should fork repo to org', function(done) { 116 | remoteRepo.forkToOrg(testUser.ORGANIZATION, assertSuccessful(done)); 117 | }); 118 | 119 | it('should list forks of repo', function(done) { 120 | remoteRepo.listForks(assertSuccessful(done, function(err, forks) { 121 | expect(forks).to.be.an.array(); 122 | expect(forks.length).to.be.above(0); 123 | done(); 124 | })); 125 | }); 126 | 127 | it('should list commits with no options', function(done) { 128 | remoteRepo.listCommits(assertSuccessful(done, function(err, commits) { 129 | expect(commits).to.be.an.array(); 130 | expect(commits.length).to.be.above(0); 131 | 132 | expect(commits[0]).to.have.own('commit'); 133 | expect(commits[0]).to.have.own('author'); 134 | 135 | done(); 136 | })); 137 | }); 138 | 139 | it('should list commits with null options', function(done) { 140 | remoteRepo.listCommits(null, assertSuccessful(done, function(err, commits) { 141 | expect(commits).to.be.an.array(); 142 | expect(commits.length).to.be.above(0); 143 | 144 | expect(commits[0]).to.have.own('commit'); 145 | expect(commits[0]).to.have.own('author'); 146 | 147 | done(); 148 | })); 149 | }); 150 | 151 | it('should list commits with all options', function(done) { 152 | const since = new Date(2015, 0, 1); 153 | const until = new Date(2016, 0, 20); 154 | const options = { 155 | sha: 'master', 156 | path: 'test', 157 | author: 'AurelioDeRosa', 158 | since, 159 | until, 160 | }; 161 | 162 | remoteRepo.listCommits(options, assertSuccessful(done, function(err, commits) { 163 | expect(commits).to.be.an.array(); 164 | expect(commits.length).to.be.above(0); 165 | 166 | const commit = commits[0]; 167 | const commitDate = new Date(commit.commit.author.date); 168 | 169 | expect(commit).to.have.own('commit'); 170 | expect(commit.author).to.have.own('login', 'AurelioDeRosa'); 171 | expect(commitDate.getTime()).to.be.between(since.getTime(), until.getTime()); 172 | done(); 173 | })); 174 | }); 175 | 176 | it('should list commits on a PR with no options', function(done) { 177 | const PR_NUMBER = 588; 178 | remoteRepo.listCommitsOnPR(PR_NUMBER, assertSuccessful(done, function(err, commits) { 179 | expect(commits).to.be.an.array(); 180 | expect(commits.length).to.be.equal(2); 181 | 182 | let message1 = 'fix(repository): prevents lib from crashing when not providing optional arguments'; 183 | expect(commits[0].author).to.have.own('login', 'hazmah0'); 184 | expect(commits[0].commit).to.have.own('message', message1); 185 | 186 | let message2 = 'test(repository): updates test to use promise instead of callback'; 187 | expect(commits[1].author).to.have.own('login', 'hazmah0'); 188 | expect(commits[1].commit).to.have.own('message', message2); 189 | 190 | done(); 191 | })); 192 | }); 193 | 194 | it('should get the latest commit from master', function(done) { 195 | remoteRepo.getSingleCommit('master', assertSuccessful(done, function(err, commit) { 196 | expect(commit).to.have.own('sha'); 197 | expect(commit).to.have.own('commit'); 198 | expect(commit).to.have.own('author'); 199 | 200 | done(); 201 | })); 202 | }); 203 | 204 | it('should fail when null ref is passed', function(done) { 205 | remoteRepo.getSingleCommit(null, assertFailure(done, function(err) { 206 | expect(err.response.status).to.be(422); 207 | done(); 208 | })); 209 | }); 210 | 211 | it('should show repo contributors', function(done) { 212 | remoteRepo.getContributors(assertSuccessful(done, function(err, contributors) { 213 | if (!(contributors instanceof Array)) { 214 | console.log(JSON.stringify(contributors, null, 2)); // eslint-disable-line 215 | } 216 | expect(contributors).to.be.an.array(); 217 | expect(contributors.length).to.be.above(1); 218 | 219 | const contributor = contributors[0]; 220 | 221 | expect(contributor).to.have.own('login'); 222 | expect(contributor).to.have.own('contributions'); 223 | 224 | done(); 225 | })); 226 | }); 227 | 228 | it('should show repo contributor stats', function(done) { 229 | remoteRepo.getContributorStats(assertSuccessful(done, function(err, contributors) { 230 | if (!(contributors instanceof Array)) { 231 | console.log(JSON.stringify(contributors, null, 2)); // eslint-disable-line 232 | } 233 | expect(contributors).to.be.an.array(); 234 | expect(contributors.length).to.be.above(1); 235 | 236 | const contributor = contributors[0]; 237 | 238 | expect(contributor).to.have.own('author'); 239 | expect(contributor).to.have.own('total'); 240 | expect(contributor).to.have.own('weeks'); 241 | 242 | done(); 243 | })); 244 | }); 245 | 246 | // @TODO repo.branch, repo.pull 247 | 248 | it('should list repo branches', function(done) { 249 | remoteRepo.listBranches(assertSuccessful(done)); 250 | }); 251 | 252 | it('should get commit from repo', function(done) { 253 | remoteRepo.getCommit(v10SHA, assertSuccessful(done, function(err, commit) { 254 | expect(commit.message).to.equal('v0.10.4'); 255 | expect(commit.author.date).to.equal('2015-03-20T17:01:42Z'); 256 | 257 | done(); 258 | })); 259 | }); 260 | 261 | it('should get statuses for a SHA from a repo', function(done) { 262 | remoteRepo.listStatuses(v10SHA, assertSuccessful(done, function(err, statuses) { 263 | expect(statuses).to.be.an.array(); 264 | expect(statuses.length).to.equal(6); 265 | 266 | const correctUrls = statuses.every(function(status) { 267 | return status.url === statusUrl; 268 | }); 269 | 270 | expect(correctUrls).to.be(true); 271 | 272 | done(); 273 | })); 274 | }); 275 | 276 | it('should get combined view of commit statuses for a SHA from a repo', function(done) { 277 | remoteRepo.getCombinedStatus(v10SHA, assertSuccessful(done, function(err, combinedStatusesView) { 278 | expect(combinedStatusesView.sha).to.equal(v10SHA); 279 | expect(combinedStatusesView.state).to.equal('success'); 280 | expect(combinedStatusesView.statuses[0].context).to.equal('continuous-integration/travis-ci/push'); 281 | expect(combinedStatusesView.total_count).to.equal(1); 282 | 283 | done(); 284 | })); 285 | }); 286 | 287 | it('should get a SHA from a repo', function(done) { 288 | remoteRepo.getSha('master', '.gitignore', assertSuccessful(done)); 289 | }); 290 | 291 | it('should get a repo by fullname', function(done) { 292 | const repoByName = github.getRepo('github-tools/github'); 293 | 294 | repoByName.getDetails(assertSuccessful(done, function(err, repo) { 295 | expect(repo).to.have.own('full_name', 'github-tools/github'); 296 | 297 | done(); 298 | })); 299 | }); 300 | 301 | it('should check if the repo is starred', function(done) { 302 | remoteRepo.isStarred(assertSuccessful(done, function(err, result) { 303 | expect(result).to.equal(false); 304 | 305 | done(); 306 | })); 307 | }); 308 | }); 309 | 310 | describe('creating/modifiying', function() { 311 | const fileName = 'test.md'; 312 | 313 | const initialText = 'This is a test.'; 314 | const initialMessage = 'This is my 44 character long commit message.'; 315 | 316 | const updatedText = 'This file has been updated.'; 317 | const updatedMessage = 'This is my 51 character long update commit message.'; 318 | 319 | const fileToDelete = 'tmp.md'; 320 | const deleteMessage = 'This is my 51 character long delete commit message.'; 321 | 322 | const unicodeFileName = '\u4E2D\u6587\u6D4B\u8BD5.md'; 323 | const unicodeText = '\u00A1\u00D3i de m\u00ED, que verg\u00FCenza!'; 324 | const unicodeMessage = 'Such na\u00EFvet\u00E9\u2026'; 325 | 326 | const imageFileName = 'image.png'; 327 | 328 | const releaseTag = 'foo'; 329 | const releaseName = 'My awesome release'; 330 | const releaseBody = 'This is my 49 character long release description.'; 331 | let sha; 332 | let releaseId; 333 | let remoteRepo; 334 | 335 | before(function() { 336 | user = github.getUser(); 337 | remoteRepo = github.getRepo(testUser.USERNAME, testRepoName); 338 | }); 339 | 340 | // 200ms between tests so that Github has a chance to settle 341 | beforeEach(function(done) { 342 | setTimeout(done, 200); 343 | }); 344 | 345 | it('should create repo', function(done) { 346 | const repoDef = { 347 | name: testRepoName, 348 | }; 349 | 350 | user.createRepo(repoDef, assertSuccessful(done, function(err, repo) { 351 | expect(repo).to.have.own('name', testRepoName); 352 | 353 | done(); 354 | })); 355 | }); 356 | 357 | it('should be able to edit repository information', function(done) { 358 | const options = { 359 | name: testRepoName, 360 | description: 'New short description', 361 | homepage: 'http://example.com', 362 | }; 363 | 364 | remoteRepo.updateRepository(options, assertSuccessful(done, 365 | function(err, repository) { 366 | expect(repository).to.have.own('homepage', options.homepage); 367 | expect(repository).to.have.own('description', options.description); 368 | expect(repository).to.have.own('name', testRepoName); 369 | done(); 370 | })); 371 | }); 372 | 373 | it('should show repo collaborators', function(done) { 374 | remoteRepo.getCollaborators(assertSuccessful(done, function(err, collaborators) { 375 | if (!(collaborators instanceof Array)) { 376 | console.log(JSON.stringify(collaborators, null, 2)); // eslint-disable-line 377 | } 378 | expect(collaborators).to.be.an.array(); 379 | expect(collaborators).to.have.length(1); 380 | 381 | const collaborator = collaborators[0]; 382 | 383 | expect(collaborator).to.have.own('login', testUser.USERNAME); 384 | expect(collaborator).to.have.own('id'); 385 | expect(collaborator).to.have.own('permissions'); 386 | 387 | done(); 388 | })); 389 | }); 390 | 391 | it('should test whether user is collaborator', function(done) { 392 | remoteRepo.isCollaborator(testUser.USERNAME, assertSuccessful(done)); 393 | }); 394 | 395 | it('should write to repo', function(done) { 396 | remoteRepo.writeFile('master', fileName, initialText, initialMessage, assertSuccessful(done, function() { 397 | wait()().then(() => remoteRepo.getContents('master', fileName, 'raw', 398 | assertSuccessful(done, function(err, fileText) { 399 | expect(fileText).to.be(initialText); 400 | 401 | done(); 402 | }))); 403 | })); 404 | }); 405 | 406 | it('should successfully write to repo when not providing optional options argument', function(done) { 407 | const promise = remoteRepo.writeFile('master', fileName, initialText, initialMessage); 408 | promise.then(() => remoteRepo.getContents('master', fileName, 'raw', 409 | assertSuccessful(done, function(err, fileText) { 410 | expect(fileText).to.be(initialText); 411 | 412 | done(); 413 | }))); 414 | }); 415 | 416 | it('should rename files', function(done) { 417 | remoteRepo.writeFile('master', fileName, initialText, initialMessage, assertSuccessful(done, function() { 418 | wait()().then(() => remoteRepo.move('master', fileName, 'new_name', assertSuccessful(done, function() { 419 | wait()().then(() => remoteRepo.getContents('master', fileName, 'raw', assertFailure(done, function(err) { 420 | expect(err.response.status).to.be(404); 421 | remoteRepo.getContents('master', 'new_name', 'raw', assertSuccessful(done, function(err, fileText) { 422 | expect(fileText).to.be(initialText); 423 | 424 | done(); 425 | })); 426 | }))); 427 | }))); 428 | })); 429 | }); 430 | 431 | it('should create a new branch', function(done) { 432 | remoteRepo.createBranch('master', 'dev', assertSuccessful(done, function(err, branch) { 433 | expect(branch).to.have.property('ref', 'refs/heads/dev'); 434 | expect(branch.object).to.have.property('sha'); 435 | 436 | done(); 437 | })); 438 | }); 439 | 440 | it('should write to repo branch', function(done) { 441 | remoteRepo.writeFile('dev', fileName, updatedText, updatedMessage, assertSuccessful(done, function() { 442 | remoteRepo.getContents('dev', fileName, 'raw', assertSuccessful(done, function(err, fileText) { 443 | expect(fileText).to.be(updatedText); 444 | 445 | done(); 446 | })); 447 | })); 448 | }); 449 | 450 | it('should compare two branches', function(done) { 451 | remoteRepo.createBranch('master', 'compare', assertSuccessful(done, function() { 452 | remoteRepo.writeFile('compare', fileName, updatedText, updatedMessage, assertSuccessful(done, function() { 453 | remoteRepo.compareBranches('master', 'compare', assertSuccessful(done, function(err, diff) { 454 | expect(diff).to.have.own('total_commits', 1); 455 | expect(diff.files[0]).to.have.own('filename', fileName); 456 | 457 | done(); 458 | })); 459 | })); 460 | })); 461 | }); 462 | 463 | it('should submit a pull request', function(done) { 464 | const base = 'master'; 465 | const head = 'pull-request'; 466 | const title = 'Test pull request'; 467 | const body = 'This is a test pull request'; 468 | const prSpec = {title, body, base, head}; 469 | 470 | remoteRepo.createBranch(base, head, assertSuccessful(done, function() { 471 | remoteRepo.writeFile(head, fileName, updatedText, updatedMessage, assertSuccessful(done, function() { 472 | remoteRepo.createPullRequest(prSpec, assertSuccessful(done, function(err, pullRequest) { 473 | expect(pullRequest).to.have.own('number'); 474 | expect(pullRequest.number).to.be.above(0); 475 | expect(pullRequest).to.have.own('title', title); 476 | expect(pullRequest).to.have.own('body', body); 477 | 478 | done(); 479 | })); 480 | })); 481 | })); 482 | }); 483 | 484 | it('should create ref on repo', function(done) { 485 | remoteRepo.getRef('heads/master', assertSuccessful(done, function(err, refSpec) { 486 | let newRef = { 487 | ref: 'refs/heads/new-test-branch', 488 | sha: refSpec.object.sha, 489 | }; 490 | remoteRepo.createRef(newRef, assertSuccessful(done)); 491 | })); 492 | }); 493 | 494 | it('should update commit status', function(done) { 495 | const status = { 496 | state: 'success', 497 | target_url: 'http://example.com', // eslint-disable-line camelcase 498 | description: 'Build was successful!', 499 | }; 500 | remoteRepo.getRef('heads/master', assertSuccessful(done, function(err, refSpec) { 501 | remoteRepo.updateStatus(refSpec.object.sha, status, assertSuccessful(done, 502 | function(err, updated) { 503 | expect(updated).to.have.own('state', status.state); 504 | expect(updated).to.have.own('target_url', status.target_url); 505 | expect(updated).to.have.own('description', status.description); 506 | expect(updated).to.have.own('context', 'default'); 507 | done(); 508 | })); 509 | })); 510 | }); 511 | 512 | it('should delete ref on repo', function(done) { 513 | remoteRepo.deleteRef('heads/new-test-branch', assertSuccessful(done)); 514 | }); 515 | 516 | it('should list tags on repo', function(done) { 517 | remoteRepo.listTags(assertSuccessful(done)); 518 | }); 519 | 520 | it('should list pulls on repo', function(done) { 521 | const filterOpts = { 522 | state: 'all', 523 | sort: 'updated', 524 | direction: 'desc', 525 | page: 1, 526 | per_page: 10 //eslint-disable-line 527 | }; 528 | 529 | remoteRepo.listPullRequests(filterOpts, assertSuccessful(done, function(err, pullRequests) { 530 | expect(pullRequests).to.be.an.array(); 531 | expect(pullRequests).to.have.length(1); 532 | 533 | done(); 534 | })); 535 | }); 536 | 537 | it('should get pull requests on repo', function(done) { 538 | const repo = github.getRepo('github-tools', 'github'); 539 | 540 | repo.getPullRequest(153, assertSuccessful(done, function(err, pr) { 541 | expect(pr).to.have.own('title'); 542 | expect(pr).to.have.own('body'); 543 | expect(pr).to.have.own('url'); 544 | 545 | done(); 546 | })); 547 | }); 548 | 549 | it('should delete a file on the repo', function(done) { 550 | remoteRepo.writeFile('master', fileToDelete, initialText, deleteMessage, assertSuccessful(done, function() { 551 | remoteRepo.deleteFile('master', fileToDelete, assertSuccessful(done)); 552 | })); 553 | }); 554 | 555 | it('should write author and committer to repo', function(done) { 556 | const options = { 557 | author: {name: 'Author Name', email: 'author@example.com'}, 558 | committer: {name: 'Committer Name', email: 'committer@example.com'}, 559 | }; 560 | 561 | remoteRepo.writeFile('dev', 562 | fileName, initialText, initialMessage, options, 563 | assertSuccessful(done, function(error, commit) { 564 | remoteRepo.getCommit(commit.commit.sha, assertSuccessful(done, function(err, commit2) { 565 | const author = commit2.author; 566 | const committer = commit2.committer; 567 | expect(author.name).to.be('Author Name'); 568 | expect(author.email).to.be('author@example.com'); 569 | expect(committer.name).to.be('Committer Name'); 570 | expect(committer.email).to.be('committer@example.com'); 571 | 572 | done(); 573 | })); 574 | }) 575 | ); 576 | }); 577 | 578 | it('should be able to write all the unicode', function(done) { 579 | remoteRepo.writeFile('master', unicodeFileName, unicodeText, unicodeMessage, assertSuccessful(done, 580 | function(err, commit) { 581 | expect(commit.content.name).to.be(unicodeFileName); 582 | expect(commit.commit.message).to.be(unicodeMessage); 583 | 584 | remoteRepo.getContents('master', unicodeFileName, 'raw', assertSuccessful(done, function(err, fileText) { 585 | expect(fileText).to.be(unicodeText); 586 | 587 | done(); 588 | })); 589 | })); 590 | }); 591 | 592 | it('should pass a regression test for _request (#14)', function(done) { 593 | remoteRepo.getRef('heads/master', assertSuccessful(done, function(err, refSpec) { 594 | let newRef = { 595 | ref: 'refs/heads/testing-14', 596 | sha: refSpec.object.sha, 597 | }; 598 | 599 | remoteRepo.createRef(newRef, assertSuccessful(done, function() { 600 | // Triggers GET: 601 | // https://api.github.com/repos/michael/cmake_cdt7_stalled/git/refs/heads/prose-integration 602 | remoteRepo.getRef('heads/master', assertSuccessful(done, function() { 603 | // Triggers DELETE: 604 | // https://api.github.com/repos/michael/cmake_cdt7_stalled/git/refs/heads/prose-integration 605 | remoteRepo.deleteRef('heads/testing-14', assertSuccessful(done, function(err, res, xhr) { 606 | expect(xhr.status).to.be(204); 607 | 608 | done(); 609 | })); 610 | })); 611 | })); 612 | })); 613 | }); 614 | 615 | it('should be able to write an image to the repo', function(done) { 616 | const opts = { 617 | encode: false, 618 | }; 619 | 620 | remoteRepo.writeFile('master', imageFileName, imageB64, initialMessage, opts, assertSuccessful(done, 621 | function(err, commit) { 622 | sha = commit.sha; 623 | 624 | done(); 625 | })); 626 | }); 627 | 628 | it('should be able to write a string blob to the repo', function(done) { 629 | remoteRepo.createBlob('String test', assertSuccessful(done)); 630 | }); 631 | 632 | it('should be able to write a file blob to the repo', function(done) { 633 | remoteRepo.createBlob(imageBlob, assertSuccessful(done)); 634 | }); 635 | 636 | it('should star the repo', function(done) { 637 | remoteRepo.star(assertSuccessful(done, function() { 638 | remoteRepo.isStarred(assertSuccessful(done)); 639 | })); 640 | }); 641 | 642 | it('should unstar the repo', function(done) { 643 | remoteRepo.unstar(assertSuccessful(done, function() { 644 | remoteRepo.isStarred(assertSuccessful(done, function(_, isStarred) { 645 | expect(isStarred).to.be(false); 646 | done(); 647 | })); 648 | })); 649 | }); 650 | 651 | it('should fail on broken commit', function(done) { 652 | remoteRepo.commit('broken-parent-hash', 'broken-tree-hash', initialMessage, assertFailure(done, function(err) { 653 | expect(err.response.status).to.be(422); 654 | done(); 655 | })); 656 | }); 657 | 658 | it('should succeed on proper commit', function(done) { 659 | let parentSHA = ''; 660 | let treeSHA = ''; 661 | remoteRepo.getRef('heads/master').then((ref) => { 662 | parentSHA = ref.data.object.sha; 663 | return remoteRepo.getCommit(parentSHA); 664 | }).then((commit) => { 665 | treeSHA = commit.data.tree.sha; 666 | return remoteRepo.commit(parentSHA, treeSHA, 'is this thing on?'); 667 | }).then((commit) => { 668 | expect(commit.data.author).to.have.own('name', 'github-tools-test'); 669 | done(); 670 | }); 671 | }); 672 | 673 | it('should allow commit to change author', function(done) { 674 | let parentSHA = ''; 675 | let treeSHA = ''; 676 | remoteRepo.getRef('heads/master').then((ref) => { 677 | parentSHA = ref.data.object.sha; 678 | return remoteRepo.getCommit(parentSHA); 679 | }).then((commit) => { 680 | treeSHA = commit.data.tree.sha; 681 | return remoteRepo.commit(parentSHA, treeSHA, 'Who made this commit?', { 682 | author: { 683 | name: 'Jimothy Halpert', 684 | email: 'jim@dundermifflin.com', 685 | }, 686 | }); 687 | }).then((commit) => { 688 | expect(commit.data.author).to.have.own('name', 'Jimothy Halpert'); 689 | expect(commit.data.author).to.have.own('email', 'jim@dundermifflin.com'); 690 | done(); 691 | }).catch((err) => { 692 | throw err; 693 | }); 694 | }); 695 | 696 | it('should create a release', function(done) { 697 | const releaseDef = { 698 | name: releaseName, 699 | tag_name: releaseTag, // eslint-disable-line 700 | target_commitish: sha // eslint-disable-line 701 | }; 702 | 703 | remoteRepo.createRelease(releaseDef, assertSuccessful(done, function(err, res) { 704 | releaseId = res.id; 705 | done(); 706 | })); 707 | }); 708 | 709 | it('should edit a release', function(done) { 710 | const releaseDef = { 711 | name: releaseName, 712 | body: releaseBody, 713 | }; 714 | 715 | remoteRepo.updateRelease(releaseId, releaseDef, assertSuccessful(done, function(err, release) { 716 | expect(release).to.have.own('name', releaseName); 717 | expect(release).to.have.own('body', releaseBody); 718 | 719 | done(); 720 | })); 721 | }); 722 | 723 | it('should read all releases', function(done) { 724 | remoteRepo.listReleases(assertSuccessful(done, function(err, releases) { 725 | expect(releases).to.be.an.array(); 726 | done(); 727 | })); 728 | }); 729 | 730 | it('should read a release', function(done) { 731 | remoteRepo.getRelease(releaseId, assertSuccessful(done, function(err, release) { 732 | expect(release).to.have.own('name', releaseName); 733 | 734 | done(); 735 | })); 736 | }); 737 | 738 | it('should delete a release', function(done) { 739 | remoteRepo.deleteRelease(releaseId, assertSuccessful(done)); 740 | }); 741 | 742 | it('should create a project', function(done) { 743 | remoteRepo.createProject({ 744 | name: 'test-project', 745 | body: 'body', 746 | }, assertSuccessful(done, function(err, project) { 747 | expect(project).to.own('name', 'test-project'); 748 | expect(project).to.own('body', 'body'); 749 | done(); 750 | })); 751 | }); 752 | 753 | it('should list repo projects', function(done) { 754 | remoteRepo.listProjects(assertSuccessful(done, function(err, projects) { 755 | expect(projects).to.be.an.array(); 756 | expect(projects.length).to.equal(1); 757 | done(); 758 | })); 759 | }); 760 | }); 761 | 762 | describe('deleting', function() { 763 | let remoteRepo; 764 | before(function() { 765 | remoteRepo = github.getRepo(testUser.USERNAME, testRepoName); 766 | }); 767 | 768 | // 200ms between tests so that Github has a chance to settle 769 | beforeEach(function(done) { 770 | setTimeout(done, 200); 771 | }); 772 | 773 | it('should delete the repo', function(done) { 774 | remoteRepo.deleteRepo(assertSuccessful(done, function(err, result) { 775 | expect(result).to.be(true); 776 | 777 | done(); 778 | })); 779 | }); 780 | }); 781 | }); 782 | -------------------------------------------------------------------------------- /test/search.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | import nock from 'nock'; 3 | 4 | import Github from '../lib/GitHub'; 5 | import testUser from './fixtures/user.js'; 6 | 7 | describe('Search', function() { 8 | this.timeout(20 * 1000); // eslint-disable-line no-invalid-this 9 | let github; 10 | 11 | before(function() { 12 | github = new Github({ 13 | username: testUser.USERNAME, 14 | password: testUser.PASSWORD, 15 | auth: 'basic', 16 | }); 17 | nock.load('test/fixtures/search.json'); 18 | }); 19 | 20 | it('should search repositories', function() { 21 | let options; 22 | let search = github.search({ 23 | q: 'tetris language:assembly', 24 | sort: 'stars', 25 | order: 'desc', 26 | }); 27 | 28 | return search.forRepositories(options) 29 | .then(function({data}) { 30 | expect(data).to.be.an.array(); 31 | expect(data.length).to.be.above(0); 32 | }); 33 | }); 34 | 35 | it('should search code', function() { 36 | let options; 37 | let search = github.search({ 38 | q: 'addClass in:file language:js repo:jquery/jquery', 39 | }); 40 | 41 | return search.forCode(options) 42 | .then(function({data}) { 43 | expect(data).to.be.an.array(); 44 | expect(data.length).to.be.above(0); 45 | }); 46 | }); 47 | 48 | it('should search issues', function() { 49 | let options; 50 | let search = github.search({ 51 | q: 'windows pip label:bug language:python state:open ', 52 | sort: 'created', 53 | order: 'asc', 54 | }); 55 | 56 | return search.forIssues(options) 57 | .then(function({data}) { 58 | expect(data).to.be.an.array(); 59 | expect(data.length).to.be.above(0); 60 | }); 61 | }); 62 | 63 | it('should search users', function() { 64 | let options; 65 | let search = github.search({ 66 | q: 'tom repos:>42 followers:>1000', 67 | }); 68 | 69 | return search.forUsers(options) 70 | .then(function({data}) { 71 | expect(data).to.be.an.array(); 72 | expect(data.length).to.be.above(0); 73 | }); 74 | }); 75 | 76 | after(function() { 77 | nock.cleanAll(); 78 | nock.restore(); 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /test/team.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import testUser from './fixtures/user.js'; 5 | import {assertFailure} from './helpers/callbacks'; 6 | import getTestRepoName from './helpers/getTestRepoName'; 7 | 8 | const altUser = { 9 | USERNAME: 'mtscout6-test', 10 | }; 11 | 12 | function createTestTeam() { 13 | const name = getTestRepoName(); 14 | 15 | const github = new Github({ 16 | username: testUser.USERNAME, 17 | password: testUser.PASSWORD, 18 | auth: 'basic', 19 | }); 20 | 21 | const org = github.getOrganization(testUser.ORGANIZATION); 22 | 23 | return org.createTeam({ 24 | name, 25 | privacy: 'closed', 26 | }).then(({data: result}) => { 27 | const team = github.getTeam(result.id); 28 | return {team, name}; 29 | }); 30 | } 31 | 32 | let team; 33 | let name; 34 | 35 | describe('Team', function() { // Isolate tests that are based on a fixed team 36 | before(function() { 37 | const github = new Github({ 38 | username: testUser.USERNAME, 39 | password: testUser.PASSWORD, 40 | auth: 'basic', 41 | }); 42 | 43 | const org = github.getOrganization(testUser.ORGANIZATION); 44 | 45 | /* eslint-disable no-console */ 46 | // The code below add a fixed-test-repo-1 47 | let promiseRepo = new Promise((resolve) => { 48 | org 49 | .createRepo({name: 'fixed-test-repo-1'}) 50 | .then(resolve, () => { 51 | console.log('skiped fixed-test-repo-1 creation'); 52 | resolve(); 53 | }); 54 | }); 55 | 56 | // The code below add a fixed-test-repo-1 57 | let promiseTeam = org 58 | .createTeam({ 59 | name: 'fixed-test-repo-1', 60 | repo_names: [testUser.ORGANIZATION + '/fixed-test-repo-1'], // eslint-disable-line camelcase 61 | }) 62 | .then(({data: team}) => team) 63 | .catch(() => { 64 | console.log('skiped fixed-test-repo-1 creation'); 65 | // Team already exists, fetch the team 66 | return org.getTeams().then(({data: teams}) => { 67 | let team = teams 68 | .filter((team) => team.name === 'fixed-test-repo-1') 69 | .pop(); 70 | if (!team) { 71 | throw new Error('missing fixed-test-repo-1'); 72 | } 73 | return team; 74 | }); 75 | }); 76 | /* eslint-enable no-console */ 77 | 78 | return promiseRepo.then(() => { 79 | return promiseTeam 80 | .then((t) => { 81 | team = github.getTeam(t.id); 82 | return team; 83 | }) 84 | .then((team) => { 85 | let setupTeam = [ 86 | team.addMembership(altUser.USERNAME), 87 | team.addMembership(testUser.USERNAME), 88 | team.manageRepo(testUser.ORGANIZATION, 'fixed-test-repo-1'), 89 | ]; 90 | return Promise.all(setupTeam); 91 | }); 92 | }); 93 | }); 94 | 95 | it('should get membership for a given user', function() { 96 | return team.getMembership(altUser.USERNAME) 97 | .then(function({data}) { 98 | expect(data.state).to.equal('active'); 99 | expect(data.role).to.equal('member'); 100 | }); 101 | }); 102 | 103 | it('should list the users in the team', function() { 104 | return team.listMembers() 105 | .then(function({data: members}) { 106 | expect(members).to.be.an.array(); 107 | 108 | const hasTestUser = members.some((member) => member.login === testUser.USERNAME); 109 | 110 | expect(hasTestUser).to.be.true(); 111 | }); 112 | }); 113 | 114 | it('should get team repos', function() { 115 | return team.listRepos() 116 | .then(({data}) => { 117 | const hasRepo = data.some((repo) => repo.name === 'fixed-test-repo-1'); 118 | 119 | expect(hasRepo).to.be.true(); 120 | }); 121 | }); 122 | 123 | it('should get team', function() { 124 | return team.getTeam() 125 | .then(({data}) => { 126 | expect(data.name).to.equal('fixed-test-repo-1'); 127 | }); 128 | }); 129 | 130 | it('should check if team manages repo', function() { 131 | return team.isManagedRepo(testUser.ORGANIZATION, 'fixed-test-repo-1') 132 | .then((result) => { 133 | expect(result).to.be.true(); 134 | }); 135 | }); 136 | }); 137 | 138 | describe('Team', function() { // Isolate tests that need a new team per test 139 | beforeEach(function() { 140 | return createTestTeam() 141 | .then((x) => { 142 | team = x.team; 143 | name = x.name; 144 | }); 145 | }); 146 | 147 | // Test for Team deletion 148 | afterEach(function(done) { 149 | team.deleteTeam() 150 | .then(() => team.getTeam(assertFailure(done))); 151 | }); 152 | 153 | it('should update team', function() { 154 | const newName = `${name}-updated`; 155 | return team.editTeam({name: newName}) 156 | .then(function({data}) { 157 | expect(data.name).to.equal(newName); 158 | }); 159 | }); 160 | 161 | it('should add membership for a given user', function() { 162 | return team.addMembership(altUser.USERNAME) 163 | .then(({data}) => { 164 | const {state, role} = data; 165 | expect(state === 'active' || state === 'pending').to.be.true(); 166 | expect(role).to.equal('member'); 167 | }); 168 | }); 169 | 170 | it('should add membership as a maintainer for a given user', function() { 171 | return team.addMembership(altUser.USERNAME, {role: 'maintainer'}) 172 | .then(({data}) => { 173 | const {state, role} = data; 174 | expect(state === 'active' || state === 'pending').to.be.true(); 175 | expect(role).to.equal('maintainer'); 176 | }); 177 | }); 178 | 179 | it('should add/remove team management of repo', function() { 180 | return team.manageRepo(testUser.ORGANIZATION, 'fixed-test-repo-1', {permission: 'pull'}) 181 | .then((result) => { 182 | expect(result).to.be.true(); 183 | return team.unmanageRepo(testUser.ORGANIZATION, 'fixed-test-repo-1'); 184 | }) 185 | .then((result) => { 186 | expect(result).to.be.true(); 187 | }); 188 | }); 189 | }); 190 | -------------------------------------------------------------------------------- /test/user.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'must'; 2 | 3 | import Github from '../lib/GitHub'; 4 | import testUser from './fixtures/user.js'; 5 | import {assertSuccessful, assertArray} from './helpers/callbacks'; 6 | 7 | describe('User', function() { 8 | let github; 9 | let user; 10 | 11 | before(function() { 12 | github = new Github({ 13 | username: testUser.USERNAME, 14 | password: testUser.PASSWORD, 15 | auth: 'basic', 16 | }); 17 | user = github.getUser(); 18 | }); 19 | 20 | it('should get user repos', function(done) { 21 | user.listRepos(assertArray(done)); 22 | }); 23 | 24 | it('should get user repos with options', function(done) { 25 | const filterOpts = { 26 | type: 'owner', 27 | sort: 'updated', 28 | per_page: 90, // eslint-disable-line 29 | page: 10, 30 | }; 31 | 32 | user.listRepos(filterOpts, assertArray(done)); 33 | }); 34 | 35 | it('should get user orgs', function(done) { 36 | user.listOrgs(assertArray(done)); 37 | }); 38 | 39 | it('should get user followers', function(done) { 40 | user.listFollowers(assertArray(done)); 41 | }); 42 | 43 | it('should get user following list', function(done) { 44 | user.listFollowing(assertArray(done)); 45 | }); 46 | 47 | it('should get user gists', function(done) { 48 | user.listGists(assertArray(done)); 49 | }); 50 | 51 | it('should get user notifications', function(done) { 52 | user.listNotifications(assertArray(done)); 53 | }); 54 | 55 | it('should get user notifications with options', function(done) { 56 | const filterOpts = { 57 | all: true, 58 | participating: true, 59 | since: '2015-01-01T00:00:00Z', 60 | before: '2015-02-01T00:00:00Z', 61 | }; 62 | 63 | user.listNotifications(filterOpts, assertArray(done)); 64 | }); 65 | 66 | it('should get the user\'s profile', function(done) { 67 | user.getProfile(assertSuccessful(done)); 68 | }); 69 | 70 | it('should show user\'s starred repos', function(done) { 71 | user.listStarredRepos(assertArray(done)); 72 | }); 73 | 74 | it('should show user\'s starred gists', function(done) { 75 | const option = { 76 | since: '2015-01-01T00:00:00Z', 77 | }; 78 | user.listStarredGists(option, assertArray(done)); 79 | }); 80 | 81 | describe('following a user', function() { 82 | const userToFollow = 'ingalls'; 83 | 84 | before(function() { 85 | return user.unfollow(userToFollow); 86 | }); 87 | 88 | it('should follow user', function(done) { 89 | user.follow(userToFollow, assertSuccessful(done, function(err, resp) { 90 | user._request('GET', '/user/following', null, assertSuccessful(done, function(err, following) { 91 | expect((following.some((user) => user['login'] === userToFollow))).to.be.true(); 92 | done(); 93 | })); 94 | })); 95 | }); 96 | }); 97 | 98 | describe('following yourself', function() { 99 | const userToFollow = testUser.USERNAME; 100 | 101 | before(function() { 102 | return user.unfollow(userToFollow); 103 | }); 104 | 105 | it('should not list yourself as one of your followers', function(done) { 106 | user.follow(userToFollow, assertSuccessful(done, function(err, resp) { 107 | user._request('GET', '/user/following', null, assertSuccessful(done, function(err, following) { 108 | expect((following.some((user) => user['login'] === userToFollow))).to.be.false(); 109 | done(); 110 | })); 111 | })); 112 | }); 113 | }); 114 | 115 | describe('unfollowing a user', function(done) { 116 | const userToUnfollow = 'ingalls'; 117 | 118 | before(function() { 119 | return user.follow(userToUnfollow); 120 | }); 121 | 122 | it('should unfollow a user', function(done) { 123 | user.unfollow(userToUnfollow, assertSuccessful(done, function(err, resp) { 124 | user._request('GET', '/user/following', null, assertSuccessful(done, function(err, following) { 125 | expect((following.some((user) => user['login'] === userToUnfollow))).to.be.false(); 126 | done(); 127 | })); 128 | })); 129 | }); 130 | }); 131 | 132 | it('should list the email addresses of the user', function(done) { 133 | user.getEmails(assertSuccessful(done)); 134 | }); 135 | }); 136 | -------------------------------------------------------------------------------- /test/vendor/Blob.js: -------------------------------------------------------------------------------- 1 | /* Blob.js 2 | * A Blob implementation. 3 | * 2014-07-24 4 | * 5 | * By Eli Grey, http://eligrey.com 6 | * By Devin Samarin, https://github.com/dsamarin 7 | * License: MIT 8 | * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md 9 | */ 10 | 11 | /*global self, unescape */ 12 | /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, 13 | plusplus: true */ 14 | 15 | /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ 16 | 17 | (function (view) { 18 | "use strict"; 19 | 20 | view.URL = view.URL || view.webkitURL; 21 | 22 | if (view.Blob && view.URL) { 23 | try { 24 | new Blob; 25 | return; 26 | } catch (e) {} 27 | } 28 | 29 | // Internally we use a BlobBuilder implementation to base Blob off of 30 | // in order to support older browsers that only have BlobBuilder 31 | var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) { 32 | var 33 | get_class = function(object) { 34 | return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; 35 | } 36 | , FakeBlobBuilder = function BlobBuilder() { 37 | this.data = []; 38 | } 39 | , FakeBlob = function Blob(data, type, encoding) { 40 | this.data = data; 41 | this.size = data.length; 42 | this.type = type; 43 | this.encoding = encoding; 44 | } 45 | , FBB_proto = FakeBlobBuilder.prototype 46 | , FB_proto = FakeBlob.prototype 47 | , FileReaderSync = view.FileReaderSync 48 | , FileException = function(type) { 49 | this.code = this[this.name = type]; 50 | } 51 | , file_ex_codes = ( 52 | "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " 53 | + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" 54 | ).split(" ") 55 | , file_ex_code = file_ex_codes.length 56 | , real_URL = view.URL || view.webkitURL || view 57 | , real_create_object_URL = real_URL.createObjectURL 58 | , real_revoke_object_URL = real_URL.revokeObjectURL 59 | , URL = real_URL 60 | , btoa = view.btoa 61 | , atob = view.atob 62 | 63 | , ArrayBuffer = view.ArrayBuffer 64 | , Uint8Array = view.Uint8Array 65 | 66 | , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/ 67 | ; 68 | FakeBlob.fake = FB_proto.fake = true; 69 | while (file_ex_code--) { 70 | FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; 71 | } 72 | // Polyfill URL 73 | if (!real_URL.createObjectURL) { 74 | URL = view.URL = function(uri) { 75 | var 76 | uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a") 77 | , uri_origin 78 | ; 79 | uri_info.href = uri; 80 | if (!("origin" in uri_info)) { 81 | if (uri_info.protocol.toLowerCase() === "data:") { 82 | uri_info.origin = null; 83 | } else { 84 | uri_origin = uri.match(origin); 85 | uri_info.origin = uri_origin && uri_origin[1]; 86 | } 87 | } 88 | return uri_info; 89 | }; 90 | } 91 | URL.createObjectURL = function(blob) { 92 | var 93 | type = blob.type 94 | , data_URI_header 95 | ; 96 | if (type === null) { 97 | type = "application/octet-stream"; 98 | } 99 | if (blob instanceof FakeBlob) { 100 | data_URI_header = "data:" + type; 101 | if (blob.encoding === "base64") { 102 | return data_URI_header + ";base64," + blob.data; 103 | } else if (blob.encoding === "URI") { 104 | return data_URI_header + "," + decodeURIComponent(blob.data); 105 | } if (btoa) { 106 | return data_URI_header + ";base64," + btoa(blob.data); 107 | } else { 108 | return data_URI_header + "," + encodeURIComponent(blob.data); 109 | } 110 | } else if (real_create_object_URL) { 111 | return real_create_object_URL.call(real_URL, blob); 112 | } 113 | }; 114 | URL.revokeObjectURL = function(object_URL) { 115 | if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { 116 | real_revoke_object_URL.call(real_URL, object_URL); 117 | } 118 | }; 119 | FBB_proto.append = function(data/*, endings*/) { 120 | var bb = this.data; 121 | // decode data to a binary string 122 | if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { 123 | var 124 | str = "" 125 | , buf = new Uint8Array(data) 126 | , i = 0 127 | , buf_len = buf.length 128 | ; 129 | for (; i < buf_len; i++) { 130 | str += String.fromCharCode(buf[i]); 131 | } 132 | bb.push(str); 133 | } else if (get_class(data) === "Blob" || get_class(data) === "File") { 134 | if (FileReaderSync) { 135 | var fr = new FileReaderSync; 136 | bb.push(fr.readAsBinaryString(data)); 137 | } else { 138 | // async FileReader won't work as BlobBuilder is sync 139 | throw new FileException("NOT_READABLE_ERR"); 140 | } 141 | } else if (data instanceof FakeBlob) { 142 | if (data.encoding === "base64" && atob) { 143 | bb.push(atob(data.data)); 144 | } else if (data.encoding === "URI") { 145 | bb.push(decodeURIComponent(data.data)); 146 | } else if (data.encoding === "raw") { 147 | bb.push(data.data); 148 | } 149 | } else { 150 | if (typeof data !== "string") { 151 | data += ""; // convert unsupported types to strings 152 | } 153 | // decode UTF-16 to binary string 154 | bb.push(unescape(encodeURIComponent(data))); 155 | } 156 | }; 157 | FBB_proto.getBlob = function(type) { 158 | if (!arguments.length) { 159 | type = null; 160 | } 161 | return new FakeBlob(this.data.join(""), type, "raw"); 162 | }; 163 | FBB_proto.toString = function() { 164 | return "[object BlobBuilder]"; 165 | }; 166 | FB_proto.slice = function(start, end, type) { 167 | var args = arguments.length; 168 | if (args < 3) { 169 | type = null; 170 | } 171 | return new FakeBlob( 172 | this.data.slice(start, args > 1 ? end : this.data.length) 173 | , type 174 | , this.encoding 175 | ); 176 | }; 177 | FB_proto.toString = function() { 178 | return "[object Blob]"; 179 | }; 180 | FB_proto.close = function() { 181 | this.size = 0; 182 | delete this.data; 183 | }; 184 | return FakeBlobBuilder; 185 | }(view)); 186 | 187 | view.Blob = function(blobParts, options) { 188 | var type = options ? (options.type || "") : ""; 189 | var builder = new BlobBuilder(); 190 | if (blobParts) { 191 | for (var i = 0, len = blobParts.length; i < len; i++) { 192 | if (Uint8Array && blobParts[i] instanceof Uint8Array) { 193 | builder.append(blobParts[i].buffer); 194 | } 195 | else { 196 | builder.append(blobParts[i]); 197 | } 198 | } 199 | } 200 | var blob = builder.getBlob(type); 201 | if (!blob.slice && blob.webkitSlice) { 202 | blob.slice = blob.webkitSlice; 203 | } 204 | return blob; 205 | }; 206 | 207 | var getPrototypeOf = Object.getPrototypeOf || function(object) { 208 | return object.__proto__; 209 | }; 210 | view.Blob.prototype = getPrototypeOf(new view.Blob()); 211 | }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); 212 | --------------------------------------------------------------------------------