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)
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