Skip to content

Commit 5f7fb6c

Browse files
authored
feat: adds unit testing relevance methods (#777)
1 parent 536f4a6 commit 5f7fb6c

File tree

5 files changed

+285
-0
lines changed

5 files changed

+285
-0
lines changed

src/Index.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,69 @@ Index.prototype.exists = function(callback) {
923923
});
924924
};
925925

926+
Index.prototype.findObject = function(findCallback, requestOptions, callback) {
927+
requestOptions = requestOptions === undefined ? {} : requestOptions;
928+
var paginate = requestOptions.paginate !== undefined ? requestOptions.paginate : true;
929+
var query = requestOptions.query !== undefined ? requestOptions.query : '';
930+
931+
var that = this;
932+
var page = 0;
933+
934+
var paginateLoop = function() {
935+
requestOptions.page = page;
936+
937+
return that.search(query, requestOptions).then(function(result) {
938+
var hits = result.hits;
939+
940+
for (var position = 0; position < hits.length; position++) {
941+
var hit = hits[position];
942+
if (findCallback(hit)) {
943+
return {
944+
object: hit,
945+
position: position,
946+
page: page
947+
};
948+
}
949+
}
950+
951+
page += 1;
952+
953+
// paginate if option was set and has next page
954+
if (!paginate || page >= result.nbPages) {
955+
throw new errors.ObjectNotFound('Object not found');
956+
}
957+
958+
return paginateLoop();
959+
});
960+
};
961+
962+
var promise = paginateLoop(page);
963+
964+
if (callback === undefined) {
965+
return promise;
966+
}
967+
968+
promise
969+
.then(function(res) {
970+
callback(null, res);
971+
})
972+
.catch(function(err) {
973+
callback(err);
974+
});
975+
};
976+
977+
Index.prototype.getObjectPosition = function(result, objectID) {
978+
var hits = result.hits;
979+
980+
for (var position = 0; position < hits.length; position++) {
981+
if (hits[position].objectID === objectID) {
982+
return position;
983+
}
984+
}
985+
986+
return -1;
987+
};
988+
926989
/*
927990
* Set settings for this index
928991
*

src/errors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ module.exports = {
7575
'JSONPScriptError',
7676
'<script> unable to load due to an `error` event on it'
7777
),
78+
ObjectNotFound: createCustomError(
79+
'ObjectNotFound',
80+
'Object not found'
81+
),
7882
Unknown: createCustomError(
7983
'Unknown',
8084
'Unknown error occured'

test/spec/common/index/findObject.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
'use strict';
2+
3+
var test = require('tape');
4+
var fauxJax = require('faux-jax');
5+
var bind = require('lodash-compat/function/bind');
6+
7+
var createFixture = require('../../../utils/create-fixture');
8+
var fixture = createFixture();
9+
10+
var hits = [
11+
{company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
12+
{company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
13+
{company: 'Amazon', name: 'Jeff Bezos'},
14+
{company: 'Arista Networks', name: 'Jayshree Ullal'},
15+
{company: 'Google', name: 'Larry Page'},
16+
{company: 'Google', name: 'Rob Pike'},
17+
{company: 'Google', name: 'Serguey Brin'},
18+
{company: 'Apple', name: 'Steve Jobs'},
19+
{company: 'Apple', name: 'Steve Wozniak'},
20+
{company: 'Microsoft', name: 'Bill Gates'},
21+
{company: 'SpaceX', name: 'Elon Musk'},
22+
{company: 'Tesla', name: 'Elon Musk'},
23+
{company: 'Yahoo', name: 'Marissa Mayer'}
24+
];
25+
26+
fauxJax.install();
27+
28+
test('findObject: no object was found when callback always return false', function(t) {
29+
var index = fixture.index;
30+
t.plan(1);
31+
32+
fauxJax.once('request', function(req) {
33+
req.respond(
34+
200,
35+
{},
36+
JSON.stringify({
37+
hits: hits,
38+
nbPages: 1
39+
})
40+
);
41+
});
42+
43+
index
44+
.findObject(function() {
45+
return false;
46+
})
47+
.then(bind(t.fail, t))
48+
.catch(function(error) {
49+
t.same(error, {
50+
name: 'AlgoliaSearchObjectNotFoundError',
51+
message: 'Object not found'
52+
});
53+
});
54+
});
55+
56+
test('findObject: the first object is returned with a `position=0` and `page=0`', function(t) {
57+
var index = fixture.index;
58+
t.plan(1);
59+
60+
fauxJax.once('request', function(req) {
61+
req.respond(
62+
200,
63+
{},
64+
JSON.stringify({
65+
hits: hits,
66+
nbPages: 1
67+
})
68+
);
69+
});
70+
71+
index
72+
.findObject(function() {
73+
return true;
74+
})
75+
.then(function(result) {
76+
t.same(result, {
77+
object: {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
78+
position: 0,
79+
page: 0
80+
});
81+
})
82+
.catch(bind(t.fail, t));
83+
});
84+
85+
test('findObject: object not found with non matching query', function(t) {
86+
var index = fixture.index;
87+
t.plan(1);
88+
89+
fauxJax.once('request', function(req) {
90+
req.respond(
91+
200,
92+
{},
93+
JSON.stringify({
94+
hits: hits.filter(function(hit) {
95+
return hit.company === 'Algolia';
96+
}),
97+
nbPages: 1
98+
})
99+
);
100+
});
101+
102+
index
103+
.findObject(function(hit) {
104+
return hit.company === 'Apple';
105+
}, {
106+
query: 'Algolia'
107+
})
108+
.then(bind(t.fail, t))
109+
.catch(function(error) {
110+
t.same(error, {
111+
name: 'AlgoliaSearchObjectNotFoundError',
112+
message: 'Object not found'
113+
});
114+
});
115+
});
116+
117+
test('findObject: object not found without pagination', function(t) {
118+
var index = fixture.index;
119+
t.plan(1);
120+
121+
var page = 0;
122+
fauxJax.once('request', function(req) {
123+
req.respond(
124+
200,
125+
{},
126+
JSON.stringify({
127+
hits: hits.slice(0, page * 5),
128+
nbPages: 3
129+
})
130+
);
131+
132+
page++;
133+
});
134+
135+
index
136+
.findObject(function(hit) {
137+
return hit.company === 'Apple';
138+
}, {
139+
query: '',
140+
paginate: false
141+
})
142+
.then(bind(t.fail, t))
143+
.catch(function(error) {
144+
t.same(error, {
145+
name: 'AlgoliaSearchObjectNotFoundError',
146+
message: 'Object not found'
147+
});
148+
});
149+
});
150+
151+
test('findObject: object found with pagination', function(t) {
152+
var index = fixture.index;
153+
t.plan(1);
154+
155+
var page = 0;
156+
fauxJax.on('request', function(req) {
157+
req.respond(
158+
200,
159+
{},
160+
JSON.stringify({
161+
hits: hits.slice(0, page * 5),
162+
nbPages: 3
163+
})
164+
);
165+
166+
page++;
167+
});
168+
169+
index
170+
.findObject(function(hit) {
171+
return hit.company === 'Apple';
172+
}, {
173+
query: '',
174+
paginate: true
175+
})
176+
.then(function(result) {
177+
t.same(result, {
178+
object: {company: 'Apple', name: 'Steve Jobs'},
179+
position: 7,
180+
page: 2
181+
});
182+
})
183+
.catch(t.fail, t);
184+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
var test = require('tape');
4+
var createFixture = require('../../../utils/create-fixture');
5+
var index = createFixture().index;
6+
7+
var hits = [
8+
{company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
9+
{company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
10+
{company: 'Amazon', name: 'Jeff Bezos'},
11+
{company: 'Arista Networks', name: 'Jayshree Ullal'},
12+
{company: 'Google', name: 'Larry Page'},
13+
{company: 'Google', name: 'Rob Pike'}
14+
];
15+
16+
test('getObjectPosition: find position 0', function(t) {
17+
t.plan(1);
18+
19+
t.same(index.getObjectPosition({hits: hits}, 'julien-lemoine'), 0);
20+
});
21+
22+
test('getObjectPosition: find position 1', function(t) {
23+
t.plan(1);
24+
25+
t.same(index.getObjectPosition({hits: hits}, 'nicolas-dessaigne'), 1);
26+
});
27+
28+
test('getObjectPosition: find no position', function(t) {
29+
t.plan(1);
30+
31+
t.same(index.getObjectPosition({hits: hits}, 'foooo'), -1);
32+
});

test/spec/common/index/interface.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ test('AlgoliaSearch index API spec', function(t) {
4545
'exists',
4646
'exportSynonyms',
4747
'exportRules',
48+
'findObject',
4849
'getObject',
50+
'getObjectPosition',
4951
'getObjects',
5052
'getSettings',
5153
'getSynonym',

0 commit comments

Comments
 (0)