Skip to content

Commit

Permalink
fix(GeoQuery): fix near when radius is set to 0, fixes #178
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelSolati committed Jun 8, 2020
1 parent 30a7df3 commit 65db67f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 22 deletions.
15 changes: 8 additions & 7 deletions src/GeoQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ export class GeoQuery {
.enablePersistence
) === '[object Function]';
if (queryCriteria) {
if (queryCriteria.limit) {
if (typeof queryCriteria.limit === 'number') {
this._limit = queryCriteria.limit;
}
if (queryCriteria.center && queryCriteria.radius) {

if (queryCriteria.center && typeof queryCriteria.radius === 'number') {
// Validate and save the query criteria
validateQueryCriteria(queryCriteria);
this._center = queryCriteria.center;
Expand Down Expand Up @@ -74,7 +75,7 @@ export class GeoQuery {
onNext: (snapshot: GeoQuerySnapshot) => void,
onError?: (error: Error) => void
): (() => void) => {
if (this._center && this._radius) {
if (this._center && typeof this._radius === 'number') {
return new GeoJoinerOnSnapshot(
this._generateQuery(),
this._queryCriteria,
Expand Down Expand Up @@ -106,7 +107,7 @@ export class GeoQuery {
get(
options: GeoFirestoreTypes.web.GetOptions = {source: 'default'}
): Promise<GeoQuerySnapshot> {
if (this._center && typeof this._radius !== 'undefined') {
if (this._center && typeof this._radius === 'number') {
const queries = this._generateQuery().map(query =>
this._isWeb ? query.get(options) : query.get()
);
Expand Down Expand Up @@ -150,9 +151,9 @@ export class GeoQuery {
*/
near(newGeoQueryCriteria: GeoFirestoreTypes.QueryCriteria): GeoQuery {
// Validate and save the new query criteria
validateQueryCriteria(newGeoQueryCriteria);
this._center = newGeoQueryCriteria.center || this._center;
this._radius = newGeoQueryCriteria.radius || this._radius;
validateQueryCriteria(newGeoQueryCriteria, true);
this._center = newGeoQueryCriteria.center;
this._radius = newGeoQueryCriteria.radius;

return new GeoQuery(this._query, this._queryCriteria);
}
Expand Down
94 changes: 79 additions & 15 deletions test/GeoQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('GeoQuery Tests:', () => {
});

describe('onSnapshot:', () => {
it('onSnapshot returns dummy data, without any geo related filters', done => {
it('onSnapshot returns data, without any geo related filters', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
const subscription = query.onSnapshot(snapshot => {
Expand All @@ -66,7 +66,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('onSnapshot returns dummy data, without any geo related filters and with a `where` statement', done => {
it('onSnapshot returns data, without any geo related filters and with a `where` statement', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
const subscription = query
Expand Down Expand Up @@ -96,7 +96,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('onSnapshot returns dummy data, with geo related filters', done => {
it('onSnapshot returns data, with geo related filters', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
const subscription = query
Expand Down Expand Up @@ -135,6 +135,34 @@ describe('GeoQuery Tests:', () => {
});
});

it('onSnapshot returns data, when radius is set to 0 and point exists at exact coordinate', done => {
const center = new firebase.firestore.GeoPoint(2, 3);
const query = new GeoQuery(collection);
stubDatabase().then(() => {
const subscription = query
.near({center, radius: 0})
.onSnapshot(snapshot => {
subscription();
expect(snapshot.size).to.equal(1);
done();
});
});
});

it('onSnapshot returns no data, when radius is set to 0 and no point exists at exact coordinate', done => {
const center = new firebase.firestore.GeoPoint(0, 0);
const query = new GeoQuery(collection);
stubDatabase().then(() => {
const subscription = query
.near({center, radius: 0})
.onSnapshot(snapshot => {
subscription();
expect(snapshot.size).to.equal(0);
done();
});
});
});

it('onSnapshot updates when a new document, that matches the query, is added to collection', done => {
const center = new firebase.firestore.GeoPoint(-50, -50);
const doc = geocollection.doc();
Expand Down Expand Up @@ -269,7 +297,7 @@ describe('GeoQuery Tests:', () => {
});

describe('get():', () => {
it('get() returns dummy data, without any geo related filters', done => {
it('get() returns data, without any geo related filters', done => {
const query = new GeoQuery(collection);
stubDatabase()
.then(() => query.get())
Expand All @@ -280,7 +308,7 @@ describe('GeoQuery Tests:', () => {
.then(done);
});

it('get() returns dummy data, without any geo related filters and with a `where` statement', done => {
it('get() returns data, without any geo related filters and with a `where` statement', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
Expand Down Expand Up @@ -310,7 +338,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns dummy data, with geo related filters', done => {
it('get() returns data, with geo related filters', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
Expand All @@ -335,6 +363,34 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns data, when radius is set to 0 and point exists at exact coordinate', done => {
const center = new firebase.firestore.GeoPoint(2, 3);
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
.near({center, radius: 0})
.get()
.then(snapshot => {
expect(snapshot.size).to.equal(1);
})
.then(done);
});
});

it('get() returns no data, when radius is set to 0 and no point exists at exact coordinate', done => {
const center = new firebase.firestore.GeoPoint(0, 0);
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
.near({center, radius: 0})
.get()
.then(snapshot => {
expect(snapshot.size).to.equal(0);
})
.then(done);
});
});

it("get() docChanges() returns an array of the 'added' docs as well as their index and `type`", done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
Expand Down Expand Up @@ -384,7 +440,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns dummy data, when not on web', done => {
it('get() returns data, when not on web', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query['_isWeb'] = false;
Expand All @@ -398,7 +454,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns dummy data, with geo related filters, when not on web', done => {
it('get() returns data, with geo related filters, when not on web', done => {
let query = new GeoQuery(collection);
stubDatabase().then(() => {
query = query.near({
Expand Down Expand Up @@ -427,7 +483,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns dummy data from server (web only)', done => {
it('get() returns data from server (web only)', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
Expand All @@ -440,7 +496,7 @@ describe('GeoQuery Tests:', () => {
});
});

it('get() returns dummy data, with geo related filters from server (web only)', done => {
it('get() returns data, with geo related filters from server (web only)', done => {
const query = new GeoQuery(collection);
stubDatabase().then(() => {
query
Expand Down Expand Up @@ -508,10 +564,14 @@ describe('GeoQuery Tests:', () => {
expect(() =>
query.near({center: new firebase.firestore.GeoPoint(0, 0), radius: 100})
).not.to.throw();
});

it('near() throws error with missing argument', () => {
const query = new GeoQuery(collection);
expect(() =>
query.near({center: new firebase.firestore.GeoPoint(1, 1)})
).not.to.throw();
expect(() => query.near({radius: 500})).not.to.throw();
).to.throw();
expect(() => query.near({radius: 500})).to.throw();
});

it('near() throws error with no arguments', () => {
Expand Down Expand Up @@ -584,17 +644,21 @@ describe('GeoQuery Tests:', () => {
.near({center: new firebase.firestore.GeoPoint(0, 0), radius: 100})
.where('count', '==', 0)
).not.to.throw();
});

it('near().where() does throw an error with missing arguments', () => {
const query = new GeoQuery(collection);
expect(() =>
query
.near({center: new firebase.firestore.GeoPoint(1, 1)})
.where('count', '>', 0)
).not.to.throw();
).to.throw();
expect(() =>
query.near({radius: 500}).where('count', '<=', 0)
).not.to.throw();
).to.throw();
expect(() =>
query.near({radius: 500}).where('array', 'array-contains', 'one')
).not.to.throw();
).to.throw();
});
});

Expand Down

0 comments on commit 65db67f

Please sign in to comment.