mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-05-12 17:58:40 +08:00
[v6] Implement Realtime Database (#2195)
* [database] recreate database branch based off of #2185 * [database] cleanup linting issues * [database] enable tests * [database] add to tests deps
This commit is contained in:
committed by
Elliot Hesp
parent
da9c32000d
commit
fe959bb842
27
packages/database/e2e/DatabaseStatics.e2e.js
Normal file
27
packages/database/e2e/DatabaseStatics.e2e.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database.X', () => {
|
||||
describe('ServerValue.TIMESTAMP', () => {
|
||||
it('returns a valid object', () => {
|
||||
const { TIMESTAMP } = firebase.database.ServerValue;
|
||||
should.equal(Object.keys(TIMESTAMP).length, 1);
|
||||
TIMESTAMP.should.have.property('.sv');
|
||||
TIMESTAMP['.sv'].should.eql('timestamp');
|
||||
});
|
||||
});
|
||||
});
|
||||
196
packages/database/e2e/database.e2e.js
Normal file
196
packages/database/e2e/database.e2e.js
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database()', () => {
|
||||
describe('namespace', () => {
|
||||
it('accessible from firebase.app()', () => {
|
||||
const app = firebase.app();
|
||||
should.exist(app.database);
|
||||
app.database().app.should.eql(app);
|
||||
});
|
||||
|
||||
it('supports multiple apps', async () => {
|
||||
firebase.database().app.name.should.eql('[DEFAULT]');
|
||||
|
||||
firebase
|
||||
.database(firebase.app('secondaryFromNative'))
|
||||
.app.name.should.eql('secondaryFromNative');
|
||||
|
||||
firebase
|
||||
.app('secondaryFromNative')
|
||||
.database()
|
||||
.app.name.should.eql('secondaryFromNative');
|
||||
});
|
||||
});
|
||||
|
||||
it('supports custom database URL', async () => {
|
||||
firebase.database().app.name.should.eql('[DEFAULT]');
|
||||
|
||||
firebase
|
||||
.database(firebase.app('secondaryFromNative'))
|
||||
.app.name.should.eql('secondaryFromNative');
|
||||
|
||||
firebase
|
||||
.app('secondaryFromNative')
|
||||
.database()
|
||||
.app.name.should.eql('secondaryFromNative');
|
||||
});
|
||||
|
||||
describe('ref()', () => {
|
||||
it('throws if path is not a string', async () => {
|
||||
try {
|
||||
firebase.database().ref({ foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'path' must be a string value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if path is not a valid string', async () => {
|
||||
try {
|
||||
firebase.database().ref('$$$$$');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('refFromURL()', () => {
|
||||
it('throws if url is not a url', async () => {
|
||||
try {
|
||||
firebase.database().refFromURL('foobar');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'url' must be a valid database URL`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if url from a different domain', async () => {
|
||||
try {
|
||||
firebase.database().refFromURL('https://foobar.firebaseio.com');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'url' must be the same domain as the current instance`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns a reference', async () => {
|
||||
const ref1 = firebase.database().refFromURL(firebase.database()._customUrlOrRegion);
|
||||
const ref2 = firebase
|
||||
.database()
|
||||
.refFromURL(`${firebase.database()._customUrlOrRegion}/foo/bar`);
|
||||
const ref3 = firebase
|
||||
.database()
|
||||
.refFromURL(`${firebase.database()._customUrlOrRegion}/foo/bar?baz=foo`);
|
||||
should.equal(ref1.path, '/');
|
||||
should.equal(ref2.path, 'foo/bar');
|
||||
should.equal(ref3.path, 'foo/bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('goOnline()', () => {
|
||||
it('calls goOnline successfully', async () => {
|
||||
await firebase.database().goOnline();
|
||||
});
|
||||
});
|
||||
|
||||
describe('goOffline()', () => {
|
||||
it('calls goOffline successfully', async () => {
|
||||
// await Utils.sleep(5000);
|
||||
await firebase.database().goOffline();
|
||||
|
||||
await firebase.database().goOnline();
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPersistenceEnabled()', () => {
|
||||
it('throws if enabled is not a boolean', async () => {
|
||||
try {
|
||||
firebase.database().setPersistenceEnabled('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'enabled' must be a boolean value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('calls setPersistenceEnabled successfully', async () => {
|
||||
firebase.database().setPersistenceEnabled(true);
|
||||
firebase.database().setPersistenceEnabled(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setLoggingEnabled()', () => {
|
||||
it('throws if enabled is not a boolean', async () => {
|
||||
try {
|
||||
firebase.database().setLoggingEnabled('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'enabled' must be a boolean value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('calls setLoggingEnabled successfully', async () => {
|
||||
firebase.database().setLoggingEnabled(true);
|
||||
firebase.database().setLoggingEnabled(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPersistenceCacheSizeBytes()', () => {
|
||||
it('throws if bytes is not a number', async () => {
|
||||
try {
|
||||
firebase.database().setPersistenceCacheSizeBytes('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'bytes' must be a number value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if bytes is less than 1MB', async () => {
|
||||
try {
|
||||
firebase.database().setPersistenceCacheSizeBytes(1234);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'bytes' must be greater than 1000000 (1MB)`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if bytes is greater than 10MB', async () => {
|
||||
try {
|
||||
firebase.database().setPersistenceCacheSizeBytes(100000000000000);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'bytes' must be less than 100000000 (10MB)`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('calls setPersistenceCacheSizeBytes successfully', async () => {
|
||||
firebase.database().setPersistenceCacheSizeBytes(1000000);
|
||||
});
|
||||
});
|
||||
});
|
||||
54
packages/database/e2e/helpers.js
Normal file
54
packages/database/e2e/helpers.js
Normal file
@@ -0,0 +1,54 @@
|
||||
// TODO make more unique?
|
||||
const ID = Date.now();
|
||||
|
||||
const PATH = `tests/${ID}`;
|
||||
|
||||
const CONTENT = {
|
||||
TYPES: {
|
||||
array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
boolean: true,
|
||||
string: 'foobar',
|
||||
number: 123567890,
|
||||
object: {
|
||||
foo: 'bar',
|
||||
bar: 'baz',
|
||||
},
|
||||
},
|
||||
QUERY: {
|
||||
a: {
|
||||
string: 'foo',
|
||||
number: 10,
|
||||
},
|
||||
b: {
|
||||
string: 'bar',
|
||||
number: 5,
|
||||
},
|
||||
c: {
|
||||
string: 'baz',
|
||||
number: 8,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
exports.seed = function seed(path) {
|
||||
return Promise.all([
|
||||
firebase
|
||||
.database()
|
||||
.ref(`${path}/types`)
|
||||
.set(CONTENT.TYPES),
|
||||
firebase
|
||||
.database()
|
||||
.ref(`${path}/query`)
|
||||
.set(CONTENT.QUERY),
|
||||
]);
|
||||
};
|
||||
|
||||
exports.wipe = function wipe(path) {
|
||||
return firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.remove();
|
||||
};
|
||||
|
||||
exports.PATH = PATH;
|
||||
exports.CONTENT = CONTENT;
|
||||
62
packages/database/e2e/internal/connected.e2e.js
Normal file
62
packages/database/e2e/internal/connected.e2e.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe(`database().ref('.info/connected')`, () => {
|
||||
after(() => firebase.database().goOnline());
|
||||
|
||||
it('returns false when used with once', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref('.info/connected')
|
||||
.once('value');
|
||||
snapshot.val().should.equal(false);
|
||||
});
|
||||
|
||||
it('returns true when used with once with a previous call', async () => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref('tests')
|
||||
.once('value');
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref('.info/connected')
|
||||
.once('value');
|
||||
snapshot.val().should.equal(true);
|
||||
});
|
||||
|
||||
it('subscribes to online state', async () => {
|
||||
const callback = sinon.spy();
|
||||
await firebase.database().goOffline();
|
||||
|
||||
const ref = firebase.database().ref('.info/connected');
|
||||
|
||||
const handler = $ => {
|
||||
callback($.val());
|
||||
};
|
||||
|
||||
ref.on('value', handler);
|
||||
|
||||
await Utils.sleep(1000);
|
||||
await firebase.database().goOnline();
|
||||
await Utils.sleep(1000);
|
||||
ref.off('value', handler);
|
||||
|
||||
callback.should.be.calledTwice();
|
||||
callback.getCall(0).args[0].should.equal(false);
|
||||
callback.getCall(1).args[0].should.equal(true);
|
||||
});
|
||||
});
|
||||
27
packages/database/e2e/internal/serverTimeOffset.e2e.js
Normal file
27
packages/database/e2e/internal/serverTimeOffset.e2e.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe(`database().ref('.info/serverTimeOffset')`, () => {
|
||||
it('returns a valid number value', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref('.info/serverTimeOffset')
|
||||
.once('value');
|
||||
|
||||
should.equal(typeof snapshot.val(), 'number');
|
||||
});
|
||||
});
|
||||
73
packages/database/e2e/onDisconnect/cancel.e2e.js
Normal file
73
packages/database/e2e/onDisconnect/cancel.e2e.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/onDisconnectCancel`;
|
||||
|
||||
describe('database().ref().onDisconnect().cancel()', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
afterEach(() => {
|
||||
// Ensures the db is online before running each test
|
||||
firebase.database().goOnline();
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.cancel('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('cancels all previously queued events', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set('foobar');
|
||||
const value = Date.now();
|
||||
|
||||
await ref.onDisconnect().set(value);
|
||||
await ref.onDisconnect().cancel();
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql('foobar');
|
||||
});
|
||||
|
||||
it('calls back to the onComplete function', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
// Set an initial value
|
||||
await ref.set('foo');
|
||||
|
||||
await ref.onDisconnect().set('bar');
|
||||
await ref.onDisconnect().cancel(callback);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
});
|
||||
76
packages/database/e2e/onDisconnect/remove.e2e.js
Normal file
76
packages/database/e2e/onDisconnect/remove.e2e.js
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/onDisconnectRemove`;
|
||||
|
||||
describe('database().ref().onDisconnect().remove()', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
afterEach(() => {
|
||||
// Ensures the db is online before running each test
|
||||
firebase.database().goOnline();
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.remove('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('removes a node whilst offline', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('removeMe');
|
||||
|
||||
await ref.set('foobar');
|
||||
|
||||
await ref.onDisconnect().remove();
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.exists().should.eql(false);
|
||||
});
|
||||
|
||||
it('calls back to the onComplete function', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('removeMe');
|
||||
|
||||
// Set an initial value
|
||||
await ref.set('foo');
|
||||
|
||||
await ref.onDisconnect().remove(callback);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
});
|
||||
84
packages/database/e2e/onDisconnect/set.e2e.js
Normal file
84
packages/database/e2e/onDisconnect/set.e2e.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/onDisconnectSet`;
|
||||
|
||||
describe('database().ref().onDisconnect().set()', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
afterEach(() => {
|
||||
// Ensures the db is online before running each test
|
||||
firebase.database().goOnline();
|
||||
});
|
||||
|
||||
it('throws if value is not a defined', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.set();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.set(null, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('sets value when disconnected', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const value = Date.now();
|
||||
|
||||
await ref.onDisconnect().set(value);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql(value);
|
||||
});
|
||||
|
||||
it('calls back to the onComplete function', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
// Set an initial value
|
||||
await ref.set('foo');
|
||||
|
||||
await ref.onDisconnect().set('bar', callback);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
});
|
||||
99
packages/database/e2e/onDisconnect/setWithPriority.e2e.js
Normal file
99
packages/database/e2e/onDisconnect/setWithPriority.e2e.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/onDisconnectSetWithPriority`;
|
||||
|
||||
describe('database().ref().onDisconnect().setWithPriority()', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
afterEach(() => {
|
||||
// Ensures the db is online before running each test
|
||||
firebase.database().goOnline();
|
||||
});
|
||||
|
||||
it('throws if value is not a defined', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.setWithPriority();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if priority is not a valid type', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.setWithPriority(null, { foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'priority' must be a number, string or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.setWithPriority(null, 1, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('sets value with priority when disconnected', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const value = Date.now();
|
||||
|
||||
await ref.onDisconnect().setWithPriority(value, 3);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.exportVal()['.value'].should.eql(value);
|
||||
snapshot.exportVal()['.priority'].should.eql(3);
|
||||
});
|
||||
|
||||
it('calls back to the onComplete function', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
// Set an initial value
|
||||
await ref.set('foo');
|
||||
|
||||
await ref.onDisconnect().setWithPriority('bar', 2, callback);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
});
|
||||
111
packages/database/e2e/onDisconnect/update.e2e.js
Normal file
111
packages/database/e2e/onDisconnect/update.e2e.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/onDisconnectUpdate`;
|
||||
|
||||
describe('database().ref().onDisconnect().update()', () => {
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
afterEach(() => {
|
||||
// Ensures the db is online before running each test
|
||||
firebase.database().goOnline();
|
||||
});
|
||||
|
||||
it('throws if values is not an object', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect()
|
||||
.update('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' must be an object`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if values does not contain any values', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect()
|
||||
.update({});
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' must be an object containing multiple values`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.onDisconnect();
|
||||
try {
|
||||
ref.update({ foo: 'bar' }, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('updates value when disconnected', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const value = Date.now();
|
||||
await ref.set({
|
||||
foo: {
|
||||
bar: 'baz',
|
||||
},
|
||||
});
|
||||
|
||||
await ref
|
||||
.child('foo')
|
||||
.onDisconnect()
|
||||
.update({
|
||||
bar: value,
|
||||
});
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
const snapshot = await ref.child('foo').once('value');
|
||||
snapshot.val().should.eql(
|
||||
jet.contextify({
|
||||
bar: value,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('calls back to the onComplete function', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
// Set an initial value
|
||||
await ref.set('foo');
|
||||
await ref.onDisconnect().update({ foo: 'bar' }, callback);
|
||||
await firebase.database().goOffline();
|
||||
await firebase.database().goOnline();
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
});
|
||||
156
packages/database/e2e/query/endAt.e2e.js
Normal file
156
packages/database/e2e/query/endAt.e2e.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/endAt`;
|
||||
|
||||
describe('database().ref().endAt()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if an value is undefined', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.endAt();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be a number, string, boolean or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if an key is not a string', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.endAt('foo', 1234);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'key' must be a string value if defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if a ending point has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.equalTo('foo')
|
||||
.endAt('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Ending point was already set (by another call to endAt or equalTo)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by key and the key param is set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByKey('foo')
|
||||
.endAt('foo', 'bar');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by key, you may only pass a value argument to startAt(), endAt(), or equalTo()`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by key and the value param is not a string', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByKey('foo')
|
||||
.endAt(123);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by key, the value of startAt(), endAt(), or equalTo() must be a string`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by priority and the value param is not priority type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByPriority()
|
||||
.endAt(true);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by priority, the first value of startAt(), endAt(), or equalTo() must be a valid priority value (null, a number, or a string)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('snapshot value returns all when no ordering modifier is applied', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
});
|
||||
|
||||
const expected = ['a', 'b', 'c', 'd'];
|
||||
|
||||
const snapshot = await ref.endAt(2).once('value');
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('ends at the correct value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
});
|
||||
|
||||
const snapshot = await ref
|
||||
.orderByValue()
|
||||
.endAt(2)
|
||||
.once('value');
|
||||
|
||||
const expected = ['a', 'b'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
120
packages/database/e2e/query/equalTo.e2e.js
Normal file
120
packages/database/e2e/query/equalTo.e2e.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/equalTo`;
|
||||
|
||||
describe('database().ref().equalTo()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if value is not a valid type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.equalTo({ foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be a number, string, boolean or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if key is not a string', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.equalTo('bar', 123);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'key' must be a string value if defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if a starting point has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.startAt('foo')
|
||||
.equalTo('bar');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Starting point was already set (by another call to startAt or equalTo)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if a ending point has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.endAt('foo')
|
||||
.equalTo('bar');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Ending point was already set (by another call to endAt or equalTo)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('snapshot value is null when no ordering modifier is applied', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
});
|
||||
|
||||
const snapshot = await ref.equalTo(2).once('value');
|
||||
should.equal(snapshot.val(), null);
|
||||
});
|
||||
|
||||
it('returns the correct equal to values', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
e: 2,
|
||||
});
|
||||
|
||||
const snapshot = await ref
|
||||
.orderByValue()
|
||||
.equalTo(2)
|
||||
.once('value');
|
||||
|
||||
const expected = ['b', 'e'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
62
packages/database/e2e/query/isEqual.e2e.js
Normal file
62
packages/database/e2e/query/isEqual.e2e.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().isEqual()', () => {
|
||||
it('throws if limit other param is not a query instance', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.isEqual('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'other' must be an instance of Query.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns true if the query is the same instance', async () => {
|
||||
const query = await firebase.database().ref();
|
||||
const same = query.isEqual(query);
|
||||
same.should.eql(true);
|
||||
});
|
||||
|
||||
it('returns false if the query is different', async () => {
|
||||
const query = await firebase.database().ref();
|
||||
const other = await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToLast(2);
|
||||
const same = query.isEqual(other);
|
||||
same.should.eql(false);
|
||||
});
|
||||
|
||||
it('returns true if the query is created differently', async () => {
|
||||
const query = await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToFirst(1)
|
||||
.orderByChild('foo');
|
||||
const other = await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild('foo')
|
||||
.limitToFirst(1);
|
||||
const same = query.isEqual(other);
|
||||
same.should.eql(true);
|
||||
});
|
||||
});
|
||||
40
packages/database/e2e/query/keepSynced.e2e.js
Normal file
40
packages/database/e2e/query/keepSynced.e2e.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().keepSynced()', () => {
|
||||
it('throws if bool is not a valid type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.keepSynced('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'bool' value must be a boolean value.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('toggles keepSynced on and off without throwing', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref('noop')
|
||||
.orderByValue();
|
||||
await ref.keepSynced(true);
|
||||
await ref.keepSynced(false);
|
||||
});
|
||||
});
|
||||
115
packages/database/e2e/query/limitToFirst.e2e.js
Normal file
115
packages/database/e2e/query/limitToFirst.e2e.js
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/limitToFirst`;
|
||||
|
||||
describe('database().ref().limitToFirst()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if limit is invalid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToFirst('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'limit' must be a positive integer value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if limit has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToLast(2)
|
||||
.limitToFirst(3);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Limit was already set (by another call to limitToFirst, or limitToLast)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns a limited array data set', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = {
|
||||
0: 'foo',
|
||||
1: 'bar',
|
||||
2: 'baz',
|
||||
};
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToFirst(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
snapshot.val().should.eql(jet.contextify(['foo', 'bar']));
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a limited object data set', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = {
|
||||
a: 'foo',
|
||||
b: 'bar',
|
||||
c: 'baz',
|
||||
};
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToFirst(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
snapshot.val().should.eql(
|
||||
jet.contextify({
|
||||
a: 'foo',
|
||||
b: 'bar',
|
||||
}),
|
||||
);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a null value when not possible to limit', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = 'foo';
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToFirst(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
should.equal(snapshot.val(), null);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
115
packages/database/e2e/query/limitToLast.e2e.js
Normal file
115
packages/database/e2e/query/limitToLast.e2e.js
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/limitToLast`;
|
||||
|
||||
describe('database().ref().limitToLast()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if limit is invalid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToLast('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'limit' must be a positive integer value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if limit has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.limitToFirst(3)
|
||||
.limitToLast(2);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Limit was already set (by another call to limitToFirst, or limitToLast)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns a limited array data set', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = {
|
||||
0: 'foo',
|
||||
1: 'bar',
|
||||
2: 'baz',
|
||||
};
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToLast(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
snapshot.val().should.eql(jet.contextify([null, 'bar', 'baz']));
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a limited object data set', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = {
|
||||
a: 'foo',
|
||||
b: 'bar',
|
||||
c: 'baz',
|
||||
};
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToLast(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
snapshot.val().should.eql(
|
||||
jet.contextify({
|
||||
b: 'bar',
|
||||
c: 'baz',
|
||||
}),
|
||||
);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a null value when not possible to limit', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}`);
|
||||
|
||||
const initial = 'foo';
|
||||
|
||||
await ref.set(initial);
|
||||
|
||||
return ref
|
||||
.limitToFirst(2)
|
||||
.once('value')
|
||||
.then(snapshot => {
|
||||
should.equal(snapshot.val(), null);
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
1
packages/database/e2e/query/off.e2e.js
Normal file
1
packages/database/e2e/query/off.e2e.js
Normal file
@@ -0,0 +1 @@
|
||||
// TODO
|
||||
244
packages/database/e2e/query/on.e2e.js
Normal file
244
packages/database/e2e/query/on.e2e.js
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/on`;
|
||||
|
||||
describe('database().ref().on()', () => {
|
||||
it('throws if event type is invalid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.on('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'eventType' must be one of`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if callback is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.on('value', 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'callback' must be a function`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if cancel callback is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.on('value', () => {}, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'cancelCallbackOrContext' must be a function or object`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if context is not an object', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.on('value', () => {}, () => {}, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'context' must be an object.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('should callback with an initial value', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/init`);
|
||||
const value = Date.now();
|
||||
await ref.set(value);
|
||||
|
||||
ref.on('value', $ => {
|
||||
callback($.val());
|
||||
});
|
||||
|
||||
await Utils.sleep(500);
|
||||
callback.should.be.calledOnce();
|
||||
callback.should.be.calledWith(value);
|
||||
|
||||
ref.off('value');
|
||||
});
|
||||
|
||||
it('should callback multiple times when the value changes', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/changes`);
|
||||
await ref.set('foo');
|
||||
|
||||
ref.on('value', $ => {
|
||||
callback($.val());
|
||||
});
|
||||
|
||||
await Utils.sleep(500);
|
||||
await ref.set('bar');
|
||||
await Utils.sleep(500);
|
||||
|
||||
ref.off('value');
|
||||
callback.should.be.calledTwice();
|
||||
callback.getCall(0).args[0].should.equal('foo');
|
||||
callback.getCall(1).args[0].should.equal('bar');
|
||||
});
|
||||
|
||||
it('should cancel when something goes wrong', async () => {
|
||||
const successCallback = sinon.spy();
|
||||
const cancelCallback = sinon.spy();
|
||||
const ref = firebase.database().ref(`nope`);
|
||||
|
||||
ref.on(
|
||||
'value',
|
||||
$ => {
|
||||
successCallback($.val());
|
||||
},
|
||||
error => {
|
||||
error.message.should.containEql(
|
||||
`Client doesn't have permission to access the desired data`,
|
||||
);
|
||||
cancelCallback();
|
||||
},
|
||||
);
|
||||
|
||||
await Utils.sleep(1200); // takes a while to call at times
|
||||
ref.off('value');
|
||||
successCallback.should.be.callCount(0);
|
||||
cancelCallback.should.be.calledOnce();
|
||||
});
|
||||
|
||||
it('subscribe to child added events', async () => {
|
||||
const successCallback = sinon.spy();
|
||||
const cancelCallback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childAdded`);
|
||||
|
||||
ref.on(
|
||||
'child_added',
|
||||
$ => {
|
||||
successCallback($.val());
|
||||
},
|
||||
() => {
|
||||
cancelCallback();
|
||||
},
|
||||
);
|
||||
|
||||
await Utils.sleep(500);
|
||||
await ref.child('child1').set('foo');
|
||||
await ref.child('child2').set('bar');
|
||||
await Utils.sleep(500);
|
||||
ref.off('child_added');
|
||||
successCallback.should.be.callCount(2);
|
||||
successCallback.getCall(0).args[0].should.equal('foo');
|
||||
successCallback.getCall(1).args[0].should.equal('bar');
|
||||
cancelCallback.should.be.callCount(0);
|
||||
});
|
||||
|
||||
it('subscribe to child changed events', async () => {
|
||||
const successCallback = sinon.spy();
|
||||
const cancelCallback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childChanged`);
|
||||
const child = ref.child('changeme');
|
||||
await child.set('foo');
|
||||
|
||||
ref.on(
|
||||
'child_changed',
|
||||
$ => {
|
||||
successCallback($.val());
|
||||
},
|
||||
() => {
|
||||
cancelCallback();
|
||||
},
|
||||
);
|
||||
|
||||
const value1 = Date.now();
|
||||
const value2 = Date.now() + 123;
|
||||
|
||||
await Utils.sleep(500);
|
||||
await child.set(value1);
|
||||
await child.set(value2);
|
||||
await Utils.sleep(500);
|
||||
ref.off('child_changed');
|
||||
successCallback.should.be.callCount(2);
|
||||
successCallback.getCall(0).args[0].should.equal(value1);
|
||||
successCallback.getCall(1).args[0].should.equal(value2);
|
||||
cancelCallback.should.be.callCount(0);
|
||||
});
|
||||
|
||||
it('subscribe to child removed events', async () => {
|
||||
const successCallback = sinon.spy();
|
||||
const cancelCallback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childRemoved`);
|
||||
const child = ref.child('removeme');
|
||||
await child.set('foo');
|
||||
|
||||
ref.on(
|
||||
'child_removed',
|
||||
$ => {
|
||||
successCallback($.val());
|
||||
},
|
||||
() => {
|
||||
cancelCallback();
|
||||
},
|
||||
);
|
||||
|
||||
await Utils.sleep(500);
|
||||
await child.remove();
|
||||
await Utils.sleep(500);
|
||||
ref.off('child_removed');
|
||||
successCallback.should.be.callCount(1);
|
||||
successCallback.getCall(0).args[0].should.equal('foo');
|
||||
cancelCallback.should.be.callCount(0);
|
||||
});
|
||||
|
||||
it('subscribe to child moved events', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childMoved`);
|
||||
const orderedRef = ref.orderByChild('nuggets');
|
||||
|
||||
const initial = {
|
||||
alex: { nuggets: 60 },
|
||||
rob: { nuggets: 56 },
|
||||
vassili: { nuggets: 55.5 },
|
||||
tony: { nuggets: 52 },
|
||||
greg: { nuggets: 52 },
|
||||
};
|
||||
|
||||
orderedRef.on('child_moved', $ => {
|
||||
// console.log($);
|
||||
callback($.val());
|
||||
});
|
||||
await ref.set(initial);
|
||||
await ref.child('greg/nuggets').set(57);
|
||||
await ref.child('rob/nuggets').set(61);
|
||||
await Utils.sleep(500);
|
||||
ref.off('child_moved');
|
||||
callback.should.be.calledTwice();
|
||||
callback.getCall(0).args[0].should.be.eql(jet.contextify({ nuggets: 57 }));
|
||||
callback.getCall(1).args[0].should.be.eql(jet.contextify({ nuggets: 61 }));
|
||||
});
|
||||
});
|
||||
178
packages/database/e2e/query/once.e2e.js
Normal file
178
packages/database/e2e/query/once.e2e.js
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, CONTENT, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/once`;
|
||||
|
||||
describe('database().ref().once()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if event type is invalid', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.once('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'eventType' must be one of`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if success callback is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.once('value', 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'successCallBack' must be a function`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if failure callback is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.once('value', () => {}, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'failureCallbackOrContext' must be a function or context`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if context is not an object', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.once('value', () => {}, () => {}, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'context' must be a context object.`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns a promise', async () => {
|
||||
const ref = firebase.database().ref('tests/types/number');
|
||||
const returnValue = ref.once('value');
|
||||
returnValue.should.be.Promise();
|
||||
});
|
||||
|
||||
it('resolves with the correct values', async () => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/types`);
|
||||
|
||||
await Promise.all(
|
||||
Object.keys(CONTENT.TYPES).map(async key => {
|
||||
const value = CONTENT.TYPES[key];
|
||||
const snapsnot = await ref.child(key).once('value');
|
||||
snapsnot.val().should.eql(jet.contextify(value));
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('is is called when the value is changed', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/types/number`);
|
||||
ref.once('value').then(callback);
|
||||
await ref.set(1337);
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
|
||||
it('errors if permission denied', async () => {
|
||||
const ref = firebase.database().ref('nope');
|
||||
try {
|
||||
await ref.once('value');
|
||||
return Promise.reject(new Error('No permission denied error'));
|
||||
} catch (error) {
|
||||
error.code.includes('database/permission-denied').should.be.true();
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('it calls when a child is added', async () => {
|
||||
const value = Date.now();
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childAdded`);
|
||||
|
||||
ref.once('child_added').then($ => callback($.val()));
|
||||
await ref.child('foo').set(value);
|
||||
await Utils.sleep(100);
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
callback.should.be.calledWith(value);
|
||||
});
|
||||
|
||||
it('resolves when a child is changed', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childChanged`);
|
||||
|
||||
await ref.child('foo').set(1);
|
||||
ref.once('child_changed').then($ => callback($.val()));
|
||||
await Utils.sleep(300);
|
||||
await ref.child('foo').set(2);
|
||||
await Utils.sleep(300);
|
||||
callback.should.be.calledOnce();
|
||||
callback.should.be.calledWith(2);
|
||||
});
|
||||
|
||||
it('resolves when a child is removed', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childRemoved`);
|
||||
const child = ref.child('removeme');
|
||||
await child.set('foo');
|
||||
|
||||
ref.once('child_removed').then($ => callback($.val()));
|
||||
await Utils.sleep(300);
|
||||
await child.remove();
|
||||
await Utils.sleep(300);
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
callback.should.be.calledWith('foo');
|
||||
});
|
||||
|
||||
// https://github.com/firebase/firebase-js-sdk/blob/6b53e0058483c9002d2fe56119f86fc9fb96b56c/packages/database/test/order_by.test.ts#L104
|
||||
it('resolves when a child is moved', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/childMoved`);
|
||||
const orderedRef = ref.orderByChild('nuggets');
|
||||
|
||||
const initial = {
|
||||
alex: { nuggets: 60 },
|
||||
rob: { nuggets: 56 },
|
||||
vassili: { nuggets: 55.5 },
|
||||
tony: { nuggets: 52 },
|
||||
greg: { nuggets: 52 },
|
||||
};
|
||||
|
||||
orderedRef.once('child_moved').then($ => callback($.val()));
|
||||
await ref.set(initial);
|
||||
await ref.child('greg/nuggets').set(57);
|
||||
await Utils.sleep(100);
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
callback.should.be.calledWith({ nuggets: 57 });
|
||||
});
|
||||
});
|
||||
86
packages/database/e2e/query/orderByChild.e2e.js
Normal file
86
packages/database/e2e/query/orderByChild.e2e.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/orderByChild`;
|
||||
|
||||
describe('database().ref().orderByChild()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if path is not a string value', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild({ foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'path' must be a string value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if path is an empty path', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild('/');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'path' cannot be empty. Use orderByValue instead`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if an orderBy call has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByKey()
|
||||
.orderByChild('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`You can't combine multiple orderBy calls`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('order by a child value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
try {
|
||||
const snapshot = await ref
|
||||
.child('query')
|
||||
.orderByChild('number')
|
||||
.once('value');
|
||||
|
||||
const expected = ['b', 'c', 'a'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
60
packages/database/e2e/query/orderByKey.e2e.js
Normal file
60
packages/database/e2e/query/orderByKey.e2e.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/orderByKey`;
|
||||
|
||||
describe('database().ref().orderByKey()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if an orderBy call has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild('foo')
|
||||
.orderByKey();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`You can't combine multiple orderBy calls`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('order by a key', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
try {
|
||||
const snapshot = await ref
|
||||
.child('query')
|
||||
.orderByKey()
|
||||
.once('value');
|
||||
|
||||
const expected = ['a', 'b', 'c'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
66
packages/database/e2e/query/orderByPriority.e2e.js
Normal file
66
packages/database/e2e/query/orderByPriority.e2e.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/orderByPriority`;
|
||||
|
||||
describe('database().ref().orderByPriority()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if an orderBy call has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild('foo')
|
||||
.orderByPriority();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`You can't combine multiple orderBy calls`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('order by priority', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('query');
|
||||
|
||||
await Promise.all([
|
||||
ref.child('a').setPriority(2),
|
||||
ref.child('b').setPriority(3),
|
||||
ref.child('c').setPriority(1),
|
||||
]);
|
||||
|
||||
try {
|
||||
const snapshot = await ref.orderByPriority().once('value');
|
||||
|
||||
const expected = ['c', 'a', 'b'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
66
packages/database/e2e/query/orderByValue.e2e.js
Normal file
66
packages/database/e2e/query/orderByValue.e2e.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/orderByValue`;
|
||||
|
||||
describe('database().ref().orderByValue()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if an orderBy call has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByChild('foo')
|
||||
.orderByValue();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`You can't combine multiple orderBy calls`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('order by value', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('query');
|
||||
|
||||
await ref.set({
|
||||
a: 2,
|
||||
b: 3,
|
||||
c: 1,
|
||||
});
|
||||
|
||||
try {
|
||||
const snapshot = await ref.orderByValue().once('value');
|
||||
|
||||
const expected = ['c', 'a', 'b'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
151
packages/database/e2e/query/startAt.e2e.js
Normal file
151
packages/database/e2e/query/startAt.e2e.js
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/startAt`;
|
||||
|
||||
describe('database().ref().startAt()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if an value is undefined', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.startAt();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be a number, string, boolean or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if an key is not a string', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.startAt('foo', 1234);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'key' must be a string value if defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if a starting point has already been set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.equalTo('foo')
|
||||
.startAt('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`Starting point was already set (by another call to startAt or equalTo)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by key and the key param is set', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByKey('foo')
|
||||
.startAt('foo', 'bar');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by key, you may only pass a value argument to startAt(), endAt(), or equalTo()`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by key and the value param is not a string', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByKey('foo')
|
||||
.startAt(123);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by key, the value of startAt(), endAt(), or equalTo() must be a string`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if ordering by priority and the value param is not priority type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.orderByPriority()
|
||||
.startAt(true);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(
|
||||
`When ordering by priority, the first value of startAt(), endAt(), or equalTo() must be a valid priority value (null, a number, or a string)`,
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('snapshot value is null when no ordering modifier is applied', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
});
|
||||
|
||||
const snapshot = await ref.startAt(2).once('value');
|
||||
should.equal(snapshot.val(), null);
|
||||
});
|
||||
|
||||
it('starts at the correct value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
await ref.set({
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4,
|
||||
});
|
||||
|
||||
const snapshot = await ref
|
||||
.orderByValue()
|
||||
.startAt(2)
|
||||
.once('value');
|
||||
|
||||
const expected = ['b', 'c', 'd'];
|
||||
|
||||
snapshot.forEach((childSnapshot, i) => {
|
||||
childSnapshot.key.should.eql(expected[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
27
packages/database/e2e/query/toJSON.e2e.js
Normal file
27
packages/database/e2e/query/toJSON.e2e.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().toJSON()', () => {
|
||||
it('returns a string version of the current query path', async () => {
|
||||
const res = firebase
|
||||
.database()
|
||||
.ref('foo/bar/baz')
|
||||
.toJSON();
|
||||
const expected = `${firebase.database()._customUrlOrRegion}/foo/bar/baz`;
|
||||
should.equal(res, expected);
|
||||
});
|
||||
});
|
||||
44
packages/database/e2e/reference/child.e2e.js
Normal file
44
packages/database/e2e/reference/child.e2e.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().child()', () => {
|
||||
it('throws if path is not a string', async () => {
|
||||
try {
|
||||
firebase
|
||||
.database()
|
||||
.ref()
|
||||
.child({ foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'path' must be a string value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if path is not a valid string', async () => {
|
||||
try {
|
||||
firebase
|
||||
.database()
|
||||
.ref()
|
||||
.child('$$$$$');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`Paths must be non-empty strings and can't contain`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
30
packages/database/e2e/reference/key.e2e.js
Normal file
30
packages/database/e2e/reference/key.e2e.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().key', () => {
|
||||
it('returns null when no reference path is provides', () => {
|
||||
const ref = firebase.database().ref();
|
||||
should.equal(ref.key, null);
|
||||
});
|
||||
|
||||
it('return last token in reference path', () => {
|
||||
const ref1 = firebase.database().ref('foo');
|
||||
const ref2 = firebase.database().ref('foo/bar/baz');
|
||||
ref1.key.should.equal('foo');
|
||||
ref2.key.should.equal('baz');
|
||||
});
|
||||
});
|
||||
28
packages/database/e2e/reference/onDisconnect.e2e.js
Normal file
28
packages/database/e2e/reference/onDisconnect.e2e.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// See onDisconnect directory for specific tests
|
||||
|
||||
describe('database().ref().onDisconnect()', () => {
|
||||
it('returns a new DatabaseOnDisconnect instance', () => {
|
||||
const instance = firebase
|
||||
.database()
|
||||
.ref()
|
||||
.onDisconnect();
|
||||
instance.constructor.name.should.eql('DatabaseOnDisconnect');
|
||||
});
|
||||
});
|
||||
30
packages/database/e2e/reference/parent.e2e.js
Normal file
30
packages/database/e2e/reference/parent.e2e.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().parent', () => {
|
||||
it('returns null when no reference path is provides', () => {
|
||||
const ref = firebase.database().ref();
|
||||
should.equal(ref.parent, null);
|
||||
});
|
||||
|
||||
it('return last token in reference path', () => {
|
||||
const ref1 = firebase.database().ref('/foo').parent;
|
||||
const ref2 = firebase.database().ref('/foo/bar/baz').parent;
|
||||
should.equal(ref1, null);
|
||||
ref2.key.should.equal('bar');
|
||||
});
|
||||
});
|
||||
26
packages/database/e2e/reference/push.e2e.js
Normal file
26
packages/database/e2e/reference/push.e2e.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
// const TEST_PATH = `${PATH}/push`;
|
||||
|
||||
xdescribe('database().ref().push()', () => {
|
||||
// before(() => seed(TEST_PATH));
|
||||
// after(() => wipe(TEST_PATH));
|
||||
// TODO
|
||||
});
|
||||
43
packages/database/e2e/reference/remove.e2e.js
Normal file
43
packages/database/e2e/reference/remove.e2e.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/remove`;
|
||||
|
||||
describe('database().ref().remove()', () => {
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.remove('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('removes a value at the path', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
await ref.set('foo');
|
||||
await ref.remove();
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.exists().should.equal(false);
|
||||
});
|
||||
});
|
||||
23
packages/database/e2e/reference/root.e2e.js
Normal file
23
packages/database/e2e/reference/root.e2e.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('database().ref().root', () => {
|
||||
it('returns a root reference', () => {
|
||||
const ref = firebase.database().ref('foo/bar/baz');
|
||||
should.equal(ref.root.key, null);
|
||||
});
|
||||
});
|
||||
83
packages/database/e2e/reference/set.e2e.js
Normal file
83
packages/database/e2e/reference/set.e2e.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/set`;
|
||||
|
||||
describe('database().ref().set()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if no value is provided', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.set();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'value' must be defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.set(null, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('sets a new value', async () => {
|
||||
const value = Date.now();
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
await ref.set(value);
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql(value);
|
||||
});
|
||||
|
||||
it('callback if function is passed', async () => {
|
||||
const value = Date.now();
|
||||
return new Promise(async resolve => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.set(value, resolve);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws if permission defined', async () => {
|
||||
const value = Date.now();
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref('nope/foo')
|
||||
.set(value);
|
||||
return Promise.reject(new Error('Did not throw error.'));
|
||||
} catch (error) {
|
||||
error.code.includes('database/permission-denied').should.be.true();
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
101
packages/database/e2e/reference/setPriority.e2e.js
Normal file
101
packages/database/e2e/reference/setPriority.e2e.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, CONTENT, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/priority`;
|
||||
|
||||
describe('database().ref().setPriority()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if priority is not a valid type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.setPriority({});
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'priority' must be a number, string or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.setPriority(null, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('should correctly set a priority for all non-null values', async () => {
|
||||
await Promise.all(
|
||||
Object.keys(CONTENT.TYPES).map(async dataRef => {
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/types/${dataRef}`);
|
||||
await ref.setPriority(1);
|
||||
const snapshot = await ref.once('value');
|
||||
if (snapshot.val() !== null) {
|
||||
snapshot.getPriority().should.eql(1);
|
||||
}
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('callback if function is passed', async () => {
|
||||
const value = Date.now();
|
||||
return new Promise(async resolve => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${TEST_PATH}/types/string`)
|
||||
.set(value, resolve);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws if setting priority on non-existent node', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref('tests/siudfhsuidfj')
|
||||
.setPriority(1);
|
||||
return Promise.reject(new Error('Did not throw error.'));
|
||||
} catch (error) {
|
||||
// WEB SDK: INVALID_PARAMETERS: could not set priority on non-existent node
|
||||
// TODO Get this error? Native code = -999 Unknown
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if permission defined', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref('nope/foo')
|
||||
.setPriority(1);
|
||||
return Promise.reject(new Error('Did not throw error.'));
|
||||
} catch (error) {
|
||||
error.code.includes('database/permission-denied').should.be.true();
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
83
packages/database/e2e/reference/setWithPriority.e2e.js
Normal file
83
packages/database/e2e/reference/setWithPriority.e2e.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/setWithPriority`;
|
||||
|
||||
describe('database().ref().setWithPriority()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if newVal is not defined', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.setWithPriority();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'newVal' must be defined`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if newPriority is incorrect type', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.setWithPriority(null, { foo: 'bar' });
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'newPriority' must be a number, string or null value`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.setWithPriority(null, null, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('callback if function is passed', async () => {
|
||||
const value = Date.now();
|
||||
return new Promise(async resolve => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${TEST_PATH}/setValueWithCallback`)
|
||||
.setWithPriority(value, 2, resolve);
|
||||
});
|
||||
});
|
||||
|
||||
it('sets with a new value and priority', async () => {
|
||||
const value = Date.now();
|
||||
const ref = firebase.database().ref(`${TEST_PATH}/setValue`);
|
||||
await ref.setWithPriority(value, 2);
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql(value);
|
||||
snapshot.getPriority().should.eql(2);
|
||||
});
|
||||
});
|
||||
217
packages/database/e2e/reference/transaction.e2e.js
Normal file
217
packages/database/e2e/reference/transaction.e2e.js
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/transaction`;
|
||||
const NOOP = () => {};
|
||||
|
||||
describe('database().ref().transaction()', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('throws if no transactionUpdate is provided', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.transaction();
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'transactionUpdate' must be a function`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.transaction(NOOP, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if applyLocally is not a boolean', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref()
|
||||
.transaction(NOOP, NOOP, 'foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'applyLocally' must be a boolean value if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('updates the value via a transaction', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('transaction');
|
||||
await ref.set(1);
|
||||
|
||||
const { committed, snapshot } = await ref.transaction(value => {
|
||||
return value + 1;
|
||||
});
|
||||
|
||||
should.equal(committed, true, 'Transaction did not commit.');
|
||||
snapshot.val().should.equal(2);
|
||||
});
|
||||
|
||||
it('aborts transaction if undefined returned', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('transaction');
|
||||
await ref.set(1);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ref.transaction(
|
||||
() => {
|
||||
return undefined;
|
||||
},
|
||||
(error, committed) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
if (!committed) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
return reject(new Error('Transaction did not abort commit.'));
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('passes valid data through the callback', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('transaction');
|
||||
await ref.set(1);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ref.transaction(
|
||||
$ => {
|
||||
return $ + 1;
|
||||
},
|
||||
(error, committed, snapshot) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
if (!committed) {
|
||||
return reject(new Error('Transaction aborted when it should not have done'));
|
||||
}
|
||||
|
||||
should.equal(snapshot.val(), 2);
|
||||
return resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when an error occurs', async () => {
|
||||
const ref = firebase.database().ref('nope');
|
||||
|
||||
try {
|
||||
await ref.transaction($ => {
|
||||
return $ + 1;
|
||||
});
|
||||
return Promise.reject(new Error('Did not throw error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`Client doesn't have permission to access the desired data`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('passes error back to the callback', async () => {
|
||||
const ref = firebase.database().ref('nope');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ref
|
||||
.transaction(
|
||||
$ => {
|
||||
return $ + 1;
|
||||
},
|
||||
(error, committed, snapshot) => {
|
||||
if (snapshot !== null) {
|
||||
return reject(new Error('Snapshot should not be available'));
|
||||
}
|
||||
|
||||
if (committed === true) {
|
||||
return reject(new Error('Transaction should not have committed'));
|
||||
}
|
||||
|
||||
error.message.should.containEql(
|
||||
`Client doesn't have permission to access the desired data`,
|
||||
);
|
||||
return resolve();
|
||||
},
|
||||
)
|
||||
.catch(() => {
|
||||
// catch unhandled rejection
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets a value if one does not exist', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('create');
|
||||
await ref.remove(); // Ensure it's clear
|
||||
|
||||
const value = Date.now();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ref.transaction(
|
||||
$ => {
|
||||
if ($ === null) {
|
||||
return { foo: value };
|
||||
}
|
||||
|
||||
throw new Error('Value should not exist');
|
||||
},
|
||||
(error, committed, snapshot) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
if (!committed) {
|
||||
return reject(new Error('Transaction should have committed'));
|
||||
}
|
||||
|
||||
snapshot.val().should.eql(
|
||||
jet.contextify({
|
||||
foo: value,
|
||||
}),
|
||||
);
|
||||
return resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
100
packages/database/e2e/reference/update.e2e.js
Normal file
100
packages/database/e2e/reference/update.e2e.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH } = require('../helpers');
|
||||
|
||||
describe('database().ref().update()', () => {
|
||||
after(async () => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${PATH}/update`)
|
||||
.remove();
|
||||
});
|
||||
|
||||
it('throws if values is not an object', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${PATH}/update`)
|
||||
.update('foo');
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' must be an object`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if values does not contain any values', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${PATH}/update`)
|
||||
.update({});
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'values' must be an object containing multiple values`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if onComplete is not a function', async () => {
|
||||
try {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${PATH}/update`)
|
||||
.update(
|
||||
{
|
||||
foo: 'bar',
|
||||
},
|
||||
'foo',
|
||||
);
|
||||
return Promise.reject(new Error('Did not throw an Error.'));
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'onComplete' must be a function if provided`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
it('updates values', async () => {
|
||||
const value = Date.now();
|
||||
const ref = firebase.database().ref(`${PATH}/update`);
|
||||
await ref.update({
|
||||
foo: value,
|
||||
});
|
||||
const snapshot = await ref.once('value');
|
||||
snapshot.val().should.eql(
|
||||
jet.contextify({
|
||||
foo: value,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('callback if function is passed', async () => {
|
||||
const value = Date.now();
|
||||
return new Promise(async resolve => {
|
||||
await firebase
|
||||
.database()
|
||||
.ref(`${PATH}/update`)
|
||||
.update(
|
||||
{
|
||||
foo: value,
|
||||
},
|
||||
resolve,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
302
packages/database/e2e/snapshot/snapshot.e2e.js
Normal file
302
packages/database/e2e/snapshot/snapshot.e2e.js
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present Invertase Limited & Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this library except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const { PATH, CONTENT, seed, wipe } = require('../helpers');
|
||||
|
||||
const TEST_PATH = `${PATH}/snapshot`;
|
||||
|
||||
describe('database()...snapshot', () => {
|
||||
before(() => seed(TEST_PATH));
|
||||
after(() => wipe(TEST_PATH));
|
||||
|
||||
it('returns the snapshot key', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/boolean')
|
||||
.once('value');
|
||||
|
||||
snapshot.key.should.equal('boolean');
|
||||
});
|
||||
|
||||
it('returns the snapshot reference', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/boolean')
|
||||
.once('value');
|
||||
|
||||
snapshot.ref.key.should.equal('boolean');
|
||||
});
|
||||
|
||||
it('returns the correct boolean for exists', async () => {
|
||||
const snapshot1 = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/boolean')
|
||||
.once('value');
|
||||
|
||||
const snapshot2 = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/nope')
|
||||
.once('value');
|
||||
|
||||
snapshot1.exists().should.equal(true);
|
||||
snapshot2.exists().should.equal(false);
|
||||
});
|
||||
|
||||
it('exports a valid object', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/string')
|
||||
.once('value');
|
||||
|
||||
const exported = snapshot.exportVal();
|
||||
|
||||
exported.should.have.property('.value');
|
||||
exported.should.have.property('.priority');
|
||||
exported['.value'].should.equal('foobar');
|
||||
should.equal(exported['.priority'], null);
|
||||
});
|
||||
|
||||
it('exports a valid object with a object value', async () => {
|
||||
const snapshot = await firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/object')
|
||||
.once('value');
|
||||
|
||||
const exported = snapshot.exportVal();
|
||||
|
||||
exported.should.have.property('.value');
|
||||
exported.should.have.property('.priority');
|
||||
exported['.value'].should.eql(jet.contextify(CONTENT.TYPES.object));
|
||||
should.equal(exported['.priority'], null);
|
||||
});
|
||||
|
||||
it('forEach throws if action param is not a function', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('unorderedList');
|
||||
|
||||
await ref.set({
|
||||
a: 3,
|
||||
b: 1,
|
||||
c: 2,
|
||||
});
|
||||
|
||||
const snapshot = await ref.orderByValue().once('value');
|
||||
|
||||
try {
|
||||
snapshot.forEach('foo');
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'action' must be a function`);
|
||||
}
|
||||
});
|
||||
|
||||
it('forEach returns an ordered list of snapshots', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('unorderedList');
|
||||
|
||||
await ref.set({
|
||||
a: 3,
|
||||
b: 1,
|
||||
c: 2,
|
||||
});
|
||||
|
||||
const snapshot = await ref.orderByValue().once('value');
|
||||
const expected = ['b', 'c', 'a'];
|
||||
|
||||
snapshot.forEach((childSnap, i) => {
|
||||
childSnap.val().should.equal(i + 1);
|
||||
childSnap.key.should.equal(expected[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('forEach works with arrays', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types');
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
snapshot.child('array').forEach((childSnap, i) => {
|
||||
callback();
|
||||
childSnap.val().should.equal(i);
|
||||
childSnap.key.should.equal(i.toString());
|
||||
});
|
||||
|
||||
callback.should.be.callCount(snapshot.child('array').numChildren());
|
||||
});
|
||||
|
||||
it('forEach works with objects and cancels when returning true', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/object')
|
||||
.orderByKey();
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
snapshot.forEach(childSnap => {
|
||||
callback();
|
||||
childSnap.key.should.equal('bar');
|
||||
childSnap.val().should.equal('baz');
|
||||
return true;
|
||||
});
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
|
||||
it('forEach works with arrays and cancels when returning true', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types');
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
snapshot.child('array').forEach(childSnap => {
|
||||
callback();
|
||||
childSnap.val().should.equal(0);
|
||||
childSnap.key.should.equal('0');
|
||||
return true;
|
||||
});
|
||||
|
||||
callback.should.be.calledOnce();
|
||||
});
|
||||
|
||||
it('forEach returns false when no child keys', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/boolean');
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
const bool = snapshot.forEach(() => {
|
||||
callback();
|
||||
});
|
||||
|
||||
bool.should.equal(false);
|
||||
callback.should.be.callCount(0);
|
||||
});
|
||||
|
||||
it('forEach cancels iteration when returning true', async () => {
|
||||
const callback = sinon.spy();
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/array');
|
||||
|
||||
const snapshot = await ref.orderByValue().once('value');
|
||||
|
||||
const cancelled = snapshot.forEach(childSnap => {
|
||||
callback(childSnap.val());
|
||||
return true;
|
||||
});
|
||||
|
||||
cancelled.should.equal(true);
|
||||
callback.should.be.callCount(1);
|
||||
callback.getCall(0).args[0].should.equal(0);
|
||||
});
|
||||
|
||||
it('getPriority returns the correct value', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('getPriority');
|
||||
|
||||
await ref.setWithPriority('foo', 'bar');
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
snapshot.getPriority().should.equal('bar');
|
||||
});
|
||||
|
||||
it('hasChild throws if path is not a string value', async () => {
|
||||
const ref = firebase
|
||||
.database()
|
||||
.ref(TEST_PATH)
|
||||
.child('types/boolean');
|
||||
|
||||
const snapshot = await ref.once('value');
|
||||
|
||||
try {
|
||||
snapshot.hasChild({ foo: 'bar' });
|
||||
} catch (error) {
|
||||
error.message.should.containEql(`'path' must be a string value`);
|
||||
}
|
||||
});
|
||||
|
||||
it('hasChild returns the correct boolean value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const snapshot1 = await ref.child('types/boolean').once('value');
|
||||
const snapshot2 = await ref.child('types').once('value');
|
||||
|
||||
snapshot1.hasChild('foo').should.equal(false);
|
||||
snapshot2.hasChild('boolean').should.equal(true);
|
||||
});
|
||||
|
||||
it('hasChildren returns the correct boolean value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
const snapshot = await ref.child('types/object').once('value');
|
||||
snapshot.hasChildren().should.equal(true);
|
||||
});
|
||||
|
||||
it('numChildren returns the correct number value', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const snapshot1 = await ref.child('types/boolean').once('value');
|
||||
const snapshot2 = await ref.child('types/array').once('value');
|
||||
const snapshot3 = await ref.child('types/object').once('value');
|
||||
|
||||
snapshot1.numChildren().should.equal(0);
|
||||
snapshot2.numChildren().should.equal(CONTENT.TYPES.array.length);
|
||||
snapshot3.numChildren().should.equal(Object.keys(CONTENT.TYPES.object).length);
|
||||
});
|
||||
|
||||
it('toJSON returns the value of the snapshot', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const snapshot1 = await ref.child('types/string').once('value');
|
||||
const snapshot2 = await ref.child('types/object').once('value');
|
||||
|
||||
snapshot1.toJSON().should.equal('foobar');
|
||||
snapshot2.toJSON().should.eql(jet.contextify(CONTENT.TYPES.object));
|
||||
});
|
||||
|
||||
it('val returns the value of the snapshot', async () => {
|
||||
const ref = firebase.database().ref(TEST_PATH);
|
||||
|
||||
const snapshot1 = await ref.child('types/string').once('value');
|
||||
const snapshot2 = await ref.child('types/object').once('value');
|
||||
|
||||
snapshot1.val().should.equal('foobar');
|
||||
snapshot2.val().should.eql(jet.contextify(CONTENT.TYPES.object));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user