mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-09 22:43:19 +08:00
[crashlytics] Fixes: #1643, #1848, #1964, #1920, #1884, #1783, #1966, #1940, #1447 Features/Bugs Todo: Capture JS Exceptions with stack traces automatically Capture Unhandled Promise Rejections with stack traces automatically [Android] .crash() not captured in debug due to RN RedBox; see #1921 Support advanced user identifier features [Android] Enable Crashlyics NDK reporting by default (gist) Support toggling native crash logging off/on (e.g. disable in DEV) Support toggling JS crash logging off/on (e.g. disable in DEV) [ios] Static framework support for all modules [ios] Implement CocoaPods Firebase RN modules auto-loader script Implement firebase.json config loader; Android & iOS [tests] Fix false positive tests that catch errors (tests did not check that errors actually threw) [android] Cleanup manifest permissions for all modules [android] Implement Content provider base class [android] Investigate/fix issue where setDataCollectionDefaultEnabled is false by default in Firebase - it disables Crashlytics reporting
249 lines
7.8 KiB
JavaScript
249 lines
7.8 KiB
JavaScript
/* eslint-disable consistent-return */
|
|
/*
|
|
* 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('analytics()', () => {
|
|
describe('namespace', () => {
|
|
it('accessible from firebase.app()', () => {
|
|
const app = firebase.app();
|
|
should.exist(app.analytics);
|
|
app.analytics().logEvent.should.be.a.Function();
|
|
app.analytics().emitter.should.be.a.Object();
|
|
});
|
|
|
|
it('throws if non default app arg provided to firebase.analytics(APP)', () => {
|
|
const app = firebase.app('secondaryFromNative');
|
|
try {
|
|
firebase.analytics(app);
|
|
return Promise.reject(new Error('Did not throw'));
|
|
} catch (e) {
|
|
e.message.should.containEql('does not support multiple Firebase Apps');
|
|
return Promise.resolve();
|
|
}
|
|
});
|
|
|
|
it('throws if analytics access from a non default app', () => {
|
|
const app = firebase.app('secondaryFromNative');
|
|
try {
|
|
app.analytics();
|
|
return Promise.reject(new Error('Did not throw'));
|
|
} catch (e) {
|
|
e.message.should.containEql('does not support multiple Firebase Apps');
|
|
return Promise.resolve();
|
|
}
|
|
});
|
|
|
|
// TODO in app/registry/namespace.js - if (!hasCustomUrlOrRegionSupport)
|
|
xit('throws if args provided to firebase.app().analytics(ARGS)', () => {
|
|
try {
|
|
firebase.app().analytics('foo', 'arg2');
|
|
return Promise.reject(new Error('Did not throw'));
|
|
} catch (e) {
|
|
e.message.should.containEql('does not support multiple Firebase Apps');
|
|
return Promise.resolve();
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('logEvent()', () => {
|
|
it('errors on using a reserved name', () => {
|
|
try {
|
|
firebase.analytics().logEvent('session_start');
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('reserved event');
|
|
}
|
|
});
|
|
|
|
it('errors if name not alphanumeric', () => {
|
|
try {
|
|
firebase.analytics().logEvent('!@£$%^&*');
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('is invalid');
|
|
}
|
|
});
|
|
|
|
it('errors if more than 25 params provided', () => {
|
|
try {
|
|
firebase.analytics().logEvent('invertase', Object.assign({}, new Array(26).fill(1)));
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('Maximum number of parameters exceeded');
|
|
}
|
|
});
|
|
|
|
it('errors if name is not a string', () => {
|
|
(() => {
|
|
firebase.analytics().logEvent(13377331);
|
|
}).should.throw(
|
|
`firebase.analytics().logEvent(*): First argument 'name' is required and must be a string value.`,
|
|
);
|
|
});
|
|
|
|
it('errors if params is not an object', () => {
|
|
(() => {
|
|
firebase.analytics().logEvent('invertase_event', 'this should be an object');
|
|
}).should.throw(
|
|
`firebase.analytics().logEvent(_, *): Second optional argument 'params' must be an object if provided.`,
|
|
);
|
|
});
|
|
|
|
it('log an event without parameters', async () => {
|
|
await firebase.analytics().logEvent('invertase_event');
|
|
});
|
|
|
|
it('log an event with parameters', async () => {
|
|
await firebase.analytics().logEvent('invertase_event', {
|
|
boolean: true,
|
|
number: 1,
|
|
string: 'string',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('setAnalyticsCollectionEnabled()', () => {
|
|
it('true', async () => {
|
|
await firebase.analytics().setAnalyticsCollectionEnabled(true);
|
|
});
|
|
|
|
it('false', async () => {
|
|
await firebase.analytics().setAnalyticsCollectionEnabled(false);
|
|
});
|
|
});
|
|
|
|
describe('resetAnalyticsData()', () => {
|
|
it('calls native fn without error', async () => {
|
|
await firebase.analytics().resetAnalyticsData();
|
|
});
|
|
});
|
|
|
|
describe('setCurrentScreen()', () => {
|
|
it('screenName only', async () => {
|
|
await firebase.analytics().setCurrentScreen('invertase screen');
|
|
});
|
|
|
|
it('screenName with screenClassOverride', async () => {
|
|
await firebase.analytics().setCurrentScreen('invertase screen', 'invertase class override');
|
|
});
|
|
|
|
it('errors if screenName not a string', async () => {
|
|
try {
|
|
await firebase.analytics().setCurrentScreen(666.1337);
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be a string');
|
|
}
|
|
});
|
|
|
|
it('errors if screenClassOverride not a string', async () => {
|
|
try {
|
|
await firebase.analytics().setCurrentScreen('invertase screen', 666.1337);
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be undefined or a string');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('setMinimumSessionDuration()', () => {
|
|
it('default duration', async () => {
|
|
await firebase.analytics().setMinimumSessionDuration();
|
|
});
|
|
|
|
it('custom duration', async () => {
|
|
await firebase.analytics().setMinimumSessionDuration(1337);
|
|
});
|
|
});
|
|
|
|
describe('setSessionTimeoutDuration()', () => {
|
|
it('default duration', async () => {
|
|
await firebase.analytics().setSessionTimeoutDuration();
|
|
});
|
|
|
|
it('custom duration', async () => {
|
|
await firebase.analytics().setSessionTimeoutDuration(13371337);
|
|
});
|
|
});
|
|
|
|
describe('setUserId()', () => {
|
|
it('allows a null values to be set', async () => {
|
|
await firebase.analytics().setUserId(null);
|
|
});
|
|
|
|
it('accepts string values', async () => {
|
|
await firebase.analytics().setUserId('rn-firebase');
|
|
});
|
|
|
|
it('rejects none string none null values', async () => {
|
|
try {
|
|
await firebase.analytics().setUserId(666.1337);
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be a string');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('setUserProperty()', () => {
|
|
it('allows a null values to be set', async () => {
|
|
await firebase.analytics().setUserProperty('invertase', null);
|
|
});
|
|
|
|
it('accepts string values', async () => {
|
|
await firebase.analytics().setUserProperty('invertase2', 'rn-firebase');
|
|
});
|
|
|
|
it('rejects none string none null values', async () => {
|
|
try {
|
|
await firebase.analytics().setUserProperty('invertase3', 33.3333);
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be a string');
|
|
}
|
|
});
|
|
|
|
it('errors if property name is not a string', async () => {
|
|
try {
|
|
await firebase.analytics().setUserProperty(1337, 'invertase');
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be a string');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('setUserProperties()', () => {
|
|
it('errors if arg is not an object', async () => {
|
|
try {
|
|
await firebase.analytics().setUserProperties(1337);
|
|
return Promise.reject(new Error('Did not throw.'));
|
|
} catch (e) {
|
|
e.message.should.containEql('must be an object');
|
|
}
|
|
});
|
|
|
|
it('allows null values to be set', async () => {
|
|
await firebase.analytics().setUserProperties({ invertase: null });
|
|
});
|
|
|
|
it('accepts string values', async () => {
|
|
await firebase.analytics().setUserProperties({ invertase2: 'rn-firebase' });
|
|
});
|
|
});
|
|
});
|