Skip to content

Commit

Permalink
added support for snapshot#docChanges
Browse files Browse the repository at this point in the history
  • Loading branch information
zeevl committed Feb 21, 2020
1 parent bd85b69 commit 6ff3e34
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 9 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 36 additions & 5 deletions src/firestore-query-snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
var _ = require('./lodash');
var DocumentSnapshot = require('./firestore-document-snapshot');

function MockFirestoreQuerySnapshot (ref, data) {
function MockFirestoreQuerySnapshot (ref, data, priorData) {
var self = this;

this._ref = ref;
this.data = _.cloneDeep(data) || {};
if (_.isObject(this.data) && _.isEmpty(this.data)) {
Expand All @@ -12,17 +14,46 @@ function MockFirestoreQuerySnapshot (ref, data) {
this.size = _.size(this.data);
this.empty = this.size === 0;

var self = this;
this.docs = _.map(this.data, function (value, key) {
return new DocumentSnapshot(key, self._ref.doc(key), value);
});

var prior = priorData || {};
this._changes = _.reduce(
this.docs,
function(changes, doc) {
if (!prior[doc.id]) changes.push({ type: "added", doc });
if (prior[doc.id] && !_.isEqual(doc.data(), prior[doc.id]))
changes.push({ type: "modified", doc });

return changes;
},
[]
);

_.forEach(prior, function (value, key) {
if (!data[key]) self._changes.push({
type: 'removed',
doc: new DocumentSnapshot(key, self._ref.doc(key), value)
});
})
}

MockFirestoreQuerySnapshot.prototype.forEach = function (callback, context) {
var self = this;
_.forEach(this.docs, function (doc) {
MockFirestoreQuerySnapshot.prototype.forEach = function(callback, context) {
_.forEach(this.docs, function(doc) {
callback.call(context, doc);
});
};

MockFirestoreQuerySnapshot.prototype.docChanges = function() {
var self = this;
return {
forEach: function(callback, context) {
_.forEach(self._changes, function(change) {
callback.call(context, change);
});
}
};
};

module.exports = MockFirestoreQuerySnapshot;
8 changes: 4 additions & 4 deletions src/firestore-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,22 @@ MockFirestoreQuery.prototype.onSnapshot = function (optionsOrObserverOrOnNext, o
var context = {
data: self._results(),
};
var onSnapshot = function (forceTrigger) {
var onSnapshot = function (initialCall) {
// compare the current state to the one from when this function was created
// and send the data to the callback if different.
if (err === null) {
if (forceTrigger) {
if (initialCall) {
const results = self._results();
if (_.size(self.data) !== 0) {
onNext(new QuerySnapshot(self.parent === null ? self : self.parent.collection(self.id), results));
onNext(new QuerySnapshot(self.parent === null ? self : self.parent.collection(self.id), results, {}));
} else {
onNext(new QuerySnapshot(self.parent === null ? self : self.parent.collection(self.id)));
}
} else {
self.get().then(function (querySnapshot) {
var results = self._results();
if (!_.isEqual(results, context.data) || includeMetadataChanges) {
onNext(new QuerySnapshot(self.parent === null ? self : self.parent.collection(self.id), results));
onNext(new QuerySnapshot(self.parent === null ? self : self.parent.collection(self.id), results, context.data));
context.data = results;
}
});
Expand Down
79 changes: 79 additions & 0 deletions test/unit/firestore-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,5 +649,84 @@ describe('MockFirestoreCollection', function () {
collection.flush();
});

describe('snapshot#docChange', () => {
beforeEach(function () {
db.collection('docChange').doc('123').set({ name: 'A' });
db.collection('docChange').doc('456').set({ name: 'B' });
db.collection('docChange').flush();
})

it('should initially provide all collection results as "added"', () => {
db.collection('docChange').onSnapshot(function(snap) {
const changes = [];
snap
.docChanges()
.forEach(ch =>
changes.push({ type: ch.type, data: ch.doc.data() })
);

expect(changes).to.deep.equal([
{ type: 'added', data: { name: 'A' } },
{ type: 'added', data: { name: 'B' } }
]);
});
});

it('should show subsequently changed data as "modified"', function(done) {
let callCount = 0;
db.collection('docChange').onSnapshot(function(snap) {
try {
const changes = [];

if (callCount++ !== 1) return;

snap
.docChanges()
.forEach(ch =>
changes.push({ type: ch.type, data: ch.doc.data() })
);

expect(changes).to.deep.equal([
{ type: 'modified', data: { name: 'AA' } },
]);
done();
}
catch(e) {
done(e);
}
});

db.collection('docChange').doc('123').set({ name: 'AA' });
db.flush();
});

it('should show subsequently removed data as "removed"', function(done) {
let callCount = 0;
db.collection('docChange').onSnapshot(function(snap) {
try {
const changes = [];

if (callCount++ !== 1) return;

snap
.docChanges()
.forEach(ch =>
changes.push({ type: ch.type, data: ch.doc.data() })
);

expect(changes).to.deep.equal([
{ type: 'removed', data: { name: 'A' } },
]);
done();
}
catch(e) {
done(e);
}
});

db.collection('docChange').doc('123').delete();
db.flush();
})
});
});
});

0 comments on commit 6ff3e34

Please sign in to comment.