Skip to content

Commit 7c73463

Browse files
committed
fix(search): compensate for the search api returning an object instead of an array
closes #335
1 parent 2d102be commit 7c73463

File tree

3 files changed

+65
-35
lines changed

3 files changed

+65
-35
lines changed

CHANGELOG.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Change Log
22

3-
## master
3+
## 2.2.0 - 2016/05/27
44
### Features
55
* add `Issue.listIssueEvents`
66

77
### Fixes
8+
* Search returns results again
89

9-
## 2.1.0
10+
## 2.1.0 - 2016/05/26
1011
### Features
1112
Team API
1213
* `Organization.createTeam`
@@ -40,7 +41,7 @@ User
4041
### Fixes
4142
* `Repository`: Replace invalid references to `postTree` with `createTree`
4243

43-
## 1.2.0 - 2015/05/11
44+
## 1.2.0 - 2016/05/11
4445
### Features
4546
* Search API now returns all pages of results
4647
* Added `Repository.listReleases`
@@ -58,7 +59,7 @@ Added functions for issue comments
5859
### Fixes
5960
* all functions now return a Promise
6061

61-
## 1.1.0 - 2015/05/03
62+
## 1.1.0 - 2016/05/03
6263
### Features
6364
Added methods for commenting on Gists:
6465
* `Gist.listComments`
@@ -70,7 +71,7 @@ Added methods for commenting on Gists:
7071
### Fixes
7172
* `Repository.deleteFile` now correctly returns a promise.
7273

73-
## 1.0.0 - 2015/04/27
74+
## 1.0.0 - 2016/04/27
7475
Complete rewrite in ES2015.
7576

7677
* Promise-ified the API

lib/Requestable.js

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ if (typeof Promise === 'undefined') {
1616
polyfill();
1717
}
1818

19+
/**
20+
* The error structure returned when a network call fails
21+
*/
22+
class ResponseError extends Error {
23+
/**
24+
* Construct a new ResponseError
25+
* @param {string} message - an message to return instead of the the default error message
26+
* @param {string} path - the requested path
27+
* @param {Object} response - the object returned by Axios
28+
*/
29+
constructor(message, path, response) {
30+
super(message);
31+
this.path = path;
32+
this.request = response.config;
33+
this.response = response;
34+
this.status = response.status;
35+
}
36+
}
37+
1938
/**
2039
* Requestable wraps the logic for making http requests to the API
2140
*/
@@ -208,7 +227,16 @@ class Requestable {
208227

209228
return this._request('GET', path, options)
210229
.then((response) => {
211-
results.push.apply(results, response.data);
230+
let thisGroup;
231+
if (response.data instanceof Array) {
232+
thisGroup = response.data;
233+
} else if (response.data.items instanceof Array) {
234+
thisGroup = response.data.items;
235+
} else {
236+
let message = `cannot figure out how to append ${response.data} to the result set`;
237+
throw new ResponseError(message, path, response);
238+
}
239+
results.push.apply(results, thisGroup);
212240

213241
const nextUrl = getNextPage(response.headers.link);
214242
if (nextUrl) {
@@ -231,24 +259,6 @@ module.exports = Requestable;
231259
// ////////////////////////// //
232260
// Private helper functions //
233261
// ////////////////////////// //
234-
/**
235-
* The error structure returned when a network call fails
236-
*/
237-
class ResponseError extends Error {
238-
/**
239-
* Construct a new ResponseError
240-
* @param {string} path - the requested path
241-
* @param {Object} response - the object returned by Axios
242-
*/
243-
constructor(path, response) {
244-
super(`error making request ${response.config.method} ${response.config.url}`);
245-
this.path = path;
246-
this.request = response.config;
247-
this.response = response;
248-
this.status = response.status;
249-
}
250-
}
251-
252262
const METHODS_WITH_NO_BODY = ['GET', 'HEAD', 'DELETE'];
253263
function methodHasNoBody(method) {
254264
return METHODS_WITH_NO_BODY.indexOf(method) !== -1;
@@ -267,8 +277,9 @@ function getNextPage(linksHeader = '') {
267277

268278
function callbackErrorOrThrow(cb, path) {
269279
return function handler(response) {
270-
log(`error making request ${response.config.method} ${response.config.url} ${JSON.stringify(response.data)}`);
271-
let error = new ResponseError(path, response);
280+
let message = `error making request ${response.config.method} ${response.config.url}`;
281+
let error = new ResponseError(message, path, response);
282+
log(`${message} ${JSON.stringify(response.data)}`);
272283
if (cb) {
273284
log('going to error callback');
274285
cb(error);

test/search.spec.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import expect from 'must';
2+
13
import Github from '../lib/GitHub';
24
import testUser from './fixtures/user.json';
3-
import {assertSuccessful} from './helpers/callbacks';
45

56
describe('Search', function() {
7+
this.timeout(20 * 1000);
68
let github;
79

810
before(function() {
@@ -13,43 +15,59 @@ describe('Search', function() {
1315
});
1416
});
1517

16-
it('should search repositories', function(done) {
18+
it('should search repositories', function() {
1719
let options;
1820
let search = github.search({
1921
q: 'tetris language:assembly',
2022
sort: 'stars',
2123
order: 'desc'
2224
});
2325

24-
search.forRepositories(options, assertSuccessful(done));
26+
return search.forRepositories(options)
27+
.then(function({data}) {
28+
expect(data).to.be.an.array();
29+
expect(data.length).to.be.above(0);
30+
});
2531
});
2632

27-
it('should search code', function(done) {
33+
it('should search code', function() {
2834
let options;
2935
let search = github.search({
3036
q: 'addClass in:file language:js repo:jquery/jquery'
3137
});
3238

33-
search.forCode(options, assertSuccessful(done));
39+
return search.forCode(options)
40+
.then(function({data}) {
41+
expect(data).to.be.an.array();
42+
expect(data.length).to.be.above(0);
43+
});
3444
});
3545

36-
it('should search issues', function(done) {
46+
it('should search issues', function() {
3747
let options;
3848
let search = github.search({
3949
q: 'windows pip label:bug language:python state:open ',
4050
sort: 'created',
4151
order: 'asc'
4252
});
4353

44-
search.forIssues(options, assertSuccessful(done));
54+
return search.forIssues(options)
55+
.then(function({data}) {
56+
expect(data).to.be.an.array();
57+
expect(data.length).to.be.above(0);
58+
});
4559
});
4660

47-
it('should search users', function(done) {
61+
it('should search users', function() {
4862
let options;
4963
let search = github.search({
5064
q: 'tom repos:>42 followers:>1000'
5165
});
5266

53-
search.forUsers(options, assertSuccessful(done));
67+
return search.forUsers(options)
68+
.then(function({data}) {
69+
expect(data).to.be.an.array();
70+
expect(data.length).to.be.above(0);
71+
});
5472
});
5573
});

0 commit comments

Comments
 (0)