Skip to content

fix: e2e modular deprecation fixes + auth MFA modular fixes #8499

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/app-distribution/e2e/app-distribution.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@

describe('appDistribution()', function () {
describe('v8 compatibility', function () {
beforeEach(async function beforeEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = true;
});

afterEach(async function afterEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = false;
});

describe('native module is loaded', function () {
it('checks native module load status', function () {
firebase.appDistribution().native;
Expand Down
22 changes: 15 additions & 7 deletions packages/app/e2e/app.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@

describe('modular', function () {
describe('firebase v8 compat', function () {
beforeEach(async function beforeEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = true;
});

afterEach(async function afterEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = false;
});

it('it should allow read the default app from native', function () {
if (Platform.other) return; // Not supported on non-native platforms.
// app is created in tests app before all hook
Expand Down Expand Up @@ -201,21 +211,20 @@ describe('modular', function () {
});

it('it should initialize dynamic apps', async function () {
const { initializeApp, getApps, getApp } = modular;
const { initializeApp, getApps, getApp, deleteApp } = modular;

const appCount = firebase.apps.length;
const appCount = getApps().length;
const name = `testscoreapp${FirebaseHelpers.id}`;
const platformAppConfig = FirebaseHelpers.app.config();
const newApp = await initializeApp(platformAppConfig, name);
newApp.name.should.equal(name);
newApp.toString().should.equal(name);
newApp.options.apiKey.should.equal(platformAppConfig.apiKey);

const apps = getApps();

should.equal(apps.includes(getApp(name)), true);
should.equal(apps.length, appCount + 1);
return newApp.delete();
return deleteApp(newApp);
});

it('should error if dynamic app initialization values are incorrect', async function () {
Expand Down Expand Up @@ -257,8 +266,8 @@ describe('modular', function () {
} catch (e) {
e.code.should.containEql('app/unknown');
e.message.should.containEql('Configuration fails');
should.equal(firebase.apps.length, appCount);
should.equal(firebase.apps.includes('myname'), false);
should.equal(getApps().length, appCount);
should.equal(getApps().includes('myname'), false);
}
});

Expand All @@ -270,7 +279,6 @@ describe('modular', function () {
const newApp = await initializeApp(platformAppConfig, name);

newApp.name.should.equal(name);
newApp.toString().should.equal(name);
newApp.options.apiKey.should.equal(platformAppConfig.apiKey);

await deleteApp(newApp);
Expand Down
18 changes: 12 additions & 6 deletions packages/app/e2e/asyncStorage.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('throws if asyncStorage is not an object', function () {
const { setReactNativeAsyncStorage } = modular;
try {
firebase.setReactNativeAsyncStorage(123);
setReactNativeAsyncStorage(123);
return Promise.reject(new Error('Did not throw an Error.'));
} catch (error) {
error.message.should.containEql("'asyncStorage' must be an object");
Expand All @@ -26,8 +27,9 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('throws if asyncStorage.setItem is not a function', function () {
const { setReactNativeAsyncStorage } = modular;
try {
firebase.setReactNativeAsyncStorage({ setItem: 123 });
setReactNativeAsyncStorage({ setItem: 123 });
return Promise.reject(new Error('Did not throw an Error.'));
} catch (error) {
error.message.should.containEql("'asyncStorage.setItem' must be a function");
Expand All @@ -36,8 +38,9 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('throws if asyncStorage.getItem is not a function', function () {
const { setReactNativeAsyncStorage } = modular;
try {
firebase.setReactNativeAsyncStorage({ setItem: sinon.spy(), getItem: 123 });
setReactNativeAsyncStorage({ setItem: sinon.spy(), getItem: 123 });
return Promise.reject(new Error('Did not throw an Error.'));
} catch (error) {
error.message.should.containEql("'asyncStorage.getItem' must be a function");
Expand All @@ -46,8 +49,9 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('throws if asyncStorage.removeItem is not a function', function () {
const { setReactNativeAsyncStorage } = modular;
try {
firebase.setReactNativeAsyncStorage({
setReactNativeAsyncStorage({
setItem: sinon.spy(),
getItem: sinon.spy(),
removeItem: 123,
Expand All @@ -60,13 +64,14 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('sets the async storage instance', async function () {
const { setReactNativeAsyncStorage } = modular;
isMemoryStorage().should.equal(true);

const setItemSpy = sinon.spy();
const getItemSpy = sinon.spy();
const removeItemSpy = sinon.spy();

firebase.setReactNativeAsyncStorage({
setReactNativeAsyncStorage({
setItem: setItemSpy,
getItem: getItemSpy,
removeItem: removeItemSpy,
Expand All @@ -84,10 +89,11 @@ describe('firebase.setReactNativeAsyncStorage()', function () {
});

it('works with @react-native-async-storage/async-storage', async function () {
const { setReactNativeAsyncStorage } = modular;
isMemoryStorage().should.equal(true);
const key = Date.now().toString();
const value = 'bar';
firebase.setReactNativeAsyncStorage(asyncStorage);
setReactNativeAsyncStorage(asyncStorage);
isMemoryStorage().should.equal(false);

// Through our internals,
Expand Down
37 changes: 21 additions & 16 deletions packages/app/e2e/config.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
describe('config', function () {
describe('meta', function () {
it('should read Info.plist/AndroidManifest.xml meta data', async function () {
const metaData = await NativeModules.RNFBAppModule.metaGetAll();
const { metaGetAll } = modular;
const metaData = await metaGetAll();
if (Platform.other) return;
metaData.rnfirebase_meta_testing_string.should.equal('abc');
metaData.rnfirebase_meta_testing_boolean_false.should.equal(false);
Expand All @@ -28,7 +29,8 @@ describe('config', function () {

describe('json', function () {
it('should read firebase.json data', async function () {
const jsonData = await NativeModules.RNFBAppModule.jsonGetAll();
const { jsonGetAll } = modular;
const jsonData = await jsonGetAll();
if (Platform.other) return;
jsonData.rnfirebase_json_testing_string.should.equal('abc');
jsonData.rnfirebase_json_testing_boolean_false.should.equal(false);
Expand All @@ -38,40 +40,43 @@ describe('config', function () {

describe('prefs', function () {
beforeEach(async function () {
await NativeModules.RNFBAppModule.preferencesClearAll();
const { preferencesClearAll } = modular;
await preferencesClearAll();
});

// NOTE: "preferencesClearAll" clears Firestore settings. Set DB as emulator again.
after(async function () {
const { connectFirestoreEmulator, getFirestore } = firestoreModular;
if (Platform.other) return;
await firebase
.firestore()
.settings({ host: 'localhost:8080', ssl: false, persistence: true });
connectFirestoreEmulator(getFirestore(), 'localhost', 8080);
});

it('should set bool values', async function () {
const prefsBefore = await NativeModules.RNFBAppModule.preferencesGetAll();
const { preferencesGetAll, preferencesSetBool } = modular;
const prefsBefore = await preferencesGetAll();
should.equal(prefsBefore.invertase_oss, undefined);
await NativeModules.RNFBAppModule.preferencesSetBool('invertase_oss', true);
const prefsAfter = await NativeModules.RNFBAppModule.preferencesGetAll();
await preferencesSetBool('invertase_oss', true);
const prefsAfter = await preferencesGetAll();
prefsAfter.invertase_oss.should.equal(true);
});

it('should set string values', async function () {
const prefsBefore = await NativeModules.RNFBAppModule.preferencesGetAll();
const { preferencesGetAll, preferencesSetString } = modular;
const prefsBefore = await preferencesGetAll();
should.equal(prefsBefore.invertase_oss, undefined);
await NativeModules.RNFBAppModule.preferencesSetString('invertase_oss', 'invertase.io');
const prefsAfter = await NativeModules.RNFBAppModule.preferencesGetAll();
await preferencesSetString('invertase_oss', 'invertase.io');
const prefsAfter = await preferencesGetAll();
prefsAfter.invertase_oss.should.equal('invertase.io');
});

it('should clear all values', async function () {
await NativeModules.RNFBAppModule.preferencesSetString('invertase_oss', 'invertase.io');
const prefsBefore = await NativeModules.RNFBAppModule.preferencesGetAll();
const { preferencesClearAll, preferencesGetAll, preferencesSetString } = modular;
await preferencesSetString('invertase_oss', 'invertase.io');
const prefsBefore = await preferencesGetAll();
prefsBefore.invertase_oss.should.equal('invertase.io');

await NativeModules.RNFBAppModule.preferencesClearAll();
const prefsAfter = await NativeModules.RNFBAppModule.preferencesGetAll();
await preferencesClearAll();
const prefsAfter = await preferencesGetAll();
should.equal(prefsAfter.invertase_oss, undefined);
});
});
Expand Down
46 changes: 28 additions & 18 deletions packages/app/e2e/utils.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,44 @@ describe('utils()', function () {
if (Platform.other) return; // Not supported on non-native platforms.

describe('namespace', function () {
beforeEach(async function beforeEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = true;
});

afterEach(async function afterEachTest() {
// @ts-ignore
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = false;
});

it('accessible from firebase.app()', function () {
const app = firebase.app();
should.exist(app.utils);
app.utils().app.should.equal(app);
});
});

describe('isRunningInTestLab', function () {
it('returns true or false', function () {
should.equal(firebase.utils().isRunningInTestLab, false);
describe('isRunningInTestLab', function () {
it('returns true or false', function () {
should.equal(firebase.utils().isRunningInTestLab, false);
});
});
});

describe('playServicesAvailability', function () {
it('returns isAvailable and Play Service status', async function () {
const playService = await firebase.utils().playServicesAvailability;
//iOS always returns { isAvailable: true, status: 0}
should(playService.isAvailable).equal(true);
should(playService.status).equal(0);
describe('playServicesAvailability', function () {
it('returns isAvailable and Play Service status', async function () {
const playService = await firebase.utils().playServicesAvailability;
//iOS always returns { isAvailable: true, status: 0}
should(playService.isAvailable).equal(true);
should(playService.status).equal(0);
});
});
});

describe('getPlayServicesStatus', function () {
it('returns isAvailable and Play Service status', async function () {
const status = await firebase.utils().getPlayServicesStatus();
//iOS always returns { isAvailable: true, status: 0}
should(status.isAvailable).equal(true);
should(status.status).equal(0);
describe('getPlayServicesStatus', function () {
it('returns isAvailable and Play Service status', async function () {
const status = await firebase.utils().getPlayServicesStatus();
//iOS always returns { isAvailable: true, status: 0}
should(status.isAvailable).equal(true);
should(status.status).equal(0);
});
});
});
});
2 changes: 1 addition & 1 deletion packages/app/lib/FirebaseApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default class FirebaseApp {
}

toString() {
warnIfNotModularCall(arguments);
warnIfNotModularCall(arguments, '.name property');
return this.name;
}
}
40 changes: 40 additions & 0 deletions packages/app/lib/modular/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,46 @@ export function getApp(name?: string): FirebaseApp;
*/
export function setLogLevel(logLevel: LogLevelString): void;

/**
* Gets react-native-firebase specific "meta" data from native Info.plist / AndroidManifest.xml
* @returns map of key / value pairs containing native meta data
*/
export function metaGetAll(): Promise<{ [keyof: string]: string | boolean }>;

/**
* Gets react-native-firebase specific "firebase.json" data
* @returns map of key / value pairs containing native firebase.json constants
*/
export function jsonGetAll(): Promise<{ [keyof: string]: string | boolean }>;

/**
* Clears react-native-firebase specific native preferences
* @returns Promise<void>
*/
export function preferencesClearAll(): Promise<void>;

/**
* Gets react-native-firebase specific native preferences
* @returns map of key / value pairs containing native preferences data
*/
export function preferencesGetAll(): Promise<{ [keyof: string]: string | boolean }>;

/**
* Sets react-native-firebase specific native boolean preference
* @param key the name of the native preference to set
* @param value the value of the native preference to set
* @returns Promise<void>
*/
export function preferencesSetBool(key: string, value: boolean): Promise<void>;

/**
* Sets react-native-firebase specific native string preference
* @param key the name of the native preference to set
* @param value the value of the native preference to set
* @returns Promise<void>
*/
export function preferencesSetString(key: string, value: string): Promise<void>;

/**
* The `AsyncStorage` implementation to use for persisting data on 'Other' platforms.
* If not specified, in memory persistence is used.
Expand Down
Loading
Loading