Skip to content

Commit

Permalink
feat: adds unit testing relevance methods (#777)
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro authored Sep 25, 2019
1 parent 536f4a6 commit 5f7fb6c
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/Index.js
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,69 @@ Index.prototype.exists = function(callback) {
});
};

Index.prototype.findObject = function(findCallback, requestOptions, callback) {
requestOptions = requestOptions === undefined ? {} : requestOptions;
var paginate = requestOptions.paginate !== undefined ? requestOptions.paginate : true;
var query = requestOptions.query !== undefined ? requestOptions.query : '';

var that = this;
var page = 0;

var paginateLoop = function() {
requestOptions.page = page;

return that.search(query, requestOptions).then(function(result) {
var hits = result.hits;

for (var position = 0; position < hits.length; position++) {
var hit = hits[position];
if (findCallback(hit)) {
return {
object: hit,
position: position,
page: page
};
}
}

page += 1;

// paginate if option was set and has next page
if (!paginate || page >= result.nbPages) {
throw new errors.ObjectNotFound('Object not found');
}

return paginateLoop();
});
};

var promise = paginateLoop(page);

if (callback === undefined) {
return promise;
}

promise
.then(function(res) {
callback(null, res);
})
.catch(function(err) {
callback(err);
});
};

Index.prototype.getObjectPosition = function(result, objectID) {
var hits = result.hits;

for (var position = 0; position < hits.length; position++) {
if (hits[position].objectID === objectID) {
return position;
}
}

return -1;
};

/*
* Set settings for this index
*
Expand Down
4 changes: 4 additions & 0 deletions src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ module.exports = {
'JSONPScriptError',
'<script> unable to load due to an `error` event on it'
),
ObjectNotFound: createCustomError(
'ObjectNotFound',
'Object not found'
),
Unknown: createCustomError(
'Unknown',
'Unknown error occured'
Expand Down
184 changes: 184 additions & 0 deletions test/spec/common/index/findObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
'use strict';

var test = require('tape');
var fauxJax = require('faux-jax');
var bind = require('lodash-compat/function/bind');

var createFixture = require('../../../utils/create-fixture');
var fixture = createFixture();

var hits = [
{company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
{company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
{company: 'Amazon', name: 'Jeff Bezos'},
{company: 'Arista Networks', name: 'Jayshree Ullal'},
{company: 'Google', name: 'Larry Page'},
{company: 'Google', name: 'Rob Pike'},
{company: 'Google', name: 'Serguey Brin'},
{company: 'Apple', name: 'Steve Jobs'},
{company: 'Apple', name: 'Steve Wozniak'},
{company: 'Microsoft', name: 'Bill Gates'},
{company: 'SpaceX', name: 'Elon Musk'},
{company: 'Tesla', name: 'Elon Musk'},
{company: 'Yahoo', name: 'Marissa Mayer'}
];

fauxJax.install();

test('findObject: no object was found when callback always return false', function(t) {
var index = fixture.index;
t.plan(1);

fauxJax.once('request', function(req) {
req.respond(
200,
{},
JSON.stringify({
hits: hits,
nbPages: 1
})
);
});

index
.findObject(function() {
return false;
})
.then(bind(t.fail, t))
.catch(function(error) {
t.same(error, {
name: 'AlgoliaSearchObjectNotFoundError',
message: 'Object not found'
});
});
});

test('findObject: the first object is returned with a `position=0` and `page=0`', function(t) {
var index = fixture.index;
t.plan(1);

fauxJax.once('request', function(req) {
req.respond(
200,
{},
JSON.stringify({
hits: hits,
nbPages: 1
})
);
});

index
.findObject(function() {
return true;
})
.then(function(result) {
t.same(result, {
object: {company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
position: 0,
page: 0
});
})
.catch(bind(t.fail, t));
});

test('findObject: object not found with non matching query', function(t) {
var index = fixture.index;
t.plan(1);

fauxJax.once('request', function(req) {
req.respond(
200,
{},
JSON.stringify({
hits: hits.filter(function(hit) {
return hit.company === 'Algolia';
}),
nbPages: 1
})
);
});

index
.findObject(function(hit) {
return hit.company === 'Apple';
}, {
query: 'Algolia'
})
.then(bind(t.fail, t))
.catch(function(error) {
t.same(error, {
name: 'AlgoliaSearchObjectNotFoundError',
message: 'Object not found'
});
});
});

test('findObject: object not found without pagination', function(t) {
var index = fixture.index;
t.plan(1);

var page = 0;
fauxJax.once('request', function(req) {
req.respond(
200,
{},
JSON.stringify({
hits: hits.slice(0, page * 5),
nbPages: 3
})
);

page++;
});

index
.findObject(function(hit) {
return hit.company === 'Apple';
}, {
query: '',
paginate: false
})
.then(bind(t.fail, t))
.catch(function(error) {
t.same(error, {
name: 'AlgoliaSearchObjectNotFoundError',
message: 'Object not found'
});
});
});

test('findObject: object found with pagination', function(t) {
var index = fixture.index;
t.plan(1);

var page = 0;
fauxJax.on('request', function(req) {
req.respond(
200,
{},
JSON.stringify({
hits: hits.slice(0, page * 5),
nbPages: 3
})
);

page++;
});

index
.findObject(function(hit) {
return hit.company === 'Apple';
}, {
query: '',
paginate: true
})
.then(function(result) {
t.same(result, {
object: {company: 'Apple', name: 'Steve Jobs'},
position: 7,
page: 2
});
})
.catch(t.fail, t);
});
32 changes: 32 additions & 0 deletions test/spec/common/index/getObjectPosition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

var test = require('tape');
var createFixture = require('../../../utils/create-fixture');
var index = createFixture().index;

var hits = [
{company: 'Algolia', name: 'Julien Lemoine', objectID: 'julien-lemoine'},
{company: 'Algolia', name: 'Nicolas Dessaigne', objectID: 'nicolas-dessaigne'},
{company: 'Amazon', name: 'Jeff Bezos'},
{company: 'Arista Networks', name: 'Jayshree Ullal'},
{company: 'Google', name: 'Larry Page'},
{company: 'Google', name: 'Rob Pike'}
];

test('getObjectPosition: find position 0', function(t) {
t.plan(1);

t.same(index.getObjectPosition({hits: hits}, 'julien-lemoine'), 0);
});

test('getObjectPosition: find position 1', function(t) {
t.plan(1);

t.same(index.getObjectPosition({hits: hits}, 'nicolas-dessaigne'), 1);
});

test('getObjectPosition: find no position', function(t) {
t.plan(1);

t.same(index.getObjectPosition({hits: hits}, 'foooo'), -1);
});
2 changes: 2 additions & 0 deletions test/spec/common/index/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ test('AlgoliaSearch index API spec', function(t) {
'exists',
'exportSynonyms',
'exportRules',
'findObject',
'getObject',
'getObjectPosition',
'getObjects',
'getSettings',
'getSynonym',
Expand Down

0 comments on commit 5f7fb6c

Please sign in to comment.