Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds unit testing relevance methods #777

Merged
merged 7 commits into from
Sep 25, 2019
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;
nunomaduro marked this conversation as resolved.
Show resolved Hide resolved
var paginate = requestOptions.paginate !== undefined ? requestOptions.paginate : true;
nunomaduro marked this conversation as resolved.
Show resolved Hide resolved
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 or has next page
nunomaduro marked this conversation as resolved.
Show resolved Hide resolved
if (!paginate || page >= result.nbPages) {
throw new errors.ObjectNotFound('Object not found');
}

return paginateLoop();
});
};

var promise = paginateLoop(page);

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

return promise
nunomaduro marked this conversation as resolved.
Show resolved Hide resolved
.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