mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-15 01:01:43 +10:00
Firebase Stub: added support for data remove
This commit is contained in:
@ -384,5 +384,63 @@ describe('FirebaseStub', () => {
|
|||||||
expect(snapshotValue[existingResume.id]).toBeTruthy();
|
expect(snapshotValue[existingResume.id]).toBeTruthy();
|
||||||
expect(snapshotValue[existingResume.id].name).toBe(existingResume.name);
|
expect(snapshotValue[existingResume.id].name).toBe(existingResume.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('triggers callback with removed resume when removing an existing one', async () => {
|
||||||
|
const userUid = DatabaseConstants.user1.uid;
|
||||||
|
|
||||||
|
let valueCallbackSnapshotValue = null;
|
||||||
|
const valueCallback = jest.fn((snapshot) => {
|
||||||
|
valueCallbackSnapshotValue = snapshot.val();
|
||||||
|
});
|
||||||
|
FirebaseStub.database()
|
||||||
|
.ref(DatabaseConstants.resumesPath)
|
||||||
|
.orderByChild('user')
|
||||||
|
.equalTo(userUid)
|
||||||
|
.on('value', valueCallback);
|
||||||
|
await waitFor(() => valueCallback.mock.calls[0][0]);
|
||||||
|
expect(valueCallback.mock.calls).toHaveLength(1);
|
||||||
|
valueCallback.mockClear();
|
||||||
|
expect(valueCallbackSnapshotValue).not.toBeNull();
|
||||||
|
expect(Object.keys(valueCallbackSnapshotValue)).toHaveLength(2);
|
||||||
|
Object.values(valueCallbackSnapshotValue).forEach((resume) =>
|
||||||
|
expect(resume.user).toEqual(userUid),
|
||||||
|
);
|
||||||
|
valueCallbackSnapshotValue = null;
|
||||||
|
|
||||||
|
let childRemovedCallbackSnapshotValue = null;
|
||||||
|
const childRemovedCallback = jest.fn((snapshot) => {
|
||||||
|
childRemovedCallbackSnapshotValue = snapshot.val();
|
||||||
|
});
|
||||||
|
FirebaseStub.database()
|
||||||
|
.ref(DatabaseConstants.resumesPath)
|
||||||
|
.orderByChild('user')
|
||||||
|
.equalTo(userUid)
|
||||||
|
.on('child_removed', childRemovedCallback);
|
||||||
|
|
||||||
|
const removedResume = (
|
||||||
|
await FirebaseStub.database()
|
||||||
|
.ref(
|
||||||
|
`${DatabaseConstants.resumesPath}/${DatabaseConstants.demoStateResume1Id}`,
|
||||||
|
)
|
||||||
|
.once('value')
|
||||||
|
).val();
|
||||||
|
expect(removedResume).toBeTruthy();
|
||||||
|
expect(removedResume.user).toEqual(userUid);
|
||||||
|
await FirebaseStub.database()
|
||||||
|
.ref(`${DatabaseConstants.resumesPath}/${removedResume.id}`)
|
||||||
|
.remove();
|
||||||
|
|
||||||
|
await waitFor(() => childRemovedCallback.mock.calls[0][0]);
|
||||||
|
expect(childRemovedCallback.mock.calls).toHaveLength(1);
|
||||||
|
childRemovedCallback.mockClear();
|
||||||
|
expect(childRemovedCallbackSnapshotValue).toBeTruthy();
|
||||||
|
expect(childRemovedCallbackSnapshotValue.id).toBe(removedResume.id);
|
||||||
|
|
||||||
|
await waitFor(() => valueCallback.mock.calls[0][0]);
|
||||||
|
expect(valueCallback.mock.calls).toHaveLength(1);
|
||||||
|
valueCallback.mockClear();
|
||||||
|
expect(valueCallbackSnapshotValue).toBeTruthy();
|
||||||
|
expect(removedResume.id in valueCallbackSnapshotValue).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import AuthConstants from './auth';
|
import AuthConstants from './auth';
|
||||||
|
|
||||||
const valueEventType = 'value';
|
const valueEventType = 'value';
|
||||||
|
const childRemovedEventType = 'child_removed';
|
||||||
|
|
||||||
const resumesPath = 'resumes';
|
const resumesPath = 'resumes';
|
||||||
const usersPath = 'users';
|
const usersPath = 'users';
|
||||||
@ -24,6 +25,10 @@ class Database {
|
|||||||
return valueEventType;
|
return valueEventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get childRemovedEventType() {
|
||||||
|
return childRemovedEventType;
|
||||||
|
}
|
||||||
|
|
||||||
static get resumesPath() {
|
static get resumesPath() {
|
||||||
return resumesPath;
|
return resumesPath;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,6 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
/* eslint-disable no-underscore-dangle */
|
||||||
import DatabaseConstants from '../constants/database';
|
|
||||||
|
|
||||||
class DataSnapshot {
|
class DataSnapshot {
|
||||||
constructor(eventType, getData, value = undefined) {
|
constructor(getData, value = undefined) {
|
||||||
if (!eventType) {
|
|
||||||
throw new Error('eventType must be provided.');
|
|
||||||
} else if (typeof eventType !== 'string') {
|
|
||||||
throw new Error('eventType should be a string.');
|
|
||||||
}
|
|
||||||
|
|
||||||
this._eventType = eventType;
|
|
||||||
|
|
||||||
if (!getData) {
|
if (!getData) {
|
||||||
throw new Error('getData must be provided.');
|
throw new Error('getData must be provided.');
|
||||||
} else if (typeof getData !== 'function') {
|
} else if (typeof getData !== 'function') {
|
||||||
@ -22,21 +12,13 @@ class DataSnapshot {
|
|||||||
this._value = value;
|
this._value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get eventType() {
|
|
||||||
return this._eventType;
|
|
||||||
}
|
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
return this._value;
|
return this._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
val() {
|
val() {
|
||||||
if (this.eventType === DatabaseConstants.valueEventType) {
|
|
||||||
return typeof this.value !== 'undefined' ? this.value : this._getData();
|
return typeof this.value !== 'undefined' ? this.value : this._getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DataSnapshot;
|
export default DataSnapshot;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class Reference {
|
|||||||
|
|
||||||
this._uuid = uuidv4();
|
this._uuid = uuidv4();
|
||||||
|
|
||||||
this._dataSnapshots = {};
|
this._dataSnapshot = null;
|
||||||
|
|
||||||
if (!getDatabaseData) {
|
if (!getDatabaseData) {
|
||||||
throw new Error('getDatabaseData must be provided.');
|
throw new Error('getDatabaseData must be provided.');
|
||||||
@ -91,31 +91,42 @@ class Reference {
|
|||||||
throw new Error('value must be provided.');
|
throw new Error('value must be provided.');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._setDatabaseData(this.path, value);
|
const currentData = this._getData();
|
||||||
|
|
||||||
this.debounceEventCallback(DatabaseConstants.valueEventType);
|
|
||||||
|
|
||||||
const pathElements = this.path.split('/');
|
const pathElements = this.path.split('/');
|
||||||
|
let parentReference = null;
|
||||||
if (pathElements.length === 2) {
|
if (pathElements.length === 2) {
|
||||||
const parentReference = this._getReference(pathElements[0]);
|
parentReference = this._getReference(pathElements[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setDatabaseData(this.path, value);
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
if (parentReference) {
|
if (parentReference) {
|
||||||
|
parentReference.debounceEventCallback(
|
||||||
|
DatabaseConstants.childRemovedEventType,
|
||||||
|
currentData,
|
||||||
|
);
|
||||||
parentReference.debounceEventCallback(DatabaseConstants.valueEventType);
|
parentReference.debounceEventCallback(DatabaseConstants.valueEventType);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const eventType = DatabaseConstants.valueEventType;
|
||||||
|
this.debounceEventCallback(eventType);
|
||||||
|
if (parentReference) {
|
||||||
|
parentReference.debounceEventCallback(eventType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debounceEventCallback(eventType) {
|
debounceEventCallback(eventType, snapshotValue = undefined) {
|
||||||
if (!(eventType in this.eventCallbacks)) {
|
if (!(eventType in this.eventCallbacks)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshot = new DataSnapshot(eventType, () => this._getData(), null);
|
const snapshot =
|
||||||
|
this.path === DatabaseConstants.connectedPath
|
||||||
if (this.path === DatabaseConstants.connectedPath) {
|
? new DataSnapshot(() => this._getData(), true)
|
||||||
snapshot = new DataSnapshot(eventType, () => this._getData(), true);
|
: new DataSnapshot(() => this._getData(), snapshotValue);
|
||||||
} else if (this.path === DatabaseConstants.resumesPath) {
|
|
||||||
snapshot = new DataSnapshot(eventType, () => this._getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
const debouncedEventCallback = debounce(
|
const debouncedEventCallback = debounce(
|
||||||
this.eventCallbacks[eventType],
|
this.eventCallbacks[eventType],
|
||||||
@ -139,23 +150,27 @@ class Reference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on(eventType, callback) {
|
on(eventType, callback) {
|
||||||
if (eventType !== DatabaseConstants.valueEventType) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._eventCallbacks[eventType] = callback;
|
this._eventCallbacks[eventType] = callback;
|
||||||
|
|
||||||
|
if (eventType === DatabaseConstants.valueEventType) {
|
||||||
this.debounceEventCallback(eventType);
|
this.debounceEventCallback(eventType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async once(eventType) {
|
async once(eventType) {
|
||||||
const newDataSnapshot = new DataSnapshot(eventType, () => this._getData());
|
if (!eventType) {
|
||||||
const existingDataSnapshot = this._dataSnapshots[newDataSnapshot.eventType];
|
throw new Error('eventType must be provided.');
|
||||||
if (existingDataSnapshot) {
|
} else if (typeof eventType !== 'string') {
|
||||||
return Promise.resolve(existingDataSnapshot);
|
throw new Error('eventType should be a string.');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dataSnapshots[newDataSnapshot.eventType] = newDataSnapshot;
|
if (this._dataSnapshot) {
|
||||||
|
return Promise.resolve(this._dataSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newDataSnapshot = new DataSnapshot(() => this._getData());
|
||||||
|
this._dataSnapshot = newDataSnapshot;
|
||||||
|
|
||||||
return Promise.resolve(newDataSnapshot);
|
return Promise.resolve(newDataSnapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +185,12 @@ class Reference {
|
|||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async remove() {
|
||||||
|
this._setData(null);
|
||||||
|
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
async set(value) {
|
async set(value) {
|
||||||
this._setData(value);
|
this._setData(value);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user